mirror of https://github.com/ARMmbed/mbed-os.git
Remove Nordic SoftDevice BLE driver
parent
897acb8f8e
commit
a85c157952
|
@ -1,344 +0,0 @@
|
||||||
# Change Log
|
|
||||||
|
|
||||||
## [v2.5.3](https://github.com/ARMmbed/ble-nrf51822/tree/v2.5.3) (2016-02-16)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.5.2...v2.5.3)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Fix for compilation errors with S110 softdevice in btle.cpp [\#109](https://github.com/ARMmbed/ble-nrf51822/pull/109) ([ddavidebor](https://github.com/ddavidebor))
|
|
||||||
|
|
||||||
## [v2.5.2](https://github.com/ARMmbed/ble-nrf51822/tree/v2.5.2) (2016-02-16)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.5.1...v2.5.2)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Sync develop against master [\#113](https://github.com/ARMmbed/ble-nrf51822/pull/113) ([pan-](https://github.com/pan-))
|
|
||||||
- Fix incorrect handles of characteristics descriptors. [\#112](https://github.com/ARMmbed/ble-nrf51822/pull/112) ([pan-](https://github.com/pan-))
|
|
||||||
|
|
||||||
## [v2.5.1](https://github.com/ARMmbed/ble-nrf51822/tree/v2.5.1) (2016-01-27)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.5.0...v2.5.1)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Remove Gap::state updates from this module [\#108](https://github.com/ARMmbed/ble-nrf51822/pull/108) ([andresag01](https://github.com/andresag01))
|
|
||||||
- merge version [\#106](https://github.com/ARMmbed/ble-nrf51822/pull/106) ([pan-](https://github.com/pan-))
|
|
||||||
|
|
||||||
## [v2.5.0](https://github.com/ARMmbed/ble-nrf51822/tree/v2.5.0) (2016-01-12)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.4.1...v2.5.0)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Fix access to enum member [\#105](https://github.com/ARMmbed/ble-nrf51822/pull/105) ([pan-](https://github.com/pan-))
|
|
||||||
- Hotfix dependency [\#104](https://github.com/ARMmbed/ble-nrf51822/pull/104) ([pan-](https://github.com/pan-))
|
|
||||||
- Finish implementation of getAddressesFromBondTable [\#103](https://github.com/ARMmbed/ble-nrf51822/pull/103) ([andresag01](https://github.com/andresag01))
|
|
||||||
|
|
||||||
## [v2.4.1](https://github.com/ARMmbed/ble-nrf51822/tree/v2.4.1) (2016-01-11)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.4.0...v2.4.1)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- merge branch develop \(v2.4.0\) [\#100](https://github.com/ARMmbed/ble-nrf51822/pull/100) ([pan-](https://github.com/pan-))
|
|
||||||
|
|
||||||
## [v2.4.0](https://github.com/ARMmbed/ble-nrf51822/tree/v2.4.0) (2016-01-10)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.3.1...v2.4.0)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Add implementation of experimental whitelisting API [\#99](https://github.com/ARMmbed/ble-nrf51822/pull/99) ([andresag01](https://github.com/andresag01))
|
|
||||||
|
|
||||||
## [v2.3.1](https://github.com/ARMmbed/ble-nrf51822/tree/v2.3.1) (2016-01-07)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.3.0...v2.3.1)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Update yotta module dependencies [\#98](https://github.com/ARMmbed/ble-nrf51822/pull/98) ([pan-](https://github.com/pan-))
|
|
||||||
|
|
||||||
## [v2.3.0](https://github.com/ARMmbed/ble-nrf51822/tree/v2.3.0) (2015-12-23)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.10...v2.3.0)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Implementation of Characteristic descriptor discovery [\#74](https://github.com/ARMmbed/ble-nrf51822/pull/74) ([pan-](https://github.com/pan-))
|
|
||||||
|
|
||||||
## [v2.2.10](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.10) (2015-12-23)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.9...v2.2.10)
|
|
||||||
|
|
||||||
**Fixed bugs:**
|
|
||||||
|
|
||||||
- nRF5xn::init don't verify if errors have occurred during btle\_init [\#59](https://github.com/ARMmbed/ble-nrf51822/issues/59)
|
|
||||||
|
|
||||||
**Closed issues:**
|
|
||||||
|
|
||||||
- A call to shutdown does not clear the state of some components of BLE API [\#85](https://github.com/ARMmbed/ble-nrf51822/issues/85)
|
|
||||||
- Memory allocation issue on the NRF51DK board. [\#76](https://github.com/ARMmbed/ble-nrf51822/issues/76)
|
|
||||||
- Terrible handling of initLen / minLen and variable length characteristics. [\#56](https://github.com/ARMmbed/ble-nrf51822/issues/56)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Fix shutdown of Gap instance to avoid NULL refs [\#96](https://github.com/ARMmbed/ble-nrf51822/pull/96) ([andresag01](https://github.com/andresag01))
|
|
||||||
- Add check for return code of ble\_init [\#95](https://github.com/ARMmbed/ble-nrf51822/pull/95) ([andresag01](https://github.com/andresag01))
|
|
||||||
|
|
||||||
## [v2.2.9](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.9) (2015-12-18)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.8...v2.2.9)
|
|
||||||
|
|
||||||
**Closed issues:**
|
|
||||||
|
|
||||||
- Cannot open source input file "system\_nrf51.h" [\#52](https://github.com/ARMmbed/ble-nrf51822/issues/52)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Remove occurrence of deprecated appearance enum [\#92](https://github.com/ARMmbed/ble-nrf51822/pull/92) ([andresag01](https://github.com/andresag01))
|
|
||||||
|
|
||||||
## [v2.2.8](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.8) (2015-12-16)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.7...v2.2.8)
|
|
||||||
|
|
||||||
## [v2.2.7](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.7) (2015-12-15)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.6...v2.2.7)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Replace deprecated inclusions of mbed.h [\#89](https://github.com/ARMmbed/ble-nrf51822/pull/89) ([andresag01](https://github.com/andresag01))
|
|
||||||
- Improve shutdown to clear BLE API and not just SD [\#87](https://github.com/ARMmbed/ble-nrf51822/pull/87) ([andresag01](https://github.com/andresag01))
|
|
||||||
|
|
||||||
## [v2.2.6](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.6) (2015-12-15)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.5...v2.2.6)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- follow the extraction of address related types from Gap.h into BLEProtocol.h [\#88](https://github.com/ARMmbed/ble-nrf51822/pull/88) ([rgrover](https://github.com/rgrover))
|
|
||||||
|
|
||||||
## [v2.2.5](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.5) (2015-12-11)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.3...v2.2.5)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Added SecurityManager::setLinkSecurity call for elevating security settings on a particular connection. [\#86](https://github.com/ARMmbed/ble-nrf51822/pull/86) ([marcuschangarm](https://github.com/marcuschangarm))
|
|
||||||
|
|
||||||
## [v2.2.3](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.3) (2015-12-10)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.2...v2.2.3)
|
|
||||||
|
|
||||||
## [v2.2.2](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.2) (2015-12-08)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.1...v2.2.2)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Add -Wno-unused-function to supress-warnings.cmake [\#83](https://github.com/ARMmbed/ble-nrf51822/pull/83) ([andresag01](https://github.com/andresag01))
|
|
||||||
|
|
||||||
## [v2.2.1](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.1) (2015-12-08)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.2.0...v2.2.1)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- WIP: UUID endian change [\#82](https://github.com/ARMmbed/ble-nrf51822/pull/82) ([marcuschangarm](https://github.com/marcuschangarm))
|
|
||||||
|
|
||||||
## [v2.2.0](https://github.com/ARMmbed/ble-nrf51822/tree/v2.2.0) (2015-12-02)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.1.4...v2.2.0)
|
|
||||||
|
|
||||||
## [v2.1.4](https://github.com/ARMmbed/ble-nrf51822/tree/v2.1.4) (2015-12-02)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.1.3...v2.1.4)
|
|
||||||
|
|
||||||
## [v2.1.3](https://github.com/ARMmbed/ble-nrf51822/tree/v2.1.3) (2015-12-02)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.1.2...v2.1.3)
|
|
||||||
|
|
||||||
## [v2.1.2](https://github.com/ARMmbed/ble-nrf51822/tree/v2.1.2) (2015-12-02)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.1.1...v2.1.2)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Allow GattAttributes to have variable length [\#81](https://github.com/ARMmbed/ble-nrf51822/pull/81) ([andresag01](https://github.com/andresag01))
|
|
||||||
|
|
||||||
## [v2.1.1](https://github.com/ARMmbed/ble-nrf51822/tree/v2.1.1) (2015-12-02)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.1.0...v2.1.1)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Fixed endianness bug in nRF5xServiceDiscovery::processDiscoverUUIDResponse so it is consistent with BLE API. [\#80](https://github.com/ARMmbed/ble-nrf51822/pull/80) ([marcuschangarm](https://github.com/marcuschangarm))
|
|
||||||
- Fixed bug in nRF5xGap.setAddress where random adresses where not set properly. [\#79](https://github.com/ARMmbed/ble-nrf51822/pull/79) ([marcuschangarm](https://github.com/marcuschangarm))
|
|
||||||
- Separate concept of minlen and len for BLE chars [\#78](https://github.com/ARMmbed/ble-nrf51822/pull/78) ([andresag01](https://github.com/andresag01))
|
|
||||||
- Split nordic sdk into its own module [\#75](https://github.com/ARMmbed/ble-nrf51822/pull/75) ([LiyouZhou](https://github.com/LiyouZhou))
|
|
||||||
|
|
||||||
## [v2.1.0](https://github.com/ARMmbed/ble-nrf51822/tree/v2.1.0) (2015-11-27)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.8...v2.1.0)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Update to sdk 8.1 [\#77](https://github.com/ARMmbed/ble-nrf51822/pull/77) ([LiyouZhou](https://github.com/LiyouZhou))
|
|
||||||
|
|
||||||
## [v2.0.8](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.8) (2015-11-26)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.7...v2.0.8)
|
|
||||||
|
|
||||||
## [v2.0.7](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.7) (2015-11-26)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.6...v2.0.7)
|
|
||||||
|
|
||||||
**Closed issues:**
|
|
||||||
|
|
||||||
- test2000 [\#72](https://github.com/ARMmbed/ble-nrf51822/issues/72)
|
|
||||||
- test1000000 [\#71](https://github.com/ARMmbed/ble-nrf51822/issues/71)
|
|
||||||
- test4 [\#70](https://github.com/ARMmbed/ble-nrf51822/issues/70)
|
|
||||||
- test3 [\#69](https://github.com/ARMmbed/ble-nrf51822/issues/69)
|
|
||||||
- test2 [\#68](https://github.com/ARMmbed/ble-nrf51822/issues/68)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- use Extern c around \#include to use nordic sdk headers implemented in C [\#73](https://github.com/ARMmbed/ble-nrf51822/pull/73) ([LiyouZhou](https://github.com/LiyouZhou))
|
|
||||||
|
|
||||||
## [v2.0.6](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.6) (2015-11-17)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.5...v2.0.6)
|
|
||||||
|
|
||||||
**Closed issues:**
|
|
||||||
|
|
||||||
- test [\#66](https://github.com/ARMmbed/ble-nrf51822/issues/66)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- add Nordic's license agreement. [\#67](https://github.com/ARMmbed/ble-nrf51822/pull/67) ([rgrover](https://github.com/rgrover))
|
|
||||||
|
|
||||||
## [v2.0.5](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.5) (2015-11-16)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.4...v2.0.5)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Post radio notification callback through minar [\#65](https://github.com/ARMmbed/ble-nrf51822/pull/65) ([andresag01](https://github.com/andresag01))
|
|
||||||
|
|
||||||
## [v2.0.4](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.4) (2015-11-13)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.3...v2.0.4)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Fix assembly sequence to start bootloader in GCC [\#64](https://github.com/ARMmbed/ble-nrf51822/pull/64) ([andresag01](https://github.com/andresag01))
|
|
||||||
|
|
||||||
## [v2.0.3](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.3) (2015-11-09)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.2...v2.0.3)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Added watchdog header file from Nordic SDK 8.1 [\#62](https://github.com/ARMmbed/ble-nrf51822/pull/62) ([marcuschangarm](https://github.com/marcuschangarm))
|
|
||||||
|
|
||||||
## [v2.0.2](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.2) (2015-11-03)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/mbedos-release-15-11...v2.0.2)
|
|
||||||
|
|
||||||
## [mbedos-release-15-11](https://github.com/ARMmbed/ble-nrf51822/tree/mbedos-release-15-11) (2015-11-03)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.1...mbedos-release-15-11)
|
|
||||||
|
|
||||||
## [v2.0.1](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.1) (2015-11-02)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v2.0.0...v2.0.1)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Ensure that the initialization flags is set to false if the BLE stack is shutdown properly. [\#58](https://github.com/ARMmbed/ble-nrf51822/pull/58) ([pan-](https://github.com/pan-))
|
|
||||||
|
|
||||||
## [v2.0.0](https://github.com/ARMmbed/ble-nrf51822/tree/v2.0.0) (2015-11-02)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v1.1.0...v2.0.0)
|
|
||||||
|
|
||||||
**Closed issues:**
|
|
||||||
|
|
||||||
- Nordic SDK and SoftDevice [\#57](https://github.com/ARMmbed/ble-nrf51822/issues/57)
|
|
||||||
- shouldn't eab6631cb be merged into master? [\#54](https://github.com/ARMmbed/ble-nrf51822/issues/54)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Introduced changes for memory savings [\#55](https://github.com/ARMmbed/ble-nrf51822/pull/55) ([andresag01](https://github.com/andresag01))
|
|
||||||
|
|
||||||
## [v1.1.0](https://github.com/ARMmbed/ble-nrf51822/tree/v1.1.0) (2015-10-28)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v1.0.0...v1.1.0)
|
|
||||||
|
|
||||||
**Closed issues:**
|
|
||||||
|
|
||||||
- target dependencies in module.json [\#50](https://github.com/ARMmbed/ble-nrf51822/issues/50)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- When connecting, if no scanning parameters are passed, use values from Gap parent. [\#53](https://github.com/ARMmbed/ble-nrf51822/pull/53) ([marcuschangarm](https://github.com/marcuschangarm))
|
|
||||||
|
|
||||||
## [v1.0.0](https://github.com/ARMmbed/ble-nrf51822/tree/v1.0.0) (2015-10-19)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/mbedos-techcon-oob2...v1.0.0)
|
|
||||||
|
|
||||||
## [mbedos-techcon-oob2](https://github.com/ARMmbed/ble-nrf51822/tree/mbedos-techcon-oob2) (2015-10-19)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v0.4.8...mbedos-techcon-oob2)
|
|
||||||
|
|
||||||
**Closed issues:**
|
|
||||||
|
|
||||||
- rename the bootloader files with \_fota in the name? [\#51](https://github.com/ARMmbed/ble-nrf51822/issues/51)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Update S110 detection macros, again [\#49](https://github.com/ARMmbed/ble-nrf51822/pull/49) ([jpbrucker](https://github.com/jpbrucker))
|
|
||||||
- Error check number of characteristics [\#48](https://github.com/ARMmbed/ble-nrf51822/pull/48) ([Timmmm](https://github.com/Timmmm))
|
|
||||||
|
|
||||||
## [v0.4.8](https://github.com/ARMmbed/ble-nrf51822/tree/v0.4.8) (2015-09-25)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v0.4.7...v0.4.8)
|
|
||||||
|
|
||||||
**Closed issues:**
|
|
||||||
|
|
||||||
- Error real cause loss in nRF5xGattServer.cpp [\#44](https://github.com/ARMmbed/ble-nrf51822/issues/44)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- rgrover patch fixed [\#47](https://github.com/ARMmbed/ble-nrf51822/pull/47) ([fabiencomte](https://github.com/fabiencomte))
|
|
||||||
- Update S110 detection macros [\#43](https://github.com/ARMmbed/ble-nrf51822/pull/43) ([jpbrucker](https://github.com/jpbrucker))
|
|
||||||
- remove some unnecessary include paths [\#42](https://github.com/ARMmbed/ble-nrf51822/pull/42) ([autopulated](https://github.com/autopulated))
|
|
||||||
- Add FOTA bootloader image [\#41](https://github.com/ARMmbed/ble-nrf51822/pull/41) ([jpbrucker](https://github.com/jpbrucker))
|
|
||||||
|
|
||||||
## [v0.4.7](https://github.com/ARMmbed/ble-nrf51822/tree/v0.4.7) (2015-08-13)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v0.4.6...v0.4.7)
|
|
||||||
|
|
||||||
## [v0.4.6](https://github.com/ARMmbed/ble-nrf51822/tree/v0.4.6) (2015-08-11)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v0.4.5...v0.4.6)
|
|
||||||
|
|
||||||
**Closed issues:**
|
|
||||||
|
|
||||||
- remove duplication of global static variable BLE\_EVT\_BUFFER [\#39](https://github.com/ARMmbed/ble-nrf51822/issues/39)
|
|
||||||
- clearScanResponse\(\) [\#30](https://github.com/ARMmbed/ble-nrf51822/issues/30)
|
|
||||||
- Debug builds fail due to missing bsp.h [\#11](https://github.com/ARMmbed/ble-nrf51822/issues/11)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Disable GattClient features when using S110 SoftDevice [\#38](https://github.com/ARMmbed/ble-nrf51822/pull/38) ([jpbrucker](https://github.com/jpbrucker))
|
|
||||||
|
|
||||||
## [v0.4.5](https://github.com/ARMmbed/ble-nrf51822/tree/v0.4.5) (2015-08-10)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v0.4.4...v0.4.5)
|
|
||||||
|
|
||||||
## [v0.4.4](https://github.com/ARMmbed/ble-nrf51822/tree/v0.4.4) (2015-08-07)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/ble-nrf51822/compare/v0.4.3...v0.4.4)
|
|
||||||
|
|
||||||
**Closed issues:**
|
|
||||||
|
|
||||||
- nrf51822 hangs after calling sd\_flash\_page\_erase\(\) [\#35](https://github.com/ARMmbed/ble-nrf51822/issues/35)
|
|
||||||
- nRF5xn::getVersion return \(Unknown\) with version 8 soft device [\#29](https://github.com/ARMmbed/ble-nrf51822/issues/29)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Changed Gap:: to GapAdvertisingParams:: because of change in BLE [\#34](https://github.com/ARMmbed/ble-nrf51822/pull/34) ([jslater8](https://github.com/jslater8))
|
|
||||||
- Select the clock source dynamically on SoftDevice initialisation [\#32](https://github.com/ARMmbed/ble-nrf51822/pull/32) ([jpbrucker](https://github.com/jpbrucker))
|
|
||||||
- Add S110 SoftDevice compatibility [\#28](https://github.com/ARMmbed/ble-nrf51822/pull/28) ([jpbrucker](https://github.com/jpbrucker))
|
|
||||||
|
|
||||||
## [v0.4.3](https://github.com/ARMmbed/ble-nrf51822/tree/v0.4.3) (2015-07-22)
|
|
||||||
**Closed issues:**
|
|
||||||
|
|
||||||
- Target polling failed [\#24](https://github.com/ARMmbed/ble-nrf51822/issues/24)
|
|
||||||
- support handling of HVX Events \(notifications and indications\). [\#22](https://github.com/ARMmbed/ble-nrf51822/issues/22)
|
|
||||||
- provide an implementation for GattServer::areUpdatesEnabled\(\) [\#21](https://github.com/ARMmbed/ble-nrf51822/issues/21)
|
|
||||||
- getValueHandle\(\) returns characteristicIndex instead of attribute-handle [\#20](https://github.com/ARMmbed/ble-nrf51822/issues/20)
|
|
||||||
- Clash With Definition And Enum Naming [\#16](https://github.com/ARMmbed/ble-nrf51822/issues/16)
|
|
||||||
- Errors in GCC build [\#14](https://github.com/ARMmbed/ble-nrf51822/issues/14)
|
|
||||||
- bring s110 support back [\#10](https://github.com/ARMmbed/ble-nrf51822/issues/10)
|
|
||||||
- Allow adding a User Description descriptor to a GattCharacteristic. [\#9](https://github.com/ARMmbed/ble-nrf51822/issues/9)
|
|
||||||
- device\_manager\_peripheral.c includes app\_trace.h [\#7](https://github.com/ARMmbed/ble-nrf51822/issues/7)
|
|
||||||
- linking esb\_gcc.a \(nrf51822 enhanced shock burst\) with mbed [\#5](https://github.com/ARMmbed/ble-nrf51822/issues/5)
|
|
||||||
- The app\_timer usage may conflict [\#2](https://github.com/ARMmbed/ble-nrf51822/issues/2)
|
|
||||||
- Nordic License [\#1](https://github.com/ARMmbed/ble-nrf51822/issues/1)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Develop [\#25](https://github.com/ARMmbed/ble-nrf51822/pull/25) ([zoujixing](https://github.com/zoujixing))
|
|
||||||
- Remove unnecessary 'compiler\_abstraction.h' to get rid of duplicate '… [\#23](https://github.com/ARMmbed/ble-nrf51822/pull/23) ([adfernandes](https://github.com/adfernandes))
|
|
||||||
- restructure for minimal yotta compatibility [\#15](https://github.com/ARMmbed/ble-nrf51822/pull/15) ([autopulated](https://github.com/autopulated))
|
|
||||||
- Fix various GCC compilation issues. [\#12](https://github.com/ARMmbed/ble-nrf51822/pull/12) ([adfernandes](https://github.com/adfernandes))
|
|
||||||
- Fix for GCC lost in SDK v8.0 update [\#8](https://github.com/ARMmbed/ble-nrf51822/pull/8) ([rosterloh](https://github.com/rosterloh))
|
|
||||||
- new target DELTA\_DFCM\_NNN40 with nrf51822 chip, config internal RC crystal. [\#6](https://github.com/ARMmbed/ble-nrf51822/pull/6) ([Marcomissyou](https://github.com/Marcomissyou))
|
|
||||||
- Updated return value for nRF51GattServer::updateValue. Will now report w... [\#4](https://github.com/ARMmbed/ble-nrf51822/pull/4) ([marcuschangarm](https://github.com/marcuschangarm))
|
|
||||||
- Added optional data and length fields to the return struct for authorize... [\#3](https://github.com/ARMmbed/ble-nrf51822/pull/3) ([marcuschangarm](https://github.com/marcuschangarm))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
|
|
@ -1,6 +0,0 @@
|
||||||
This module contains softdevice which comes with The Nordic Softdevice License Agreement,
|
|
||||||
a BSD-like licence for binary distributions, offered by Nordic for use in mbed. Some
|
|
||||||
other files come from the mbed SDK, and are licensed under Apache-2.0. Unless
|
|
||||||
specifically indicated otherwise in a file, files are licensed under the
|
|
||||||
Apache 2.0 license, as can be found in: apache-2.0.txt. The Nordic Semiconductor Softdevice
|
|
||||||
License Agreement can be found in softdevice_nrf51822_licence_agreement.txt.
|
|
|
@ -1,13 +0,0 @@
|
||||||
Copyright (c) 2015 ARM Limited
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
|
@ -1,463 +0,0 @@
|
||||||
:020000040003F7
|
|
||||||
:20C00000983C002005DD030017DD030019DD03000000000000000000000000000000000057
|
|
||||||
:20C0200000000000000000000000000069C1030000000000000000001DDD03001FDD0300D7
|
|
||||||
:20C0400021DD030021DD030021DD030021DD030021DD03000000000021DD030021DD0300D9
|
|
||||||
:20C0600021DD030021DD030021DD030021DD030021DD030021DD030021DD030021DD0300B8
|
|
||||||
:20C0800021DD030057D8030021DD030021DD03006DD8030021DD03004DF4030021DD0300DD
|
|
||||||
:20C0A00021DD030021DD03000000000000000000000000000000000000000000000000007E
|
|
||||||
:20C0C00000F002F800F040F80CA030C8083824182D18A246671EAB4654465D46AC4201D18E
|
|
||||||
:20C0E00000F032F87E460F3E0FCCB6460126334200D0FB1AA246AB463343184710370000C8
|
|
||||||
:20C1000030370000103A02D378C878C1FAD8520701D330C830C101D504680C6070470000D3
|
|
||||||
:20C120000023002400250026103A01D378C1FBD8520700D330C100D50B6070471FB5C04655
|
|
||||||
:20C14000C0461FBD10B510BD03F0E3FA1146FFF7F5FF00F0D3F803F0FBFA03B4FFF7F2FF19
|
|
||||||
:20C1600003BC03F0FFFA00000648704502D1EFF3098101E0EFF30881886902380078024A97
|
|
||||||
:20C1800010470000FDFFFFFF39D50300401E00BF00BF00BF00BF00BF00BF00BF00BF00BF28
|
|
||||||
:20C1A00000BF00BF00BFF1D170470000401E00BF00BF00BF00BF00BF00BF00BF00BF00BFB4
|
|
||||||
:20C1C00000BF00BF00BFF1D170470000401E00BF00BF00BF00BF00BF00BF00BF00BF00BF94
|
|
||||||
:20C1E00000BF00BF00BFF1D170470000056885F3088846680A4AEFF305839A42304602D183
|
|
||||||
:20C20000084CA6463047074C064D0646064FF0B4034C034D024E024FF0B404480047000005
|
|
||||||
:20C2200000000000FFFFFFFF00000021F9FFFFFF70B505460C46164602E00FCC0FC5103EEE
|
|
||||||
:20C24000102EFAD2082E02D303CC03C5083E042E07D301CC01C5361F03E021782970641C63
|
|
||||||
:20C260006D1C761EF9D270BD0A4610B50146664803F064F810BD10B502F078FC10BD10B5C6
|
|
||||||
:20C28000624C86B01ECC03946C460EC4002807D0684618DF002803D00022114603F04EF864
|
|
||||||
:20C2A0000F20800313DF002803D00022114603F045F8574B48225749092003F0A3F80028AB
|
|
||||||
:20C2C00003D00022114603F039F800200490059001206946087404A860DF002803D0002251
|
|
||||||
:20C2E000114603F02BF84C4803F0A8F8002803D00022114603F022F806B010BD08B547485A
|
|
||||||
:20C30000C169B12943D0002445480F2140698903884204D000221146104603F00FF8012068
|
|
||||||
:20C320000007006901218902884204D000221146104603F003F83B4800903B4B05220321A1
|
|
||||||
:20C34000002001F0BAFA002803D00022114602F0F5FF00F067FC00F0AAFC012500281AD09D
|
|
||||||
:20C3600000F0B4FC002803D00022114602F0E6FF20466840FFF783FF00F038F800F0CCFC74
|
|
||||||
:20C3800000280ED00022114602F0D8FF09E001240021C161B8E720466840FFF770FF00F002
|
|
||||||
:20C3A00025F803252D03002C04D1A86800F090FB002807D100F047FC002803D000221146D5
|
|
||||||
:20C3C00002F0BCFFA86800F083FB002806D000F06EFC002802D1A86800F041FCBFF34F8F12
|
|
||||||
:20C3E00013491248C860BFF34F8FFEE7094A10B548321421082002F00BFF002803D00022E2
|
|
||||||
:20C40000114602F09BFF10BDEFBEADDE8CF703006BF30300342B002077C20300000500404D
|
|
||||||
:20C4200000100010EFDC0300F42800200400FA0500ED00E070B5FC4C1E46A06815460229A3
|
|
||||||
:20C4400002D0042916D108E0052813D1A369002B10D03246294604200BE002280AD1F348B0
|
|
||||||
:20C46000406880470320A060A369002B02D0324629469847280003D00022114602F05EFF98
|
|
||||||
:20C4800070BD4CB5E84E0120307005200195009400F058FB4CBD10B5E34C2078002801D057
|
|
||||||
:20C4A000082010BD206901F0F4FA002803D00022114602F043FF0F2100228904206901F01E
|
|
||||||
:20C4C000ABFA040003D00022114602F037FF204610BDD54910B5D448243141610221816012
|
|
||||||
:20C4E000C168243002F059FD002803D00022114602F024FF10BDCC4910B5CB481C31416145
|
|
||||||
:20C50000022181600320000380680F218903081A4108C5481C3002F040FD002803D000223D
|
|
||||||
:20C52000114602F00BFF10BD704700B589B01822BF4902A8FFF77CFE06980799009001917A
|
|
||||||
:20C5400002A80FC800F0FEFA09B000BD00B5B64987B049886A461181032109038968069146
|
|
||||||
:20C56000B249012050394A6803928A680492C9680591069A0091019202A90EC900F0E2FA6E
|
|
||||||
:20C58000002007B000BD30B5A84CA748503C89B02430E16802F001FD002803D00022114679
|
|
||||||
:20C5A00002F0CCFEA048E2681C3041680023083002F0C3FC050012D1182102A802F0E6FFEA
|
|
||||||
:20C5C00000209949029049886A469181E1680691079A0091019203A90EC900F0B3FA284601
|
|
||||||
:20C5E00009B030BD00B5904987B049886A4611818E49032050394A6803928A680492C9683A
|
|
||||||
:20C600000591069A0091019202A90EC900F09AFA0020B6E73EB5864A6B46183207CA07C3A4
|
|
||||||
:20C62000814D00246C7029466C802431684602F068FC002801D0AC603EBD03207A4900038F
|
|
||||||
:20C6400080682431486024390A46526ACA610F218903091A490840187349764A1C31486068
|
|
||||||
:20C6600071480021103001F07BF9002803D00022114602F063FE0F2100228904286901F013
|
|
||||||
:20C68000CBF9002803D00022114602F057FE01206C60A86000203EBD63498861704770B59A
|
|
||||||
:20C6A000426862481468536891685038D26804604360C26081600078440701D5840705D130
|
|
||||||
:20C6C0009C0703D18C0701D1940701D0062070BD5B189A18544D0F239B02EA60994213D81A
|
|
||||||
:20C6E0005549564B514CC60709D08868181A90420AD3534820605348606053480FE08968F6
|
|
||||||
:20C70000591A4908914201D20C2070BD4F4921604F496160800701D54E4800E04E48A0607B
|
|
||||||
:20C72000A868012802D00826304670BDFFF7B3FE0600FAD12168E8688847F5E770B50500F7
|
|
||||||
:20C7400004D0287A800703D0102070BD0E2070BD354CA068032805D0042801D0052803D0CB
|
|
||||||
:20C76000082070BD0520A0606868E168860060688019884204D90020C04360600C2070BD5C
|
|
||||||
:20C78000FFF789FE0028FAD1A96832466368606902F0D3FB0028F2D1616889196160E268EB
|
|
||||||
:20C7A0009142ECD0092070BD10B51F4C08206168002900D010BDA1680429FBD11B4861786F
|
|
||||||
:20C7C000403802F021FC002802D00021617010BD0521A16010BDF8B5134C0746A068032899
|
|
||||||
:20C7E00004D0042804D008252846F8BD0420A0606068002801D00820F8BDFFF74CFE05000E
|
|
||||||
:20C80000FAD17868860060788119402901D90920F8BD064AB968403A1018324602F057FE82
|
|
||||||
:20C82000607880196070DFE7002800201C2D00209CF7030083C403000030000000C003006D
|
|
||||||
:20C84000D3C403002BC503004DC50300F7C4030029C50300E5C5030087C5030010B5894CF1
|
|
||||||
:20C86000A068052813D1E168606888420FD10620A060FFF710FE002808D16069E1684068FF
|
|
||||||
:20C8800002F0FCFB002801D10721A16010BD082010BD10B57B488168072901D0082010BD63
|
|
||||||
:20C8A000006901F0F6F8002803D00022114602F045FD75488068804710BD1CB506200195C2
|
|
||||||
:20C8C000009400F03FF91CBDF8B51C4617460D46064600F0C1F8002817D001200003854215
|
|
||||||
:20C8E00007D92346291B301B1A46FFF7EDFF00280BD13A462946304600F0B9F8002804D117
|
|
||||||
:20C900003A462946304600F0A7F8F8BDF0B589B0684600F015FA049800282AD001210903F7
|
|
||||||
:20C92000079A4018904226D9501A45081046049A0C468718024668001618001908900320DF
|
|
||||||
:20C9400000038068049988420DD261190846042200F08DF800280CD121460422084600F073
|
|
||||||
:20C9600086F8002805D1BA1B2B4630460899FFF7ABFF09B0F0BD049A079800F078F8F8E75C
|
|
||||||
:20C9800000B58DB004A800F0DBF9099800280DD0089800280CD008990B984018019000219D
|
|
||||||
:20C9A0000998009180080290684618DF0DB000BD0320000380680F218903091A4908ECE7FB
|
|
||||||
:20C9C00000B58DB004A800F0BBF909980028EDD00F210898890300280CD0089A0B98019158
|
|
||||||
:20C9E0008018029003220998009280080390684618DFDBE70320000380680A1A5208EEE7D2
|
|
||||||
:20CA000030B591B0684600F09BF90498002814D001210903079A4018904214D9501A43087B
|
|
||||||
:20CA20001046049A5C0082180019611803242403A468049DAC4202D20E2011B030BD121AB5
|
|
||||||
:20CA4000FFF742FFF9E703200CAB07C3049880080F900CA818DFF0E71FB5032301909008B3
|
|
||||||
:20CA6000039000930291684618DF04B010BD1FB5012301909008039000930291684618DF58
|
|
||||||
:20CA8000F3E70000002800201C2D002010B5BB480368012B02D1022900D10160100003D099
|
|
||||||
:20CAA0000022114602F04AFC10BD10B5B34C48DF002803D00022114602F040FC02F0FCFB82
|
|
||||||
:20CAC0002068022803D0032801D00428EFD110BD38B50068401C19D00024684600F058F96F
|
|
||||||
:20CAE00000980168012910D1818800290AD0C168032000038068002202F0CEFA0099898861
|
|
||||||
:20CB0000814201D1012400E00024204638BD10B504469A482021001D02F0B9F9002803D00E
|
|
||||||
:20CB20000022114602F00AFC9448002320222146001D02F01BF9002803D00022114602F053
|
|
||||||
:20CB4000FDFB10BD0FB4F8B5684600F021F96846818B069D0122894CFF238948002D13D090
|
|
||||||
:20CB6000012D17D0032D2BD00021022D37D02A46052D46D0042D4ED0062A01D10420206071
|
|
||||||
:20CB8000F8BC08BC04B0184781800A9983600260C16010E08180099D089949190A9D49195D
|
|
||||||
:20CBA000C160A52183600160089901610999856141610B99C16122607148FFF7A8FFDFE7B9
|
|
||||||
:20CBC00000990B6803608B888380C968C160AA21816008990161099941610A990BE0009D60
|
|
||||||
:20CBE0002E68A52E09D00660AE888680ED68C5600161836041618161DDE781800360C160C5
|
|
||||||
:20CC0000F6E700F085F9002803D00022114602F095FB0320B3E781800360C1600099896807
|
|
||||||
:20CC20008160C9E70EB557480090202001900120029002F001F8002804D150496846091D98
|
|
||||||
:20CC400002F023F80EBD10B5FFF7E4FC002805D100F02FFB0446FFF728FF204610BD70B58A
|
|
||||||
:20CC600011DF002803D00022114602F067FB464900200B68444C012180340A4682401A4206
|
|
||||||
:20CC800004D0C506ED0E0A46AA402260401C2028F3D303242403A06813DF002803D000226F
|
|
||||||
:20CCA000114602F04BFBA06802F0F2F970BD08B5684600F06DF800980168A52904D0806888
|
|
||||||
:20CCC000AA2801D0002008BD012008BD10B5FFF797FE002803D1FFF773FE00281BD064209C
|
|
||||||
:20CCE00001F0F2FDFFF712FE002803D00022114602F024FBFFF784FE002803D000221146DD
|
|
||||||
:20CD000002F01CFBFFF73CFE040003D00022114602F014FB204610BD00B589B018221B49CA
|
|
||||||
:20CD200002A8FFF785FA069807990090019102A80FC8FFF707FFFFF7B8FE002009B000BDB5
|
|
||||||
:20CD400010B50E4988B0044600232022091D684602F04FF80098206068468088A08003983A
|
|
||||||
:20CD6000E0600298A06004982061059860610698A0610798E06108B010BD00002C280020E6
|
|
||||||
:20CD8000282D00208DCA030000E100E0C0F70300014901607047000000FC030008280CD0DC
|
|
||||||
:20CDA00004DC002807D006280FD108E00B280AD00C280AD105E001207047022070470320C9
|
|
||||||
:20CDC000704704207047042901D0062070470520704770B515460A46032823D0042820D1FF
|
|
||||||
:20CDE000FE4C002906D0E088FD49884219D0132176DF10E0284602F0A3F9002803D00022F7
|
|
||||||
:20CE0000114602F09BFAE069A8420AD101220321F44801F003F8002803D00022114602F051
|
|
||||||
:20CE20008DFA70BD01211046FFF7B8FF02460121EEE7F0B5054608790E4685B081070CD07C
|
|
||||||
:20CE400003221146284600F0E9FF002803D00022114602F073FA05B0F0BDE04900901831D9
|
|
||||||
:20CE600002F047F9010011D1DC4CB168009AA06902F02DFB009802F097F9010006D1204647
|
|
||||||
:20CE80006946183002F09CF9010003D0284600F0AFFAE0E704200190009880080290A06902
|
|
||||||
:20CEA000039001A8FFF74AFC07000BD0092F10D0A06902F045F9010002D0284600F098FA04
|
|
||||||
:20CEC0003946E3E73079616940186061A069E061C1E7307961694118616160780028BAD073
|
|
||||||
:20CEE0006089401E0004000C6081B4D1284601F0E9F8002803D00022114602F01FFA20890D
|
|
||||||
:20CF00006081A8E710B50022114602F017FA10BD10B5B24C01202070E088B149884208D01B
|
|
||||||
:20CF2000132176DF002810D00022114602F006FA0BE0A078002808D074DF002803D0002282
|
|
||||||
:20CF4000114602F0FBF90020A07001F034FC002803D00022114602F0F1F9002010BD70B5E1
|
|
||||||
:20CF60000D68044601209D4A2B0002F002FC0A2B3043061320575C466012FFF76FFC0421FD
|
|
||||||
:20CF8000FFF70CFF024604212EE00022114602F0D5F970BDFFF7BCFF002803D0002211468A
|
|
||||||
:20CFA00002F0CCF9FFF775FC002808D170BDFFF7AFFF002803D00022114602F0BFF9FFF76D
|
|
||||||
:20CFC0007CFC70BD106188680078107170BD02201061886800780128F8D1FFF7E5FB02213F
|
|
||||||
:20CFE000FFF7DCFE02460221204600F017FF0028CBD170BD0320106170BD12692046012ACC
|
|
||||||
:20D0000006D0022A07D0032AF6D1FFF712FF70BD00F001FA70BD00F03BFA70BD50708888D5
|
|
||||||
:20D020001081508170BD00205070108170BD2046516901F010F8DAE710B5044669488EB0EB
|
|
||||||
:20D0400081796846817068490180342101A802F09DFA022001900021684641728472012131
|
|
||||||
:20D0600001820590002101A801F03FFA002803D00022114602F062F90EB010BDF0B5574C10
|
|
||||||
:20D080008BB0A07800283AD156481821183802F07DFA2046534CC078183C00250126002875
|
|
||||||
:20D0A00037D02746483700950195029510226946F81D039502F0DEF9002822D0F81D08909D
|
|
||||||
:20D0C00009976846067509A804906846067708A806900420FFF7B0FF25700220207204A813
|
|
||||||
:20D0E000E060282020823F486582183873DF002803D00022114602F021F9384886700BB045
|
|
||||||
:20D10000F0BD0520FFF798FF2670676025722582E9E70620FFF790FF257065602572E0E7E2
|
|
||||||
:20D1200070B52E4C01880022E588A6B017290AD01EDC11293FD008DC022977D0102902D123
|
|
||||||
:20D140008088E080A27026B070BD264C303426461836132951D01429F5D1C289638D002106
|
|
||||||
:20D160009A4200D1314600238088E21D82DF1BE0512970D00EDC18296CD01929E3D18079F5
|
|
||||||
:20D180000028E0D1A270E068401EE0604FD0FFF775FFD8E7522976D05529D4D18079002871
|
|
||||||
:20D1A000D1D11321284676DF0028CCD00022114602F0C4F8C7E78020694688803220E06054
|
|
||||||
:20D1C000012301AA06A92846AADF002803D00022114602F0B3F82078002807E038280020A2
|
|
||||||
:20D1E000FFFF0000602D00203015000001D1FFF745FF0020C043E080A5E70722C14910A839
|
|
||||||
:20D2000002F065F91022E11D0CA802F060F91C22314612A802F05BF90CA80A9012A8099039
|
|
||||||
:20D2200006ABB94A852128467FDFBDE70DE01822B64906A8FEF7FCFF0A980B9900900191F8
|
|
||||||
:20D2400006A80FC8FFF77EFC7DE70021284667DFAAE700E017E0817900299AD0807A042885
|
|
||||||
:20D2600003D0062801D0052893D1022909D0012069460872FF208330888102A92846A8DF82
|
|
||||||
:20D2800092E70220F4E700F08DF88DE710B5044601F0C2FA9B482146303800F09AFE2046D3
|
|
||||||
:20D2A000FFF73EFF10BD10B50022114602F046F810BD30B5944D87B00024203D2C7094483D
|
|
||||||
:20D2C0002C6102F0B3F800286AD19248FFF7E4F901F000FF002863D18A4800F059F900288C
|
|
||||||
:20D2E00001D10120E87011206946087207228AA102A87CDF002803D00022114602F01EF8B4
|
|
||||||
:20D3000000940C2168460194018018214180FF2184809131C1807ADF002803D0002211469A
|
|
||||||
:20D3200002F00CF804206946009408807C4801907C4802907348303800F00BFE002803D046
|
|
||||||
:20D340000022114601F0FAFF1C21684602F01EF9754801900120800302900094032168468C
|
|
||||||
:20D360000173C4810474714806900594684601F0FEF9002803D00022114601F0DFFF624910
|
|
||||||
:20D38000E12208784008400010400C30DF22104008700720487010208870FFF76FFE0020A3
|
|
||||||
:20D3A00007B030BD70B5584C614D203CE088A84201D1082070BDE178002914D05149012359
|
|
||||||
:20D3C00008223431A9DF0028F4D12A460C21E088A7DF5849884204D0082802D0891C88420E
|
|
||||||
:20D3E000E8D1002070BD00231A461946A9DF70BD10B50A46044603211046FFF7CFFC0246AE
|
|
||||||
:20D400000321204600F00AFD002803D00022114601F094FF10BD30B5054687B000200090AF
|
|
||||||
:20D4200001900290039038486A46203800791070364A0C3A1068926804906846069205900E
|
|
||||||
:20D4400008790C2806D003221BE00022114601F075FFA5E78C68204600F049F80190201D5E
|
|
||||||
:20D4600000F045F802902046083000F040F8039004A8FFF714F9002892D00121FFF78EFCB9
|
|
||||||
:20D4800002460121284600F0C9FC0028DDD187E7FEB50446087982070ED08207920F042385
|
|
||||||
:20D4A0009B1A0022154604E08E683554401CC0B2521C9A42F8D30871012000908868029048
|
|
||||||
:20D4C0000879800801906846FFF785F900280DD00221FFF763FC02460221204600F09EFCB8
|
|
||||||
:20D4E000002803D00022114601F028FFFEBD10B5044602F04DF80002E178000A09060843E0
|
|
||||||
:20D5000010BD0000902D002058280020E4F703008DD20300D3CD0300446675546172670031
|
|
||||||
:20D520005FCF0300A7D20300CD0C000005CF0300FFFF00000230000010B50C46002802D04D
|
|
||||||
:20D540000120086010BD2168002911D01C48421A814212D03C2A0DD23C303C3101220B78B9
|
|
||||||
:20D5600003701346491E401E521C3C2BF7D904E00E200BE03C2201F0AAFF00223C211048A9
|
|
||||||
:20D5800001F08AFD0E49891E08800020206010BD70B5054600223C21094801F07DFD084C21
|
|
||||||
:20D5A000A41E2188884201D00B2070BD3C220449284601F08CFF2088401C2080002070BD87
|
|
||||||
:20D5C000823F00208307FF22DB0E9A408907090E994000280BDA0007000F08388308FA484C
|
|
||||||
:20D5E0009B001B18D86990430843D86170478308F6489B001B1818689043084318607047AA
|
|
||||||
:20D6000070B50124F24960040860F24940108860F04940398860F04D6C602F20FEF7B6FDAC
|
|
||||||
:20D62000AC60EE4D00242F206C61FEF7AFFD2C7170BDF0B5E94F2821BC6841430D19396962
|
|
||||||
:20D640004A1C09D028224A431619AB68B268934204D8D21AB26069623861F0BD0A4602E066
|
|
||||||
:20D660000A46796A9B1B4E1C0BD028264E433719BE689E42F4D328264E433619B768FF1A1A
|
|
||||||
:20D68000B760AB60696228214A4311194862F0BD70B5D24C2269A5681346114606E0814212
|
|
||||||
:20D6A00007D00A46282671434919496A4E1CF6D170BD002EFCD08A420CD1282043435819EC
|
|
||||||
:20D6C000406A2061401C05D1C34B01209860002363616071282041434819282381685A4310
|
|
||||||
:20D6E000406A52195062421CE2D028225043401982685118816070BDF8B5B84C2569681CF9
|
|
||||||
:20D7000035D0B748002640686169401A07023F0A19E028204543A0682A189068B84214D8D0
|
|
||||||
:20D72000A3693F1A8619556A002B09D0116AD0699847002807D00022114601F0FFFD02E048
|
|
||||||
:20D74000D169106A8847681CE3D1A178E078814206D1401CC0B2E070022801D10020E07079
|
|
||||||
:20D760009E490006800D1C310E5000F0BAF9F8BDF8B50446994800270169009146785CE038
|
|
||||||
:20D780009648F100C2688D1851E0601C07D0934A28209268604321468018446A24E0287854
|
|
||||||
:20D7A000182141436A68401CC0B252182870A978884200D12F70894B516828209B6848434C
|
|
||||||
:20D7C000C0181368012B34D1037E002B31D19368C360D368036113694361526902627F4A52
|
|
||||||
:20D7E0005279002A00D0C7607C4BC2685B6996469C46D31A1A027B4B120A9A4202D20369C3
|
|
||||||
:20D80000D21808E0724663469A1A12020369120A934202D99A1A826000E08760C76001222E
|
|
||||||
:20D8200007610276921E42620846FFF702FF601CABD1287869788842A7D13046761EF6B202
|
|
||||||
:20D8400000289DD1654801690098814201D00120F8BD0020F8BD644900200860486088607F
|
|
||||||
:20D86000C860614940390860486045E7FEB50020C0435A4D02906869019068462E6900F07B
|
|
||||||
:20D8800035F9074600F04FF90446002F08D002AA0199009800F08FF90298FFF769FF06E050
|
|
||||||
:20D8A0000298FFF765FF002801D1002C02D0304600F0AAF900206871FEBDFFB59807002448
|
|
||||||
:20D8C00081B01E4615460F4600280BD1002E09D0FFF796FE41490A9888610F703246002042
|
|
||||||
:20D8E0008E6008E0072005B0F0BD28234343D4509B181C76401CB842F7DB28204743BB19C1
|
|
||||||
:20D90000032048700F461846CB6019461830002218232E465E43D3005B181C705C709D708A
|
|
||||||
:20D9200058603018521C032AF5DB0020C0433861BC70FC7001242D482405046003211420A9
|
|
||||||
:20D94000FFF740FE224880380460254C0198A06003211120FFF736FE606878610020C2E71A
|
|
||||||
:20D9600070B51E4CA568002D06D0002A06D0002804D00023247809E0082070BD072070BDBB
|
|
||||||
:20D9800028265E43AE59002E04D05B1CA342F7DB042070BD282401265C432E516419E261BF
|
|
||||||
:20D9A00061600360002070BD07494868C005C00D2CD010381CD50207120F083A9208920097
|
|
||||||
:20D9C0005118C96919E0000000ED00E000E400E080E100E040130140001001406028002054
|
|
||||||
:20D9E00000150140FFFF7F004011014080E200E08108B14A8900891809688007C00EC1400B
|
|
||||||
:20DA00000806800F012803D0032803D0022070470020704701207047FEB50446A74817469E
|
|
||||||
:20DA200082680D46002A0CD001788C4201D2052D01D20720FEBD2146282359435358012B7D
|
|
||||||
:20DA400001D00820FEBD8818406801281DD00026FFF7AAFFC00099490190C9684018694684
|
|
||||||
:20DA600000F018F9002812D0012144600160944949680830E2C091490198C9684118009877
|
|
||||||
:20DA8000487000F02EF80020FEBD2E46E0E70420FEBDF8B5894D0446A868002809D0297844
|
|
||||||
:20DAA0008C4201D30720F8BD282161434058012801D00820F8BDFFF777FFC600E86869465B
|
|
||||||
:20DAC000301800F0E7F8002809D0022112C0E86831180098487000F004F80020F8BD04206B
|
|
||||||
:20DAE000F8BD0120774900050860704710B5734900238A78CC78A24212D0521CD2B28A70D0
|
|
||||||
:20DB0000022A00D18B708A786C4B92001C339A580260486910180002000A4861012010BDA3
|
|
||||||
:20DB20000360002010BDF8B5644801690091457833E06248E900C0680E1834782AE01820A2
|
|
||||||
:20DB400060437168641C0818B178E4B2A14200D100240168022902D003291BD113E0574A00
|
|
||||||
:20DB600040682821926841438F18397E002911D0FFF78EFD002038760CE028277843C018B1
|
|
||||||
:20DB80000276406A03E04D4900228B680869471CF3D108617078A042D1D128466D1EEDB2D0
|
|
||||||
:20DBA0000028C6D1454801690098814201D00120F8BD0020F8BDF7B5404C0025A7682369E0
|
|
||||||
:20DBC0001EE028215943C9198E68864202D9301A886017E0801B751900268E600E764E6946
|
|
||||||
:20DBE0009C464B6AB646002E0AD0019E76193602360ACE6076460E6116684E626146116045
|
|
||||||
:20DC0000591CDED12361FEBDF8B52C4801694A1C3DD028225143826889188E6828494C681F
|
|
||||||
:20DC200047690079E11B0D022D0AED1C002815D10120254A00045060234A403A506021491D
|
|
||||||
:20DC4000400080310860214908602149012008602F20FEF79BFA194901200871B54200D208
|
|
||||||
:20DC60003546E81900021649000A4031086014494968001B091B0902090A0002C91C000A88
|
|
||||||
:20DC8000814203D901200F4940040860F8BDFFF7B7FCF8BD42788378521C934200D10022C2
|
|
||||||
:20DCA0000378934201D1002070470A6041684078182250430818704700E400E06028002090
|
|
||||||
:20DCC0000015014000E200E04013014000E100E00010014010B50446082904D000221146F9
|
|
||||||
:20DCE000104601F02BFB21686068884710BD1CB501910090024A0821684601F09DFA1CBD53
|
|
||||||
:20DD0000D5DC03000A48026803210A4302600948804709480047FEE7FEE7FEE7FEE7FEE797
|
|
||||||
:20DD2000FEE7000005480649064A074B70470000240500404DDD0300C1C003009830002007
|
|
||||||
:20DD4000983C00209834002098340020F8B500F035F82B4E002804D02A4870602A49F01300
|
|
||||||
:20DD600088612A480124018CC9B201290DD1818C09070AD1018D0906090F042905D1808D56
|
|
||||||
:20DD80000006000F01D1224884600027B461214D6F60A8058460686800280ED1C820FEF790
|
|
||||||
:20DDA00005FA1D487F1C8742F5D30020B06101208007846068680028FCD0F8BD1348018CB5
|
|
||||||
:20DDC000C9B2012917D1818C090714D1018D09060A0F03D1828D1206120F0ED0090F0129C2
|
|
||||||
:20DDE00003D1828D1206120F07D0032903D1808D0006000F01D0002070470120704700008E
|
|
||||||
:20DE000000050040DFFF07C0006C0040C00F00F000060040000100408813000030B585B071
|
|
||||||
:20DE2000002822D00388FE4CA34220D0FD4B1B78002B1CD0FB4B10255B1C1D7059700024C0
|
|
||||||
:20DE400001259A70032269460A820094019402940394028A0A808D708C8004A902910393E7
|
|
||||||
:20DE600000886946A6DF05B030BD0E20FBE70820F9E7F0B58BB0044602276846077300268B
|
|
||||||
:20DE800009968784C68408A80A900D46A18A208809AAA5DF002804D0E16A00291AD08847BE
|
|
||||||
:20DEA00018E06846008CC007C00F13D068460682208803A9A8DF002813D1A97E28461B30BA
|
|
||||||
:20DEC00001220B0001F055FC09430F1B202224263E284300FF20FE3069460882208803A94D
|
|
||||||
:20DEE000A8DF0BB0F0BD00960AE0062219E069460A71029022E0204690470020F1E700920D
|
|
||||||
:20DF00002B8B022BF3D2F0E700971DE003201AE0042018E0052016E0298B032905D20322BE
|
|
||||||
:20DF200008212046FFF77AFFDBE741780278080210436946888003D006200090A26ADAE784
|
|
||||||
:20DF40000720FAE7092000906946A26AD3E70322E7E730B585B00D46040038D0002D36D0EC
|
|
||||||
:20DF60006868002833D00020C043AF4B20800FCB049301AB07C3AD4869460880891C01A888
|
|
||||||
:20DF800063DF002822D1221D69460120A0DF00281CD168468078A071204600F0CEF8002886
|
|
||||||
:20DFA00014D1204600F055F900280FD12946204600F002F9002809D16868A062A868002804
|
|
||||||
:20DFC00000D0E06297490120087000204BE70E2049E73EB5002828D0002926D0826A002ABE
|
|
||||||
:20DFE00023D00A88102A21D0112A30D0502A1FD0512A1AD104460846891D0A78022A14D196
|
|
||||||
:20E000004A88238A9A4210D1807A04280DD006280BD0052809D0891C2046FFF72AFF002860
|
|
||||||
:20E0200003D0E16A002900D088473EBD898810E0CA8803899A42F8D1082200928A7F6B4605
|
|
||||||
:20E040001A7120310291826A694690473EBD0021C94301803EBDF0B585B00A4605002DD00F
|
|
||||||
:20E0600028886F4988422BD06E480078002827D06C4C1020641C2070072060700127A770F8
|
|
||||||
:20E080000321684601820026E11C104600F04CF801466846008A0918684601820096019680
|
|
||||||
:20E0A00002960396298A01808770868004A80394029028886946A6DF05B0F0BD0E20FBE7D3
|
|
||||||
:20E0C0000820F9E7F0B585B00A46050028D028885349884226D053480078002822D0514C3B
|
|
||||||
:20E0E0001120641C20700127684607820026611C104600F019F801466846008A0918684638
|
|
||||||
:20E1000001820096019602960396298A01808770868004A80394029028886946A6DFCBE782
|
|
||||||
:20E120000E20C9E70820C7E70870020A4A70020C8A70000EC8700420704730B58FB0054655
|
|
||||||
:20E140001C21684601F022FA694608780421084369460870002401940394049405940694E6
|
|
||||||
:20E16000A87908A9887031486946801C0884601C00070794000F0C77103048778A7FF920B4
|
|
||||||
:20E180000240921CE7200240012002438A77142109A801F0FBF908A8099007A80A906946D3
|
|
||||||
:20E1A0008C851420CC8508860D942B46A888083309AAA2DF0FB030BDF0B58FB00F4605465A
|
|
||||||
:20E1C0001C21684601F0E2F968460178022631430170002401940394049405940694A97917
|
|
||||||
:20E1E00008A8817011496846091D0184601C0107090F103168460794017700200146684618
|
|
||||||
:20E200004177817FF9200140891CE72001400120014368468177142109A801F0B7F907E086
|
|
||||||
:20E22000FFFF000088280020FCF703003015000008A8099007A80A9068468685C4850686B5
|
|
||||||
:20E240000D972B46A888203309AA6946A2DF0FB0F0BD30B58FB005461C21684601F096F9FD
|
|
||||||
:20E2600069460878082108431022104369460870002401940394049405940694A87908A962
|
|
||||||
:20E280008870144869460884601C00070794000F0C7710304877887FF9210840801CF72123
|
|
||||||
:20E2A000084010430121084369468877142109A801F06CF908A8099007A80A9069468C851A
|
|
||||||
:20E2C0001720CC8508860D942B46A888103309AAA2DF6FE731150000FFB583B0074600207F
|
|
||||||
:20E2E0000C9C8646267805463AE07868A90041180A88684682804988C1800022694601A8F7
|
|
||||||
:20E3000065DF002810D1684601780598814226D17046002801D0002200E002222078891824
|
|
||||||
:20E3200041181F2902D90C2007B0F0BD7146002908D1401CC0B2411C069B049A21701A54AF
|
|
||||||
:20E3400001208646217806980A18694601A865DF0028E9D1694620780978401820706D1CC0
|
|
||||||
:20E360003888A842C1DC7046002804D020780699801B401E88550020D6E7F8B51546069C10
|
|
||||||
:20E380001E46074602220094FFF7A6FF002806D133461022294638460094FFF79DFFF8BD07
|
|
||||||
:20E3A000F7B582B000260546167000681446002805D02846039900F0CAF8060008D168794D
|
|
||||||
:20E3C00000281ED02078039F001D1F2802D90C2005B0F0BD684679DF0028F9D1217803226A
|
|
||||||
:20E3E000481C20707A5421781922481C20707A542078C1196846008800F0A4F821784018A0
|
|
||||||
:20E400002070A8790223002810D02078039A411C2170135420780399471C012227700A54E5
|
|
||||||
:20E420002078AA79471C039927700A54A868002815D00021415620788C460246C01C03992E
|
|
||||||
:20E440001F28C4D8501C20708B5422780A23501C20708B5420786246431C23700A54A8899B
|
|
||||||
:20E46000002809D028460094062202210C30039BFFF783FF0600ABD1A88A002809D02846D9
|
|
||||||
:20E480000094072203211430039BFFF776FF06009ED1A88B002809D0284600941522142137
|
|
||||||
:20E4A0001C30039BFFF769FF060091D1686A002805D02246039900F07FF8060088D1A86A01
|
|
||||||
:20E4C000002805D02246039900F0B5F8060084D13020405D002806D022462846039900F0F6
|
|
||||||
:20E4E000DCF80600C7D1304672E770B50C4692B000216A46117007251171002809D0817927
|
|
||||||
:20E5000049070CD502A9FFF74BFF002808D102AE00E00026002C0ED0A079002802D028469D
|
|
||||||
:20E5200012B070BD01AA0AA92046FFF739FF0028F6D10AAA00E0002268460379017830463C
|
|
||||||
:20E5400072DFEDE70870000A487002207047F8B514780746A01C15460E461F2803D83879BF
|
|
||||||
:20E56000801C1F2801D90C20F8BD1D20001B80B26946864608803019801C7DDF0028F3D143
|
|
||||||
:20E580003868022805D168460088704501D8092107E038790821002801D0704501D96846F6
|
|
||||||
:20E5A0000088421C3255641CE2B2B1542978801C081828700020F8BDF8B50D461178064636
|
|
||||||
:20E5C000881D14461F2801D90C20F8BD33880720062BFAD31927FF01BB4202D94D4A9342D6
|
|
||||||
:20E5E000F3D17288062AF0D3BA4202D9494FBA42EBD1484FBB4203D0BA4201D09342E4D87E
|
|
||||||
:20E60000481C052220706A5420781222411C21702A54207841193088FFF794FF21784018C5
|
|
||||||
:20E62000C0B2207041197088FFF78CFF2178401820700020F8BD70B5054600790E46801CD6
|
|
||||||
:20E640001446C0B21178821C8A181F2A01D90C2070BD0A46491C401C2170B0542078FF224A
|
|
||||||
:20E66000411C21703254207881192888FFF76AFF21784018C0B22070AA88002A09D0A968AC
|
|
||||||
:20E68000002908D0801900F022FF2078297940182070002070BD072070BDF7B582B0029894
|
|
||||||
:20E6A0001446C06A0F46002832D0029800252030009028E00298C16A0C2068430E18217855
|
|
||||||
:20E6C00030794A1CC01C2270785421781622481C20707A542078C1193088FFF733FF217873
|
|
||||||
:20E6E0004018C0B22070B288002A09D0B16800290ED0C01900F0EBFE207831794018207087
|
|
||||||
:20E700006D1C0098EDB2007CA842D3D800205FE607205DE6FFFF000038B56749674A48883D
|
|
||||||
:20E7200090420FD04A78664C521CD2B24A70237B934208D3083175DF002803D0A1690029FF
|
|
||||||
:20E7400000D0884738BD00254D70217C002907D03B2176DF002803D0A169002900D0884728
|
|
||||||
:20E7600061690029EED068460095884738BD70B5054601461C225248FDF75AFD4E4C002647
|
|
||||||
:20E7800026702968002907D00822A01800F09FFE204608307ADF02E0474808307BDF0028C1
|
|
||||||
:20E7A00008D1401E608044486670464A0021001DFFF7D6F870BD10B53F484068FFF769F9D5
|
|
||||||
:20E7C00010BDF8B53C48103000F069F800263A4D3B4C002806D06169002919D001200090EB
|
|
||||||
:20E7E000684614E02878002804D0616900290FD00096F5E7687800280CD0A16800226868B8
|
|
||||||
:20E80000FFF70AF9002803D0A169002900D088472E70F8BD6168F1E7F8B5294C028800276B
|
|
||||||
:20E82000254DE689102A18D029464968112A21D0122A2DD0502A0FD1801D0288B2420BD1FF
|
|
||||||
:20E84000028B022A08D1C27E837E10021843C007C00F13D0FFF7B5FFF8BD81886980014667
|
|
||||||
:20E86000154808221631103000F031FE6F70002EF0D0F8BD0020C04368806F700846FFF7BB
|
|
||||||
:20E8800008F90028F5D0A1690029F2D08847F8BD811D09480822103000F019FEDAE7418827
|
|
||||||
:20E8A000054808300288914204D34088814201D8012070470020704790280020FFFF0000B6
|
|
||||||
:20E8C000CC2D002019E7030031B5054C04E0401E00902046FDF77AFC00980028F7D138BDC6
|
|
||||||
:20E8E000E703000018225043FE4A00218018017181604161012281610261C1607047FFB577
|
|
||||||
:20E9000081B0F94C049B039A054626691A4303200092002E03D1002A0ED001222261276919
|
|
||||||
:20E92000039A0126360792003B0000F022FF072707162940526127000222EFE770693269FC
|
|
||||||
:20E9400092B25043326933691204920C9BB2594329DF002812D102210FE0084628DF00286A
|
|
||||||
:20E960000CD10399002901D0032106E00499002916D12978042946D017E0216105B0F0BDAE
|
|
||||||
:20E980007069326992B25043326993B24B4301461846039A29DF0028F0D10499002901D0F4
|
|
||||||
:20E9A0000421EAE72978042920D00521E5E773693069366980B2434368681B189B18B6B2C7
|
|
||||||
:20E9C0004E43301880181946049A29DF0028E9D0D4E7306980B24843696880188A08696902
|
|
||||||
:20E9E00029DF0028CAD1009900290CD00621C4E77069316989B24843316989B200F0D9FD08
|
|
||||||
:20EA000028DF0028BAD10721B7E7F8B5B54918230A780F205A435418241DB3492278266970
|
|
||||||
:20EA2000CF68022A1BD001252D07042A2AD0052A5BD1286981B2304600F0BBFD0146A36877
|
|
||||||
:20EA400028699A1980B24843101A820860681818861928694B1C80B25843801B34E0B8023C
|
|
||||||
:20EA600062686169121A0918A3683018181801239B029A4202D2920829DF31E0FF220132BA
|
|
||||||
:20EA800029DF2DE0E268974914205043F4314018001D0BC8B04203D160685943814218D02E
|
|
||||||
:20EAA000022A16D0286981B2304600F082FD0146286980B24843301A820828694B1C80B208
|
|
||||||
:20EAC000584363689B19C01A83082046FFF717FF06E0286981B2304600F06BFDC01928DFED
|
|
||||||
:20EAE000002802D17F4901228A70F8BDF8B57D4C069E65780A2D1DD027787D19EDB20A2D5B
|
|
||||||
:20EB000001D30A3DEDB218277D432D192871AA6103C9EE60AB6069612861A1780020002978
|
|
||||||
:20EB200004D1FFF772FF112800D100206178491C6170F8BD0420F8BD38B5024669481823B1
|
|
||||||
:20EB400001785943081803690179022B0AD014246343644CF434E4588368009383691030F7
|
|
||||||
:20EB6000A04738BD604B14331C68F5E7F8B55D4B9978012914D100255B499D700A69082A77
|
|
||||||
:20EB800005D002280FD003280AD10D2006E0022807D00D7000F025FA002801D0FFF7CCFF37
|
|
||||||
:20EBA000F8BD0D61F6E74F48182403784E496343CC681818641C001DCC600378022B05D11F
|
|
||||||
:20EBC0004668A102B14201D3012700E00027052B01D1072A03D00021042B02D003E00121C1
|
|
||||||
:20EBE000FAE7072A03D00026042B02D007E00126FAE74068A302834201D3002A1AD0002000
|
|
||||||
:20EC0000314301433943C5D0374E28463561FFF793FF344C2078FFF765FEF5606078401E1E
|
|
||||||
:20EC200060702078401CC0B220700A28B2D30A382070AFE70120E3E770B500252A4C2948D3
|
|
||||||
:20EC4000E56025610570457085702E463046FFF749FE761C0A2EF9D3012212076560516952
|
|
||||||
:20EC600028461269491E92B25143E560A1601D49F4310D608D600D61CD601B4914310D6090
|
|
||||||
:20EC8000888001212170206170BDF8B5164A044610780E46002830D0002C30D0002E2ED058
|
|
||||||
:20ECA000206800282BD0012000076768016989B28F4228D8102F26D3A168002923D09568E2
|
|
||||||
:20ECC000794343694A19006980B243439A421AD801200007006980B2814212D901200007E1
|
|
||||||
:20ECE000006903E0E82D0020A828002080B2394600F05FFC002906D103E00820F8BD0E20B9
|
|
||||||
:20ED0000F8BDB80701D00720F8BDBD49486801281CD00F461421BB4A21C641438E18756092
|
|
||||||
:20ED2000236853506168B160A168F160A268616800235143012212075B1C14699BB2A4B214
|
|
||||||
:20ED40008C4205D21469A4B2091B02E00420F8BD00211469A4B265191469A4B28C42EBD985
|
|
||||||
:20ED6000BD60401C336178600020F8BDF8B50446A3481E46007815460F46002807D0002F3D
|
|
||||||
:20ED800007D0002C05D02068002817D103E00820F8BD0E20F8BD9B48016800290ED0C268E3
|
|
||||||
:20EDA000816840684A4310186268904206D9002D04D0A94202D3A819884201D90720F8BD90
|
|
||||||
:20EDC000384600F008F9002811D0304600F003F900280CD0606800F0FEF8002807D02B4637
|
|
||||||
:20EDE0003A46214602200096FFF780FEF8BD1020F8BDFFB5824881B000781F4616460D462B
|
|
||||||
:20EE0000002808D0002D08D00198002805D02868002817D103E00820B0E50E20AEE5794C91
|
|
||||||
:20EE2000206800280ED0E168A0686268414389186A68914206D9002E04D0B04202D3F119AD
|
|
||||||
:20EE4000814201D9072099E5019800F0C4F800281BD0384600F0BFF8002816D0686800F025
|
|
||||||
:20EE6000BAF8002811D068683246C119019800F02EFB00962868142148432458002203215B
|
|
||||||
:20EE80002846019BA047002078E5102076E5F8B505465B480F460078002805D0002D05D012
|
|
||||||
:20EEA0002868002821D103E00820F8BD0E20F8BD544C00262068002817D0A168E0684843CC
|
|
||||||
:20EEC00061684118686881420FD900F084F800280DD0296814225143091968684A68896834
|
|
||||||
:20EEE000801A00F066FB002903D00720F8BD1020F8BD3B460022294604200096FFF7F6FDB5
|
|
||||||
:20EF0000F8BD3F4A1278002A0DD000280DD000290BD00268002A08D0394A14321368002B3E
|
|
||||||
:20EF200005D004207047082070470E20704702230B600068106000207047F8B504463048AF
|
|
||||||
:20EF40001E46007817460D46002807D0002D07D0002C05D0206802281BD103E00820F8BDC3
|
|
||||||
:20EF60000E20F8BD264814300068002811D0084600F031F800280ED0304600F02CF800286C
|
|
||||||
:20EF800009D03B462A46214602200096FFF7AEFDF8BD0720F8BD1020F8BD08B5184A1278C8
|
|
||||||
:20EFA000002A05D0002805D00268022A11D103E0082008BD0E2008BD114A14321268002AD5
|
|
||||||
:20EFC00007D00B460022014604200092FFF78EFD08BD072008BD800701D000207047012068
|
|
||||||
:20EFE0007047084910B5F43949780020002906D0FFF70BFD002802D0112800D1002010BD48
|
|
||||||
:20F00000A8280020DC2E002070B500250C290ED304464318008941000919581A0A38C2B2BD
|
|
||||||
:20F020001748022A027002D30A318B4201D2092070BD144800F04BFA134914480A8882422E
|
|
||||||
:20F0400002D02388934217D14988814202D06088884211D10D4A0323521E20891B03A842DE
|
|
||||||
:20F060000AD9690009194989914203D09E896D1CB142F4D1002070BD0B2070BD00207047C6
|
|
||||||
:20F08000C4280020F02E002080100010FFFF000010B5FDF7ABF810BD10B50446002A02D054
|
|
||||||
:20F0A0001088002210E00A48FBE7030A00020343A05C584003061B0F43401803584083B2EB
|
|
||||||
:20F0C0001806C00C5840521C8A42EED310BD0000FFFF00004B48002101704C484A4A026039
|
|
||||||
:20F0E0008160C160016108224161426081610846704710B500291DD000220A60434A5368A8
|
|
||||||
:20F10000002B1BD0202817D85B1E5360D0682423401CD060106914684343E3180B60012366
|
|
||||||
:20F1200083409169401C19434007400F91611061002010BD0E2010BD0C2010BD042010BD8F
|
|
||||||
:20F14000F0B5324A0646916800292BD057691020791A4907490F14680B4624254D436519D6
|
|
||||||
:20F16000B54206D1012495698C4065400020956104E0491C4907490F8F42EED1491C4E07DC
|
|
||||||
:20F18000760F956901210C469C402B4623420AD19368002B07D05B1E936053685B1C53609D
|
|
||||||
:20F1A0003346F0E70420F0BD184A2423117C1268491E4907490F594320315050002070470B
|
|
||||||
:20F1C00070B500281AD0002918D0104AD368002B16D05B1ED360936824265B1C936053692A
|
|
||||||
:20F1E00015681C467343EE1820330660E858641C08606007400F5061002070BD0E2070BD84
|
|
||||||
:20F20000042070BDC5280020FC2E00201C30002030B5CB0008339DB293070024002B01D0E6
|
|
||||||
:20F22000072030BD3B4B9A605219DA605C701C7058809980002030BDF7B5364C0E466088D5
|
|
||||||
:20F24000814237D8344F00F069F822786078A188884201DA401C00E00020C0B2904202D155
|
|
||||||
:20F2600000F062F824E065786078884201DA401C00E00020607000F057F8BD4218D0A0688C
|
|
||||||
:20F28000EF000299C151009900290CD0002E0AD0608832464543E068281800F018F9A068B3
|
|
||||||
:20F2A0003818868002E00021381881800020FEBD0420FEBD0920FEBD0EB504E068468188A8
|
|
||||||
:20F2C000029A0098904702AA01A9684600F003F80028F3D00EBD70B50E4B05241D785E786C
|
|
||||||
:20F2E000AE4215D01D781C789E88B44201DA641C00E000241C705C88DE686C43A41904600F
|
|
||||||
:20F300009B68E800C418A4880C80185800241060204670BDCC280020FFFF000072B606484F
|
|
||||||
:20F320000168491C0160704703490868401E086000D162B670470000DC280020BFF34F8F11
|
|
||||||
:20F3400003490248C860BFF34F8FFEE70400FA0500ED00E010B5002904D000221146104619
|
|
||||||
:20F36000FFF7ECFF00F010F810BD10B50021024A0846FFF761FF10BD55F3030010B50846E6
|
|
||||||
:20F380001146FCF771FF10BDF8B5384C2078002837D02069002807D00026E068002805D0FB
|
|
||||||
:20F3A0000025002E04D013E00126F6E70125F8E7684651DF052806D0002806D000221146D2
|
|
||||||
:20F3C000FFF7BCFF04E0012602E0216900988847002D12D1608869460880A06861DF0528FA
|
|
||||||
:20F3E00006D0002806D000221146FFF7A7FF04E0012502E0E168A0688847002ED8D0002D15
|
|
||||||
:20F40000CFD0F8BD70B5002901D08C0701D0072070BD164C0125A16062801549636010DF46
|
|
||||||
:20F420000028F5D1257016202EDF70BD002803D00E49C860002070470E207047002803D0A8
|
|
||||||
:20F440000A490861002070470E20704710B507484068002807D08047002803D0002211463E
|
|
||||||
:20F46000FFF76CFF10BDFFF78FFF10BDE02800207DF30300034610B50B439B070FD1042A66
|
|
||||||
:20F480000DD308C810C9121FA342F8D018BA21BA884201D9012010BD0020C04310BD002AAC
|
|
||||||
:20F4A00003D0D30703D0521C07E0002010BD03780C78401C491C1B1B07D103780C78401C61
|
|
||||||
:20F4C000491C1B1B01D1921EF1D1184610BDF8B5042A2CD3830712D00B78491C0370401C25
|
|
||||||
:20F4E000521E83070BD00B78491C0370401C521E830704D00B78491C0370401C521E8B07F9
|
|
||||||
:20F500009B0F05D0C91ADF002023DE1B08C90AE0FCF78EFEF8BD1D4608C9FD401C46B440B8
|
|
||||||
:20F520002C4310C0121F042AF5D2F308C91A521EF0D40B78491C0370401C521EEAD40B78EC
|
|
||||||
:20F54000491C0370401C521EE4D409780170F8BD01E004C0091F0429FBD28B0701D50280F7
|
|
||||||
:20F56000801CC90700D00270704700290BD0C30702D00270401C491E022904D3830702D5EE
|
|
||||||
:20F580000280801C891EE3E70022EEE70022DFE70378C2781946437812061B0219438378A2
|
|
||||||
:20F5A000C0781B04194311430902090A000608437047002203098B422CD3030A8B4211D366
|
|
||||||
:20F5C00000239C464EE003460B433CD4002243088B4231D303098B421CD3030A8B4201D39D
|
|
||||||
:20F5E00094463FE0C3098B4201D3CB01C01A524183098B4201D38B01C01A524143098B422D
|
|
||||||
:20F6000001D34B01C01A524103098B4201D30B01C01A5241C3088B4201D3CB00C01A524193
|
|
||||||
:20F6200083088B4201D38B00C01A524143088B4201D34B00C01A5241411A00D201465241FB
|
|
||||||
:20F64000104670475DE0CA0F00D04942031000D34042534000229C4603098B422DD3030A47
|
|
||||||
:20F660008B4212D3FC22890112BA030A8B420CD3890192118B4208D3890192118B4204D305
|
|
||||||
:20F6800089013AD0921100E08909C3098B4201D3CB01C01A524183098B4201D38B01C01A88
|
|
||||||
:20F6A000524143098B4201D34B01C01A524103098B4201D30B01C01A5241C3088B4201D37F
|
|
||||||
:20F6C000CB00C01A524183088B4201D38B00C01A5241D9D243088B4201D34B00C01A52417F
|
|
||||||
:20F6E000411A00D20146634652415B10104601D34042002B00D54942704763465B1000D31A
|
|
||||||
:20F70000404201B50020C046C04602BD704770477047754600F022F8AE460500694653469B
|
|
||||||
:20F72000C008C000854618B020B5FEF7FBFA60BC00274908B6460026C0C5C0C5C0C5C0C525
|
|
||||||
:20F74000C0C5C0C5C0C5C0C5403D49008D4670470446C046C0462046FCF7FFFC004870479C
|
|
||||||
:20F760003830002001491820ABBEFEE726000200704730B47446641E2578641CAB4200D256
|
|
||||||
:20F780001D46635D5B00E31830BC184702000000000000000000000000000000040000009F
|
|
||||||
:20F7A000000000000000000000000000000000000000000035C4030000000000000000004D
|
|
||||||
:20F7C000020000000000000000000000000000000000000000000000030000000000000024
|
|
||||||
:20F7E0000000000005000000000000000000000000000000000000000000000023D1BCEA6A
|
|
||||||
:20F800005F782315DEEF1212000000002CF8030000280020F400000004C1030020F90300A1
|
|
||||||
:20F82000F4280020A413000020C103000000000000000000000000000000000000000000F1
|
|
||||||
:20F840000000000000000000000000000000000000000000000000000000000000000000A8
|
|
||||||
:20F8600000000000000000000000FFFF000000003200000000000000000000000000000058
|
|
||||||
:20F88000000000000000000000000000000000000000000000000000000000000000000068
|
|
||||||
:20F8A000000000000000000000000000000000000024F40000000000000000000000000030
|
|
||||||
:20F8C000000000000000000000000000000000000000000000000000000000000000000028
|
|
||||||
:20F8E000000000000000000000000000000000000000000000000000000000000000000008
|
|
||||||
:20F900000000000000000000000000000000000000000000000000000000000000000000E7
|
|
||||||
:20FC00000100000000000000FE0000000000000000000000000000000000000000000000E5
|
|
||||||
:020000041000EA
|
|
||||||
:0410140000C0030015
|
|
||||||
:040000050003C0C173
|
|
||||||
:00000001FF
|
|
|
@ -1,463 +0,0 @@
|
||||||
:020000040003F7
|
|
||||||
:20C00000983C002005DD030017DD030019DD03000000000000000000000000000000000057
|
|
||||||
:20C0200000000000000000000000000069C1030000000000000000001DDD03001FDD0300D7
|
|
||||||
:20C0400021DD030021DD030021DD030021DD030021DD03000000000021DD030021DD0300D9
|
|
||||||
:20C0600021DD030021DD030021DD030021DD030021DD030021DD030021DD030021DD0300B8
|
|
||||||
:20C0800021DD030057D8030021DD030021DD03006DD8030021DD03004DF4030021DD0300DD
|
|
||||||
:20C0A00021DD030021DD03000000000000000000000000000000000000000000000000007E
|
|
||||||
:20C0C00000F002F800F040F80CA030C8083824182D18A246671EAB4654465D46AC4201D18E
|
|
||||||
:20C0E00000F032F87E460F3E0FCCB6460126334200D0FB1AA246AB463343184710370000C8
|
|
||||||
:20C1000030370000103A02D378C878C1FAD8520701D330C830C101D504680C6070470000D3
|
|
||||||
:20C120000023002400250026103A01D378C1FBD8520700D330C100D50B6070471FB5C04655
|
|
||||||
:20C14000C0461FBD10B510BD03F0E3FA1146FFF7F5FF00F0D3F803F0FBFA03B4FFF7F2FF19
|
|
||||||
:20C1600003BC03F0FFFA00000648704502D1EFF3098101E0EFF30881886902380078024A97
|
|
||||||
:20C1800010470000FDFFFFFF39D50300401E00BF00BF00BF00BF00BF00BF00BF00BF00BF28
|
|
||||||
:20C1A00000BF00BF00BFF1D170470000401E00BF00BF00BF00BF00BF00BF00BF00BF00BFB4
|
|
||||||
:20C1C00000BF00BF00BFF1D170470000401E00BF00BF00BF00BF00BF00BF00BF00BF00BF94
|
|
||||||
:20C1E00000BF00BF00BFF1D170470000056885F3088846680A4AEFF305839A42304602D183
|
|
||||||
:20C20000084CA6463047074C064D0646064FF0B4034C034D024E024FF0B404480047000005
|
|
||||||
:20C2200000000000FFFFFFFF00000021F9FFFFFF70B505460C46164602E00FCC0FC5103EEE
|
|
||||||
:20C24000102EFAD2082E02D303CC03C5083E042E07D301CC01C5361F03E021782970641C63
|
|
||||||
:20C260006D1C761EF9D270BD0A4610B50146664803F064F810BD10B502F078FC10BD10B5C6
|
|
||||||
:20C28000624C86B01ECC03946C460EC4002807D0684618DF002803D00022114603F04EF864
|
|
||||||
:20C2A0000F20800313DF002803D00022114603F045F8574B48225749092003F0A3F80028AB
|
|
||||||
:20C2C00003D00022114603F039F800200490059001206946087404A860DF002803D0002251
|
|
||||||
:20C2E000114603F02BF84C4803F0A8F8002803D00022114603F022F806B010BD08B547485A
|
|
||||||
:20C30000C169B12943D0002445480F2140698903884204D000221146104603F00FF8012068
|
|
||||||
:20C320000007006901218902884204D000221146104603F003F83B4800903B4B05220321A1
|
|
||||||
:20C34000002001F0BAFA002803D00022114602F0F5FF00F067FC00F0AAFC012500281AD09D
|
|
||||||
:20C3600000F0B4FC002803D00022114602F0E6FF20466840FFF783FF00F038F800F0CCFC74
|
|
||||||
:20C3800000280ED00022114602F0D8FF09E001240021C161B8E720466840FFF770FF00F002
|
|
||||||
:20C3A00025F803252D03002C04D1A86800F090FB002807D100F047FC002803D000221146D5
|
|
||||||
:20C3C00002F0BCFFA86800F083FB002806D000F06EFC002802D1A86800F041FCBFF34F8F12
|
|
||||||
:20C3E00013491248C860BFF34F8FFEE7094A10B548321421082002F00BFF002803D00022E2
|
|
||||||
:20C40000114602F09BFF10BDEFBEADDE8CF703006BF30300342B002077C20300000500404D
|
|
||||||
:20C4200000100010EFDC0300F42800200400FA0500ED00E070B5FC4C1E46A06815460229A3
|
|
||||||
:20C4400002D0042916D108E0052813D1A369002B10D03246294604200BE002280AD1F348B0
|
|
||||||
:20C46000406880470320A060A369002B02D0324629469847280003D00022114602F05EFF98
|
|
||||||
:20C4800070BD4CB5E84E0120307005200195009400F058FB4CBD10B5E34C2078002801D057
|
|
||||||
:20C4A000082010BD206901F0F4FA002803D00022114602F043FF0F2100228904206901F01E
|
|
||||||
:20C4C000ABFA040003D00022114602F037FF204610BDD54910B5D448243141610221816012
|
|
||||||
:20C4E000C168243002F059FD002803D00022114602F024FF10BDCC4910B5CB481C31416145
|
|
||||||
:20C50000022181600320000380680F218903081A4108C5481C3002F040FD002803D000223D
|
|
||||||
:20C52000114602F00BFF10BD704700B589B01822BF4902A8FFF77CFE06980799009001917A
|
|
||||||
:20C5400002A80FC800F0FEFA09B000BD00B5B64987B049886A461181032109038968069146
|
|
||||||
:20C56000B249012050394A6803928A680492C9680591069A0091019202A90EC900F0E2FA6E
|
|
||||||
:20C58000002007B000BD30B5A84CA748503C89B02430E16802F001FD002803D00022114679
|
|
||||||
:20C5A00002F0CCFEA048E2681C3041680023083002F0C3FC050012D1182102A802F0E6FFEA
|
|
||||||
:20C5C00000209949029049886A469181E1680691079A0091019203A90EC900F0B3FA284601
|
|
||||||
:20C5E00009B030BD00B5904987B049886A4611818E49032050394A6803928A680492C9683A
|
|
||||||
:20C600000591069A0091019202A90EC900F09AFA0020B6E73EB5864A6B46183207CA07C3A4
|
|
||||||
:20C62000814D00246C7029466C802431684602F068FC002801D0AC603EBD03207A4900038F
|
|
||||||
:20C6400080682431486024390A46526ACA610F218903091A490840187349764A1C31486068
|
|
||||||
:20C6600071480021103001F07BF9002803D00022114602F063FE0F2100228904286901F013
|
|
||||||
:20C68000CBF9002803D00022114602F057FE01206C60A86000203EBD63498861704770B59A
|
|
||||||
:20C6A000426862481468536891685038D26804604360C26081600078440701D5840705D130
|
|
||||||
:20C6C0009C0703D18C0701D1940701D0062070BD5B189A18544D0F239B02EA60994213D81A
|
|
||||||
:20C6E0005549564B514CC60709D08868181A90420AD3534820605348606053480FE08968F6
|
|
||||||
:20C70000591A4908914201D20C2070BD4F4921604F496160800701D54E4800E04E48A0607B
|
|
||||||
:20C72000A868012802D00826304670BDFFF7B3FE0600FAD12168E8688847F5E770B50500F7
|
|
||||||
:20C7400004D0287A800703D0102070BD0E2070BD354CA068032805D0042801D0052803D0CB
|
|
||||||
:20C76000082070BD0520A0606868E168860060688019884204D90020C04360600C2070BD5C
|
|
||||||
:20C78000FFF789FE0028FAD1A96832466368606902F0D3FB0028F2D1616889196160E268EB
|
|
||||||
:20C7A0009142ECD0092070BD10B51F4C08206168002900D010BDA1680429FBD11B4861786F
|
|
||||||
:20C7C000403802F021FC002802D00021617010BD0521A16010BDF8B5134C0746A068032899
|
|
||||||
:20C7E00004D0042804D008252846F8BD0420A0606068002801D00820F8BDFFF74CFE05000E
|
|
||||||
:20C80000FAD17868860060788119402901D90920F8BD064AB968403A1018324602F057FE82
|
|
||||||
:20C82000607880196070DFE7002800201C2D00209CF7030083C403000030000000C003006D
|
|
||||||
:20C84000D3C403002BC503004DC50300F7C4030029C50300E5C5030087C5030010B5894CF1
|
|
||||||
:20C86000A068052813D1E168606888420FD10620A060FFF710FE002808D16069E1684068FF
|
|
||||||
:20C8800002F0FCFB002801D10721A16010BD082010BD10B57B488168072901D0082010BD63
|
|
||||||
:20C8A000006901F0F6F8002803D00022114602F045FD75488068804710BD1CB506200195C2
|
|
||||||
:20C8C000009400F03FF91CBDF8B51C4617460D46064600F0C1F8002817D001200003854215
|
|
||||||
:20C8E00007D92346291B301B1A46FFF7EDFF00280BD13A462946304600F0B9F8002804D117
|
|
||||||
:20C900003A462946304600F0A7F8F8BDF0B589B0684600F015FA049800282AD001210903F7
|
|
||||||
:20C92000079A4018904226D9501A45081046049A0C468718024668001618001908900320DF
|
|
||||||
:20C9400000038068049988420DD261190846042200F08DF800280CD121460422084600F073
|
|
||||||
:20C9600086F8002805D1BA1B2B4630460899FFF7ABFF09B0F0BD049A079800F078F8F8E75C
|
|
||||||
:20C9800000B58DB004A800F0DBF9099800280DD0089800280CD008990B984018019000219D
|
|
||||||
:20C9A0000998009180080290684618DF0DB000BD0320000380680F218903091A4908ECE7FB
|
|
||||||
:20C9C00000B58DB004A800F0BBF909980028EDD00F210898890300280CD0089A0B98019158
|
|
||||||
:20C9E0008018029003220998009280080390684618DFDBE70320000380680A1A5208EEE7D2
|
|
||||||
:20CA000030B591B0684600F09BF90498002814D001210903079A4018904214D9501A43087B
|
|
||||||
:20CA20001046049A5C0082180019611803242403A468049DAC4202D20E2011B030BD121AB5
|
|
||||||
:20CA4000FFF742FFF9E703200CAB07C3049880080F900CA818DFF0E71FB5032301909008B3
|
|
||||||
:20CA6000039000930291684618DF04B010BD1FB5012301909008039000930291684618DF58
|
|
||||||
:20CA8000F3E70000002800201C2D002010B5BB480368012B02D1022900D10160100003D099
|
|
||||||
:20CAA0000022114602F04AFC10BD10B5B34C48DF002803D00022114602F040FC02F0FCFB82
|
|
||||||
:20CAC0002068022803D0032801D00428EFD110BD38B50068401C19D00024684600F058F96F
|
|
||||||
:20CAE00000980168012910D1818800290AD0C168032000038068002202F0CEFA0099898861
|
|
||||||
:20CB0000814201D1012400E00024204638BD10B504469A482021001D02F0B9F9002803D00E
|
|
||||||
:20CB20000022114602F00AFC9448002320222146001D02F01BF9002803D00022114602F053
|
|
||||||
:20CB4000FDFB10BD0FB4F8B5684600F021F96846818B069D0122894CFF238948002D13D090
|
|
||||||
:20CB6000012D17D0032D2BD00021022D37D02A46052D46D0042D4ED0062A01D10420206071
|
|
||||||
:20CB8000F8BC08BC04B0184781800A9983600260C16010E08180099D089949190A9D49195D
|
|
||||||
:20CBA000C160A52183600160089901610999856141610B99C16122607148FFF7A8FFDFE7B9
|
|
||||||
:20CBC00000990B6803608B888380C968C160AA21816008990161099941610A990BE0009D60
|
|
||||||
:20CBE0002E68A52E09D00660AE888680ED68C5600161836041618161DDE781800360C160C5
|
|
||||||
:20CC0000F6E700F085F9002803D00022114602F095FB0320B3E781800360C1600099896807
|
|
||||||
:20CC20008160C9E70EB557480090202001900120029002F001F8002804D150496846091D98
|
|
||||||
:20CC400002F023F80EBD10B5FFF7E4FC002805D100F02FFB0446FFF728FF204610BD70B58A
|
|
||||||
:20CC600011DF002803D00022114602F067FB464900200B68444C012180340A4682401A4206
|
|
||||||
:20CC800004D0C506ED0E0A46AA402260401C2028F3D303242403A06813DF002803D000226F
|
|
||||||
:20CCA000114602F04BFBA06802F0F2F970BD08B5684600F06DF800980168A52904D0806888
|
|
||||||
:20CCC000AA2801D0002008BD012008BD10B5FFF797FE002803D1FFF773FE00281BD064209C
|
|
||||||
:20CCE00001F0F2FDFFF712FE002803D00022114602F024FBFFF784FE002803D000221146DD
|
|
||||||
:20CD000002F01CFBFFF73CFE040003D00022114602F014FB204610BD00B589B018221B49CA
|
|
||||||
:20CD200002A8FFF785FA069807990090019102A80FC8FFF707FFFFF7B8FE002009B000BDB5
|
|
||||||
:20CD400010B50E4988B0044600232022091D684602F04FF80098206068468088A08003983A
|
|
||||||
:20CD6000E0600298A06004982061059860610698A0610798E06108B010BD00002C280020E6
|
|
||||||
:20CD8000282D00208DCA030000E100E0C0F70300014901607047000000FC030008280CD0DC
|
|
||||||
:20CDA00004DC002807D006280FD108E00B280AD00C280AD105E001207047022070470320C9
|
|
||||||
:20CDC000704704207047042901D0062070470520704770B515460A46032823D0042820D1FF
|
|
||||||
:20CDE000FE4C002906D0E088FD49884219D0132176DF10E0284602F0A3F9002803D00022F7
|
|
||||||
:20CE0000114602F09BFAE069A8420AD101220321F44801F003F8002803D00022114602F051
|
|
||||||
:20CE20008DFA70BD01211046FFF7B8FF02460121EEE7F0B5054608790E4685B081070CD07C
|
|
||||||
:20CE400003221146284600F0E9FF002803D00022114602F073FA05B0F0BDE04900901831D9
|
|
||||||
:20CE600002F047F9010011D1DC4CB168009AA06902F02DFB009802F097F9010006D1204647
|
|
||||||
:20CE80006946183002F09CF9010003D0284600F0AFFAE0E704200190009880080290A06902
|
|
||||||
:20CEA000039001A8FFF74AFC07000BD0092F10D0A06902F045F9010002D0284600F098FA04
|
|
||||||
:20CEC0003946E3E73079616940186061A069E061C1E7307961694118616160780028BAD073
|
|
||||||
:20CEE0006089401E0004000C6081B4D1284601F0E9F8002803D00022114602F01FFA20890D
|
|
||||||
:20CF00006081A8E710B50022114602F017FA10BD10B5B24C01202070E088B149884208D01B
|
|
||||||
:20CF2000132176DF002810D00022114602F006FA0BE0A078002808D074DF002803D0002282
|
|
||||||
:20CF4000114602F0FBF90020A07001F034FC002803D00022114602F0F1F9002010BD70B5E1
|
|
||||||
:20CF60000D68044601209D4A2B0002F002FC0A2B3043061320575C466012FFF76FFC0421FD
|
|
||||||
:20CF8000FFF70CFF024604212EE00022114602F0D5F970BDFFF7BCFF002803D0002211468A
|
|
||||||
:20CFA00002F0CCF9FFF775FC002808D170BDFFF7AFFF002803D00022114602F0BFF9FFF76D
|
|
||||||
:20CFC0007CFC70BD106188680078107170BD02201061886800780128F8D1FFF7E5FB02213F
|
|
||||||
:20CFE000FFF7DCFE02460221204600F017FF0028CBD170BD0320106170BD12692046012ACC
|
|
||||||
:20D0000006D0022A07D0032AF6D1FFF712FF70BD00F001FA70BD00F03BFA70BD50708888D5
|
|
||||||
:20D020001081508170BD00205070108170BD2046516901F010F8DAE710B5044669488EB0EB
|
|
||||||
:20D0400081796846817068490180342101A802F09DFA022001900021684641728472012131
|
|
||||||
:20D0600001820590002101A801F03FFA002803D00022114602F062F90EB010BDF0B5574C10
|
|
||||||
:20D080008BB0A07800283AD156481821183802F07DFA2046534CC078183C00250126002875
|
|
||||||
:20D0A00037D02746483700950195029510226946F81D039502F0DEF9002822D0F81D08909D
|
|
||||||
:20D0C00009976846067509A804906846067708A806900420FFF7B0FF25700220207204A813
|
|
||||||
:20D0E000E060282020823F486582183873DF002803D00022114602F021F9384886700BB045
|
|
||||||
:20D10000F0BD0520FFF798FF2670676025722582E9E70620FFF790FF257065602572E0E7E2
|
|
||||||
:20D1200070B52E4C01880022E588A6B017290AD01EDC11293FD008DC022977D0102902D123
|
|
||||||
:20D140008088E080A27026B070BD264C303426461836132951D01429F5D1C289638D002106
|
|
||||||
:20D160009A4200D1314600238088E21D82DF1BE0512970D00EDC18296CD01929E3D18079F5
|
|
||||||
:20D180000028E0D1A270E068401EE0604FD0FFF775FFD8E7522976D05529D4D18079002871
|
|
||||||
:20D1A000D1D11321284676DF0028CCD00022114602F0C4F8C7E78020694688803220E06054
|
|
||||||
:20D1C000012301AA06A92846AADF002803D00022114602F0B3F82078002807E038280020A2
|
|
||||||
:20D1E000FFFF0000602D00203015000001D1FFF745FF0020C043E080A5E70722C14910A839
|
|
||||||
:20D2000002F065F91022E11D0CA802F060F91C22314612A802F05BF90CA80A9012A8099039
|
|
||||||
:20D2200006ABB94A852128467FDFBDE70DE01822B64906A8FEF7FCFF0A980B9900900191F8
|
|
||||||
:20D2400006A80FC8FFF77EFC7DE70021284667DFAAE700E017E0817900299AD0807A042885
|
|
||||||
:20D2600003D0062801D0052893D1022909D0012069460872FF208330888102A92846A8DF82
|
|
||||||
:20D2800092E70220F4E700F08DF88DE710B5044601F0C2FA9B482146303800F09AFE2046D3
|
|
||||||
:20D2A000FFF73EFF10BD10B50022114602F046F810BD30B5944D87B00024203D2C7094483D
|
|
||||||
:20D2C0002C6102F0B3F800286AD19248FFF7E4F901F000FF002863D18A4800F059F900288C
|
|
||||||
:20D2E00001D10120E87011206946087207228AA102A87CDF002803D00022114602F01EF8B4
|
|
||||||
:20D3000000940C2168460194018018214180FF2184809131C1807ADF002803D0002211469A
|
|
||||||
:20D3200002F00CF804206946009408807C4801907C4802907348303800F00BFE002803D046
|
|
||||||
:20D340000022114601F0FAFF1C21684602F01EF9754801900120800302900094032168468C
|
|
||||||
:20D360000173C4810474714806900594684601F0FEF9002803D00022114601F0DFFF624910
|
|
||||||
:20D38000E12208784008400010400C30DF22104008700720487010208870FFF76FFE0020A3
|
|
||||||
:20D3A00007B030BD70B5584C614D203CE088A84201D1082070BDE178002914D05149012359
|
|
||||||
:20D3C00008223431A9DF0028F4D12A460C21E088A7DF5849884204D0082802D0891C88420E
|
|
||||||
:20D3E000E8D1002070BD00231A461946A9DF70BD10B50A46044603211046FFF7CFFC0246AE
|
|
||||||
:20D400000321204600F00AFD002803D00022114601F094FF10BD30B5054687B000200090AF
|
|
||||||
:20D4200001900290039038486A46203800791070364A0C3A1068926804906846069205900E
|
|
||||||
:20D4400008790C2806D003221BE00022114601F075FFA5E78C68204600F049F80190201D5E
|
|
||||||
:20D4600000F045F802902046083000F040F8039004A8FFF714F9002892D00121FFF78EFCB9
|
|
||||||
:20D4800002460121284600F0C9FC0028DDD187E7FEB50446087982070ED08207920F042385
|
|
||||||
:20D4A0009B1A0022154604E08E683554401CC0B2521C9A42F8D30871012000908868029048
|
|
||||||
:20D4C0000879800801906846FFF785F900280DD00221FFF763FC02460221204600F09EFCB8
|
|
||||||
:20D4E000002803D00022114601F028FFFEBD10B5044602F04DF80002E178000A09060843E0
|
|
||||||
:20D5000010BD0000902D002058280020E4F703008DD20300D3CD0300446675546172670031
|
|
||||||
:20D520005FCF0300A7D20300CD0C000005CF0300FFFF00000230000010B50C46002802D04D
|
|
||||||
:20D540000120086010BD2168002911D01C48421A814212D03C2A0DD23C303C3101220B78B9
|
|
||||||
:20D5600003701346491E401E521C3C2BF7D904E00E200BE03C2201F0AAFF00223C211048A9
|
|
||||||
:20D5800001F08AFD0E49891E08800020206010BD70B5054600223C21094801F07DFD084C21
|
|
||||||
:20D5A000A41E2188884201D00B2070BD3C220449284601F08CFF2088401C2080002070BD87
|
|
||||||
:20D5C000823F00208307FF22DB0E9A408907090E994000280BDA0007000F08388308FA484C
|
|
||||||
:20D5E0009B001B18D86990430843D86170478308F6489B001B1818689043084318607047AA
|
|
||||||
:20D6000070B50124F24960040860F24940108860F04940398860F04D6C602F20FEF7B6FDAC
|
|
||||||
:20D62000AC60EE4D00242F206C61FEF7AFFD2C7170BDF0B5E94F2821BC6841430D19396962
|
|
||||||
:20D640004A1C09D028224A431619AB68B268934204D8D21AB26069623861F0BD0A4602E066
|
|
||||||
:20D660000A46796A9B1B4E1C0BD028264E433719BE689E42F4D328264E433619B768FF1A1A
|
|
||||||
:20D68000B760AB60696228214A4311194862F0BD70B5D24C2269A5681346114606E0814212
|
|
||||||
:20D6A00007D00A46282671434919496A4E1CF6D170BD002EFCD08A420CD1282043435819EC
|
|
||||||
:20D6C000406A2061401C05D1C34B01209860002363616071282041434819282381685A4310
|
|
||||||
:20D6E000406A52195062421CE2D028225043401982685118816070BDF8B5B84C2569681CF9
|
|
||||||
:20D7000035D0B748002640686169401A07023F0A19E028204543A0682A189068B84214D8D0
|
|
||||||
:20D72000A3693F1A8619556A002B09D0116AD0699847002807D00022114601F0FFFD02E048
|
|
||||||
:20D74000D169106A8847681CE3D1A178E078814206D1401CC0B2E070022801D10020E07079
|
|
||||||
:20D760009E490006800D1C310E5000F0BAF9F8BDF8B50446994800270169009146785CE038
|
|
||||||
:20D780009648F100C2688D1851E0601C07D0934A28209268604321468018446A24E0287854
|
|
||||||
:20D7A000182141436A68401CC0B252182870A978884200D12F70894B516828209B6848434C
|
|
||||||
:20D7C000C0181368012B34D1037E002B31D19368C360D368036113694361526902627F4A52
|
|
||||||
:20D7E0005279002A00D0C7607C4BC2685B6996469C46D31A1A027B4B120A9A4202D20369C3
|
|
||||||
:20D80000D21808E0724663469A1A12020369120A934202D99A1A826000E08760C76001222E
|
|
||||||
:20D8200007610276921E42620846FFF702FF601CABD1287869788842A7D13046761EF6B202
|
|
||||||
:20D8400000289DD1654801690098814201D00120F8BD0020F8BD644900200860486088607F
|
|
||||||
:20D86000C860614940390860486045E7FEB50020C0435A4D02906869019068462E6900F07B
|
|
||||||
:20D8800035F9074600F04FF90446002F08D002AA0199009800F08FF90298FFF769FF06E050
|
|
||||||
:20D8A0000298FFF765FF002801D1002C02D0304600F0AAF900206871FEBDFFB59807002448
|
|
||||||
:20D8C00081B01E4615460F4600280BD1002E09D0FFF796FE41490A9888610F703246002042
|
|
||||||
:20D8E0008E6008E0072005B0F0BD28234343D4509B181C76401CB842F7DB28204743BB19C1
|
|
||||||
:20D90000032048700F461846CB6019461830002218232E465E43D3005B181C705C709D708A
|
|
||||||
:20D9200058603018521C032AF5DB0020C0433861BC70FC7001242D482405046003211420A9
|
|
||||||
:20D94000FFF740FE224880380460254C0198A06003211120FFF736FE606878610020C2E71A
|
|
||||||
:20D9600070B51E4CA568002D06D0002A06D0002804D00023247809E0082070BD072070BDBB
|
|
||||||
:20D9800028265E43AE59002E04D05B1CA342F7DB042070BD282401265C432E516419E261BF
|
|
||||||
:20D9A00061600360002070BD07494868C005C00D2CD010381CD50207120F083A9208920097
|
|
||||||
:20D9C0005118C96919E0000000ED00E000E400E080E100E040130140001001406028002054
|
|
||||||
:20D9E00000150140FFFF7F004011014080E200E08108B14A8900891809688007C00EC1400B
|
|
||||||
:20DA00000806800F012803D0032803D0022070470020704701207047FEB50446A74817469E
|
|
||||||
:20DA200082680D46002A0CD001788C4201D2052D01D20720FEBD2146282359435358012B7D
|
|
||||||
:20DA400001D00820FEBD8818406801281DD00026FFF7AAFFC00099490190C9684018694684
|
|
||||||
:20DA600000F018F9002812D0012144600160944949680830E2C091490198C9684118009877
|
|
||||||
:20DA8000487000F02EF80020FEBD2E46E0E70420FEBDF8B5894D0446A868002809D0297844
|
|
||||||
:20DAA0008C4201D30720F8BD282161434058012801D00820F8BDFFF777FFC600E86869465B
|
|
||||||
:20DAC000301800F0E7F8002809D0022112C0E86831180098487000F004F80020F8BD04206B
|
|
||||||
:20DAE000F8BD0120774900050860704710B5734900238A78CC78A24212D0521CD2B28A70D0
|
|
||||||
:20DB0000022A00D18B708A786C4B92001C339A580260486910180002000A4861012010BDA3
|
|
||||||
:20DB20000360002010BDF8B5644801690091457833E06248E900C0680E1834782AE01820A2
|
|
||||||
:20DB400060437168641C0818B178E4B2A14200D100240168022902D003291BD113E0574A00
|
|
||||||
:20DB600040682821926841438F18397E002911D0FFF78EFD002038760CE028277843C018B1
|
|
||||||
:20DB80000276406A03E04D4900228B680869471CF3D108617078A042D1D128466D1EEDB2D0
|
|
||||||
:20DBA0000028C6D1454801690098814201D00120F8BD0020F8BDF7B5404C0025A7682369E0
|
|
||||||
:20DBC0001EE028215943C9198E68864202D9301A886017E0801B751900268E600E764E6946
|
|
||||||
:20DBE0009C464B6AB646002E0AD0019E76193602360ACE6076460E6116684E626146116045
|
|
||||||
:20DC0000591CDED12361FEBDF8B52C4801694A1C3DD028225143826889188E6828494C681F
|
|
||||||
:20DC200047690079E11B0D022D0AED1C002815D10120254A00045060234A403A506021491D
|
|
||||||
:20DC4000400080310860214908602149012008602F20FEF79BFA194901200871B54200D208
|
|
||||||
:20DC60003546E81900021649000A4031086014494968001B091B0902090A0002C91C000A88
|
|
||||||
:20DC8000814203D901200F4940040860F8BDFFF7B7FCF8BD42788378521C934200D10022C2
|
|
||||||
:20DCA0000378934201D1002070470A6041684078182250430818704700E400E06028002090
|
|
||||||
:20DCC0000015014000E200E04013014000E100E00010014010B50446082904D000221146F9
|
|
||||||
:20DCE000104601F02BFB21686068884710BD1CB501910090024A0821684601F09DFA1CBD53
|
|
||||||
:20DD0000D5DC03000A48026803210A4302600948804709480047FEE7FEE7FEE7FEE7FEE797
|
|
||||||
:20DD2000FEE7000005480649064A074B70470000240500404DDD0300C1C003009830002007
|
|
||||||
:20DD4000983C00209834002098340020F8B500F035F82B4E002804D02A4870602A49F01300
|
|
||||||
:20DD600088612A480124018CC9B201290DD1818C09070AD1018D0906090F042905D1808D56
|
|
||||||
:20DD80000006000F01D1224884600027B461214D6F60A8058460686800280ED1C820FEF790
|
|
||||||
:20DDA00005FA1D487F1C8742F5D30020B06101208007846068680028FCD0F8BD1348018CB5
|
|
||||||
:20DDC000C9B2012917D1818C090714D1018D09060A0F03D1828D1206120F0ED0090F0129C2
|
|
||||||
:20DDE00003D1828D1206120F07D0032903D1808D0006000F01D0002070470120704700008E
|
|
||||||
:20DE000000050040DFFF07C0006C0040C00F00F000060040000100408813000030B585B071
|
|
||||||
:20DE2000002822D00388FE4CA34220D0FD4B1B78002B1CD0FB4B10255B1C1D7059700024C0
|
|
||||||
:20DE400001259A70032269460A820094019402940394028A0A808D708C8004A902910393E7
|
|
||||||
:20DE600000886946A6DF05B030BD0E20FBE70820F9E7F0B58BB0044602276846077300268B
|
|
||||||
:20DE800009968784C68408A80A900D46A18A208809AAA5DF002804D0E16A00291AD08847BE
|
|
||||||
:20DEA00018E06846008CC007C00F13D068460682208803A9A8DF002813D1A97E28461B30BA
|
|
||||||
:20DEC00001220B0001F055FC09430F1B202224263E284300FF20FE3069460882208803A94D
|
|
||||||
:20DEE000A8DF0BB0F0BD00960AE0062219E069460A71029022E0204690470020F1E700920D
|
|
||||||
:20DF00002B8B022BF3D2F0E700971DE003201AE0042018E0052016E0298B032905D20322BE
|
|
||||||
:20DF200008212046FFF77AFFDBE741780278080210436946888003D006200090A26ADAE784
|
|
||||||
:20DF40000720FAE7092000906946A26AD3E70322E7E730B585B00D46040038D0002D36D0EC
|
|
||||||
:20DF60006868002833D00020C043AF4B20800FCB049301AB07C3AD4869460880891C01A888
|
|
||||||
:20DF800063DF002822D1221D69460120A0DF00281CD168468078A071204600F0CEF8002886
|
|
||||||
:20DFA00014D1204600F055F900280FD12946204600F002F9002809D16868A062A868002804
|
|
||||||
:20DFC00000D0E06297490120087000204BE70E2049E73EB5002828D0002926D0826A002ABE
|
|
||||||
:20DFE00023D00A88102A21D0112A30D0502A1FD0512A1AD104460846891D0A78022A14D196
|
|
||||||
:20E000004A88238A9A4210D1807A04280DD006280BD0052809D0891C2046FFF72AFF002860
|
|
||||||
:20E0200003D0E16A002900D088473EBD898810E0CA8803899A42F8D1082200928A7F6B4605
|
|
||||||
:20E040001A7120310291826A694690473EBD0021C94301803EBDF0B585B00A4605002DD00F
|
|
||||||
:20E0600028886F4988422BD06E480078002827D06C4C1020641C2070072060700127A770F8
|
|
||||||
:20E080000321684601820026E11C104600F04CF801466846008A0918684601820096019680
|
|
||||||
:20E0A00002960396298A01808770868004A80394029028886946A6DF05B0F0BD0E20FBE7D3
|
|
||||||
:20E0C0000820F9E7F0B585B00A46050028D028885349884226D053480078002822D0514C3B
|
|
||||||
:20E0E0001120641C20700127684607820026611C104600F019F801466846008A0918684638
|
|
||||||
:20E1000001820096019602960396298A01808770868004A80394029028886946A6DFCBE782
|
|
||||||
:20E120000E20C9E70820C7E70870020A4A70020C8A70000EC8700420704730B58FB0054655
|
|
||||||
:20E140001C21684601F022FA694608780421084369460870002401940394049405940694E6
|
|
||||||
:20E16000A87908A9887031486946801C0884601C00070794000F0C77103048778A7FF920B4
|
|
||||||
:20E180000240921CE7200240012002438A77142109A801F0FBF908A8099007A80A906946D3
|
|
||||||
:20E1A0008C851420CC8508860D942B46A888083309AAA2DF0FB030BDF0B58FB00F4605465A
|
|
||||||
:20E1C0001C21684601F0E2F968460178022631430170002401940394049405940694A97917
|
|
||||||
:20E1E00008A8817011496846091D0184601C0107090F103168460794017700200146684618
|
|
||||||
:20E200004177817FF9200140891CE72001400120014368468177142109A801F0B7F907E086
|
|
||||||
:20E22000FFFF000088280020FCF703003015000008A8099007A80A9068468685C4850686B5
|
|
||||||
:20E240000D972B46A888203309AA6946A2DF0FB0F0BD30B58FB005461C21684601F096F9FD
|
|
||||||
:20E2600069460878082108431022104369460870002401940394049405940694A87908A962
|
|
||||||
:20E280008870144869460884601C00070794000F0C7710304877887FF9210840801CF72123
|
|
||||||
:20E2A000084010430121084369468877142109A801F06CF908A8099007A80A9069468C851A
|
|
||||||
:20E2C0001720CC8508860D942B46A888103309AAA2DF6FE731150000FFB583B0074600207F
|
|
||||||
:20E2E0000C9C8646267805463AE07868A90041180A88684682804988C1800022694601A8F7
|
|
||||||
:20E3000065DF002810D1684601780598814226D17046002801D0002200E002222078891824
|
|
||||||
:20E3200041181F2902D90C2007B0F0BD7146002908D1401CC0B2411C069B049A21701A54AF
|
|
||||||
:20E3400001208646217806980A18694601A865DF0028E9D1694620780978401820706D1CC0
|
|
||||||
:20E360003888A842C1DC7046002804D020780699801B401E88550020D6E7F8B51546069C10
|
|
||||||
:20E380001E46074602220094FFF7A6FF002806D133461022294638460094FFF79DFFF8BD07
|
|
||||||
:20E3A000F7B582B000260546167000681446002805D02846039900F0CAF8060008D168794D
|
|
||||||
:20E3C00000281ED02078039F001D1F2802D90C2005B0F0BD684679DF0028F9D1217803226A
|
|
||||||
:20E3E000481C20707A5421781922481C20707A542078C1196846008800F0A4F821784018A0
|
|
||||||
:20E400002070A8790223002810D02078039A411C2170135420780399471C012227700A54E5
|
|
||||||
:20E420002078AA79471C039927700A54A868002815D00021415620788C460246C01C03992E
|
|
||||||
:20E440001F28C4D8501C20708B5422780A23501C20708B5420786246431C23700A54A8899B
|
|
||||||
:20E46000002809D028460094062202210C30039BFFF783FF0600ABD1A88A002809D02846D9
|
|
||||||
:20E480000094072203211430039BFFF776FF06009ED1A88B002809D0284600941522142137
|
|
||||||
:20E4A0001C30039BFFF769FF060091D1686A002805D02246039900F07FF8060088D1A86A01
|
|
||||||
:20E4C000002805D02246039900F0B5F8060084D13020405D002806D022462846039900F0F6
|
|
||||||
:20E4E000DCF80600C7D1304672E770B50C4692B000216A46117007251171002809D0817927
|
|
||||||
:20E5000049070CD502A9FFF74BFF002808D102AE00E00026002C0ED0A079002802D028469D
|
|
||||||
:20E5200012B070BD01AA0AA92046FFF739FF0028F6D10AAA00E0002268460379017830463C
|
|
||||||
:20E5400072DFEDE70870000A487002207047F8B514780746A01C15460E461F2803D83879BF
|
|
||||||
:20E56000801C1F2801D90C20F8BD1D20001B80B26946864608803019801C7DDF0028F3D143
|
|
||||||
:20E580003868022805D168460088704501D8092107E038790821002801D0704501D96846F6
|
|
||||||
:20E5A0000088421C3255641CE2B2B1542978801C081828700020F8BDF8B50D461178064636
|
|
||||||
:20E5C000881D14461F2801D90C20F8BD33880720062BFAD31927FF01BB4202D94D4A9342D6
|
|
||||||
:20E5E000F3D17288062AF0D3BA4202D9494FBA42EBD1484FBB4203D0BA4201D09342E4D87E
|
|
||||||
:20E60000481C052220706A5420781222411C21702A54207841193088FFF794FF21784018C5
|
|
||||||
:20E62000C0B2207041197088FFF78CFF2178401820700020F8BD70B5054600790E46801CD6
|
|
||||||
:20E640001446C0B21178821C8A181F2A01D90C2070BD0A46491C401C2170B0542078FF224A
|
|
||||||
:20E66000411C21703254207881192888FFF76AFF21784018C0B22070AA88002A09D0A968AC
|
|
||||||
:20E68000002908D0801900F022FF2078297940182070002070BD072070BDF7B582B0029894
|
|
||||||
:20E6A0001446C06A0F46002832D0029800252030009028E00298C16A0C2068430E18217855
|
|
||||||
:20E6C00030794A1CC01C2270785421781622481C20707A542078C1193088FFF733FF217873
|
|
||||||
:20E6E0004018C0B22070B288002A09D0B16800290ED0C01900F0EBFE207831794018207087
|
|
||||||
:20E700006D1C0098EDB2007CA842D3D800205FE607205DE6FFFF000038B56749674A48883D
|
|
||||||
:20E7200090420FD04A78664C521CD2B24A70237B934208D3083175DF002803D0A1690029FF
|
|
||||||
:20E7400000D0884738BD00254D70217C002907D03B2176DF002803D0A169002900D0884728
|
|
||||||
:20E7600061690029EED068460095884738BD70B5054601461C225248FDF75AFD4E4C002647
|
|
||||||
:20E7800026702968002907D00822A01800F09FFE204608307ADF02E0474808307BDF0028C1
|
|
||||||
:20E7A00008D1401E608044486670464A0021001DFFF7D6F870BD10B53F484068FFF769F9D5
|
|
||||||
:20E7C00010BDF8B53C48103000F069F800263A4D3B4C002806D06169002919D001200090EB
|
|
||||||
:20E7E000684614E02878002804D0616900290FD00096F5E7687800280CD0A16800226868B8
|
|
||||||
:20E80000FFF70AF9002803D0A169002900D088472E70F8BD6168F1E7F8B5294C028800276B
|
|
||||||
:20E82000254DE689102A18D029464968112A21D0122A2DD0502A0FD1801D0288B2420BD1FF
|
|
||||||
:20E84000028B022A08D1C27E837E10021843C007C00F13D0FFF7B5FFF8BD81886980014667
|
|
||||||
:20E86000154808221631103000F031FE6F70002EF0D0F8BD0020C04368806F700846FFF7BB
|
|
||||||
:20E8800008F90028F5D0A1690029F2D08847F8BD811D09480822103000F019FEDAE7418827
|
|
||||||
:20E8A000054808300288914204D34088814201D8012070470020704790280020FFFF0000B6
|
|
||||||
:20E8C000CC2D002019E7030031B5054C04E0401E00902046FDF77AFC00980028F7D138BDC6
|
|
||||||
:20E8E000E703000018225043FE4A00218018017181604161012281610261C1607047FFB577
|
|
||||||
:20E9000081B0F94C049B039A054626691A4303200092002E03D1002A0ED001222261276919
|
|
||||||
:20E92000039A0126360792003B0000F022FF072707162940526127000222EFE770693269FC
|
|
||||||
:20E9400092B25043326933691204920C9BB2594329DF002812D102210FE0084628DF00286A
|
|
||||||
:20E960000CD10399002901D0032106E00499002916D12978042946D017E0216105B0F0BDAE
|
|
||||||
:20E980007069326992B25043326993B24B4301461846039A29DF0028F0D10499002901D0F4
|
|
||||||
:20E9A0000421EAE72978042920D00521E5E773693069366980B2434368681B189B18B6B2C7
|
|
||||||
:20E9C0004E43301880181946049A29DF0028E9D0D4E7306980B24843696880188A08696902
|
|
||||||
:20E9E00029DF0028CAD1009900290CD00621C4E77069316989B24843316989B200F0D9FD08
|
|
||||||
:20EA000028DF0028BAD10721B7E7F8B5B54918230A780F205A435418241DB3492278266970
|
|
||||||
:20EA2000CF68022A1BD001252D07042A2AD0052A5BD1286981B2304600F0BBFD0146A36877
|
|
||||||
:20EA400028699A1980B24843101A820860681818861928694B1C80B25843801B34E0B8023C
|
|
||||||
:20EA600062686169121A0918A3683018181801239B029A4202D2920829DF31E0FF220132BA
|
|
||||||
:20EA800029DF2DE0E268974914205043F4314018001D0BC8B04203D160685943814218D02E
|
|
||||||
:20EAA000022A16D0286981B2304600F082FD0146286980B24843301A820828694B1C80B208
|
|
||||||
:20EAC000584363689B19C01A83082046FFF717FF06E0286981B2304600F06BFDC01928DFED
|
|
||||||
:20EAE000002802D17F4901228A70F8BDF8B57D4C069E65780A2D1DD027787D19EDB20A2D5B
|
|
||||||
:20EB000001D30A3DEDB218277D432D192871AA6103C9EE60AB6069612861A1780020002978
|
|
||||||
:20EB200004D1FFF772FF112800D100206178491C6170F8BD0420F8BD38B5024669481823B1
|
|
||||||
:20EB400001785943081803690179022B0AD014246343644CF434E4588368009383691030F7
|
|
||||||
:20EB6000A04738BD604B14331C68F5E7F8B55D4B9978012914D100255B499D700A69082A77
|
|
||||||
:20EB800005D002280FD003280AD10D2006E0022807D00D7000F025FA002801D0FFF7CCFF37
|
|
||||||
:20EBA000F8BD0D61F6E74F48182403784E496343CC681818641C001DCC600378022B05D11F
|
|
||||||
:20EBC0004668A102B14201D3012700E00027052B01D1072A03D00021042B02D003E00121C1
|
|
||||||
:20EBE000FAE7072A03D00026042B02D007E00126FAE74068A302834201D3002A1AD0002000
|
|
||||||
:20EC0000314301433943C5D0374E28463561FFF793FF344C2078FFF765FEF5606078401E1E
|
|
||||||
:20EC200060702078401CC0B220700A28B2D30A382070AFE70120E3E770B500252A4C2948D3
|
|
||||||
:20EC4000E56025610570457085702E463046FFF749FE761C0A2EF9D3012212076560516952
|
|
||||||
:20EC600028461269491E92B25143E560A1601D49F4310D608D600D61CD601B4914310D6090
|
|
||||||
:20EC8000888001212170206170BDF8B5164A044610780E46002830D0002C30D0002E2ED058
|
|
||||||
:20ECA000206800282BD0012000076768016989B28F4228D8102F26D3A168002923D09568E2
|
|
||||||
:20ECC000794343694A19006980B243439A421AD801200007006980B2814212D901200007E1
|
|
||||||
:20ECE000006903E0E82D0020A828002080B2394600F05FFC002906D103E00820F8BD0E20B9
|
|
||||||
:20ED0000F8BDB80701D00720F8BDBD49486801281CD00F461421BB4A21C641438E18756092
|
|
||||||
:20ED2000236853506168B160A168F160A268616800235143012212075B1C14699BB2A4B214
|
|
||||||
:20ED40008C4205D21469A4B2091B02E00420F8BD00211469A4B265191469A4B28C42EBD985
|
|
||||||
:20ED6000BD60401C336178600020F8BDF8B50446A3481E46007815460F46002807D0002F3D
|
|
||||||
:20ED800007D0002C05D02068002817D103E00820F8BD0E20F8BD9B48016800290ED0C268E3
|
|
||||||
:20EDA000816840684A4310186268904206D9002D04D0A94202D3A819884201D90720F8BD90
|
|
||||||
:20EDC000384600F008F9002811D0304600F003F900280CD0606800F0FEF8002807D02B4637
|
|
||||||
:20EDE0003A46214602200096FFF780FEF8BD1020F8BDFFB5824881B000781F4616460D462B
|
|
||||||
:20EE0000002808D0002D08D00198002805D02868002817D103E00820B0E50E20AEE5794C91
|
|
||||||
:20EE2000206800280ED0E168A0686268414389186A68914206D9002E04D0B04202D3F119AD
|
|
||||||
:20EE4000814201D9072099E5019800F0C4F800281BD0384600F0BFF8002816D0686800F025
|
|
||||||
:20EE6000BAF8002811D068683246C119019800F02EFB00962868142148432458002203215B
|
|
||||||
:20EE80002846019BA047002078E5102076E5F8B505465B480F460078002805D0002D05D012
|
|
||||||
:20EEA0002868002821D103E00820F8BD0E20F8BD544C00262068002817D0A168E0684843CC
|
|
||||||
:20EEC00061684118686881420FD900F084F800280DD0296814225143091968684A68896834
|
|
||||||
:20EEE000801A00F066FB002903D00720F8BD1020F8BD3B460022294604200096FFF7F6FDB5
|
|
||||||
:20EF0000F8BD3F4A1278002A0DD000280DD000290BD00268002A08D0394A14321368002B3E
|
|
||||||
:20EF200005D004207047082070470E20704702230B600068106000207047F8B504463048AF
|
|
||||||
:20EF40001E46007817460D46002807D0002D07D0002C05D0206802281BD103E00820F8BDC3
|
|
||||||
:20EF60000E20F8BD264814300068002811D0084600F031F800280ED0304600F02CF800286C
|
|
||||||
:20EF800009D03B462A46214602200096FFF7AEFDF8BD0720F8BD1020F8BD08B5184A1278C8
|
|
||||||
:20EFA000002A05D0002805D00268022A11D103E0082008BD0E2008BD114A14321268002AD5
|
|
||||||
:20EFC00007D00B460022014604200092FFF78EFD08BD072008BD800701D000207047012068
|
|
||||||
:20EFE0007047084910B5F43949780020002906D0FFF70BFD002802D0112800D1002010BD48
|
|
||||||
:20F00000A8280020DC2E002070B500250C290ED304464318008941000919581A0A38C2B2BD
|
|
||||||
:20F020001748022A027002D30A318B4201D2092070BD144800F04BFA134914480A8882422E
|
|
||||||
:20F0400002D02388934217D14988814202D06088884211D10D4A0323521E20891B03A842DE
|
|
||||||
:20F060000AD9690009194989914203D09E896D1CB142F4D1002070BD0B2070BD00207047C6
|
|
||||||
:20F08000C4280020F02E002080100010FFFF000010B5FDF7ABF810BD10B50446002A02D054
|
|
||||||
:20F0A0001088002210E00A48FBE7030A00020343A05C584003061B0F43401803584083B2EB
|
|
||||||
:20F0C0001806C00C5840521C8A42EED310BD0000FFFF00004B48002101704C484A4A026039
|
|
||||||
:20F0E0008160C160016108224161426081610846704710B500291DD000220A60434A5368A8
|
|
||||||
:20F10000002B1BD0202817D85B1E5360D0682423401CD060106914684343E3180B60012366
|
|
||||||
:20F1200083409169401C19434007400F91611061002010BD0E2010BD0C2010BD042010BD8F
|
|
||||||
:20F14000F0B5324A0646916800292BD057691020791A4907490F14680B4624254D436519D6
|
|
||||||
:20F16000B54206D1012495698C4065400020956104E0491C4907490F8F42EED1491C4E07DC
|
|
||||||
:20F18000760F956901210C469C402B4623420AD19368002B07D05B1E936053685B1C53609D
|
|
||||||
:20F1A0003346F0E70420F0BD184A2423117C1268491E4907490F594320315050002070470B
|
|
||||||
:20F1C00070B500281AD0002918D0104AD368002B16D05B1ED360936824265B1C936053692A
|
|
||||||
:20F1E00015681C467343EE1820330660E858641C08606007400F5061002070BD0E2070BD84
|
|
||||||
:20F20000042070BDC5280020FC2E00201C30002030B5CB0008339DB293070024002B01D0E6
|
|
||||||
:20F22000072030BD3B4B9A605219DA605C701C7058809980002030BDF7B5364C0E466088D5
|
|
||||||
:20F24000814237D8344F00F069F822786078A188884201DA401C00E00020C0B2904202D155
|
|
||||||
:20F2600000F062F824E065786078884201DA401C00E00020607000F057F8BD4218D0A0688C
|
|
||||||
:20F28000EF000299C151009900290CD0002E0AD0608832464543E068281800F018F9A068B3
|
|
||||||
:20F2A0003818868002E00021381881800020FEBD0420FEBD0920FEBD0EB504E068468188A8
|
|
||||||
:20F2C000029A0098904702AA01A9684600F003F80028F3D00EBD70B50E4B05241D785E786C
|
|
||||||
:20F2E000AE4215D01D781C789E88B44201DA641C00E000241C705C88DE686C43A41904600F
|
|
||||||
:20F300009B68E800C418A4880C80185800241060204670BDCC280020FFFF000072B606484F
|
|
||||||
:20F320000168491C0160704703490868401E086000D162B670470000DC280020BFF34F8F11
|
|
||||||
:20F3400003490248C860BFF34F8FFEE70400FA0500ED00E010B5002904D000221146104619
|
|
||||||
:20F36000FFF7ECFF00F010F810BD10B50021024A0846FFF761FF10BD55F3030010B50846E6
|
|
||||||
:20F380001146FCF771FF10BDF8B5384C2078002837D02069002807D00026E068002805D0FB
|
|
||||||
:20F3A0000025002E04D013E00126F6E70125F8E7684651DF052806D0002806D000221146D2
|
|
||||||
:20F3C000FFF7BCFF04E0012602E0216900988847002D12D1608869460880A06861DF0528FA
|
|
||||||
:20F3E00006D0002806D000221146FFF7A7FF04E0012502E0E168A0688847002ED8D0002D15
|
|
||||||
:20F40000CFD0F8BD70B5002901D08C0701D0072070BD164C0125A16062801549636010DF46
|
|
||||||
:20F420000028F5D1257016202EDF70BD002803D00E49C860002070470E207047002803D0A8
|
|
||||||
:20F440000A490861002070470E20704710B507484068002807D08047002803D0002211463E
|
|
||||||
:20F46000FFF76CFF10BDFFF78FFF10BDE02800207DF30300034610B50B439B070FD1042A66
|
|
||||||
:20F480000DD308C810C9121FA342F8D018BA21BA884201D9012010BD0020C04310BD002AAC
|
|
||||||
:20F4A00003D0D30703D0521C07E0002010BD03780C78401C491C1B1B07D103780C78401C61
|
|
||||||
:20F4C000491C1B1B01D1921EF1D1184610BDF8B5042A2CD3830712D00B78491C0370401C25
|
|
||||||
:20F4E000521E83070BD00B78491C0370401C521E830704D00B78491C0370401C521E8B07F9
|
|
||||||
:20F500009B0F05D0C91ADF002023DE1B08C90AE0FCF78EFEF8BD1D4608C9FD401C46B440B8
|
|
||||||
:20F520002C4310C0121F042AF5D2F308C91A521EF0D40B78491C0370401C521EEAD40B78EC
|
|
||||||
:20F54000491C0370401C521EE4D409780170F8BD01E004C0091F0429FBD28B0701D50280F7
|
|
||||||
:20F56000801CC90700D00270704700290BD0C30702D00270401C491E022904D3830702D5EE
|
|
||||||
:20F580000280801C891EE3E70022EEE70022DFE70378C2781946437812061B0219438378A2
|
|
||||||
:20F5A000C0781B04194311430902090A000608437047002203098B422CD3030A8B4211D366
|
|
||||||
:20F5C00000239C464EE003460B433CD4002243088B4231D303098B421CD3030A8B4201D39D
|
|
||||||
:20F5E00094463FE0C3098B4201D3CB01C01A524183098B4201D38B01C01A524143098B422D
|
|
||||||
:20F6000001D34B01C01A524103098B4201D30B01C01A5241C3088B4201D3CB00C01A524193
|
|
||||||
:20F6200083088B4201D38B00C01A524143088B4201D34B00C01A5241411A00D201465241FB
|
|
||||||
:20F64000104670475DE0CA0F00D04942031000D34042534000229C4603098B422DD3030A47
|
|
||||||
:20F660008B4212D3FC22890112BA030A8B420CD3890192118B4208D3890192118B4204D305
|
|
||||||
:20F6800089013AD0921100E08909C3098B4201D3CB01C01A524183098B4201D38B01C01A88
|
|
||||||
:20F6A000524143098B4201D34B01C01A524103098B4201D30B01C01A5241C3088B4201D37F
|
|
||||||
:20F6C000CB00C01A524183088B4201D38B00C01A5241D9D243088B4201D34B00C01A52417F
|
|
||||||
:20F6E000411A00D20146634652415B10104601D34042002B00D54942704763465B1000D31A
|
|
||||||
:20F70000404201B50020C046C04602BD704770477047754600F022F8AE460500694653469B
|
|
||||||
:20F72000C008C000854618B020B5FEF7FBFA60BC00274908B6460026C0C5C0C5C0C5C0C525
|
|
||||||
:20F74000C0C5C0C5C0C5C0C5403D49008D4670470446C046C0462046FCF7FFFC004870479C
|
|
||||||
:20F760003830002001491820ABBEFEE726000200704730B47446641E2578641CAB4200D256
|
|
||||||
:20F780001D46635D5B00E31830BC184702000000000000000000000000000000040000009F
|
|
||||||
:20F7A000000000000000000000000000000000000000000035C4030000000000000000004D
|
|
||||||
:20F7C000020000000000000000000000000000000000000000000000030000000000000024
|
|
||||||
:20F7E0000000000005000000000000000000000000000000000000000000000023D1BCEA6A
|
|
||||||
:20F800005F782315DEEF1212000000002CF8030000280020F400000004C1030020F90300A1
|
|
||||||
:20F82000F4280020A413000020C103000000000000000000000000000000000000000000F1
|
|
||||||
:20F840000000000000000000000000000000000000000000000000000000000000000000A8
|
|
||||||
:20F8600000000000000000000000FFFF000000003200000000000000000000000000000058
|
|
||||||
:20F88000000000000000000000000000000000000000000000000000000000000000000068
|
|
||||||
:20F8A000000000000000000000000000000000000024F40000000000000000000000000030
|
|
||||||
:20F8C000000000000000000000000000000000000000000000000000000000000000000028
|
|
||||||
:20F8E000000000000000000000000000000000000000000000000000000000000000000008
|
|
||||||
:20F900000000000000000000000000000000000000000000000000000000000000000000E7
|
|
||||||
:20FC00000100000000000000FE0000000000000000000000000000000000000000000000E5
|
|
||||||
:020000041000EA
|
|
||||||
:0410140000C0030015
|
|
||||||
:040000050003C0C173
|
|
||||||
:00000001FF
|
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* S110/S120/S130 License Agreement
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015, Nordic Semiconductor ASA, All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution. Redistribution and use in binary form, without modification,
|
|
||||||
* are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* • Redistributions must reproduce the above copyright notice and the following
|
|
||||||
* disclaimer in the documentation and/or other materials provided with the
|
|
||||||
* distribution.
|
|
||||||
* • Neither the name of the copyright holder nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
* • No reverse engineering, decompilation, or disassembly of this software is
|
|
||||||
* permitted.
|
|
||||||
*
|
|
||||||
* DISCLAIMER.
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* /
|
|
|
@ -1,84 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2015-2017, ARM Limited, All Rights Reserved
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*
|
|
||||||
* 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 "cmsis.h"
|
|
||||||
#include "nrf_error.h"
|
|
||||||
#include "nrf_sdm.h"
|
|
||||||
#include "nrf_soc.h"
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
static union {
|
|
||||||
uint32_t _PRIMASK_state;
|
|
||||||
uint8_t _sd_state;
|
|
||||||
} _state = {0};
|
|
||||||
|
|
||||||
static bool _use_softdevice_routine = false;
|
|
||||||
static bool _state_saved = false;
|
|
||||||
|
|
||||||
void hal_critical_section_enter(void)
|
|
||||||
{
|
|
||||||
// Fetch the current state of interrupts
|
|
||||||
uint32_t primask = __get_PRIMASK();
|
|
||||||
uint8_t temp_state = 0;
|
|
||||||
|
|
||||||
// If interrupts are enabled, try to use the soft device
|
|
||||||
uint8_t sd_enabled;
|
|
||||||
if ((primask == 0) &&
|
|
||||||
(sd_softdevice_is_enabled(&sd_enabled) == NRF_SUCCESS) &&
|
|
||||||
(sd_enabled == 1)) {
|
|
||||||
// If the softdevice can be used, use it.
|
|
||||||
sd_nvic_critical_region_enter(&temp_state);
|
|
||||||
_use_softdevice_routine = true;
|
|
||||||
|
|
||||||
if (_state_saved == false) {
|
|
||||||
_state._sd_state = temp_state;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If interrupts are enabled, disable them.
|
|
||||||
if (primask == 0) {
|
|
||||||
__disable_irq();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store PRIMASK state, it will be restored when exiting critical
|
|
||||||
// section.
|
|
||||||
_use_softdevice_routine = false;
|
|
||||||
|
|
||||||
if (_state_saved == false) {
|
|
||||||
_state._PRIMASK_state = primask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_state_saved = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hal_critical_section_exit(void)
|
|
||||||
{
|
|
||||||
_state_saved = false;
|
|
||||||
|
|
||||||
// Restore the state as it was prior to entering the critical section.
|
|
||||||
if (_use_softdevice_routine) {
|
|
||||||
sd_nvic_critical_region_exit(_state._sd_state);
|
|
||||||
} else {
|
|
||||||
__set_PRIMASK(_state._PRIMASK_state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hal_in_critical_section(void)
|
|
||||||
{
|
|
||||||
return (_state_saved == true);
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
/* 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 "sleep_api.h"
|
|
||||||
#include "cmsis.h"
|
|
||||||
#include "mbed_interface.h"
|
|
||||||
#include "softdevice_handler.h"
|
|
||||||
#include "nrf_soc.h"
|
|
||||||
|
|
||||||
// Mask of reserved bits of the register ICSR in the System Control Block peripheral
|
|
||||||
// In this case, bits which are equal to 0 are the bits reserved in this register
|
|
||||||
#define SCB_ICSR_RESERVED_BITS_MASK 0x9E43F03F
|
|
||||||
|
|
||||||
void hal_sleep(void)
|
|
||||||
{
|
|
||||||
// ensure debug is disconnected if semihost is enabled....
|
|
||||||
|
|
||||||
// Trigger an event when an interrupt is pending. This allows to wake up
|
|
||||||
// the processor from disabled interrupts.
|
|
||||||
SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
|
|
||||||
|
|
||||||
// If the SoftDevice is enabled, its API must be used to go to sleep.
|
|
||||||
if (softdevice_handler_isEnabled()) {
|
|
||||||
sd_power_mode_set(NRF_POWER_MODE_LOWPWR);
|
|
||||||
sd_app_evt_wait();
|
|
||||||
} else {
|
|
||||||
NRF_POWER->TASKS_LOWPWR = 1;
|
|
||||||
|
|
||||||
// Note: it is not sufficient to just use WFE here, since the internal
|
|
||||||
// event register may be already set from an event that occurred in the
|
|
||||||
// past (like an SVC call to the SoftDevice) and in such case WFE will
|
|
||||||
// just clear the register and continue execution.
|
|
||||||
// Therefore, the strategy here is to first clear the event register
|
|
||||||
// by using SEV/WFE pair, and then execute WFE again, unless there is
|
|
||||||
// a pending interrupt.
|
|
||||||
|
|
||||||
// Set an event and wake up whatsoever, this will clear the event
|
|
||||||
// register from all previous events set (SVC call included)
|
|
||||||
__SEV();
|
|
||||||
__WFE();
|
|
||||||
|
|
||||||
// Test if there is an interrupt pending (mask reserved regions)
|
|
||||||
if (SCB->ICSR & (SCB_ICSR_RESERVED_BITS_MASK)) {
|
|
||||||
// Ok, there is an interrut pending, no need to go to sleep
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// next event will wakeup the CPU
|
|
||||||
// If an interrupt occured between the test of SCB->ICSR and this
|
|
||||||
// instruction, WFE will just not put the CPU to sleep
|
|
||||||
__WFE();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void hal_deepsleep(void)
|
|
||||||
{
|
|
||||||
hal_sleep();
|
|
||||||
// NRF_POWER->SYSTEMOFF=1;
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
|
@ -1,78 +0,0 @@
|
||||||
# Change Log
|
|
||||||
|
|
||||||
## [v2.2.1](https://github.com/ARMmbed/nrf51-sdk/tree/v2.2.1) (2016-01-27)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/nrf51-sdk/compare/v2.2.0...v2.2.1)
|
|
||||||
|
|
||||||
**Closed issues:**
|
|
||||||
|
|
||||||
- It's not possible to generate a debug build with nrf51-sdk 1.0.1 [\#11](https://github.com/ARMmbed/nrf51-sdk/issues/11)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Optimise to omit frame pointer even in a debug build [\#19](https://github.com/ARMmbed/nrf51-sdk/pull/19) ([LiyouZhou](https://github.com/LiyouZhou))
|
|
||||||
|
|
||||||
## [v2.2.0](https://github.com/ARMmbed/nrf51-sdk/tree/v2.2.0) (2016-01-11)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/nrf51-sdk/compare/v2.1.0...v2.2.0)
|
|
||||||
|
|
||||||
**Closed issues:**
|
|
||||||
|
|
||||||
- Update bootloader branch to sdk V10 [\#14](https://github.com/ARMmbed/nrf51-sdk/issues/14)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Add missing implementations for peer\_manager. [\#18](https://github.com/ARMmbed/nrf51-sdk/pull/18) ([pan-](https://github.com/pan-))
|
|
||||||
- Expose function in DM to calculate BLE hash [\#17](https://github.com/ARMmbed/nrf51-sdk/pull/17) ([andresag01](https://github.com/andresag01))
|
|
||||||
|
|
||||||
## [v2.1.0](https://github.com/ARMmbed/nrf51-sdk/tree/v2.1.0) (2016-01-08)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/nrf51-sdk/compare/v2.0.0...v2.1.0)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Add files from peer manager from nRF51 SDK 10.0.0 [\#15](https://github.com/ARMmbed/nrf51-sdk/pull/15) ([andresag01](https://github.com/andresag01))
|
|
||||||
|
|
||||||
## [v2.0.0](https://github.com/ARMmbed/nrf51-sdk/tree/v2.0.0) (2016-01-07)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/nrf51-sdk/compare/v1.0.1...v2.0.0)
|
|
||||||
|
|
||||||
**Closed issues:**
|
|
||||||
|
|
||||||
- nrf51-sdk generates warnings for old style declarations [\#10](https://github.com/ARMmbed/nrf51-sdk/issues/10)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Nordic sdk 10.0.0 [\#13](https://github.com/ARMmbed/nrf51-sdk/pull/13) ([LiyouZhou](https://github.com/LiyouZhou))
|
|
||||||
- Add ifdef to include correct mbed.h file in mbedOS [\#9](https://github.com/ARMmbed/nrf51-sdk/pull/9) ([andresag01](https://github.com/andresag01))
|
|
||||||
- Update files to Nordic sdk 9.0.0 [\#8](https://github.com/ARMmbed/nrf51-sdk/pull/8) ([LiyouZhou](https://github.com/LiyouZhou))
|
|
||||||
|
|
||||||
## [v1.0.1](https://github.com/ARMmbed/nrf51-sdk/tree/v1.0.1) (2015-12-10)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/nrf51-sdk/compare/v1.0.0...v1.0.1)
|
|
||||||
|
|
||||||
**Closed issues:**
|
|
||||||
|
|
||||||
- Need the ability to do version bump [\#1](https://github.com/ARMmbed/nrf51-sdk/issues/1)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Add GCC diagnostics to suppress unused-parameter warnings [\#7](https://github.com/ARMmbed/nrf51-sdk/pull/7) ([andresag01](https://github.com/andresag01))
|
|
||||||
|
|
||||||
## [v1.0.0](https://github.com/ARMmbed/nrf51-sdk/tree/v1.0.0) (2015-12-02)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/nrf51-sdk/compare/v0.0.1...v1.0.0)
|
|
||||||
|
|
||||||
**Closed issues:**
|
|
||||||
|
|
||||||
- Need to keep previous improvements while moving to nrf51-sdk [\#2](https://github.com/ARMmbed/nrf51-sdk/issues/2)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- supress warnings for the sources in nRF51 SDK [\#6](https://github.com/ARMmbed/nrf51-sdk/pull/6) ([rgrover](https://github.com/rgrover))
|
|
||||||
|
|
||||||
## [v0.0.1](https://github.com/ARMmbed/nrf51-sdk/tree/v0.0.1) (2015-12-01)
|
|
||||||
[Full Changelog](https://github.com/ARMmbed/nrf51-sdk/compare/v8.1.0...v0.0.1)
|
|
||||||
|
|
||||||
**Merged pull requests:**
|
|
||||||
|
|
||||||
- Migrate changes from ble nrf51822 [\#4](https://github.com/ARMmbed/nrf51-sdk/pull/4) ([LiyouZhou](https://github.com/LiyouZhou))
|
|
||||||
|
|
||||||
## [v8.1.0](https://github.com/ARMmbed/nrf51-sdk/tree/v8.1.0) (2015-11-17)
|
|
||||||
|
|
||||||
|
|
||||||
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
|
|
@ -1,6 +0,0 @@
|
||||||
Many of the files in this module have been inherited from the Nordic SDK for
|
|
||||||
nRF51822; they come with a BSD-like license offered by Nordic for use in mbed.
|
|
||||||
Some other files come from the mbed SDK, and are licensed under Apache-2.0.
|
|
||||||
Unless specifically indicated otherwise in a file, files are licensed
|
|
||||||
under the Apache 2.0 license, as can be found in: apache-2.0.txt.
|
|
||||||
The BSD-like Nordic license can be found in BSD-3clause-Nordic.txt
|
|
|
@ -1,32 +0,0 @@
|
||||||
# nrf51-sdk
|
|
||||||
Module to contain files provided by the nordic nRF51 SDK. The latest version of this module uses files from Nordic SDK 10.0.0. The files are extracted from [here](https://developer.nordicsemi.com/nRF5_SDK/nRF51_SDK_v10.x.x/nRF51_SDK_10.0.0_dc26b5e.zip).
|
|
||||||
|
|
||||||
## Changes made to Nordic files
|
|
||||||
The files are kept the same as much as possible to the Nordic SDK. Modifications are made in order to integrate with mbed.
|
|
||||||
- ble/common/ble_conn_state.c: Preprocessor tests regarding S110, S120 or S130 macro should be replace by TARGET_MCU_NRF51_XXK_SXXX tests
|
|
||||||
- `ble.h` in `source/nordic_sdk/components/softdevice/s130/headers/ble.h` has to be renamed `nrf_ble.h`. All files which include this file should be updated accordingly.
|
|
||||||
|
|
||||||
|
|
||||||
## Porting new versions of Nordic SDK
|
|
||||||
A list of files currently required by mbed is maintained in [script/required_files.txt](https://github.com/ARMmbed/nrf51-sdk/blob/master/script/required_files.txt). [A python script](https://github.com/ARMmbed/nrf51-sdk/blob/master/script/pick_nrf51_files.py) is written to help porting from nordic sdk releases. **required_files.txt** is parsed to find a list of filenames. The script searches for these filenames in the sdk folder, and copy then into the yotta module mirroring the folder structure in the sdk. **extraIncludes** is automatically added to module.json to allow direct inclusion of noridc headers with just the filename.
|
|
||||||
|
|
||||||
### Script usage
|
|
||||||
```
|
|
||||||
python pick_nrf51_files.py [options] <full-noridc-sdk-path> <nrf51-sdk-yotta-module-path>
|
|
||||||
options: --purge : to delete all existing files and start again
|
|
||||||
--dry-run : to list the files to be copied but not actually copy them
|
|
||||||
```
|
|
||||||
|
|
||||||
There are files in the sdk with the same filename but in different folder. This is dealt with by excluding certain directories. The excluded directories are listed in [pick_nrf51_files.py](https://github.com/ARMmbed/nrf51-sdk/blob/master/script/pick_nrf51_files.py).
|
|
||||||
|
|
||||||
After running the script, the changes in [the previous section](#changes-made-to-nordic-files) will have to be applied manually again.
|
|
||||||
|
|
||||||
Folder structure or even file name can change between releases of the nordic sdk, hence a degree of manual adjustment is needed when porting.
|
|
||||||
|
|
||||||
## Using Noridc Headers
|
|
||||||
The nordic sdk is written in C and yotta modules support C++. If you are trying to include Nordic files in a cpp program, you need to use the `extern "C"` keyword around the includes.
|
|
||||||
```c
|
|
||||||
extern "C" {
|
|
||||||
#include "softdevice_handler.h"
|
|
||||||
}
|
|
||||||
```
|
|
|
@ -1,31 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
|
@ -1,141 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
# Copyright (c) 2015-2016 ARM Limited
|
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
import os, shutil, json, pprint, sys
|
|
||||||
from collections import OrderedDict
|
|
||||||
|
|
||||||
help_text = """
|
|
||||||
Usage: python {} [options] <full-noridc-sdk-path> <nrf51-sdk-yotta-module-path>
|
|
||||||
options: --purge : to delete all existing files and start again
|
|
||||||
--dry-run : to list the files to be copied but not actually copy them
|
|
||||||
""".format(os.path.basename(__file__))
|
|
||||||
|
|
||||||
# exclude path to avoid confusion over files of the same name
|
|
||||||
exclude_path = ["examples", "SVD", "s110", "s120", "s210", "s310", "nrf_soc_nosd", "serialization/connectivity",
|
|
||||||
'components/libraries/hci/config', 'components/libraries/bootloader_dfu/ble_transport']
|
|
||||||
|
|
||||||
def find(name, path):
|
|
||||||
paths = []
|
|
||||||
for root, dirs, files in os.walk(path):
|
|
||||||
if True not in [x in root for x in exclude_path]:
|
|
||||||
if name in files:
|
|
||||||
paths.append(os.path.join(root, name))
|
|
||||||
|
|
||||||
if len(paths) == 0:
|
|
||||||
print "-"*30
|
|
||||||
print "Warning! No {} found!!!!".format(name)
|
|
||||||
print "-"*30
|
|
||||||
return None
|
|
||||||
elif len(paths) > 1:
|
|
||||||
print "-"*30
|
|
||||||
print "Warning! More than one {} found!!!!".format(name)
|
|
||||||
print paths
|
|
||||||
print "-"*30
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
return paths[0]
|
|
||||||
|
|
||||||
def find_dir(dir_name, path):
|
|
||||||
paths = []
|
|
||||||
for root, dirs, files in os.walk(path):
|
|
||||||
if dir_name in root:
|
|
||||||
for fn in files:
|
|
||||||
paths.append(os.path.join(root, fn))
|
|
||||||
return paths
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
# define source and destination of copy
|
|
||||||
arg_valid = True
|
|
||||||
if len(sys.argv) not in [3, 4]:
|
|
||||||
arg_valid = False
|
|
||||||
else:
|
|
||||||
src_folder = sys.argv[-2]
|
|
||||||
yt_module_dir = sys.argv[-1]
|
|
||||||
|
|
||||||
for d in [src_folder, yt_module_dir]:
|
|
||||||
if not os.path.isdir(d):
|
|
||||||
arg_valid = False
|
|
||||||
print src_folder, "is not a folder"
|
|
||||||
|
|
||||||
purge = ("--purge" in sys.argv)
|
|
||||||
dry_run = ("--dry-run" in sys.argv)
|
|
||||||
|
|
||||||
if not arg_valid:
|
|
||||||
print help_text
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
dst_folder = os.path.join(yt_module_dir, "source/nordic_sdk")
|
|
||||||
|
|
||||||
# build a file_list from required_files.txt
|
|
||||||
file_list = []
|
|
||||||
with open("required_files.txt", "r") as fd:
|
|
||||||
for line in fd:
|
|
||||||
line = line.strip()
|
|
||||||
if line.startswith("D "):
|
|
||||||
directory = line.split(" ")[-1]
|
|
||||||
file_list += find_dir(directory, src_folder)
|
|
||||||
elif not line.startswith("#") and line != '':
|
|
||||||
fn = os.path.basename(line).strip()
|
|
||||||
fn = find(fn, src_folder)
|
|
||||||
file_list.append(fn)
|
|
||||||
|
|
||||||
# remove everything from the destination folder
|
|
||||||
if purge and not dry_run and os.path.exists(dst_folder):
|
|
||||||
shutil.rmtree(dst_folder)
|
|
||||||
|
|
||||||
# copy files
|
|
||||||
extra_includes = []
|
|
||||||
for src in file_list:
|
|
||||||
if src:
|
|
||||||
rel_dst = os.path.relpath(src, src_folder)
|
|
||||||
dst = os.path.join(dst_folder, rel_dst)
|
|
||||||
print src, "->", dst
|
|
||||||
|
|
||||||
directory = os.path.dirname(dst)
|
|
||||||
if not os.path.exists(directory):
|
|
||||||
print "Creating directory:", directory
|
|
||||||
if not dry_run:
|
|
||||||
os.makedirs(directory)
|
|
||||||
if not os.path.isfile(dst):
|
|
||||||
print "Copying file", dst
|
|
||||||
if not dry_run:
|
|
||||||
shutil.copyfile(src, dst)
|
|
||||||
|
|
||||||
# build a list of extra includes to be added to module.json
|
|
||||||
if dst.endswith(".h"):
|
|
||||||
inc_rel_path = os.path.relpath(dst, yt_module_dir)
|
|
||||||
inc_dir_path = os.path.dirname(inc_rel_path)
|
|
||||||
if inc_dir_path not in extra_includes:
|
|
||||||
extra_includes.append(inc_dir_path)
|
|
||||||
|
|
||||||
# write extraIncludes in the module.json file
|
|
||||||
mod_json = os.path.join(yt_module_dir, "module.json")
|
|
||||||
print "-"*30
|
|
||||||
print "Writing extra_includes to {}".format(mod_json)
|
|
||||||
print "-"*30
|
|
||||||
for n in sorted(extra_includes):
|
|
||||||
print n
|
|
||||||
|
|
||||||
if not dry_run:
|
|
||||||
with open(mod_json, 'r+') as fd:
|
|
||||||
jobj = json.loads(fd.read(), object_pairs_hook=OrderedDict)
|
|
||||||
jobj['extraIncludes'] = sorted(extra_includes)
|
|
||||||
jdump = json.dumps(jobj, indent=2, separators=(',', ': '))
|
|
||||||
fd.seek(0)
|
|
||||||
fd.write(jdump)
|
|
||||||
fd.write("\n")
|
|
||||||
fd.truncate()
|
|
|
@ -1,38 +0,0 @@
|
||||||
# Copyright (c) 2015-2016 ARM Limited
|
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
with open("copyright_header.txt", "r") as fd:
|
|
||||||
header = fd.read()
|
|
||||||
|
|
||||||
path = "../source/nordic_sdk"
|
|
||||||
for root, dirs, files in os.walk(path):
|
|
||||||
for fn in [os.path.join(root, x) for x in files]:
|
|
||||||
with open(fn, "r+") as fd:
|
|
||||||
print "+"*35
|
|
||||||
print fn
|
|
||||||
s = fd.read()
|
|
||||||
start = s.find("/*")
|
|
||||||
end = s.find("*/")
|
|
||||||
copyright_str = s[start:end+2]
|
|
||||||
if "copyright (c)" not in copyright_str.lower():
|
|
||||||
s = header + "\n\n" + s
|
|
||||||
elif copyright_str is not header:
|
|
||||||
s = s.replace(copyright_str, header)
|
|
||||||
|
|
||||||
fd.seek(0)
|
|
||||||
fd.write(s)
|
|
||||||
fd.truncate()
|
|
|
@ -1,136 +0,0 @@
|
||||||
# from cmsis-core-nrf51822:
|
|
||||||
cmsis-core-nrf51822/compiler_abstraction.h
|
|
||||||
cmsis-core-nrf51822/nrf.h
|
|
||||||
cmsis-core-nrf51822/nrf51.h
|
|
||||||
cmsis-core-nrf51822/nrf51_bitfields.h
|
|
||||||
cmsis-core-nrf51822/nrf_delay.h
|
|
||||||
cmsis-core-nrf51822/system_nrf51.h
|
|
||||||
source/system_nrf51.c
|
|
||||||
|
|
||||||
# from ble-nrf51822
|
|
||||||
source/nordic-sdk/components/ble/ble_radio_notification/ble_radio_notification.c
|
|
||||||
source/nordic-sdk/components/ble/ble_radio_notification/ble_radio_notification.h
|
|
||||||
source/nordic-sdk/components/ble/ble_services/ble_dfu/ble_dfu.c
|
|
||||||
source/nordic-sdk/components/ble/ble_services/ble_dfu/ble_dfu.h
|
|
||||||
source/nordic-sdk/components/ble/common/ble_advdata.c
|
|
||||||
source/nordic-sdk/components/ble/common/ble_advdata.h
|
|
||||||
source/nordic-sdk/components/ble/common/ble_advdata_parser.c
|
|
||||||
source/nordic-sdk/components/ble/common/ble_advdata_parser.h
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/id_manager.h
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/id_manager.c
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/peer_manager_types.h
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/ble_gatt_db.h
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/ble_conn_state.h
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/sdk_mapped_flags.h
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/peer_database.h
|
|
||||||
# source/nordic-sdk/components/ble/common/ble_conn_params.cpp the file is called
|
|
||||||
source/nordic-sdk/components/ble/common/ble_conn_params.c
|
|
||||||
source/nordic-sdk/components/ble/common/ble_conn_params.h
|
|
||||||
source/nordic-sdk/components/ble/common/ble_date_time.h
|
|
||||||
source/nordic-sdk/components/ble/common/ble_sensor_location.h
|
|
||||||
source/nordic-sdk/components/ble/common/ble_srv_common.c
|
|
||||||
source/nordic-sdk/components/ble/common/ble_srv_common.h
|
|
||||||
source/nordic-sdk/components/ble/device_manager/config/device_manager_cnfg.h
|
|
||||||
source/nordic-sdk/components/ble/device_manager/device_manager.h
|
|
||||||
source/nordic-sdk/components/ble/device_manager/device_manager_peripheral.c
|
|
||||||
source/nordic-sdk/components/drivers_nrf/ble_flash/ble_flash.c
|
|
||||||
source/nordic-sdk/components/drivers_nrf/ble_flash/ble_flash.h
|
|
||||||
source/nordic-sdk/components/drivers_nrf/hal/compiler_abstraction.h
|
|
||||||
source/nordic-sdk/components/drivers_nrf/hal/nrf.h
|
|
||||||
source/nordic-sdk/components/drivers_nrf/hal/nrf51.h
|
|
||||||
source/nordic-sdk/components/drivers_nrf/hal/nrf51_bitfields.h
|
|
||||||
source/nordic-sdk/components/drivers_nrf/hal/nrf51_deprecated.h
|
|
||||||
source/nordic-sdk/components/drivers_nrf/hal/nrf_delay.c
|
|
||||||
source/nordic-sdk/components/drivers_nrf/hal/nrf_ecb.c
|
|
||||||
source/nordic-sdk/components/drivers_nrf/hal/nrf_ecb.h
|
|
||||||
source/nordic-sdk/components/drivers_nrf/hal/nrf_gpio.h
|
|
||||||
source/nordic-sdk/components/drivers_nrf/hal/nrf_gpiote.h
|
|
||||||
source/nordic-sdk/components/drivers_nrf/hal/nrf_nvmc.c
|
|
||||||
source/nordic-sdk/components/drivers_nrf/hal/nrf_nvmc.h
|
|
||||||
source/nordic-sdk/components/drivers_nrf/hal/nrf_temp.h
|
|
||||||
source/nordic-sdk/components/drivers_nrf/pstorage/config/pstorage_platform.h
|
|
||||||
source/nordic-sdk/components/drivers_nrf/pstorage/pstorage.c
|
|
||||||
source/nordic-sdk/components/drivers_nrf/pstorage/pstorage.h
|
|
||||||
source/nordic-sdk/components/libraries/bootloader_dfu/bootloader.h
|
|
||||||
source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_types.h
|
|
||||||
source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util.h
|
|
||||||
# source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util_arm.c new file is called:
|
|
||||||
source/nordic-sdk/components/libraries/bootloader_dfu/bootloader_util.c
|
|
||||||
source/nordic-sdk/components/libraries/bootloader_dfu/dfu.h
|
|
||||||
source/nordic-sdk/components/libraries/bootloader_dfu/dfu_bank_internal.h
|
|
||||||
source/nordic-sdk/components/libraries/bootloader_dfu/dfu_ble_svc.h
|
|
||||||
source/nordic-sdk/components/libraries/bootloader_dfu/dfu_ble_svc_internal.h
|
|
||||||
source/nordic-sdk/components/libraries/bootloader_dfu/dfu_init.h
|
|
||||||
source/nordic-sdk/components/libraries/bootloader_dfu/dfu_init_template.c
|
|
||||||
source/nordic-sdk/components/libraries/bootloader_dfu/dfu_transport.h
|
|
||||||
source/nordic-sdk/components/libraries/bootloader_dfu/dfu_types.h
|
|
||||||
source/nordic-sdk/components/libraries/bootloader_dfu/experimental/dfu_app_handler.c
|
|
||||||
source/nordic-sdk/components/libraries/bootloader_dfu/experimental/dfu_app_handler.h
|
|
||||||
source/nordic-sdk/components/libraries/bootloader_dfu/hci_transport/hci_mem_pool_internal.h
|
|
||||||
source/nordic-sdk/components/libraries/crc16/crc16.c
|
|
||||||
source/nordic-sdk/components/libraries/hci/hci_mem_pool.c
|
|
||||||
source/nordic-sdk/components/libraries/hci/hci_mem_pool.h
|
|
||||||
source/nordic-sdk/components/libraries/scheduler/app_scheduler.c
|
|
||||||
source/nordic-sdk/components/libraries/util/app_error.c
|
|
||||||
source/nordic-sdk/components/libraries/util/app_util_platform.c
|
|
||||||
source/nordic-sdk/components/libraries/util/app_util_platform.h
|
|
||||||
source/nordic-sdk/components/libraries/util/common.h
|
|
||||||
source/nordic-sdk/components/libraries/util/nordic_common.h
|
|
||||||
source/nordic-sdk/components/libraries/util/nrf_assert.c
|
|
||||||
source/nordic-sdk/components/libraries/util/nrf_assert.h
|
|
||||||
source/nordic-sdk/components/libraries/util/sdk_common.h
|
|
||||||
source/nordic-sdk/components/libraries/util/sdk_errors.h
|
|
||||||
source/nordic-sdk/components/libraries/util/sdk_os.h
|
|
||||||
source/nordic-sdk/components/softdevice/common/softdevice_handler/ant_stack_handler_types.h
|
|
||||||
source/nordic-sdk/components/softdevice/common/softdevice_handler/ble_stack_handler_types.h
|
|
||||||
source/nordic-sdk/components/softdevice/common/softdevice_handler/softdevice_handler.c
|
|
||||||
source/nordic-sdk/components/softdevice/common/softdevice_handler/softdevice_handler.h
|
|
||||||
source/nordic-sdk/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.c
|
|
||||||
source/nordic-sdk/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.h
|
|
||||||
# source/nordic-sdk/components/softdevice/s130/doc/ble_api.dox uncertain of the origin of this file
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/ble.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/ble_err.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/ble_gap.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/ble_gatt.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/ble_gattc.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/ble_gatts.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/ble_hci.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/ble_l2cap.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/ble_ranges.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/ble_types.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/nrf_error.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/nrf_error_sdm.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/nrf_error_soc.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/nrf_mbr.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/nrf_sdm.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/nrf_soc.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/nrf_svc.h
|
|
||||||
source/nordic-sdk/components/softdevice/s130/include/softdevice_assert.h
|
|
||||||
source/nordic-sdk/components/drivers_nrf/hal/nrf_wdt.h
|
|
||||||
source/nordic-sdk/components/ble/common/ble_conn_state.c
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/peer_data.c
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/peer_data.h
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/peer_data_storage.c
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/peer_data_storage.h
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/peer_database.c
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/peer_id.c
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/peer_id.h
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/pm_buffer.c
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/pm_buffer.h
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/pm_mutex.c
|
|
||||||
source/nordic-sdk/components/ble/peer_manager/pm_mutex.h
|
|
||||||
source/nordic-sdk/components/libraries/experimental_section_vars/
|
|
||||||
source/nordic-sdk/components/libraries/fds/
|
|
||||||
source/nordic-sdk/components/libraries/fstorage/
|
|
||||||
source/nordic-sdk/components/libraries/util/sdk_mapped_flags.c
|
|
||||||
|
|
||||||
|
|
||||||
# from mbed-hal-nrf51822-mcu
|
|
||||||
mbed-hal-nrf51822-mcu/lib/nordic_sdk/components/libraries/crc16/crc16.h
|
|
||||||
mbed-hal-nrf51822-mcu/lib/nordic_sdk/components/libraries/scheduler/app_scheduler.h
|
|
||||||
mbed-hal-nrf51822-mcu/lib/nordic_sdk/components/libraries/util/app_error.h
|
|
||||||
mbed-hal-nrf51822-mcu/lib/nordic_sdk/components/libraries/util/app_util.h
|
|
||||||
|
|
||||||
# included from ble_conn_params.c
|
|
||||||
app_timer.h
|
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ble_radio_notification.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
|
|
||||||
static bool m_radio_active = false; /**< Current radio state. */
|
|
||||||
static ble_radio_notification_evt_handler_t m_evt_handler = NULL; /**< Application event handler for handling Radio Notification events. */
|
|
||||||
|
|
||||||
|
|
||||||
void SWI1_IRQHandler(void)
|
|
||||||
{
|
|
||||||
m_radio_active = !m_radio_active;
|
|
||||||
if (m_evt_handler != NULL)
|
|
||||||
{
|
|
||||||
m_evt_handler(m_radio_active);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_radio_notification_init(nrf_app_irq_priority_t irq_priority,
|
|
||||||
nrf_radio_notification_distance_t distance,
|
|
||||||
ble_radio_notification_evt_handler_t evt_handler)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
m_evt_handler = evt_handler;
|
|
||||||
|
|
||||||
// Initialize Radio Notification software interrupt
|
|
||||||
err_code = sd_nvic_ClearPendingIRQ(SWI1_IRQn);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_code = sd_nvic_SetPriority(SWI1_IRQn, irq_priority);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_code = sd_nvic_EnableIRQ(SWI1_IRQn);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure the event
|
|
||||||
return sd_radio_notification_cfg_set(NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, distance);
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
*
|
|
||||||
* @defgroup ble_radio_notification Radio Notification Event Handler
|
|
||||||
* @{
|
|
||||||
* @ingroup ble_sdk_lib
|
|
||||||
* @brief Module for propagating Radio Notification events to the application.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BLE_RADIO_NOTIFICATION_H__
|
|
||||||
#define BLE_RADIO_NOTIFICATION_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "nrf_soc.h"
|
|
||||||
|
|
||||||
/**@brief Application radio notification event handler type. */
|
|
||||||
typedef void (*ble_radio_notification_evt_handler_t) (bool radio_active);
|
|
||||||
|
|
||||||
/**@brief Function for initializing the Radio Notification module.
|
|
||||||
*
|
|
||||||
* @param[in] irq_priority Interrupt priority for the Radio Notification interrupt handler.
|
|
||||||
* @param[in] distance The time from an Active event until the radio is activated.
|
|
||||||
* @param[in] evt_handler Handler to be executed when a radio notification event has been
|
|
||||||
* received.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on successful initialization, otherwise an error code.
|
|
||||||
*/
|
|
||||||
uint32_t ble_radio_notification_init(nrf_app_irq_priority_t irq_priority,
|
|
||||||
nrf_radio_notification_distance_t distance,
|
|
||||||
ble_radio_notification_evt_handler_t evt_handler);
|
|
||||||
|
|
||||||
#endif // BLE_RADIO_NOTIFICATION_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,686 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ble_dfu.h"
|
|
||||||
#include "nrf_error.h"
|
|
||||||
#include "ble_types.h"
|
|
||||||
#include "ble_gatts.h"
|
|
||||||
#include "app_util.h"
|
|
||||||
#include "ble_srv_common.h"
|
|
||||||
#include "nordic_common.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#define MAX_DFU_PKT_LEN 20 /**< Maximum length (in bytes) of the DFU Packet characteristic. */
|
|
||||||
#define PKT_START_DFU_PARAM_LEN 2 /**< Length (in bytes) of the parameters for Packet Start DFU Request. */
|
|
||||||
#define PKT_INIT_DFU_PARAM_LEN 2 /**< Length (in bytes) of the parameters for Packet Init DFU Request. */
|
|
||||||
#define PKT_RCPT_NOTIF_REQ_LEN 3 /**< Length (in bytes) of the Packet Receipt Notification Request. */
|
|
||||||
#define MAX_PKTS_RCPT_NOTIF_LEN 6 /**< Maximum length (in bytes) of the Packets Receipt Notification. */
|
|
||||||
#define MAX_RESPONSE_LEN 7 /**< Maximum length (in bytes) of the response to a Control Point command. */
|
|
||||||
#define MAX_NOTIF_BUFFER_LEN MAX(MAX_PKTS_RCPT_NOTIF_LEN, MAX_RESPONSE_LEN) /**< Maximum length (in bytes) of the buffer needed by DFU Service while sending notifications to peer. */
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
OP_CODE_START_DFU = 1, /**< Value of the Op code field for 'Start DFU' command.*/
|
|
||||||
OP_CODE_RECEIVE_INIT = 2, /**< Value of the Op code field for 'Initialize DFU parameters' command.*/
|
|
||||||
OP_CODE_RECEIVE_FW = 3, /**< Value of the Op code field for 'Receive firmware image' command.*/
|
|
||||||
OP_CODE_VALIDATE = 4, /**< Value of the Op code field for 'Validate firmware' command.*/
|
|
||||||
OP_CODE_ACTIVATE_N_RESET = 5, /**< Value of the Op code field for 'Activate & Reset' command.*/
|
|
||||||
OP_CODE_SYS_RESET = 6, /**< Value of the Op code field for 'Reset System' command.*/
|
|
||||||
OP_CODE_IMAGE_SIZE_REQ = 7, /**< Value of the Op code field for 'Report received image size' command.*/
|
|
||||||
OP_CODE_PKT_RCPT_NOTIF_REQ = 8, /**< Value of the Op code field for 'Request packet receipt notification.*/
|
|
||||||
OP_CODE_RESPONSE = 16, /**< Value of the Op code field for 'Response.*/
|
|
||||||
OP_CODE_PKT_RCPT_NOTIF = 17 /**< Value of the Op code field for 'Packets Receipt Notification'.*/
|
|
||||||
};
|
|
||||||
|
|
||||||
static bool m_is_dfu_service_initialized = false; /**< Variable to check if the DFU service was initialized by the application.*/
|
|
||||||
static uint8_t m_notif_buffer[MAX_NOTIF_BUFFER_LEN]; /**< Buffer used for sending notifications to peer. */
|
|
||||||
|
|
||||||
/**@brief Function for adding DFU Packet characteristic to the BLE Stack.
|
|
||||||
*
|
|
||||||
* @param[in] p_dfu DFU Service structure.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on success. Otherwise an error code.
|
|
||||||
*/
|
|
||||||
static uint32_t dfu_pkt_char_add(ble_dfu_t * const p_dfu)
|
|
||||||
{
|
|
||||||
ble_gatts_char_md_t char_md;
|
|
||||||
ble_gatts_attr_t attr_char_value;
|
|
||||||
ble_uuid_t char_uuid;
|
|
||||||
ble_gatts_attr_md_t attr_md;
|
|
||||||
|
|
||||||
memset(&char_md, 0, sizeof(char_md));
|
|
||||||
|
|
||||||
char_md.char_props.write_wo_resp = 1;
|
|
||||||
char_md.p_char_user_desc = NULL;
|
|
||||||
char_md.p_char_pf = NULL;
|
|
||||||
char_md.p_user_desc_md = NULL;
|
|
||||||
char_md.p_cccd_md = NULL;
|
|
||||||
char_md.p_sccd_md = NULL;
|
|
||||||
|
|
||||||
char_uuid.type = p_dfu->uuid_type;
|
|
||||||
char_uuid.uuid = BLE_DFU_PKT_CHAR_UUID;
|
|
||||||
|
|
||||||
memset(&attr_md, 0, sizeof(attr_md));
|
|
||||||
|
|
||||||
BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
|
|
||||||
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
|
|
||||||
|
|
||||||
attr_md.vloc = BLE_GATTS_VLOC_STACK;
|
|
||||||
attr_md.rd_auth = 0;
|
|
||||||
attr_md.wr_auth = 0;
|
|
||||||
attr_md.vlen = 1;
|
|
||||||
|
|
||||||
memset(&attr_char_value, 0, sizeof(attr_char_value));
|
|
||||||
|
|
||||||
attr_char_value.p_uuid = &char_uuid;
|
|
||||||
attr_char_value.p_attr_md = &attr_md;
|
|
||||||
attr_char_value.init_len = 0;
|
|
||||||
attr_char_value.init_offs = 0;
|
|
||||||
attr_char_value.max_len = MAX_DFU_PKT_LEN;
|
|
||||||
attr_char_value.p_value = NULL;
|
|
||||||
|
|
||||||
return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
|
|
||||||
&char_md,
|
|
||||||
&attr_char_value,
|
|
||||||
&p_dfu->dfu_pkt_handles);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for adding DFU Revision characteristic to the BLE Stack.
|
|
||||||
*
|
|
||||||
* @param[in] p_dfu DFU Service structure.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on success. Otherwise an error code.
|
|
||||||
*/
|
|
||||||
static uint32_t dfu_rev_char_add(ble_dfu_t * const p_dfu, ble_dfu_init_t const * const p_dfu_init)
|
|
||||||
{
|
|
||||||
ble_gatts_char_md_t char_md;
|
|
||||||
ble_gatts_attr_t attr_char_value;
|
|
||||||
ble_uuid_t char_uuid;
|
|
||||||
ble_gatts_attr_md_t attr_md;
|
|
||||||
|
|
||||||
memset(&char_md, 0, sizeof(char_md));
|
|
||||||
|
|
||||||
char_md.char_props.read = 1;
|
|
||||||
char_md.p_char_user_desc = NULL;
|
|
||||||
char_md.p_char_pf = NULL;
|
|
||||||
char_md.p_user_desc_md = NULL;
|
|
||||||
char_md.p_cccd_md = NULL;
|
|
||||||
char_md.p_sccd_md = NULL;
|
|
||||||
|
|
||||||
char_uuid.type = p_dfu->uuid_type;
|
|
||||||
char_uuid.uuid = BLE_DFU_REV_CHAR_UUID;
|
|
||||||
|
|
||||||
memset(&attr_md, 0, sizeof(attr_md));
|
|
||||||
|
|
||||||
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
|
|
||||||
BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
|
|
||||||
|
|
||||||
attr_md.vloc = BLE_GATTS_VLOC_STACK;
|
|
||||||
attr_md.rd_auth = 0;
|
|
||||||
attr_md.wr_auth = 0;
|
|
||||||
attr_md.vlen = 1;
|
|
||||||
|
|
||||||
memset(&attr_char_value, 0, sizeof(attr_char_value));
|
|
||||||
|
|
||||||
attr_char_value.p_uuid = &char_uuid;
|
|
||||||
attr_char_value.p_attr_md = &attr_md;
|
|
||||||
attr_char_value.init_len = sizeof(uint16_t);
|
|
||||||
attr_char_value.init_offs = 0;
|
|
||||||
attr_char_value.max_len = sizeof(uint16_t);
|
|
||||||
attr_char_value.p_value = (uint8_t *)&p_dfu_init->revision;
|
|
||||||
|
|
||||||
return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
|
|
||||||
&char_md,
|
|
||||||
&attr_char_value,
|
|
||||||
&p_dfu->dfu_rev_handles);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for adding DFU Control Point characteristic to the BLE Stack.
|
|
||||||
*
|
|
||||||
* @param[in] p_dfu DFU Service structure.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on success. Otherwise an error code.
|
|
||||||
*/
|
|
||||||
static uint32_t dfu_ctrl_pt_add(ble_dfu_t * const p_dfu)
|
|
||||||
{
|
|
||||||
ble_gatts_char_md_t char_md;
|
|
||||||
ble_gatts_attr_t attr_char_value;
|
|
||||||
ble_uuid_t char_uuid;
|
|
||||||
ble_gatts_attr_md_t attr_md;
|
|
||||||
|
|
||||||
memset(&char_md, 0, sizeof(char_md));
|
|
||||||
|
|
||||||
char_md.char_props.write = 1;
|
|
||||||
char_md.char_props.notify = 1;
|
|
||||||
char_md.p_char_user_desc = NULL;
|
|
||||||
char_md.p_char_pf = NULL;
|
|
||||||
char_md.p_user_desc_md = NULL;
|
|
||||||
char_md.p_cccd_md = NULL;
|
|
||||||
char_md.p_sccd_md = NULL;
|
|
||||||
|
|
||||||
char_uuid.type = p_dfu->uuid_type;
|
|
||||||
char_uuid.uuid = BLE_DFU_CTRL_PT_UUID;
|
|
||||||
|
|
||||||
memset(&attr_md, 0, sizeof(attr_md));
|
|
||||||
|
|
||||||
BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
|
|
||||||
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
|
|
||||||
|
|
||||||
attr_md.vloc = BLE_GATTS_VLOC_STACK;
|
|
||||||
attr_md.rd_auth = 0;
|
|
||||||
attr_md.wr_auth = 1;
|
|
||||||
attr_md.vlen = 1;
|
|
||||||
|
|
||||||
memset(&attr_char_value, 0, sizeof(attr_char_value));
|
|
||||||
|
|
||||||
attr_char_value.p_uuid = &char_uuid;
|
|
||||||
attr_char_value.p_attr_md = &attr_md;
|
|
||||||
attr_char_value.init_len = 0;
|
|
||||||
attr_char_value.init_offs = 0;
|
|
||||||
attr_char_value.max_len = BLE_L2CAP_MTU_DEF;
|
|
||||||
attr_char_value.p_value = NULL;
|
|
||||||
|
|
||||||
return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
|
|
||||||
&char_md,
|
|
||||||
&attr_char_value,
|
|
||||||
&p_dfu->dfu_ctrl_pt_handles);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for handling the @ref BLE_GAP_EVT_CONNECTED event from the S110 SoftDevice.
|
|
||||||
*
|
|
||||||
* @param[in] p_dfu DFU Service Structure.
|
|
||||||
* @param[in] p_ble_evt Pointer to the event received from BLE stack.
|
|
||||||
*/
|
|
||||||
static void on_connect(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
|
|
||||||
{
|
|
||||||
p_dfu->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for checking if the CCCD of DFU Control point is configured for Notification.
|
|
||||||
*
|
|
||||||
* @details This function checks if the CCCD of DFU Control Point characteristic is configured
|
|
||||||
* for Notification by the DFU Controller.
|
|
||||||
*
|
|
||||||
* @param[in] p_dfu DFU Service structure.
|
|
||||||
*
|
|
||||||
* @return True if the CCCD of DFU Control Point characteristic is configured for Notification.
|
|
||||||
* False otherwise.
|
|
||||||
*/
|
|
||||||
static bool is_cccd_configured(ble_dfu_t * p_dfu)
|
|
||||||
{
|
|
||||||
// Check if the CCCDs are configured.
|
|
||||||
uint8_t cccd_val_buf[BLE_CCCD_VALUE_LEN];
|
|
||||||
ble_gatts_value_t gatts_value;
|
|
||||||
|
|
||||||
// Initialize value struct.
|
|
||||||
memset(&gatts_value, 0, sizeof(gatts_value));
|
|
||||||
|
|
||||||
gatts_value.len = BLE_CCCD_VALUE_LEN;
|
|
||||||
gatts_value.offset = 0;
|
|
||||||
gatts_value.p_value = cccd_val_buf;
|
|
||||||
|
|
||||||
// Check the CCCD Value of DFU Control Point.
|
|
||||||
uint32_t err_code = sd_ble_gatts_value_get(p_dfu->conn_handle,
|
|
||||||
p_dfu->dfu_ctrl_pt_handles.cccd_handle,
|
|
||||||
&gatts_value);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
if (p_dfu->error_handler != NULL)
|
|
||||||
{
|
|
||||||
p_dfu->error_handler(err_code);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ble_srv_is_notification_enabled(cccd_val_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for handling a Write event on the Control Point characteristic.
|
|
||||||
*
|
|
||||||
* @param[in] p_dfu DFU Service Structure.
|
|
||||||
* @param[in] p_ble_write_evt Pointer to the write event received from BLE stack.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on successful processing of control point write. Otherwise an error code.
|
|
||||||
*/
|
|
||||||
static uint32_t on_ctrl_pt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t * p_ble_write_evt)
|
|
||||||
{
|
|
||||||
ble_gatts_rw_authorize_reply_params_t write_authorize_reply;
|
|
||||||
|
|
||||||
write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
|
|
||||||
|
|
||||||
if (!is_cccd_configured(p_dfu))
|
|
||||||
{
|
|
||||||
// Send an error response to the peer indicating that the CCCD is improperly configured.
|
|
||||||
write_authorize_reply.params.write.gatt_status =
|
|
||||||
BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR;
|
|
||||||
|
|
||||||
return (sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply));
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
err_code = (sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply));
|
|
||||||
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ble_dfu_evt_t ble_dfu_evt;
|
|
||||||
|
|
||||||
switch (p_ble_write_evt->data[0])
|
|
||||||
{
|
|
||||||
case OP_CODE_START_DFU:
|
|
||||||
ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_START;
|
|
||||||
|
|
||||||
if (p_ble_write_evt->len < PKT_START_DFU_PARAM_LEN)
|
|
||||||
{
|
|
||||||
return ble_dfu_response_send(p_dfu,
|
|
||||||
(ble_dfu_procedure_t) p_ble_write_evt->data[0],
|
|
||||||
BLE_DFU_RESP_VAL_OPER_FAILED);
|
|
||||||
}
|
|
||||||
|
|
||||||
ble_dfu_evt.evt.ble_dfu_pkt_write.len = 1;
|
|
||||||
ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]);
|
|
||||||
|
|
||||||
p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OP_CODE_RECEIVE_INIT:
|
|
||||||
ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_RECEIVE_INIT_DATA;
|
|
||||||
|
|
||||||
if (p_ble_write_evt->len < PKT_INIT_DFU_PARAM_LEN)
|
|
||||||
{
|
|
||||||
return ble_dfu_response_send(p_dfu,
|
|
||||||
(ble_dfu_procedure_t) p_ble_write_evt->data[0],
|
|
||||||
BLE_DFU_RESP_VAL_OPER_FAILED);
|
|
||||||
}
|
|
||||||
|
|
||||||
ble_dfu_evt.evt.ble_dfu_pkt_write.len = 1;
|
|
||||||
ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]);
|
|
||||||
|
|
||||||
p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OP_CODE_RECEIVE_FW:
|
|
||||||
ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_RECEIVE_APP_DATA;
|
|
||||||
|
|
||||||
p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OP_CODE_VALIDATE:
|
|
||||||
ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_VALIDATE;
|
|
||||||
|
|
||||||
p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OP_CODE_ACTIVATE_N_RESET:
|
|
||||||
ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_ACTIVATE_N_RESET;
|
|
||||||
|
|
||||||
p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OP_CODE_SYS_RESET:
|
|
||||||
ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_SYS_RESET;
|
|
||||||
|
|
||||||
p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OP_CODE_PKT_RCPT_NOTIF_REQ:
|
|
||||||
if (p_ble_write_evt->len < PKT_RCPT_NOTIF_REQ_LEN)
|
|
||||||
{
|
|
||||||
return (ble_dfu_response_send(p_dfu,
|
|
||||||
BLE_DFU_PKT_RCPT_REQ_PROCEDURE,
|
|
||||||
BLE_DFU_RESP_VAL_NOT_SUPPORTED));
|
|
||||||
}
|
|
||||||
|
|
||||||
ble_dfu_evt.evt.pkt_rcpt_notif_req.num_of_pkts =
|
|
||||||
uint16_decode(&(p_ble_write_evt->data[1]));
|
|
||||||
|
|
||||||
if (ble_dfu_evt.evt.pkt_rcpt_notif_req.num_of_pkts == 0)
|
|
||||||
{
|
|
||||||
ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PKT_RCPT_NOTIF_DISABLED;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PKT_RCPT_NOTIF_ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OP_CODE_IMAGE_SIZE_REQ:
|
|
||||||
ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_BYTES_RECEIVED_SEND;
|
|
||||||
|
|
||||||
p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// Unsupported op code.
|
|
||||||
return ble_dfu_response_send(p_dfu,
|
|
||||||
(ble_dfu_procedure_t) p_ble_write_evt->data[0],
|
|
||||||
BLE_DFU_RESP_VAL_NOT_SUPPORTED);
|
|
||||||
}
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event from the S110
|
|
||||||
* Stack.
|
|
||||||
*
|
|
||||||
* @param[in] p_dfu DFU Service Structure.
|
|
||||||
* @param[in] p_ble_evt Pointer to the event received from BLE stack.
|
|
||||||
*/
|
|
||||||
static void on_rw_authorize_req(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
|
|
||||||
{
|
|
||||||
ble_gatts_evt_rw_authorize_request_t * p_authorize_request;
|
|
||||||
|
|
||||||
p_authorize_request = &(p_ble_evt->evt.gatts_evt.params.authorize_request);
|
|
||||||
|
|
||||||
if (
|
|
||||||
(p_authorize_request->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
|
|
||||||
&&
|
|
||||||
(p_authorize_request->request.write.handle == p_dfu->dfu_ctrl_pt_handles.value_handle)
|
|
||||||
&&
|
|
||||||
(p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ)
|
|
||||||
&&
|
|
||||||
(p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)
|
|
||||||
&&
|
|
||||||
(p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
err_code = on_ctrl_pt_write(p_dfu, &(p_authorize_request->request.write));
|
|
||||||
|
|
||||||
if (err_code != NRF_SUCCESS && p_dfu->error_handler != NULL)
|
|
||||||
{
|
|
||||||
p_dfu->error_handler(err_code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the S110 SoftDevice.
|
|
||||||
*
|
|
||||||
* @param[in] p_dfu DFU Service Structure.
|
|
||||||
* @param[in] p_ble_evt Pointer to the event received from BLE stack.
|
|
||||||
*/
|
|
||||||
static void on_write(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
|
|
||||||
{
|
|
||||||
if (p_ble_evt->evt.gatts_evt.params.write.handle == p_dfu->dfu_pkt_handles.value_handle)
|
|
||||||
{
|
|
||||||
// DFU Packet written
|
|
||||||
|
|
||||||
ble_dfu_evt_t ble_dfu_evt;
|
|
||||||
|
|
||||||
ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PACKET_WRITE;
|
|
||||||
ble_dfu_evt.evt.ble_dfu_pkt_write.len = p_ble_evt->evt.gatts_evt.params.write.len;
|
|
||||||
ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = p_ble_evt->evt.gatts_evt.params.write.data;
|
|
||||||
|
|
||||||
p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for handling the BLE_GAP_EVT_DISCONNECTED event from the S110 SoftDevice.
|
|
||||||
*
|
|
||||||
* @param[in] p_dfu DFU Service Structure.
|
|
||||||
* @param[in] p_ble_evt Pointer to the event received from BLE stack.
|
|
||||||
*/
|
|
||||||
static void on_disconnect(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
|
|
||||||
{
|
|
||||||
p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_dfu_init(ble_dfu_t * p_dfu, ble_dfu_init_t * p_dfu_init)
|
|
||||||
{
|
|
||||||
if ((p_dfu == NULL) || (p_dfu_init == NULL) || (p_dfu_init->evt_handler == NULL))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID;
|
|
||||||
|
|
||||||
ble_uuid_t service_uuid;
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
const ble_uuid128_t base_uuid128 =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15,
|
|
||||||
0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
service_uuid.uuid = BLE_DFU_SERVICE_UUID;
|
|
||||||
|
|
||||||
err_code = sd_ble_uuid_vs_add(&base_uuid128, &(service_uuid.type));
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
|
|
||||||
&service_uuid,
|
|
||||||
&(p_dfu->service_handle));
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
p_dfu->uuid_type = service_uuid.type;
|
|
||||||
|
|
||||||
err_code = dfu_pkt_char_add(p_dfu);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_code = dfu_ctrl_pt_add(p_dfu);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_code = dfu_rev_char_add(p_dfu, p_dfu_init);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
p_dfu->evt_handler = p_dfu_init->evt_handler;
|
|
||||||
|
|
||||||
if (p_dfu_init->error_handler != NULL)
|
|
||||||
{
|
|
||||||
p_dfu->error_handler = p_dfu_init->error_handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_is_dfu_service_initialized = true;
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ble_dfu_on_ble_evt(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt)
|
|
||||||
{
|
|
||||||
if ((p_dfu == NULL) || (p_ble_evt == NULL))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_dfu->evt_handler != NULL)
|
|
||||||
{
|
|
||||||
switch (p_ble_evt->header.evt_id)
|
|
||||||
{
|
|
||||||
case BLE_GAP_EVT_CONNECTED:
|
|
||||||
on_connect(p_dfu, p_ble_evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_GATTS_EVT_WRITE:
|
|
||||||
on_write(p_dfu, p_ble_evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_GAP_EVT_DISCONNECTED:
|
|
||||||
on_disconnect(p_dfu, p_ble_evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
|
|
||||||
on_rw_authorize_req(p_dfu, p_ble_evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// No implementation needed.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_dfu_bytes_rcvd_report(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd)
|
|
||||||
{
|
|
||||||
if (p_dfu == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ble_gatts_hvx_params_t hvx_params;
|
|
||||||
uint16_t index = 0;
|
|
||||||
|
|
||||||
// Encode the Op Code.
|
|
||||||
m_notif_buffer[index++] = OP_CODE_RESPONSE;
|
|
||||||
|
|
||||||
// Encode the Reqest Op Code.
|
|
||||||
m_notif_buffer[index++] = OP_CODE_IMAGE_SIZE_REQ;
|
|
||||||
|
|
||||||
// Encode the Response Value.
|
|
||||||
m_notif_buffer[index++] = (uint8_t)BLE_DFU_RESP_VAL_SUCCESS;
|
|
||||||
|
|
||||||
index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]);
|
|
||||||
|
|
||||||
memset(&hvx_params, 0, sizeof(hvx_params));
|
|
||||||
|
|
||||||
hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
|
|
||||||
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
|
|
||||||
hvx_params.offset = 0;
|
|
||||||
hvx_params.p_len = &index;
|
|
||||||
hvx_params.p_data = m_notif_buffer;
|
|
||||||
|
|
||||||
return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_dfu_pkts_rcpt_notify(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd)
|
|
||||||
{
|
|
||||||
if (p_dfu == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ble_gatts_hvx_params_t hvx_params;
|
|
||||||
uint16_t index = 0;
|
|
||||||
|
|
||||||
m_notif_buffer[index++] = OP_CODE_PKT_RCPT_NOTIF;
|
|
||||||
|
|
||||||
index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]);
|
|
||||||
|
|
||||||
memset(&hvx_params, 0, sizeof(hvx_params));
|
|
||||||
|
|
||||||
hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
|
|
||||||
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
|
|
||||||
hvx_params.offset = 0;
|
|
||||||
hvx_params.p_len = &index;
|
|
||||||
hvx_params.p_data = m_notif_buffer;
|
|
||||||
|
|
||||||
return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_dfu_response_send(ble_dfu_t * p_dfu,
|
|
||||||
ble_dfu_procedure_t dfu_proc,
|
|
||||||
ble_dfu_resp_val_t resp_val)
|
|
||||||
{
|
|
||||||
if (p_dfu == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ble_gatts_hvx_params_t hvx_params;
|
|
||||||
uint16_t index = 0;
|
|
||||||
|
|
||||||
m_notif_buffer[index++] = OP_CODE_RESPONSE;
|
|
||||||
|
|
||||||
// Encode the Request Op code
|
|
||||||
m_notif_buffer[index++] = (uint8_t)dfu_proc;
|
|
||||||
|
|
||||||
// Encode the Response Value.
|
|
||||||
m_notif_buffer[index++] = (uint8_t)resp_val;
|
|
||||||
|
|
||||||
memset(&hvx_params, 0, sizeof(hvx_params));
|
|
||||||
|
|
||||||
hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle;
|
|
||||||
hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
|
|
||||||
hvx_params.offset = 0;
|
|
||||||
hvx_params.p_len = &index;
|
|
||||||
hvx_params.p_data = m_notif_buffer;
|
|
||||||
|
|
||||||
return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params);
|
|
||||||
}
|
|
|
@ -1,259 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**@file
|
|
||||||
*
|
|
||||||
* @defgroup ble_sdk_srv_dfu Device Firmware Update Service
|
|
||||||
* @{
|
|
||||||
* @ingroup ble_sdk_srv
|
|
||||||
* @brief Device Firmware Update Service
|
|
||||||
*
|
|
||||||
* @details The Device Firmware Update (DFU) service is a GATT based service that can be used for
|
|
||||||
* performing firmware updates over BLE. Note that this implementation uses vendor
|
|
||||||
* specific UUIDs for service and characteristics and is intended to demonstrate the
|
|
||||||
* firmware updates over BLE. Refer @ref bledfu_transport_bleservice and @ref
|
|
||||||
* bledfu_transport_bleprofile for more information on the service and profile respectively.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BLE_DFU_H__
|
|
||||||
#define BLE_DFU_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "ble_gatts.h"
|
|
||||||
#include "ble_gap.h"
|
|
||||||
#include "nrf_ble.h"
|
|
||||||
#include "ble_srv_common.h"
|
|
||||||
|
|
||||||
#define BLE_DFU_SERVICE_UUID 0x1530 /**< The UUID of the DFU Service. */
|
|
||||||
#define BLE_DFU_PKT_CHAR_UUID 0x1532 /**< The UUID of the DFU Packet Characteristic. */
|
|
||||||
#define BLE_DFU_CTRL_PT_UUID 0x1531 /**< The UUID of the DFU Control Point. */
|
|
||||||
#define BLE_DFU_STATUS_REP_UUID 0x1533 /**< The UUID of the DFU Status Report Characteristic. */
|
|
||||||
#define BLE_DFU_REV_CHAR_UUID 0x1534 /**< The UUID of the DFU Revision Characteristic. */
|
|
||||||
|
|
||||||
/**@brief DFU Event type.
|
|
||||||
*
|
|
||||||
* @details This enumeration contains the types of events that will be received from the DFU Service.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
BLE_DFU_START, /**< The event indicating that the peer wants the application to prepare for a new firmware update. */
|
|
||||||
BLE_DFU_RECEIVE_INIT_DATA, /**< The event indicating that the peer wants the application to prepare to receive init parameters. */
|
|
||||||
BLE_DFU_RECEIVE_APP_DATA, /**< The event indicating that the peer wants the application to prepare to receive the new firmware image. */
|
|
||||||
BLE_DFU_VALIDATE, /**< The event indicating that the peer wants the application to validate the newly received firmware image. */
|
|
||||||
BLE_DFU_ACTIVATE_N_RESET, /**< The event indicating that the peer wants the application to undergo activate new firmware and restart with new valid application */
|
|
||||||
BLE_DFU_SYS_RESET, /**< The event indicating that the peer wants the application to undergo a reset and start the currently valid application image.*/
|
|
||||||
BLE_DFU_PKT_RCPT_NOTIF_ENABLED, /**< The event indicating that the peer has enabled packet receipt notifications. It is the responsibility of the application to call @ref ble_dfu_pkts_rcpt_notify each time the number of packets indicated by num_of_pkts field in @ref ble_dfu_evt_t is received.*/
|
|
||||||
BLE_DFU_PKT_RCPT_NOTIF_DISABLED, /**< The event indicating that the peer has disabled the packet receipt notifications.*/
|
|
||||||
BLE_DFU_PACKET_WRITE, /**< The event indicating that the peer has written a value to the 'DFU Packet' characteristic. The data received from the peer will be present in the @ref BLE_DFU_PACKET_WRITE element contained within @ref ble_dfu_evt_t.*/
|
|
||||||
BLE_DFU_BYTES_RECEIVED_SEND /**< The event indicating that the peer is requesting for the number of bytes of firmware data last received by the application. It is the responsibility of the application to call @ref ble_dfu_pkts_rcpt_notify in response to this event. */
|
|
||||||
} ble_dfu_evt_type_t;
|
|
||||||
|
|
||||||
/**@brief DFU Procedure type.
|
|
||||||
*
|
|
||||||
* @details This enumeration contains the types of DFU procedures.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
BLE_DFU_START_PROCEDURE = 1, /**< DFU Start procedure.*/
|
|
||||||
BLE_DFU_INIT_PROCEDURE = 2, /**< DFU Initialization procedure.*/
|
|
||||||
BLE_DFU_RECEIVE_APP_PROCEDURE = 3, /**< Firmware receiving procedure.*/
|
|
||||||
BLE_DFU_VALIDATE_PROCEDURE = 4, /**< Firmware image validation procedure .*/
|
|
||||||
BLE_DFU_PKT_RCPT_REQ_PROCEDURE = 8 /**< Packet receipt notification request procedure. */
|
|
||||||
} ble_dfu_procedure_t;
|
|
||||||
|
|
||||||
/**@brief DFU Response value type.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
BLE_DFU_RESP_VAL_SUCCESS = 1, /**< Success.*/
|
|
||||||
BLE_DFU_RESP_VAL_INVALID_STATE, /**< Invalid state.*/
|
|
||||||
BLE_DFU_RESP_VAL_NOT_SUPPORTED, /**< Operation not supported.*/
|
|
||||||
BLE_DFU_RESP_VAL_DATA_SIZE, /**< Data size exceeds limit.*/
|
|
||||||
BLE_DFU_RESP_VAL_CRC_ERROR, /**< CRC Error.*/
|
|
||||||
BLE_DFU_RESP_VAL_OPER_FAILED /**< Operation failed.*/
|
|
||||||
} ble_dfu_resp_val_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief DFU Packet structure.
|
|
||||||
*
|
|
||||||
* @details This structure contains the value of the DFU Packet characteristic as written by the
|
|
||||||
* peer and the length of the value written. It will be filled by the DFU Service when the
|
|
||||||
* peer writes to the DFU Packet characteristic.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t * p_data; /**< Pointer to the received packet. This will point to a word aligned memory location.*/
|
|
||||||
uint8_t len; /**< Length of the packet received. */
|
|
||||||
} ble_dfu_pkt_write_t;
|
|
||||||
|
|
||||||
/**@brief Packet receipt notification request structure.
|
|
||||||
*
|
|
||||||
* @details This structure contains the contents of the packet receipt notification request
|
|
||||||
* sent by the DFU Controller.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t num_of_pkts; /**< The number of packets of firmware data to be received by application before sending the next Packet Receipt Notification to the peer. */
|
|
||||||
} ble_pkt_rcpt_notif_req_t;
|
|
||||||
|
|
||||||
/**@brief DFU Event structure.
|
|
||||||
*
|
|
||||||
* @details This structure contains the event generated by the DFU Service based on the data
|
|
||||||
* received from the peer.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
ble_dfu_evt_type_t ble_dfu_evt_type; /**< Type of the event.*/
|
|
||||||
union
|
|
||||||
{
|
|
||||||
ble_dfu_pkt_write_t ble_dfu_pkt_write; /**< The DFU packet received. This field is when the @ref ble_dfu_evt_type field is set to @ref BLE_DFU_PACKET_WRITE.*/
|
|
||||||
ble_pkt_rcpt_notif_req_t pkt_rcpt_notif_req; /**< Packet receipt notification request. This field is when the @ref ble_dfu_evt_type field is set to @ref BLE_DFU_PKT_RCPT_NOTIF_ENABLED.*/
|
|
||||||
} evt;
|
|
||||||
} ble_dfu_evt_t;
|
|
||||||
|
|
||||||
// Forward declaration of the ble_dfu_t type.
|
|
||||||
typedef struct ble_dfu_s ble_dfu_t;
|
|
||||||
|
|
||||||
/**@brief DFU Service event handler type. */
|
|
||||||
typedef void (*ble_dfu_evt_handler_t) (ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt);
|
|
||||||
|
|
||||||
/**@brief DFU service structure.
|
|
||||||
*
|
|
||||||
* @details This structure contains status information related to the service.
|
|
||||||
*/
|
|
||||||
struct ble_dfu_s
|
|
||||||
{
|
|
||||||
uint16_t conn_handle; /**< Handle of the current connection (as provided by the S110 SoftDevice). This will be BLE_CONN_HANDLE_INVALID when not in a connection. */
|
|
||||||
uint16_t revision; /**< Handle of DFU Service (as provided by the S110 SoftDevice). */
|
|
||||||
uint16_t service_handle; /**< Handle of DFU Service (as provided by the S110 SoftDevice). */
|
|
||||||
uint8_t uuid_type; /**< UUID type assigned for DFU Service by the S110 SoftDevice. */
|
|
||||||
ble_gatts_char_handles_t dfu_pkt_handles; /**< Handles related to the DFU Packet characteristic. */
|
|
||||||
ble_gatts_char_handles_t dfu_ctrl_pt_handles; /**< Handles related to the DFU Control Point characteristic. */
|
|
||||||
ble_gatts_char_handles_t dfu_status_rep_handles; /**< Handles related to the DFU Status Report characteristic. */
|
|
||||||
ble_gatts_char_handles_t dfu_rev_handles; /**< Handles related to the DFU Revision characteristic. */
|
|
||||||
ble_dfu_evt_handler_t evt_handler; /**< The event handler to be called when an event is to be sent to the application.*/
|
|
||||||
ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**@brief DFU service initialization structure.
|
|
||||||
*
|
|
||||||
* @details This structure contains the initialization information for the DFU Service. The
|
|
||||||
* application needs to fill this structure and pass it to the DFU Service using the
|
|
||||||
* @ref ble_dfu_init function.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t revision; /**< Revision number to be exposed by the DFU service. */
|
|
||||||
ble_dfu_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Device Firmware Update Service. */
|
|
||||||
ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
|
|
||||||
} ble_dfu_init_t;
|
|
||||||
|
|
||||||
/**@brief Function for handling a BLE event.
|
|
||||||
*
|
|
||||||
* @details The DFU service expects the application to call this function each time an event
|
|
||||||
* is received from the S110 SoftDevice. This function processes the event, if it is
|
|
||||||
* relevant for the DFU service and calls the DFU event handler of the application if
|
|
||||||
* necessary.
|
|
||||||
*
|
|
||||||
* @param[in] p_dfu Pointer to the DFU service structure.
|
|
||||||
* @param[in] p_ble_evt Pointer to the event received from S110 SoftDevice.
|
|
||||||
*/
|
|
||||||
void ble_dfu_on_ble_evt(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt);
|
|
||||||
|
|
||||||
/**@brief Function for initializing the DFU service.
|
|
||||||
*
|
|
||||||
* @param[out] p_dfu Device Firmware Update service structure. This structure will have to be
|
|
||||||
* supplied by the application. It will be initialized by this function,
|
|
||||||
* and will later be used to identify the service instance.
|
|
||||||
* @param[in] p_dfu_init Information needed to initialize the service.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS if the DFU service and its characteristics were successfully added to the
|
|
||||||
* S110 SoftDevice. Otherwise an error code.
|
|
||||||
* This function returns NRF_ERROR_NULL if the value of evt_handler in p_dfu_init
|
|
||||||
* structure provided is NULL or if the pointers supplied as input are NULL.
|
|
||||||
*/
|
|
||||||
uint32_t ble_dfu_init(ble_dfu_t * p_dfu, ble_dfu_init_t * p_dfu_init);
|
|
||||||
|
|
||||||
/**@brief Function for sending response to a control point command.
|
|
||||||
*
|
|
||||||
* @details This function will encode a DFU Control Point response using the given input
|
|
||||||
* parameters and will send a notification of the same to the peer.
|
|
||||||
*
|
|
||||||
* @param[in] p_dfu Pointer to the DFU service structure.
|
|
||||||
* @param[in] dfu_proc Procedure for which this response is to be sent.
|
|
||||||
* @param[in] resp_val Response value.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS if the DFU Service has successfully requested the S110 SoftDevice to
|
|
||||||
* send the notification. Otherwise an error code.
|
|
||||||
* This function returns NRF_ERROR_INVALID_STATE if the device is not connected to a
|
|
||||||
* peer or if the DFU service is not initialized or if the notification of the DFU
|
|
||||||
* Status Report characteristic was not enabled by the peer. It returns NRF_ERROR_NULL
|
|
||||||
* if the pointer p_dfu is NULL.
|
|
||||||
*/
|
|
||||||
uint32_t ble_dfu_response_send(ble_dfu_t * p_dfu,
|
|
||||||
ble_dfu_procedure_t dfu_proc,
|
|
||||||
ble_dfu_resp_val_t resp_val);
|
|
||||||
|
|
||||||
/**@brief Function for notifying the peer about the number of bytes of firmware data received.
|
|
||||||
*
|
|
||||||
* @param[in] p_dfu Pointer to the DFU service structure.
|
|
||||||
* @param[in] num_of_firmware_bytes_rcvd Number of bytes.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS if the DFU Service has successfully requested the S110 SoftDevice to send
|
|
||||||
* the notification. Otherwise an error code.
|
|
||||||
* This function returns NRF_ERROR_INVALID_STATE if the device is not connected to a
|
|
||||||
* peer or if the DFU service is not initialized or if the notification of the DFU
|
|
||||||
* Status Report characteristic was not enabled by the peer. It returns NRF_ERROR_NULL
|
|
||||||
* if the pointer p_dfu is NULL.
|
|
||||||
*/
|
|
||||||
uint32_t ble_dfu_bytes_rcvd_report(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd);
|
|
||||||
|
|
||||||
/**@brief Function for sending Packet Receipt Notification to the peer.
|
|
||||||
*
|
|
||||||
* This function will encode the number of bytes received as input parameter into a
|
|
||||||
* notification of the control point characteristic and send it to the peer.
|
|
||||||
*
|
|
||||||
* @param[in] p_dfu Pointer to the DFU service structure.
|
|
||||||
* @param[in] num_of_firmware_bytes_rcvd Number of bytes of firmware image received.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS if the DFU Service has successfully requested the S110 SoftDevice to send
|
|
||||||
* the notification. Otherwise an error code.
|
|
||||||
* This function returns NRF_ERROR_INVALID_STATE if the device is not connected to a
|
|
||||||
* peer or if the DFU service is not initialized or if the notification of the DFU
|
|
||||||
* Status Report characteristic was not enabled by the peer. It returns NRF_ERROR_NULL
|
|
||||||
* if the pointer p_dfu is NULL.
|
|
||||||
*/
|
|
||||||
uint32_t ble_dfu_pkts_rcpt_notify(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd);
|
|
||||||
|
|
||||||
#endif // BLE_DFU_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,861 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ble_advdata.h"
|
|
||||||
#include "nordic_common.h"
|
|
||||||
#include "nrf_error.h"
|
|
||||||
#include "ble_gap.h"
|
|
||||||
#include "ble_srv_common.h"
|
|
||||||
#include "app_util.h"
|
|
||||||
|
|
||||||
// NOTE: For now, Security Manager Out of Band Flags (OOB) are omitted from the advertising data.
|
|
||||||
|
|
||||||
// Types of LE Bluetooth Device Address AD type
|
|
||||||
#define AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC 0UL
|
|
||||||
#define AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM 1UL
|
|
||||||
|
|
||||||
static uint32_t tk_value_encode(ble_advdata_tk_value_t * p_tk_value,
|
|
||||||
uint8_t * p_encoded_data,
|
|
||||||
uint16_t * p_offset,
|
|
||||||
uint16_t max_size)
|
|
||||||
{
|
|
||||||
int8_t i;
|
|
||||||
|
|
||||||
// Check for buffer overflow.
|
|
||||||
if (((*p_offset) + AD_TYPE_TK_VALUE_SIZE) > max_size)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_DATA_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode LE Role.
|
|
||||||
p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_TK_VALUE_DATA_SIZE);
|
|
||||||
*p_offset += ADV_LENGTH_FIELD_SIZE;
|
|
||||||
p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE;
|
|
||||||
*p_offset += ADV_AD_TYPE_FIELD_SIZE;
|
|
||||||
|
|
||||||
for (i = AD_TYPE_TK_VALUE_DATA_SIZE - 1; i >= 0; i--, (*p_offset)++)
|
|
||||||
{
|
|
||||||
p_encoded_data[*p_offset] = p_tk_value->tk[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t le_role_encode(ble_advdata_le_role_t le_role,
|
|
||||||
uint8_t * p_encoded_data,
|
|
||||||
uint16_t * p_offset,
|
|
||||||
uint16_t max_size)
|
|
||||||
{
|
|
||||||
// Check for buffer overflow.
|
|
||||||
if (((*p_offset) + AD_TYPE_LE_ROLE_SIZE) > max_size)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_DATA_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode LE Role.
|
|
||||||
p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_LE_ROLE_DATA_SIZE);
|
|
||||||
*p_offset += ADV_LENGTH_FIELD_SIZE;
|
|
||||||
p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LE_ROLE;
|
|
||||||
*p_offset += ADV_AD_TYPE_FIELD_SIZE;
|
|
||||||
switch(le_role)
|
|
||||||
{
|
|
||||||
case BLE_ADVDATA_ROLE_ONLY_PERIPH:
|
|
||||||
p_encoded_data[*p_offset] = 0;
|
|
||||||
break;
|
|
||||||
case BLE_ADVDATA_ROLE_ONLY_CENTRAL:
|
|
||||||
p_encoded_data[*p_offset] = 1;
|
|
||||||
break;
|
|
||||||
case BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED:
|
|
||||||
p_encoded_data[*p_offset] = 2;
|
|
||||||
break;
|
|
||||||
case BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED:
|
|
||||||
p_encoded_data[*p_offset] = 3;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return NRF_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
*p_offset += AD_TYPE_LE_ROLE_DATA_SIZE;
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t ble_device_addr_encode(uint8_t * p_encoded_data,
|
|
||||||
uint16_t * p_offset,
|
|
||||||
uint16_t max_size)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
ble_gap_addr_t device_addr;
|
|
||||||
|
|
||||||
// Check for buffer overflow.
|
|
||||||
if (((*p_offset) + AD_TYPE_BLE_DEVICE_ADDR_SIZE) > max_size)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_DATA_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get BLE address
|
|
||||||
err_code = sd_ble_gap_address_get(&device_addr);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode LE Bluetooth Device Address
|
|
||||||
p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE +
|
|
||||||
AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE);
|
|
||||||
*p_offset += ADV_LENGTH_FIELD_SIZE;
|
|
||||||
p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS;
|
|
||||||
*p_offset += ADV_AD_TYPE_FIELD_SIZE;
|
|
||||||
memcpy(&p_encoded_data[*p_offset], &device_addr.addr[0], BLE_GAP_ADDR_LEN);
|
|
||||||
*p_offset += BLE_GAP_ADDR_LEN;
|
|
||||||
if(BLE_GAP_ADDR_TYPE_PUBLIC == device_addr.addr_type)
|
|
||||||
{
|
|
||||||
p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM;
|
|
||||||
}
|
|
||||||
*p_offset += AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE;
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t name_encode(const ble_advdata_t * p_advdata,
|
|
||||||
uint8_t * p_encoded_data,
|
|
||||||
uint16_t * p_offset,
|
|
||||||
uint16_t max_size)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
uint16_t rem_adv_data_len;
|
|
||||||
uint16_t actual_length;
|
|
||||||
uint8_t adv_data_format;
|
|
||||||
|
|
||||||
|
|
||||||
// Validate parameters
|
|
||||||
if((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) && (0 == p_advdata->short_name_len))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for buffer overflow.
|
|
||||||
if ( (((*p_offset) + ADV_AD_DATA_OFFSET) > max_size) ||
|
|
||||||
( (BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) &&
|
|
||||||
(((*p_offset) + ADV_AD_DATA_OFFSET + p_advdata->short_name_len) > max_size)))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_DATA_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
rem_adv_data_len = max_size - (*p_offset) - ADV_AD_DATA_OFFSET;
|
|
||||||
actual_length = rem_adv_data_len;
|
|
||||||
|
|
||||||
// Get GAP device name and length
|
|
||||||
err_code = sd_ble_gap_device_name_get(&p_encoded_data[(*p_offset) + ADV_AD_DATA_OFFSET],
|
|
||||||
&actual_length);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if device intend to use short name and it can fit available data size.
|
|
||||||
if ((p_advdata->name_type == BLE_ADVDATA_FULL_NAME) && (actual_length <= rem_adv_data_len))
|
|
||||||
{
|
|
||||||
// Complete device name can fit, setting Complete Name in Adv Data.
|
|
||||||
adv_data_format = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Else short name needs to be used. Or application has requested use of short name.
|
|
||||||
adv_data_format = BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME;
|
|
||||||
|
|
||||||
// If application has set a preference on the short name size, it needs to be considered,
|
|
||||||
// else fit what can be fit.
|
|
||||||
if ((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) &&
|
|
||||||
(p_advdata->short_name_len <= rem_adv_data_len))
|
|
||||||
{
|
|
||||||
// Short name fits available size.
|
|
||||||
actual_length = p_advdata->short_name_len;
|
|
||||||
}
|
|
||||||
// Else whatever can fit the data buffer will be packed.
|
|
||||||
else
|
|
||||||
{
|
|
||||||
actual_length = rem_adv_data_len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// There is only 1 byte intended to encode length which is (actual_length + ADV_AD_TYPE_FIELD_SIZE)
|
|
||||||
if(actual_length > (0x00FF - ADV_AD_TYPE_FIELD_SIZE))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_DATA_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complete name field in encoded data.
|
|
||||||
p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + actual_length);
|
|
||||||
*p_offset += ADV_LENGTH_FIELD_SIZE;
|
|
||||||
p_encoded_data[*p_offset] = adv_data_format;
|
|
||||||
*p_offset += ADV_AD_TYPE_FIELD_SIZE;
|
|
||||||
*p_offset += actual_length;
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint32_t appearance_encode(uint8_t * p_encoded_data,
|
|
||||||
uint16_t * p_offset,
|
|
||||||
uint16_t max_size)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
uint16_t appearance;
|
|
||||||
|
|
||||||
// Check for buffer overflow.
|
|
||||||
if (((*p_offset) + AD_TYPE_APPEARANCE_SIZE) > max_size)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_DATA_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get GAP appearance field.
|
|
||||||
err_code = sd_ble_gap_appearance_get(&appearance);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode Length, AD Type and Appearance.
|
|
||||||
p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_APPEARANCE_DATA_SIZE);
|
|
||||||
*p_offset += ADV_LENGTH_FIELD_SIZE;
|
|
||||||
p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_APPEARANCE;
|
|
||||||
*p_offset += ADV_AD_TYPE_FIELD_SIZE;
|
|
||||||
*p_offset += uint16_encode(appearance, &p_encoded_data[*p_offset]);
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t flags_encode(int8_t flags,
|
|
||||||
uint8_t * p_encoded_data,
|
|
||||||
uint16_t * p_offset,
|
|
||||||
uint16_t max_size)
|
|
||||||
{
|
|
||||||
// Check for buffer overflow.
|
|
||||||
if (((*p_offset) + AD_TYPE_FLAGS_SIZE) > max_size)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_DATA_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode flags.
|
|
||||||
p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_FLAGS_DATA_SIZE);
|
|
||||||
*p_offset += ADV_LENGTH_FIELD_SIZE;
|
|
||||||
p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_FLAGS;
|
|
||||||
*p_offset += ADV_AD_TYPE_FIELD_SIZE;
|
|
||||||
p_encoded_data[*p_offset] = flags;
|
|
||||||
*p_offset += AD_TYPE_FLAGS_DATA_SIZE;
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t sec_mgr_oob_flags_encode(uint8_t oob_flags,
|
|
||||||
uint8_t * p_encoded_data,
|
|
||||||
uint16_t * p_offset,
|
|
||||||
uint16_t max_size)
|
|
||||||
{
|
|
||||||
// Check for buffer overflow.
|
|
||||||
if (((*p_offset) + AD_TYPE_OOB_FLAGS_SIZE) > max_size)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_DATA_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode flags.
|
|
||||||
p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_OOB_FLAGS_DATA_SIZE);
|
|
||||||
*p_offset += ADV_LENGTH_FIELD_SIZE;
|
|
||||||
p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS;
|
|
||||||
*p_offset += ADV_AD_TYPE_FIELD_SIZE;
|
|
||||||
p_encoded_data[*p_offset] = oob_flags;
|
|
||||||
*p_offset += AD_TYPE_OOB_FLAGS_DATA_SIZE;
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t tx_power_level_encode(int8_t tx_power_level,
|
|
||||||
uint8_t * p_encoded_data,
|
|
||||||
uint16_t * p_offset,
|
|
||||||
uint16_t max_size)
|
|
||||||
{
|
|
||||||
// Check for buffer overflow.
|
|
||||||
if (((*p_offset) + AD_TYPE_TX_POWER_LEVEL_SIZE) > max_size)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_DATA_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode TX Power Level.
|
|
||||||
p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE +
|
|
||||||
AD_TYPE_TX_POWER_LEVEL_DATA_SIZE);
|
|
||||||
*p_offset += ADV_LENGTH_FIELD_SIZE;
|
|
||||||
p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_TX_POWER_LEVEL;
|
|
||||||
*p_offset += ADV_AD_TYPE_FIELD_SIZE;
|
|
||||||
p_encoded_data[*p_offset] = tx_power_level;
|
|
||||||
*p_offset += AD_TYPE_TX_POWER_LEVEL_DATA_SIZE;
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint32_t uuid_list_sized_encode(const ble_advdata_uuid_list_t * p_uuid_list,
|
|
||||||
uint8_t adv_type,
|
|
||||||
uint8_t uuid_size,
|
|
||||||
uint8_t * p_encoded_data,
|
|
||||||
uint16_t * p_offset,
|
|
||||||
uint16_t max_size)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
bool is_heading_written = false;
|
|
||||||
uint16_t start_pos = *p_offset;
|
|
||||||
uint16_t length;
|
|
||||||
|
|
||||||
for (i = 0; i < p_uuid_list->uuid_cnt; i++)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
uint8_t encoded_size;
|
|
||||||
ble_uuid_t uuid = p_uuid_list->p_uuids[i];
|
|
||||||
|
|
||||||
// Find encoded uuid size.
|
|
||||||
err_code = sd_ble_uuid_encode(&uuid, &encoded_size, NULL);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check size.
|
|
||||||
if (encoded_size == uuid_size)
|
|
||||||
{
|
|
||||||
uint8_t heading_bytes = (is_heading_written) ? 0 : ADV_AD_DATA_OFFSET;
|
|
||||||
|
|
||||||
// Check for buffer overflow
|
|
||||||
if (((*p_offset) + encoded_size + heading_bytes) > max_size)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_DATA_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_heading_written)
|
|
||||||
{
|
|
||||||
// Write AD structure heading.
|
|
||||||
*p_offset += ADV_LENGTH_FIELD_SIZE;
|
|
||||||
p_encoded_data[*p_offset] = adv_type;
|
|
||||||
*p_offset += ADV_AD_TYPE_FIELD_SIZE;
|
|
||||||
is_heading_written = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write UUID.
|
|
||||||
err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &p_encoded_data[*p_offset]);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
*p_offset += encoded_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_heading_written)
|
|
||||||
{
|
|
||||||
// Write length.
|
|
||||||
length = (*p_offset) - (start_pos + ADV_LENGTH_FIELD_SIZE);
|
|
||||||
// There is only 1 byte intended to encode length
|
|
||||||
if(length > 0x00FF)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_DATA_SIZE;
|
|
||||||
}
|
|
||||||
p_encoded_data[start_pos] = (uint8_t)length;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint32_t uuid_list_encode(const ble_advdata_uuid_list_t * p_uuid_list,
|
|
||||||
uint8_t adv_type_16,
|
|
||||||
uint8_t adv_type_128,
|
|
||||||
uint8_t * p_encoded_data,
|
|
||||||
uint16_t * p_offset,
|
|
||||||
uint16_t max_size)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
// Encode 16 bit UUIDs.
|
|
||||||
err_code = uuid_list_sized_encode(p_uuid_list,
|
|
||||||
adv_type_16,
|
|
||||||
sizeof(uint16_le_t),
|
|
||||||
p_encoded_data,
|
|
||||||
p_offset,
|
|
||||||
max_size);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode 128 bit UUIDs.
|
|
||||||
err_code = uuid_list_sized_encode(p_uuid_list,
|
|
||||||
adv_type_128,
|
|
||||||
sizeof(ble_uuid128_t),
|
|
||||||
p_encoded_data,
|
|
||||||
p_offset,
|
|
||||||
max_size);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint32_t conn_int_check(const ble_advdata_conn_int_t *p_conn_int)
|
|
||||||
{
|
|
||||||
// Check Minimum Connection Interval.
|
|
||||||
if ((p_conn_int->min_conn_interval < 0x0006) ||
|
|
||||||
(
|
|
||||||
(p_conn_int->min_conn_interval > 0x0c80) &&
|
|
||||||
(p_conn_int->min_conn_interval != 0xffff)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check Maximum Connection Interval.
|
|
||||||
if ((p_conn_int->max_conn_interval < 0x0006) ||
|
|
||||||
(
|
|
||||||
(p_conn_int->max_conn_interval > 0x0c80) &&
|
|
||||||
(p_conn_int->max_conn_interval != 0xffff)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure Minimum Connection Interval is not bigger than Maximum Connection Interval.
|
|
||||||
if ((p_conn_int->min_conn_interval != 0xffff) &&
|
|
||||||
(p_conn_int->max_conn_interval != 0xffff) &&
|
|
||||||
(p_conn_int->min_conn_interval > p_conn_int->max_conn_interval)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint32_t conn_int_encode(const ble_advdata_conn_int_t * p_conn_int,
|
|
||||||
uint8_t * p_encoded_data,
|
|
||||||
uint16_t * p_offset,
|
|
||||||
uint16_t max_size)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
// Check for buffer overflow.
|
|
||||||
if (((*p_offset) + AD_TYPE_CONN_INT_SIZE) > max_size)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_DATA_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check parameters.
|
|
||||||
err_code = conn_int_check(p_conn_int);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode Length and AD Type.
|
|
||||||
p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_CONN_INT_DATA_SIZE);
|
|
||||||
*p_offset += ADV_LENGTH_FIELD_SIZE;
|
|
||||||
p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE;
|
|
||||||
*p_offset += ADV_AD_TYPE_FIELD_SIZE;
|
|
||||||
|
|
||||||
// Encode Minimum and Maximum Connection Intervals.
|
|
||||||
*p_offset += uint16_encode(p_conn_int->min_conn_interval, &p_encoded_data[*p_offset]);
|
|
||||||
*p_offset += uint16_encode(p_conn_int->max_conn_interval, &p_encoded_data[*p_offset]);
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint32_t manuf_specific_data_encode(const ble_advdata_manuf_data_t * p_manuf_sp_data,
|
|
||||||
uint8_t * p_encoded_data,
|
|
||||||
uint16_t * p_offset,
|
|
||||||
uint16_t max_size)
|
|
||||||
{
|
|
||||||
uint32_t data_size = AD_TYPE_MANUF_SPEC_DATA_ID_SIZE + p_manuf_sp_data->data.size;
|
|
||||||
|
|
||||||
// Check for buffer overflow.
|
|
||||||
if (((*p_offset) + ADV_AD_DATA_OFFSET + data_size) > max_size)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_DATA_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// There is only 1 byte intended to encode length which is (data_size + ADV_AD_TYPE_FIELD_SIZE)
|
|
||||||
if(data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_DATA_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode Length and AD Type.
|
|
||||||
p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + data_size);
|
|
||||||
*p_offset += ADV_LENGTH_FIELD_SIZE;
|
|
||||||
p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA;
|
|
||||||
*p_offset += ADV_AD_TYPE_FIELD_SIZE;
|
|
||||||
|
|
||||||
// Encode Company Identifier.
|
|
||||||
*p_offset += uint16_encode(p_manuf_sp_data->company_identifier, &p_encoded_data[*p_offset]);
|
|
||||||
|
|
||||||
// Encode additional manufacturer specific data.
|
|
||||||
if (p_manuf_sp_data->data.size > 0)
|
|
||||||
{
|
|
||||||
if (p_manuf_sp_data->data.p_data == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
memcpy(&p_encoded_data[*p_offset], p_manuf_sp_data->data.p_data, p_manuf_sp_data->data.size);
|
|
||||||
*p_offset += p_manuf_sp_data->data.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Implemented only for 16-bit UUIDs
|
|
||||||
static uint32_t service_data_encode(const ble_advdata_t * p_advdata,
|
|
||||||
uint8_t * p_encoded_data,
|
|
||||||
uint16_t * p_offset,
|
|
||||||
uint16_t max_size)
|
|
||||||
{
|
|
||||||
uint8_t i;
|
|
||||||
|
|
||||||
// Check parameter consistency.
|
|
||||||
if (p_advdata->p_service_data_array == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < p_advdata->service_data_count; i++)
|
|
||||||
{
|
|
||||||
ble_advdata_service_data_t * p_service_data;
|
|
||||||
uint32_t data_size;
|
|
||||||
|
|
||||||
p_service_data = &p_advdata->p_service_data_array[i];
|
|
||||||
// For now implemented only for 16-bit UUIDs
|
|
||||||
data_size = AD_TYPE_SERV_DATA_16BIT_UUID_SIZE + p_service_data->data.size;
|
|
||||||
|
|
||||||
// There is only 1 byte intended to encode length which is (data_size + ADV_AD_TYPE_FIELD_SIZE)
|
|
||||||
if(data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_DATA_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode Length and AD Type.
|
|
||||||
p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + data_size);
|
|
||||||
*p_offset += ADV_LENGTH_FIELD_SIZE;
|
|
||||||
p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SERVICE_DATA;
|
|
||||||
*p_offset += ADV_AD_TYPE_FIELD_SIZE;
|
|
||||||
|
|
||||||
// Encode service 16-bit UUID.
|
|
||||||
*p_offset += uint16_encode(p_service_data->service_uuid, &p_encoded_data[*p_offset]);
|
|
||||||
|
|
||||||
// Encode additional service data.
|
|
||||||
if (p_service_data->data.size > 0)
|
|
||||||
{
|
|
||||||
if (p_service_data->data.p_data == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
memcpy(&p_encoded_data[*p_offset], p_service_data->data.p_data, p_service_data->data.size);
|
|
||||||
*p_offset += p_service_data->data.size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t adv_data_encode(ble_advdata_t const * const p_advdata,
|
|
||||||
uint8_t * const p_encoded_data,
|
|
||||||
uint16_t * const p_len)
|
|
||||||
{
|
|
||||||
uint32_t err_code = NRF_SUCCESS;
|
|
||||||
uint16_t max_size = *p_len;
|
|
||||||
*p_len = 0;
|
|
||||||
|
|
||||||
//Encode Security Manager OOB Flags
|
|
||||||
if (p_advdata->p_sec_mgr_oob_flags != NULL)
|
|
||||||
{
|
|
||||||
err_code = sec_mgr_oob_flags_encode(*p_advdata->p_sec_mgr_oob_flags,
|
|
||||||
p_encoded_data,
|
|
||||||
p_len,
|
|
||||||
max_size);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode Security Manager TK value
|
|
||||||
if (NULL != p_advdata->p_tk_value)
|
|
||||||
{
|
|
||||||
err_code = tk_value_encode(p_advdata->p_tk_value, p_encoded_data, p_len, max_size);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode LE Role
|
|
||||||
if (BLE_ADVDATA_ROLE_NOT_PRESENT != p_advdata->le_role)
|
|
||||||
{
|
|
||||||
err_code = le_role_encode(p_advdata->le_role, p_encoded_data, p_len, max_size);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode LE Bluetooth Device Address
|
|
||||||
if (p_advdata->include_ble_device_addr)
|
|
||||||
{
|
|
||||||
err_code = ble_device_addr_encode(p_encoded_data, p_len, max_size);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode appearance.
|
|
||||||
if (p_advdata->include_appearance)
|
|
||||||
{
|
|
||||||
err_code = appearance_encode(p_encoded_data, p_len, max_size);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Encode Flags
|
|
||||||
if(p_advdata->flags != 0 )
|
|
||||||
{
|
|
||||||
err_code = flags_encode(p_advdata->flags, p_encoded_data, p_len, max_size);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode TX power level.
|
|
||||||
if (p_advdata->p_tx_power_level != NULL)
|
|
||||||
{
|
|
||||||
err_code = tx_power_level_encode(*p_advdata->p_tx_power_level,
|
|
||||||
p_encoded_data,
|
|
||||||
p_len,
|
|
||||||
max_size);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode 'more available' uuid list.
|
|
||||||
if (p_advdata->uuids_more_available.uuid_cnt > 0)
|
|
||||||
{
|
|
||||||
err_code = uuid_list_encode(&p_advdata->uuids_more_available,
|
|
||||||
BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE,
|
|
||||||
BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE,
|
|
||||||
p_encoded_data,
|
|
||||||
p_len,
|
|
||||||
max_size);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode 'complete' uuid list.
|
|
||||||
if (p_advdata->uuids_complete.uuid_cnt > 0)
|
|
||||||
{
|
|
||||||
err_code = uuid_list_encode(&p_advdata->uuids_complete,
|
|
||||||
BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE,
|
|
||||||
BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE,
|
|
||||||
p_encoded_data,
|
|
||||||
p_len,
|
|
||||||
max_size);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode 'solicited service' uuid list.
|
|
||||||
if (p_advdata->uuids_solicited.uuid_cnt > 0)
|
|
||||||
{
|
|
||||||
err_code = uuid_list_encode(&p_advdata->uuids_solicited,
|
|
||||||
BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT,
|
|
||||||
BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT,
|
|
||||||
p_encoded_data,
|
|
||||||
p_len,
|
|
||||||
max_size);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode Slave Connection Interval Range.
|
|
||||||
if (p_advdata->p_slave_conn_int != NULL)
|
|
||||||
{
|
|
||||||
err_code = conn_int_encode(p_advdata->p_slave_conn_int, p_encoded_data, p_len, max_size);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode Manufacturer Specific Data.
|
|
||||||
if (p_advdata->p_manuf_specific_data != NULL)
|
|
||||||
{
|
|
||||||
err_code = manuf_specific_data_encode(p_advdata->p_manuf_specific_data,
|
|
||||||
p_encoded_data,
|
|
||||||
p_len,
|
|
||||||
max_size);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode Service Data.
|
|
||||||
if (p_advdata->service_data_count > 0)
|
|
||||||
{
|
|
||||||
err_code = service_data_encode(p_advdata, p_encoded_data, p_len, max_size);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode name. WARNING: it is encoded last on purpose since too long device name is truncated.
|
|
||||||
if (p_advdata->name_type != BLE_ADVDATA_NO_NAME)
|
|
||||||
{
|
|
||||||
err_code = name_encode(p_advdata, p_encoded_data, p_len, max_size);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint32_t advdata_check(const ble_advdata_t * p_advdata)
|
|
||||||
{
|
|
||||||
// Flags must be included in advertising data, and the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag must be set.
|
|
||||||
if (
|
|
||||||
((p_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static uint32_t srdata_check(const ble_advdata_t * p_srdata)
|
|
||||||
{
|
|
||||||
// Flags shall not be included in the scan response data.
|
|
||||||
if (p_srdata->flags)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_advdata_set(const ble_advdata_t * p_advdata, const ble_advdata_t * p_srdata)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
uint16_t len_advdata = BLE_GAP_ADV_MAX_SIZE;
|
|
||||||
uint16_t len_srdata = BLE_GAP_ADV_MAX_SIZE;
|
|
||||||
uint8_t encoded_advdata[BLE_GAP_ADV_MAX_SIZE];
|
|
||||||
uint8_t encoded_srdata[BLE_GAP_ADV_MAX_SIZE];
|
|
||||||
uint8_t * p_encoded_advdata;
|
|
||||||
uint8_t * p_encoded_srdata;
|
|
||||||
|
|
||||||
// Encode advertising data (if supplied).
|
|
||||||
if (p_advdata != NULL)
|
|
||||||
{
|
|
||||||
err_code = advdata_check(p_advdata);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_code = adv_data_encode(p_advdata, encoded_advdata, &len_advdata);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
p_encoded_advdata = encoded_advdata;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p_encoded_advdata = NULL;
|
|
||||||
len_advdata = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode scan response data (if supplied).
|
|
||||||
if (p_srdata != NULL)
|
|
||||||
{
|
|
||||||
err_code = srdata_check(p_srdata);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_code = adv_data_encode(p_srdata, encoded_srdata, &len_srdata);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
p_encoded_srdata = encoded_srdata;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p_encoded_srdata = NULL;
|
|
||||||
len_srdata = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pass encoded advertising data and/or scan response data to the stack.
|
|
||||||
return sd_ble_gap_adv_data_set(p_encoded_advdata, len_advdata, p_encoded_srdata, len_srdata);
|
|
||||||
}
|
|
|
@ -1,232 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
*
|
|
||||||
* @defgroup ble_sdk_lib_advdata Advertising and Scan Response Data Encoder
|
|
||||||
* @{
|
|
||||||
* @ingroup ble_sdk_lib
|
|
||||||
* @brief Functions for encoding data in the Advertising and Scan Response Data format,
|
|
||||||
* and for passing the data to the stack.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BLE_ADVDATA_H__
|
|
||||||
#define BLE_ADVDATA_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "nrf_ble.h"
|
|
||||||
#include "app_util.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define ADV_LENGTH_FIELD_SIZE 1UL /**< Advertising Data and Scan Response format contains 1 octet for the length. */
|
|
||||||
#define ADV_AD_TYPE_FIELD_SIZE 1UL /**< Advertising Data and Scan Response format contains 1 octet for the AD type. */
|
|
||||||
#define ADV_AD_DATA_OFFSET (ADV_LENGTH_FIELD_SIZE + \
|
|
||||||
ADV_AD_TYPE_FIELD_SIZE) /**< Offset for the AD data field of the Advertising Data and Scan Response format. */
|
|
||||||
#define AD_TYPE_TK_VALUE_DATA_SIZE (sizeof(ble_advdata_tk_value_t)) /**< Data size (in octets) of the Security Manager TK value AD type. */
|
|
||||||
#define AD_TYPE_TK_VALUE_SIZE (ADV_AD_DATA_OFFSET + \
|
|
||||||
AD_TYPE_TK_VALUE_DATA_SIZE) /**< Size (in octets) of the Security Manager TK value AD type. */
|
|
||||||
#define AD_TYPE_LE_ROLE_DATA_SIZE 1UL /**< Data size (in octets) of the LE Bluetooth Device Address AD type. */
|
|
||||||
#define AD_TYPE_LE_ROLE_SIZE (ADV_AD_DATA_OFFSET + \
|
|
||||||
AD_TYPE_LE_ROLE_DATA_SIZE) /**< Size (in octets) of the LE Bluetooth Device Address AD type. */
|
|
||||||
#define AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE 1UL /**< Data size (in octets) of the Address type of the LE Bluetooth Device Address AD type. */
|
|
||||||
#define AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE (BLE_GAP_ADDR_LEN + \
|
|
||||||
AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE) /**< Data size (in octets) of the LE Bluetooth Device Address AD type. */
|
|
||||||
#define AD_TYPE_BLE_DEVICE_ADDR_SIZE (ADV_AD_DATA_OFFSET + \
|
|
||||||
AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE) /**< Size (in octets) of the LE Bluetooth Device Address AD type. */
|
|
||||||
#define AD_TYPE_APPEARANCE_DATA_SIZE 2UL /**< Data size (in octets) of the Appearance AD type. */
|
|
||||||
#define AD_TYPE_APPEARANCE_SIZE (ADV_AD_DATA_OFFSET + \
|
|
||||||
AD_TYPE_APPEARANCE_DATA_SIZE) /**< Size (in octets) of the Appearance AD type. */
|
|
||||||
#define AD_TYPE_FLAGS_DATA_SIZE 1UL /**< Data size (in octets) of the Flags AD type. */
|
|
||||||
#define AD_TYPE_FLAGS_SIZE (ADV_AD_DATA_OFFSET + \
|
|
||||||
AD_TYPE_FLAGS_DATA_SIZE) /**< Size (in octets) of the Flags AD type. */
|
|
||||||
#define AD_TYPE_TX_POWER_LEVEL_DATA_SIZE 1UL /**< Data size (in octets) of the TX Power Level AD type. */
|
|
||||||
#define AD_TYPE_TX_POWER_LEVEL_SIZE (ADV_AD_DATA_OFFSET + \
|
|
||||||
AD_TYPE_TX_POWER_LEVEL_DATA_SIZE) /**< Size (in octets) of the TX Power Level AD type. */
|
|
||||||
#define AD_TYPE_CONN_INT_DATA_SIZE 4UL /**< Data size (in octets) of the Slave Connection Interval Range AD type. */
|
|
||||||
#define AD_TYPE_CONN_INT_SIZE (ADV_AD_DATA_OFFSET + \
|
|
||||||
AD_TYPE_CONN_INT_DATA_SIZE) /**< Data size (in octets) of the Slave Connection Interval Range AD type. */
|
|
||||||
#define AD_TYPE_MANUF_SPEC_DATA_ID_SIZE 2UL /**< Size (in octets) of the Company Identifier Code, which is a part of the Manufacturer Specific Data AD type. */
|
|
||||||
#define AD_TYPE_SERV_DATA_16BIT_UUID_SIZE 2UL /**< Size (in octets) of the 16-bit UUID, which is a part of the Service Data AD type. */
|
|
||||||
#define AD_TYPE_OOB_FLAGS_DATA_SIZE 1UL /**< Data size (in octets) of the Security Manager OOB Flags AD type. */
|
|
||||||
#define AD_TYPE_OOB_FLAGS_SIZE (ADV_AD_DATA_OFFSET + \
|
|
||||||
AD_TYPE_OOB_FLAGS_DATA_SIZE) /**< Size (in octets) of the Security Manager OOB Flags AD type. */
|
|
||||||
|
|
||||||
#define AD_TYPE_SEC_MGR_OOB_FLAG_SET 1U /**< Security Manager OOB Flag set. Flag selection is done using _POS defines */
|
|
||||||
#define AD_TYPE_SEC_MGR_OOB_FLAG_CLEAR 0U /**< Security Manager OOB Flag clear. Flag selection is done using _POS defines */
|
|
||||||
#define AD_TYPE_SEC_MGR_OOB_FLAG_OOB_DATA_PRESENT_POS 0UL /**< Security Manager OOB Data Present Flag position. */
|
|
||||||
#define AD_TYPE_SEC_MGR_OOB_FLAG_OOB_LE_SUPPORTED_POS 1UL /**< Security Manager OOB Low Energy Supported Flag position. */
|
|
||||||
#define AD_TYPE_SEC_MGR_OOB_FLAG_SIM_LE_AND_EP_POS 2UL /**< Security Manager OOB Simultaneous LE and BR/EDR to Same Device Capable Flag position. */
|
|
||||||
#define AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_PUBLIC 0UL /**< Security Manager OOB Public Address type. */
|
|
||||||
#define AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_RANDOM 1UL /**< Security Manager OOB Random Address type. */
|
|
||||||
#define AD_TYPE_SEC_MGR_OOB_FLAG_ADDRESS_TYPE_POS 3UL /**< Security Manager OOB Address type Flag (0 = Public Address, 1 = Random Address) position. */
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Security Manager TK value. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t tk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing TK value. */
|
|
||||||
} ble_advdata_tk_value_t;
|
|
||||||
|
|
||||||
/**@brief Advertising data LE Role types. This enumeration contains the options available for the LE role inside
|
|
||||||
* the advertising data. */
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
BLE_ADVDATA_ROLE_NOT_PRESENT = 0, /**< LE Role AD structure not present. */
|
|
||||||
BLE_ADVDATA_ROLE_ONLY_PERIPH, /**< Only Peripheral Role supported. */
|
|
||||||
BLE_ADVDATA_ROLE_ONLY_CENTRAL, /**< Only Central Role supported. */
|
|
||||||
BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED, /**< Peripheral and Central Role supported. Peripheral Role preferred for connection establishment. */
|
|
||||||
BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED /**< Peripheral and Central Role supported. Central Role preferred for connection establishment */
|
|
||||||
} ble_advdata_le_role_t;
|
|
||||||
|
|
||||||
/**@brief Advertising data name type. This enumeration contains the options available for the device name inside
|
|
||||||
* the advertising data. */
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
BLE_ADVDATA_NO_NAME, /**< Include no device name in advertising data. */
|
|
||||||
BLE_ADVDATA_SHORT_NAME, /**< Include short device name in advertising data. */
|
|
||||||
BLE_ADVDATA_FULL_NAME /**< Include full device name in advertising data. */
|
|
||||||
} ble_advdata_name_type_t;
|
|
||||||
|
|
||||||
/**@brief UUID list type. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t uuid_cnt; /**< Number of UUID entries. */
|
|
||||||
ble_uuid_t * p_uuids; /**< Pointer to UUID array entries. */
|
|
||||||
} ble_advdata_uuid_list_t;
|
|
||||||
|
|
||||||
/**@brief Connection interval range structure. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t min_conn_interval; /**< Minimum connection interval, in units of 1.25 ms, range 6 to 3200 (7.5 ms to 4 s). */
|
|
||||||
uint16_t max_conn_interval; /**< Maximum connection interval, in units of 1.25 ms, range 6 to 3200 (7.5 ms to 4 s). The value 0xFFFF indicates no specific maximum. */
|
|
||||||
} ble_advdata_conn_int_t;
|
|
||||||
|
|
||||||
/**@brief Manufacturer specific data structure. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t company_identifier; /**< Company identifier code. */
|
|
||||||
uint8_array_t data; /**< Additional manufacturer specific data. */
|
|
||||||
} ble_advdata_manuf_data_t;
|
|
||||||
|
|
||||||
/**@brief Service data structure. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t service_uuid; /**< Service UUID. */
|
|
||||||
uint8_array_t data; /**< Additional service data. */
|
|
||||||
} ble_advdata_service_data_t;
|
|
||||||
|
|
||||||
/**@brief Advertising data structure. This structure contains all options and data needed for encoding and
|
|
||||||
* setting the advertising data. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
ble_advdata_name_type_t name_type; /**< Type of device name. */
|
|
||||||
uint8_t short_name_len; /**< Length of short device name (if short type is specified). */
|
|
||||||
bool include_appearance; /**< Determines if Appearance shall be included. */
|
|
||||||
uint8_t flags; /**< Advertising data Flags field. */
|
|
||||||
int8_t * p_tx_power_level; /**< TX Power Level field. */
|
|
||||||
ble_advdata_uuid_list_t uuids_more_available; /**< List of UUIDs in the 'More Available' list. */
|
|
||||||
ble_advdata_uuid_list_t uuids_complete; /**< List of UUIDs in the 'Complete' list. */
|
|
||||||
ble_advdata_uuid_list_t uuids_solicited; /**< List of solicited UUIDs. */
|
|
||||||
ble_advdata_conn_int_t * p_slave_conn_int; /**< Slave Connection Interval Range. */
|
|
||||||
ble_advdata_manuf_data_t * p_manuf_specific_data; /**< Manufacturer specific data. */
|
|
||||||
ble_advdata_service_data_t * p_service_data_array; /**< Array of Service data structures. */
|
|
||||||
uint8_t service_data_count; /**< Number of Service data structures. */
|
|
||||||
bool include_ble_device_addr; /**< Determines if LE Bluetooth Device Address shall be included. */
|
|
||||||
ble_advdata_le_role_t le_role; /**< LE Role field. Included when different from @ref BLE_ADVDATA_ROLE_NOT_PRESENT.*/
|
|
||||||
ble_advdata_tk_value_t * p_tk_value; /**< Security Manager TK value field. Included when different from NULL.*/
|
|
||||||
uint8_t * p_sec_mgr_oob_flags; /**< Security Manager Out Of Band Flags field. Included when different from NULL.*/
|
|
||||||
} ble_advdata_t;
|
|
||||||
|
|
||||||
/**@brief Function for encoding data in the Advertising and Scan Response data format
|
|
||||||
* (AD structures).
|
|
||||||
*
|
|
||||||
* @details This function encodes data into the Advertising and Scan Response data format
|
|
||||||
* (AD structures) based on the selections in the supplied structures. This function can be used to
|
|
||||||
* create a payload of Advertising packet or Scan Response packet, or a payload of NFC
|
|
||||||
* message intended for initiating the Out-of-Band pairing.
|
|
||||||
*
|
|
||||||
* @param[in] p_advdata Pointer to the structure for specifying the content of encoded data.
|
|
||||||
* @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned.
|
|
||||||
* @param[in,out] p_len \c in: Size of \p p_encoded_data buffer.
|
|
||||||
* \c out: Length of encoded data.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS If the operation was successful.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM If the operation failed because a wrong parameter was provided in \p p_advdata.
|
|
||||||
* @retval NRF_ERROR_DATA_SIZE If the operation failed because not all the requested data could fit into the
|
|
||||||
* provided buffer or some encoded AD structure is too long and its
|
|
||||||
* length cannot be encoded with one octet.
|
|
||||||
*
|
|
||||||
* @warning This API may override the application's request to use the long name and use a short name
|
|
||||||
* instead. This truncation will occur in case the long name does not fit the provided buffer size.
|
|
||||||
* The application can specify a preferred short name length if truncation is required.
|
|
||||||
* For example, if the complete device name is ABCD_HRMonitor, the application can specify the short name
|
|
||||||
* length to be 8, so that the short device name appears as ABCD_HRM instead of ABCD_HRMo or ABCD_HRMoni
|
|
||||||
* if the available size for the short name is 9 or 12 respectively, to have a more appropriate short name.
|
|
||||||
* However, it should be noted that this is just a preference that the application can specify, and
|
|
||||||
* if the preference is too large to fit in the provided buffer, the name can be truncated further.
|
|
||||||
*/
|
|
||||||
uint32_t adv_data_encode(ble_advdata_t const * const p_advdata,
|
|
||||||
uint8_t * const p_encoded_data,
|
|
||||||
uint16_t * const p_len);
|
|
||||||
|
|
||||||
/**@brief Function for encoding and setting the advertising data and/or scan response data.
|
|
||||||
*
|
|
||||||
* @details This function encodes advertising data and/or scan response data based on the selections
|
|
||||||
* in the supplied structures, and passes the encoded data to the stack.
|
|
||||||
*
|
|
||||||
* @param[in] p_advdata Structure for specifying the content of the advertising data.
|
|
||||||
* Set to NULL if advertising data is not to be set.
|
|
||||||
* @param[in] p_srdata Structure for specifying the content of the scan response data.
|
|
||||||
* Set to NULL if scan response data is not to be set.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS If the operation was successful.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM If the operation failed because a wrong parameter was provided in \p p_advdata.
|
|
||||||
* @retval NRF_ERROR_DATA_SIZE If the operation failed because not all the requested data could fit into the
|
|
||||||
* advertising packet. The maximum size of the advertisement packet
|
|
||||||
* is @ref BLE_GAP_ADV_MAX_SIZE.
|
|
||||||
*
|
|
||||||
* @warning This API may override the application's request to use the long name and use a short name
|
|
||||||
* instead. This truncation will occur in case the long name does not fit the provided buffer size.
|
|
||||||
* The application can specify a preferred short name length if truncation is required.
|
|
||||||
* For example, if the complete device name is ABCD_HRMonitor, the application can specify the short name
|
|
||||||
* length to be 8, so that the short device name appears as ABCD_HRM instead of ABCD_HRMo or ABCD_HRMoni
|
|
||||||
* if the available size for the short name is 9 or 12 respectively, to have a more appropriate short name.
|
|
||||||
* However, it should be noted that this is just a preference that the application can specify, and
|
|
||||||
* if the preference is too large to fit in the provided buffer, the name can be truncated further.
|
|
||||||
*/
|
|
||||||
uint32_t ble_advdata_set(const ble_advdata_t * p_advdata, const ble_advdata_t * p_srdata);
|
|
||||||
|
|
||||||
#endif // BLE_ADVDATA_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,386 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ble_conn_params.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "nordic_common.h"
|
|
||||||
#include "ble_hci.h"
|
|
||||||
#include "ble_srv_common.h"
|
|
||||||
#include "app_util.h"
|
|
||||||
|
|
||||||
#ifdef USE_APP_TIMER
|
|
||||||
#include "app_timer.h"
|
|
||||||
#else
|
|
||||||
#ifdef YOTTA_CFG_MBED_OS
|
|
||||||
#include "mbed-drivers/mbed.h"
|
|
||||||
#else
|
|
||||||
#include "mbed.h"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static ble_conn_params_init_t m_conn_params_config; /**< Configuration as specified by the application. */
|
|
||||||
static ble_gap_conn_params_t m_preferred_conn_params; /**< Connection parameters preferred by the application. */
|
|
||||||
static uint8_t m_update_count; /**< Number of Connection Parameter Update messages that has currently been sent. */
|
|
||||||
static uint16_t m_conn_handle; /**< Current connection handle. */
|
|
||||||
static ble_gap_conn_params_t m_current_conn_params; /**< Connection parameters received in the most recent Connect event. */
|
|
||||||
#ifdef USE_APP_TIMER
|
|
||||||
static app_timer_id_t m_conn_params_timer_id; /**< Connection parameters timer. */
|
|
||||||
#else
|
|
||||||
static Ticker m_conn_params_timer;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static bool m_change_param = false;
|
|
||||||
|
|
||||||
static bool is_conn_params_ok(ble_gap_conn_params_t * p_conn_params)
|
|
||||||
{
|
|
||||||
// Check if interval is within the acceptable range.
|
|
||||||
// NOTE: Using max_conn_interval in the received event data because this contains
|
|
||||||
// the client's connection interval.
|
|
||||||
if (
|
|
||||||
(p_conn_params->max_conn_interval >= m_preferred_conn_params.min_conn_interval)
|
|
||||||
&&
|
|
||||||
(p_conn_params->max_conn_interval <= m_preferred_conn_params.max_conn_interval)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef USE_APP_TIMER
|
|
||||||
static void update_timeout_handler(void * p_context)
|
|
||||||
{
|
|
||||||
UNUSED_PARAMETER(p_context);
|
|
||||||
|
|
||||||
#else /* #if !USE_APP_TIMER */
|
|
||||||
static void update_timeout_handler(void)
|
|
||||||
{
|
|
||||||
m_conn_params_timer.detach(); /* this is supposed to be a single-shot timer callback */
|
|
||||||
#endif /* #if !USE_APP_TIMER */
|
|
||||||
if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
|
|
||||||
{
|
|
||||||
// Check if we have reached the maximum number of attempts
|
|
||||||
m_update_count++;
|
|
||||||
if (m_update_count <= m_conn_params_config.max_conn_params_update_count)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
// Parameters are not ok, send connection parameters update request.
|
|
||||||
err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params);
|
|
||||||
if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
|
|
||||||
{
|
|
||||||
m_conn_params_config.error_handler(err_code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_update_count = 0;
|
|
||||||
|
|
||||||
// Negotiation failed, disconnect automatically if this has been configured
|
|
||||||
if (m_conn_params_config.disconnect_on_fail)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
|
|
||||||
if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
|
|
||||||
{
|
|
||||||
m_conn_params_config.error_handler(err_code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify the application that the procedure has failed
|
|
||||||
if (m_conn_params_config.evt_handler != NULL)
|
|
||||||
{
|
|
||||||
ble_conn_params_evt_t evt;
|
|
||||||
|
|
||||||
evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED;
|
|
||||||
m_conn_params_config.evt_handler(&evt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_conn_params_init(const ble_conn_params_init_t * p_init)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
m_conn_params_config = *p_init;
|
|
||||||
m_change_param = false;
|
|
||||||
if (p_init->p_conn_params != NULL)
|
|
||||||
{
|
|
||||||
m_preferred_conn_params = *p_init->p_conn_params;
|
|
||||||
|
|
||||||
// Set the connection params in stack
|
|
||||||
err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Fetch the connection params from stack
|
|
||||||
err_code = sd_ble_gap_ppcp_get(&m_preferred_conn_params);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_conn_handle = BLE_CONN_HANDLE_INVALID;
|
|
||||||
m_update_count = 0;
|
|
||||||
|
|
||||||
#ifdef USE_APP_TIMER
|
|
||||||
return app_timer_create(&m_conn_params_timer_id,
|
|
||||||
APP_TIMER_MODE_SINGLE_SHOT,
|
|
||||||
update_timeout_handler);
|
|
||||||
#else
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_conn_params_stop(void)
|
|
||||||
{
|
|
||||||
#ifdef USE_APP_TIMER
|
|
||||||
return app_timer_stop(m_conn_params_timer_id);
|
|
||||||
#else /* #if !USE_APP_TIMER */
|
|
||||||
m_conn_params_timer.detach();
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
#endif /* #if !USE_APP_TIMER */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void conn_params_negotiation(void)
|
|
||||||
{
|
|
||||||
// Start negotiation if the received connection parameters are not acceptable
|
|
||||||
if (!is_conn_params_ok(&m_current_conn_params))
|
|
||||||
{
|
|
||||||
#ifdef USE_APP_TIMER
|
|
||||||
uint32_t err_code;
|
|
||||||
#endif
|
|
||||||
uint32_t timeout_ticks;
|
|
||||||
|
|
||||||
if (m_change_param)
|
|
||||||
{
|
|
||||||
// Notify the application that the procedure has failed
|
|
||||||
if (m_conn_params_config.evt_handler != NULL)
|
|
||||||
{
|
|
||||||
ble_conn_params_evt_t evt;
|
|
||||||
|
|
||||||
evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED;
|
|
||||||
m_conn_params_config.evt_handler(&evt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (m_update_count == 0)
|
|
||||||
{
|
|
||||||
// First connection parameter update
|
|
||||||
timeout_ticks = m_conn_params_config.first_conn_params_update_delay;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
timeout_ticks = m_conn_params_config.next_conn_params_update_delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_APP_TIMER
|
|
||||||
err_code = app_timer_start(m_conn_params_timer_id, timeout_ticks, NULL);
|
|
||||||
if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
|
|
||||||
{
|
|
||||||
m_conn_params_config.error_handler(err_code);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
m_conn_params_timer.attach(update_timeout_handler, timeout_ticks / 32768);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Notify the application that the procedure has succeded
|
|
||||||
if (m_conn_params_config.evt_handler != NULL)
|
|
||||||
{
|
|
||||||
ble_conn_params_evt_t evt;
|
|
||||||
|
|
||||||
evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED;
|
|
||||||
m_conn_params_config.evt_handler(&evt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_change_param = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void on_connect(ble_evt_t * p_ble_evt)
|
|
||||||
{
|
|
||||||
// Save connection parameters
|
|
||||||
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
|
|
||||||
m_current_conn_params = p_ble_evt->evt.gap_evt.params.connected.conn_params;
|
|
||||||
m_update_count = 0; // Connection parameter negotiation should re-start every connection
|
|
||||||
|
|
||||||
// Check if we shall handle negotiation on connect
|
|
||||||
if (m_conn_params_config.start_on_notify_cccd_handle == BLE_GATT_HANDLE_INVALID)
|
|
||||||
{
|
|
||||||
conn_params_negotiation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void on_disconnect(ble_evt_t * p_ble_evt)
|
|
||||||
{
|
|
||||||
#ifdef USE_APP_TIMER
|
|
||||||
uint32_t err_code;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_conn_handle = BLE_CONN_HANDLE_INVALID;
|
|
||||||
|
|
||||||
// Stop timer if running
|
|
||||||
m_update_count = 0; // Connection parameters updates should happen during every connection
|
|
||||||
|
|
||||||
#ifdef USE_APP_TIMER
|
|
||||||
err_code = app_timer_stop(m_conn_params_timer_id);
|
|
||||||
if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
|
|
||||||
{
|
|
||||||
m_conn_params_config.error_handler(err_code);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
m_conn_params_timer.detach();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void on_write(ble_evt_t * p_ble_evt)
|
|
||||||
{
|
|
||||||
ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
|
|
||||||
|
|
||||||
// Check if this the correct CCCD
|
|
||||||
if (
|
|
||||||
(p_evt_write->handle == m_conn_params_config.start_on_notify_cccd_handle)
|
|
||||||
&&
|
|
||||||
(p_evt_write->len == 2)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Check if this is a 'start notification'
|
|
||||||
if (ble_srv_is_notification_enabled(p_evt_write->data))
|
|
||||||
{
|
|
||||||
// Do connection parameter negotiation if necessary
|
|
||||||
conn_params_negotiation();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef USE_APP_TIMER
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
// Stop timer if running
|
|
||||||
err_code = app_timer_stop(m_conn_params_timer_id);
|
|
||||||
if ((err_code != NRF_SUCCESS) && (m_conn_params_config.error_handler != NULL))
|
|
||||||
{
|
|
||||||
m_conn_params_config.error_handler(err_code);
|
|
||||||
}
|
|
||||||
#else /* #if !USE_APP_TIMER */
|
|
||||||
m_conn_params_timer.detach();
|
|
||||||
#endif /* #if !USE_APP_TIMER */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void on_conn_params_update(ble_evt_t * p_ble_evt)
|
|
||||||
{
|
|
||||||
// Copy the parameters
|
|
||||||
m_current_conn_params = p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params;
|
|
||||||
|
|
||||||
conn_params_negotiation();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ble_conn_params_on_ble_evt(ble_evt_t * p_ble_evt)
|
|
||||||
{
|
|
||||||
switch (p_ble_evt->header.evt_id)
|
|
||||||
{
|
|
||||||
case BLE_GAP_EVT_CONNECTED:
|
|
||||||
on_connect(p_ble_evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_GAP_EVT_DISCONNECTED:
|
|
||||||
on_disconnect(p_ble_evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_GATTS_EVT_WRITE:
|
|
||||||
on_write(p_ble_evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_GAP_EVT_CONN_PARAM_UPDATE:
|
|
||||||
on_conn_params_update(p_ble_evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// No implementation needed.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_conn_params_change_conn_params(ble_gap_conn_params_t * new_params)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
m_preferred_conn_params = *new_params;
|
|
||||||
// Set the connection params in stack
|
|
||||||
err_code = sd_ble_gap_ppcp_set(&m_preferred_conn_params);
|
|
||||||
if (err_code == NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
if (!is_conn_params_ok(&m_current_conn_params))
|
|
||||||
{
|
|
||||||
m_change_param = true;
|
|
||||||
err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_preferred_conn_params);
|
|
||||||
m_update_count = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Notify the application that the procedure has succeded
|
|
||||||
if (m_conn_params_config.evt_handler != NULL)
|
|
||||||
{
|
|
||||||
ble_conn_params_evt_t evt;
|
|
||||||
|
|
||||||
evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED;
|
|
||||||
m_conn_params_config.evt_handler(&evt);
|
|
||||||
}
|
|
||||||
err_code = NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err_code;
|
|
||||||
}
|
|
|
@ -1,131 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
*
|
|
||||||
* @defgroup ble_sdk_lib_conn_params Connection Parameters Negotiation
|
|
||||||
* @{
|
|
||||||
* @ingroup ble_sdk_lib
|
|
||||||
* @brief Module for initiating and executing a connection parameters negotiation procedure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BLE_CONN_PARAMS_H__
|
|
||||||
#define BLE_CONN_PARAMS_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "nrf_ble.h"
|
|
||||||
#include "ble_srv_common.h"
|
|
||||||
|
|
||||||
/**@brief Connection Parameters Module event type. */
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
BLE_CONN_PARAMS_EVT_FAILED , /**< Negotiation procedure failed. */
|
|
||||||
BLE_CONN_PARAMS_EVT_SUCCEEDED /**< Negotiation procedure succeeded. */
|
|
||||||
} ble_conn_params_evt_type_t;
|
|
||||||
|
|
||||||
/**@brief Connection Parameters Module event. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
ble_conn_params_evt_type_t evt_type; /**< Type of event. */
|
|
||||||
} ble_conn_params_evt_t;
|
|
||||||
|
|
||||||
/**@brief Connection Parameters Module event handler type. */
|
|
||||||
typedef void (*ble_conn_params_evt_handler_t) (ble_conn_params_evt_t * p_evt);
|
|
||||||
|
|
||||||
/**@brief Connection Parameters Module init structure. This contains all options and data needed for
|
|
||||||
* initialization of the connection parameters negotiation module. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
ble_gap_conn_params_t * p_conn_params; /**< Pointer to the connection parameters desired by the application. When calling ble_conn_params_init, if this parameter is set to NULL, the connection parameters will be fetched from host. */
|
|
||||||
uint32_t first_conn_params_update_delay; /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (in number of timer ticks). */
|
|
||||||
uint32_t next_conn_params_update_delay; /**< Time between each call to sd_ble_gap_conn_param_update after the first (in number of timer ticks). Recommended value 30 seconds as per BLUETOOTH SPECIFICATION Version 4.0. */
|
|
||||||
uint8_t max_conn_params_update_count; /**< Number of attempts before giving up the negotiation. */
|
|
||||||
uint16_t start_on_notify_cccd_handle; /**< If procedure is to be started when notification is started, set this to the handle of the corresponding CCCD. Set to BLE_GATT_HANDLE_INVALID if procedure is to be started on connect event. */
|
|
||||||
bool disconnect_on_fail; /**< Set to TRUE if a failed connection parameters update shall cause an automatic disconnection, set to FALSE otherwise. */
|
|
||||||
ble_conn_params_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Connection Parameters. */
|
|
||||||
ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
|
|
||||||
} ble_conn_params_init_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for initializing the Connection Parameters module.
|
|
||||||
*
|
|
||||||
* @note If the negotiation procedure should be triggered when notification/indication of
|
|
||||||
* any characteristic is enabled by the peer, then this function must be called after
|
|
||||||
* having initialized the services.
|
|
||||||
*
|
|
||||||
* @param[in] p_init This contains information needed to initialize this module.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on successful initialization, otherwise an error code.
|
|
||||||
*/
|
|
||||||
uint32_t ble_conn_params_init(const ble_conn_params_init_t * p_init);
|
|
||||||
|
|
||||||
/**@brief Function for stopping the Connection Parameters module.
|
|
||||||
*
|
|
||||||
* @details This function is intended to be used by the application to clean up the connection
|
|
||||||
* parameters update module. This will stop the connection parameters update timer if
|
|
||||||
* running, thereby preventing any impending connection parameters update procedure. This
|
|
||||||
* function must be called by the application when it needs to clean itself up (for
|
|
||||||
* example, before disabling the bluetooth SoftDevice) so that an unwanted timer expiry
|
|
||||||
* event can be avoided.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on successful initialization, otherwise an error code.
|
|
||||||
*/
|
|
||||||
uint32_t ble_conn_params_stop(void);
|
|
||||||
|
|
||||||
/**@brief Function for changing the current connection parameters to a new set.
|
|
||||||
*
|
|
||||||
* @details Use this function to change the connection parameters to a new set of parameter
|
|
||||||
* (ie different from the ones given at init of the module).
|
|
||||||
* This function is usefull for scenario where most of the time the application
|
|
||||||
* needs a relatively big connection interval, and just sometimes, for a temporary
|
|
||||||
* period requires shorter connection interval, for example to transfer a higher
|
|
||||||
* amount of data.
|
|
||||||
* If the given parameters does not match the current connection's parameters
|
|
||||||
* this function initiates a new negotiation.
|
|
||||||
*
|
|
||||||
* @param[in] new_params This contains the new connections parameters to setup.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on successful initialization, otherwise an error code.
|
|
||||||
*/
|
|
||||||
uint32_t ble_conn_params_change_conn_params(ble_gap_conn_params_t *new_params);
|
|
||||||
|
|
||||||
/**@brief Function for handling the Application's BLE Stack events.
|
|
||||||
*
|
|
||||||
* @details Handles all events from the BLE stack that are of interest to this module.
|
|
||||||
*
|
|
||||||
* @param[in] p_ble_evt The event received from the BLE stack.
|
|
||||||
*/
|
|
||||||
void ble_conn_params_on_ble_evt(ble_evt_t * p_ble_evt);
|
|
||||||
|
|
||||||
#endif // BLE_CONN_PARAMS_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,408 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ble_conn_state.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "nrf_ble.h"
|
|
||||||
#include "sdk_mapped_flags.h"
|
|
||||||
#include "app_error.h"
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__ICCARM__)
|
|
||||||
#pragma language=extended
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
/* anonymous unions are enabled by default */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define BLE_CONN_STATE_N_DEFAULT_FLAGS 5 /**< The number of flags kept for each connection, excluding user flags. */
|
|
||||||
#define BLE_CONN_STATE_N_FLAGS (BLE_CONN_STATE_N_DEFAULT_FLAGS + BLE_CONN_STATE_N_USER_FLAGS) /**< The number of flags kept for each connection, including user flags. */
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Structure containing all the flag collections maintained by the Connection State module.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
sdk_mapped_flags_t valid_flags; /**< Flags indicating which connection handles are valid. */
|
|
||||||
sdk_mapped_flags_t connected_flags; /**< Flags indicating which connections are connected, since disconnected connection handles will not immediately be invalidated. */
|
|
||||||
sdk_mapped_flags_t central_flags; /**< Flags indicating in which connections the local device is the central. */
|
|
||||||
sdk_mapped_flags_t encrypted_flags; /**< Flags indicating which connections are encrypted. */
|
|
||||||
sdk_mapped_flags_t mitm_protected_flags; /**< Flags indicating which connections have encryption with protection from man-in-the-middle attacks. */
|
|
||||||
sdk_mapped_flags_t user_flags[BLE_CONN_STATE_N_USER_FLAGS]; /**< Flags that can be reserved by the user. The flags will be cleared when a connection is invalidated, otherwise, the user is wholly responsible for the flag states. */
|
|
||||||
} ble_conn_state_flag_collections_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Structure containing the internal state of the Connection State module.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t acquired_flags; /**< Bitmap for keeping track of which user flags have been acquired. */
|
|
||||||
uint16_t valid_conn_handles[SDK_MAPPED_FLAGS_N_KEYS]; /**< List of connection handles used as keys for the sdk_mapped_flags module. */
|
|
||||||
union
|
|
||||||
{
|
|
||||||
ble_conn_state_flag_collections_t flags; /**< Flag collections kept by the Connection State module. */
|
|
||||||
sdk_mapped_flags_t flag_array[BLE_CONN_STATE_N_FLAGS]; /**< Flag collections as array to allow use of @ref sdk_mapped_flags_bulk_update_by_key() when setting all flags. */
|
|
||||||
};
|
|
||||||
} ble_conn_state_t;
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__ICCARM__)
|
|
||||||
/* leave anonymous unions enabled */
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
/* anonymous unions are enabled by default */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static ble_conn_state_t m_bcs = {0}; /**< Instantiation of the internal state. */
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for resetting all internal memory to the values it had at initialization.
|
|
||||||
*/
|
|
||||||
void bcs_internal_state_reset(void)
|
|
||||||
{
|
|
||||||
memset( &m_bcs, 0, sizeof(ble_conn_state_t) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for activating a connection record.
|
|
||||||
*
|
|
||||||
* @param p_record The record to activate.
|
|
||||||
* @param conn_handle The connection handle to copy into the record.
|
|
||||||
* @param role The role of the connection.
|
|
||||||
*
|
|
||||||
* @return whether the record was activated successfully.
|
|
||||||
*/
|
|
||||||
static bool record_activate(uint16_t conn_handle)
|
|
||||||
{
|
|
||||||
uint16_t available_index = sdk_mapped_flags_first_key_index_get(~m_bcs.flags.valid_flags);
|
|
||||||
|
|
||||||
if (available_index != SDK_MAPPED_FLAGS_INVALID_INDEX)
|
|
||||||
{
|
|
||||||
m_bcs.valid_conn_handles[available_index] = conn_handle;
|
|
||||||
sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles,
|
|
||||||
&m_bcs.flags.connected_flags,
|
|
||||||
conn_handle,
|
|
||||||
1);
|
|
||||||
sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles,
|
|
||||||
&m_bcs.flags.valid_flags,
|
|
||||||
conn_handle,
|
|
||||||
1);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for marking a connection record as invalid and resetting the values.
|
|
||||||
*
|
|
||||||
* @param p_record The record to invalidate.
|
|
||||||
*/
|
|
||||||
static void record_invalidate(uint16_t conn_handle)
|
|
||||||
{
|
|
||||||
sdk_mapped_flags_bulk_update_by_key(m_bcs.valid_conn_handles,
|
|
||||||
m_bcs.flag_array,
|
|
||||||
BLE_CONN_STATE_N_FLAGS,
|
|
||||||
conn_handle,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for marking a connection as disconnected. See @ref BLE_CONN_STATUS_DISCONNECTED.
|
|
||||||
*
|
|
||||||
* @param p_record The record of the connection to set as disconnected.
|
|
||||||
*/
|
|
||||||
static void record_set_disconnected(uint16_t conn_handle)
|
|
||||||
{
|
|
||||||
sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles,
|
|
||||||
&m_bcs.flags.connected_flags,
|
|
||||||
conn_handle,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for invalidating records with a @ref BLE_CONN_STATUS_DISCONNECTED
|
|
||||||
* connection status
|
|
||||||
*/
|
|
||||||
static void record_purge_disconnected()
|
|
||||||
{
|
|
||||||
sdk_mapped_flags_key_list_t disconnected_list;
|
|
||||||
|
|
||||||
disconnected_list = sdk_mapped_flags_key_list_get(
|
|
||||||
m_bcs.valid_conn_handles,
|
|
||||||
(~m_bcs.flags.connected_flags) & (m_bcs.flags.valid_flags));
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < disconnected_list.len; i++)
|
|
||||||
{
|
|
||||||
record_invalidate(disconnected_list.flag_keys[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for checking if a user flag has been acquired.
|
|
||||||
*
|
|
||||||
* @param[in] flag_id Which flag to check.
|
|
||||||
*
|
|
||||||
* @return Whether the flag has been acquired.
|
|
||||||
*/
|
|
||||||
static bool user_flag_is_acquired(ble_conn_state_user_flag_id_t flag_id)
|
|
||||||
{
|
|
||||||
return ((m_bcs.acquired_flags & (1 << flag_id)) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for marking a user flag as acquired.
|
|
||||||
*
|
|
||||||
* @param[in] flag_id Which flag to mark.
|
|
||||||
*/
|
|
||||||
static void user_flag_acquire(ble_conn_state_user_flag_id_t flag_id)
|
|
||||||
{
|
|
||||||
m_bcs.acquired_flags |= (1 << flag_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ble_conn_state_init(void)
|
|
||||||
{
|
|
||||||
bcs_internal_state_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ble_conn_state_on_ble_evt(ble_evt_t * p_ble_evt)
|
|
||||||
{
|
|
||||||
switch (p_ble_evt->header.evt_id)
|
|
||||||
{
|
|
||||||
case BLE_GAP_EVT_CONNECTED:
|
|
||||||
record_purge_disconnected();
|
|
||||||
|
|
||||||
if ( !record_activate(p_ble_evt->evt.gap_evt.conn_handle) )
|
|
||||||
{
|
|
||||||
// No more records available. Should not happen.
|
|
||||||
APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if defined(TARGET_MCU_NRF51_16K_S110) || defined(TARGET_MCU_NRF51_32K_S110)
|
|
||||||
bool is_central = false;
|
|
||||||
#elif defined(TARGET_MCU_NRF51_16K_S120) || defined(TARGET_MCU_NRF51_32K_S120)
|
|
||||||
bool is_central = true;
|
|
||||||
#else
|
|
||||||
bool is_central =
|
|
||||||
(p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_CENTRAL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles,
|
|
||||||
&m_bcs.flags.central_flags,
|
|
||||||
p_ble_evt->evt.gap_evt.conn_handle,
|
|
||||||
is_central);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_GAP_EVT_DISCONNECTED:
|
|
||||||
record_set_disconnected(p_ble_evt->evt.gap_evt.conn_handle);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_GAP_EVT_CONN_SEC_UPDATE:
|
|
||||||
sdk_mapped_flags_update_by_key(
|
|
||||||
m_bcs.valid_conn_handles,
|
|
||||||
&m_bcs.flags.encrypted_flags,
|
|
||||||
p_ble_evt->evt.gap_evt.conn_handle,
|
|
||||||
(p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv > 1));
|
|
||||||
sdk_mapped_flags_update_by_key(
|
|
||||||
m_bcs.valid_conn_handles,
|
|
||||||
&m_bcs.flags.mitm_protected_flags,
|
|
||||||
p_ble_evt->evt.gap_evt.conn_handle,
|
|
||||||
(p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv > 2));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool ble_conn_state_valid(uint16_t conn_handle)
|
|
||||||
{
|
|
||||||
return sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles,
|
|
||||||
m_bcs.flags.valid_flags,
|
|
||||||
conn_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t ble_conn_state_role(uint16_t conn_handle)
|
|
||||||
{
|
|
||||||
uint8_t role = BLE_GAP_ROLE_INVALID;
|
|
||||||
|
|
||||||
if ( sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles, m_bcs.flags.valid_flags, conn_handle) )
|
|
||||||
{
|
|
||||||
bool central = sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles,
|
|
||||||
m_bcs.flags.central_flags,
|
|
||||||
conn_handle);
|
|
||||||
|
|
||||||
role = central ? BLE_GAP_ROLE_CENTRAL : BLE_GAP_ROLE_PERIPH;
|
|
||||||
}
|
|
||||||
|
|
||||||
return role;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ble_conn_state_status_t ble_conn_state_status(uint16_t conn_handle)
|
|
||||||
{
|
|
||||||
ble_conn_state_status_t conn_status = BLE_CONN_STATUS_INVALID;
|
|
||||||
bool valid = sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles,
|
|
||||||
m_bcs.flags.valid_flags,
|
|
||||||
conn_handle);
|
|
||||||
|
|
||||||
if (valid)
|
|
||||||
{
|
|
||||||
bool connected = sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles,
|
|
||||||
m_bcs.flags.connected_flags,
|
|
||||||
conn_handle);
|
|
||||||
|
|
||||||
conn_status = connected ? BLE_CONN_STATUS_CONNECTED : BLE_CONN_STATUS_DISCONNECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return conn_status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool ble_conn_state_encrypted(uint16_t conn_handle)
|
|
||||||
{
|
|
||||||
return sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles,
|
|
||||||
m_bcs.flags.encrypted_flags,
|
|
||||||
conn_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool ble_conn_state_mitm_protected(uint16_t conn_handle)
|
|
||||||
{
|
|
||||||
return sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles,
|
|
||||||
m_bcs.flags.mitm_protected_flags,
|
|
||||||
conn_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_conn_state_n_connections(void)
|
|
||||||
{
|
|
||||||
return sdk_mapped_flags_n_flags_set(m_bcs.flags.connected_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_conn_state_n_centrals(void)
|
|
||||||
{
|
|
||||||
return sdk_mapped_flags_n_flags_set((m_bcs.flags.central_flags) & (m_bcs.flags.connected_flags));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_conn_state_n_peripherals(void)
|
|
||||||
{
|
|
||||||
return sdk_mapped_flags_n_flags_set((~m_bcs.flags.central_flags) & (m_bcs.flags.connected_flags));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sdk_mapped_flags_key_list_t ble_conn_state_conn_handles(void)
|
|
||||||
{
|
|
||||||
return sdk_mapped_flags_key_list_get(m_bcs.valid_conn_handles, m_bcs.flags.valid_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sdk_mapped_flags_key_list_t ble_conn_state_central_handles(void)
|
|
||||||
{
|
|
||||||
return sdk_mapped_flags_key_list_get(m_bcs.valid_conn_handles,
|
|
||||||
(m_bcs.flags.central_flags) & (m_bcs.flags.connected_flags));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sdk_mapped_flags_key_list_t ble_conn_state_periph_handles(void)
|
|
||||||
{
|
|
||||||
return sdk_mapped_flags_key_list_get(m_bcs.valid_conn_handles,
|
|
||||||
(~m_bcs.flags.central_flags) & (m_bcs.flags.connected_flags));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ble_conn_state_user_flag_id_t ble_conn_state_user_flag_acquire(void)
|
|
||||||
{
|
|
||||||
for (ble_conn_state_user_flag_id_t i = BLE_CONN_STATE_USER_FLAG0;
|
|
||||||
i < BLE_CONN_STATE_N_USER_FLAGS;
|
|
||||||
i++)
|
|
||||||
{
|
|
||||||
if ( !user_flag_is_acquired(i) )
|
|
||||||
{
|
|
||||||
user_flag_acquire(i);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return BLE_CONN_STATE_USER_FLAG_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool ble_conn_state_user_flag_get(uint16_t conn_handle, ble_conn_state_user_flag_id_t flag_id)
|
|
||||||
{
|
|
||||||
if (user_flag_is_acquired(flag_id))
|
|
||||||
{
|
|
||||||
return sdk_mapped_flags_get_by_key(m_bcs.valid_conn_handles,
|
|
||||||
m_bcs.flags.user_flags[flag_id],
|
|
||||||
conn_handle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ble_conn_state_user_flag_set(uint16_t conn_handle,
|
|
||||||
ble_conn_state_user_flag_id_t flag_id,
|
|
||||||
bool value)
|
|
||||||
{
|
|
||||||
if (user_flag_is_acquired(flag_id))
|
|
||||||
{
|
|
||||||
sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles,
|
|
||||||
&m_bcs.flags.user_flags[flag_id],
|
|
||||||
conn_handle,
|
|
||||||
value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sdk_mapped_flags_t ble_conn_state_user_flag_collection(ble_conn_state_user_flag_id_t flag_id)
|
|
||||||
{
|
|
||||||
if ( user_flag_is_acquired(flag_id) )
|
|
||||||
{
|
|
||||||
return m_bcs.flags.user_flags[flag_id];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,287 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* @defgroup ble_conn_state Connection state
|
|
||||||
* @ingroup ble_sdk_lib
|
|
||||||
* @{
|
|
||||||
* @brief Module for storing data on BLE connections.
|
|
||||||
*
|
|
||||||
* @details This module stores certain states for each connection, which can be queried by
|
|
||||||
* connection handle. The module uses BLE events to keep the states updated.
|
|
||||||
*
|
|
||||||
* In addition to the preprogrammed states, this module can also keep track of a number of
|
|
||||||
* binary user states, or <i>user flags</i>. These are reset to 0 for new connections, but
|
|
||||||
* otherwise not touched by this module.
|
|
||||||
*
|
|
||||||
* This module uses the @ref sdk_mapped_flags module, with connection handles as keys and
|
|
||||||
* the connection states as flags.
|
|
||||||
*
|
|
||||||
* @note A connection handle is not immediately invalidated when it is disconnected. Certain states,
|
|
||||||
* such as the role, can still be queried until the next time a new connection is established
|
|
||||||
* to any device.
|
|
||||||
*
|
|
||||||
* To function properly, this module must be provided with BLE events from the SoftDevice
|
|
||||||
* through the @ref ble_conn_state_on_ble_evt() function. This module should be the first
|
|
||||||
* to receive BLE events if they are dispatched to multiple modules.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BLE_CONN_STATE_H__
|
|
||||||
#define BLE_CONN_STATE_H__
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "nrf_ble.h"
|
|
||||||
#include "sdk_mapped_flags.h"
|
|
||||||
|
|
||||||
/**@brief Connection handle statuses.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
BLE_CONN_STATUS_INVALID, /**< The connection handle is invalid. */
|
|
||||||
BLE_CONN_STATUS_DISCONNECTED, /**< The connection handle refers to a connection that has been disconnected, but not yet invalidated. */
|
|
||||||
BLE_CONN_STATUS_CONNECTED, /**< The connection handle refers to an active connection. */
|
|
||||||
} ble_conn_state_status_t;
|
|
||||||
|
|
||||||
#define BLE_CONN_STATE_N_USER_FLAGS 16 /**< The number of available user flags. */
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief One ID for each user flag collection.
|
|
||||||
*
|
|
||||||
* @details These IDs are used to identify user flag collections in the API calls.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
BLE_CONN_STATE_USER_FLAG0 = 0,
|
|
||||||
BLE_CONN_STATE_USER_FLAG1,
|
|
||||||
BLE_CONN_STATE_USER_FLAG2,
|
|
||||||
BLE_CONN_STATE_USER_FLAG3,
|
|
||||||
BLE_CONN_STATE_USER_FLAG4,
|
|
||||||
BLE_CONN_STATE_USER_FLAG5,
|
|
||||||
BLE_CONN_STATE_USER_FLAG6,
|
|
||||||
BLE_CONN_STATE_USER_FLAG7,
|
|
||||||
BLE_CONN_STATE_USER_FLAG8,
|
|
||||||
BLE_CONN_STATE_USER_FLAG9,
|
|
||||||
BLE_CONN_STATE_USER_FLAG10,
|
|
||||||
BLE_CONN_STATE_USER_FLAG11,
|
|
||||||
BLE_CONN_STATE_USER_FLAG12,
|
|
||||||
BLE_CONN_STATE_USER_FLAG13,
|
|
||||||
BLE_CONN_STATE_USER_FLAG14,
|
|
||||||
BLE_CONN_STATE_USER_FLAG15,
|
|
||||||
BLE_CONN_STATE_USER_FLAG_INVALID,
|
|
||||||
} ble_conn_state_user_flag_id_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup ble_conn_state_functions BLE connection state functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for initializing or resetting the module.
|
|
||||||
*
|
|
||||||
* @details This function sets all states to their default, removing all records of connection handles.
|
|
||||||
*/
|
|
||||||
void ble_conn_state_init(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for providing BLE SoftDevice events to the connection state module.
|
|
||||||
*
|
|
||||||
* @param[in] p_ble_evt The SoftDevice event.
|
|
||||||
*/
|
|
||||||
void ble_conn_state_on_ble_evt(ble_evt_t * p_ble_evt);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for querying whether a connection handle represents a valid connection.
|
|
||||||
*
|
|
||||||
* @details A connection might be valid and have a BLE_CONN_STATUS_DISCONNECTED status.
|
|
||||||
* Those connections are invalidated after a new connection occurs.
|
|
||||||
*
|
|
||||||
* @param[in] conn_handle Handle of the connection.
|
|
||||||
*
|
|
||||||
* @retval true If conn_handle represents a valid connection, thus a connection for which
|
|
||||||
we have a record.
|
|
||||||
* @retval false If conn_handle is @ref BLE_GAP_ROLE_INVALID, or if it has never been recorded.
|
|
||||||
*/
|
|
||||||
bool ble_conn_state_valid(uint16_t conn_handle);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for querying the role of the local device in a connection.
|
|
||||||
*
|
|
||||||
* @param[in] conn_handle Handle of the connection to get the role for.
|
|
||||||
*
|
|
||||||
* @return The role of the local device in the connection (see @ref BLE_GAP_ROLES).
|
|
||||||
* If conn_handle is not valid, the function returns BLE_GAP_ROLE_INVALID.
|
|
||||||
*/
|
|
||||||
uint8_t ble_conn_state_role(uint16_t conn_handle);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for querying the status of a connection.
|
|
||||||
*
|
|
||||||
* @param[in] conn_handle Handle of the connection.
|
|
||||||
*
|
|
||||||
* @return The status of the connection.
|
|
||||||
* If conn_handle is not valid, the function returns BLE_CONN_STATE_INVALID.
|
|
||||||
*/
|
|
||||||
ble_conn_state_status_t ble_conn_state_status(uint16_t conn_handle);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for querying whether a connection is encrypted.
|
|
||||||
*
|
|
||||||
* @param[in] conn_handle Handle of connection to get the encryption state for.
|
|
||||||
*
|
|
||||||
* @retval true If the connection is encrypted.
|
|
||||||
* @retval false If the connection is not encrypted or conn_handle is invalid.
|
|
||||||
*/
|
|
||||||
bool ble_conn_state_encrypted(uint16_t conn_handle);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for querying whether a connection encryption is protected from Man in the Middle
|
|
||||||
* attacks.
|
|
||||||
*
|
|
||||||
* @param[in] conn_handle Handle of connection to get the MITM state for.
|
|
||||||
*
|
|
||||||
* @retval true If the connection is encrypted with MITM protection.
|
|
||||||
* @retval false If the connection is not encrypted, or encryption is not MITM protected, or
|
|
||||||
* conn_handle is invalid.
|
|
||||||
*/
|
|
||||||
bool ble_conn_state_mitm_protected(uint16_t conn_handle);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for querying the total number of connections.
|
|
||||||
*
|
|
||||||
* @return The total number of valid connections for which the module has a record.
|
|
||||||
*/
|
|
||||||
uint32_t ble_conn_state_n_connections(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for querying the total number of connections in which the role of the local
|
|
||||||
* device is @ref BLE_GAP_ROLE_CENTRAL.
|
|
||||||
*
|
|
||||||
* @return The number of connections in which the role of the local device is
|
|
||||||
* @ref BLE_GAP_ROLE_CENTRAL.
|
|
||||||
*/
|
|
||||||
uint32_t ble_conn_state_n_centrals(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for querying the total number of connections in which the role of the local
|
|
||||||
* device is @ref BLE_GAP_ROLE_PERIPH.
|
|
||||||
*
|
|
||||||
* @return The number of connections in which the role of the local device is
|
|
||||||
* @ref BLE_GAP_ROLE_PERIPH.
|
|
||||||
*/
|
|
||||||
uint32_t ble_conn_state_n_peripherals(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for obtaining a list of all connection handles for which the module has a record.
|
|
||||||
*
|
|
||||||
* @details This function takes into account connections whose state is BLE_CONN_STATUS_DISCONNECTED.
|
|
||||||
*
|
|
||||||
* @return A list of all valid connection handles for which the module has a record.
|
|
||||||
*/
|
|
||||||
sdk_mapped_flags_key_list_t ble_conn_state_conn_handles(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for obtaining a list of connection handles in which the role of the local
|
|
||||||
* device is @ref BLE_GAP_ROLE_CENTRAL.
|
|
||||||
*
|
|
||||||
* @details This function takes into account connections whose state is BLE_CONN_STATUS_DISCONNECTED.
|
|
||||||
*
|
|
||||||
* @return A list of all valid connection handles for which the module has a record and in which
|
|
||||||
* the role of local device is @ref BLE_GAP_ROLE_CENTRAL.
|
|
||||||
*/
|
|
||||||
sdk_mapped_flags_key_list_t ble_conn_state_central_handles(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for obtaining the handle for the connection in which the role of the local device
|
|
||||||
* is @ref BLE_GAP_ROLE_PERIPH.
|
|
||||||
*
|
|
||||||
* @details This function takes into account connections whose state is BLE_CONN_STATUS_DISCONNECTED.
|
|
||||||
*
|
|
||||||
* @return A list of all valid connection handles for which the module has a record and in which
|
|
||||||
* the role of local device is @ref BLE_GAP_ROLE_PERIPH.
|
|
||||||
*/
|
|
||||||
sdk_mapped_flags_key_list_t ble_conn_state_periph_handles(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for obtaining exclusive access to one of the user flag collections.
|
|
||||||
*
|
|
||||||
* @details The acquired collection contains one flag for each connection. These flags can be set
|
|
||||||
* and read individually for each connection.
|
|
||||||
*
|
|
||||||
* The state of user flags will not be modified by the connection state module, except to
|
|
||||||
* set it to 0 for a connection when that connection is invalidated.
|
|
||||||
*
|
|
||||||
* @return The ID of the acquired flag, or BLE_CONN_STATE_USER_FLAG_INVALID if none are available.
|
|
||||||
*/
|
|
||||||
ble_conn_state_user_flag_id_t ble_conn_state_user_flag_acquire(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for reading the value of a user flag.
|
|
||||||
*
|
|
||||||
* @param[in] conn_handle Handle of connection to get the flag state for.
|
|
||||||
* @param[in] flag_id Which flag to get the state for.
|
|
||||||
*
|
|
||||||
* @return The state of the flag. If conn_handle is invalid, the function returns false.
|
|
||||||
*/
|
|
||||||
bool ble_conn_state_user_flag_get(uint16_t conn_handle, ble_conn_state_user_flag_id_t flag_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for setting the value of a user flag.
|
|
||||||
*
|
|
||||||
* @param[in] conn_handle Handle of connection to set the flag state for.
|
|
||||||
* @param[in] flag_id Which flag to set the state for.
|
|
||||||
* @param[in] value Value to set the flag state to.
|
|
||||||
*/
|
|
||||||
void ble_conn_state_user_flag_set(uint16_t conn_handle,
|
|
||||||
ble_conn_state_user_flag_id_t flag_id,
|
|
||||||
bool value);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for getting the state of a user flag for all connection handles.
|
|
||||||
*
|
|
||||||
* @details The returned collection can be used with the @ref sdk_mapped_flags API. The returned
|
|
||||||
* collection is a copy, so modifying it has no effect on the conn_state module.
|
|
||||||
*
|
|
||||||
* @param[in] flag_id Which flag to get states for.
|
|
||||||
*
|
|
||||||
* @return The collection of flag states. The collection is always all zeros when the flag_id is
|
|
||||||
* unregistered.
|
|
||||||
*/
|
|
||||||
sdk_mapped_flags_t ble_conn_state_user_flag_collection(ble_conn_state_user_flag_id_t flag_id);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif /* BLE_CONN_STATE_H__ */
|
|
|
@ -1,97 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Attention!
|
|
||||||
* To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
|
|
||||||
* qualification listings, this section of source code must not be modified.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
* @brief Contains definition of ble_date_time structure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
*
|
|
||||||
* @defgroup ble_sdk_srv_date_time BLE Date Time characteristic type
|
|
||||||
* @{
|
|
||||||
* @ingroup ble_sdk_lib
|
|
||||||
* @brief Definition of ble_date_time_t type.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BLE_DATE_TIME_H__
|
|
||||||
#define BLE_DATE_TIME_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/**@brief Date and Time structure. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t year;
|
|
||||||
uint8_t month;
|
|
||||||
uint8_t day;
|
|
||||||
uint8_t hours;
|
|
||||||
uint8_t minutes;
|
|
||||||
uint8_t seconds;
|
|
||||||
} ble_date_time_t;
|
|
||||||
|
|
||||||
static __INLINE uint8_t ble_date_time_encode(const ble_date_time_t * p_date_time,
|
|
||||||
uint8_t * p_encoded_data)
|
|
||||||
{
|
|
||||||
uint8_t len = uint16_encode(p_date_time->year, p_encoded_data);
|
|
||||||
|
|
||||||
p_encoded_data[len++] = p_date_time->month;
|
|
||||||
p_encoded_data[len++] = p_date_time->day;
|
|
||||||
p_encoded_data[len++] = p_date_time->hours;
|
|
||||||
p_encoded_data[len++] = p_date_time->minutes;
|
|
||||||
p_encoded_data[len++] = p_date_time->seconds;
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __INLINE uint8_t ble_date_time_decode(ble_date_time_t * p_date_time,
|
|
||||||
const uint8_t * p_encoded_data)
|
|
||||||
{
|
|
||||||
uint8_t len = sizeof(uint16_t);
|
|
||||||
|
|
||||||
p_date_time->year = uint16_decode(p_encoded_data);
|
|
||||||
p_date_time->month = p_encoded_data[len++];
|
|
||||||
p_date_time->day = p_encoded_data[len++];
|
|
||||||
p_date_time->hours = p_encoded_data[len++];
|
|
||||||
p_date_time->minutes = p_encoded_data[len++];
|
|
||||||
p_date_time->seconds = p_encoded_data[len++];
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // BLE_DATE_TIME_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef BLE_GATT_DB_H__
|
|
||||||
#define BLE_GATT_DB_H__
|
|
||||||
|
|
||||||
#include "stdint.h"
|
|
||||||
#include "nrf_ble.h"
|
|
||||||
#include "ble_gattc.h"
|
|
||||||
|
|
||||||
#define BLE_GATT_DB_MAX_CHARS 4 /**< The maximum number of characteristics present in a service record. */
|
|
||||||
|
|
||||||
/**@brief Structure for holding the characteristic and the handle of its CCCD present on a server.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
ble_gattc_char_t characteristic; /**< Structure containing information about the characteristic. */
|
|
||||||
uint16_t cccd_handle; /**< CCCD Handle value for this characteristic. This will be set to BLE_GATT_HANDLE_INVALID if a CCCD is not present at the server. */
|
|
||||||
} ble_gatt_db_char_t;
|
|
||||||
|
|
||||||
/**@brief Structure for holding information about the service and the characteristics present on a
|
|
||||||
* server.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
ble_uuid_t srv_uuid; /**< UUID of the service. */
|
|
||||||
uint8_t char_count; /**< Number of characteristics present in the service. */
|
|
||||||
ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */
|
|
||||||
ble_gatt_db_char_t charateristics[BLE_GATT_DB_MAX_CHARS]; /**< Array of information related to the characteristics present in the service. This list can extend further than one. */
|
|
||||||
} ble_gatt_db_srv_t;
|
|
||||||
|
|
||||||
#endif /* BLE_GATT_DB_H__ */
|
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Attention!
|
|
||||||
* To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
|
|
||||||
* qualification listings, this section of source code must not be modified.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BLE_SENSOR_LOCATION_H__
|
|
||||||
#define BLE_SENSOR_LOCATION_H__
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BLE_SENSOR_LOCATION_OTHER = 0 , /**<-- Other */
|
|
||||||
BLE_SENSOR_LOCATION_TOP_OF_SHOE = 1 , /**<-- Top of shoe */
|
|
||||||
BLE_SENSOR_LOCATION_IN_SHOE = 2 , /**<-- In shoe */
|
|
||||||
BLE_SENSOR_LOCATION_HIP = 3 , /**<-- Hip */
|
|
||||||
BLE_SENSOR_LOCATION_FRONT_WHEEL = 4 , /**<-- Front Wheel */
|
|
||||||
BLE_SENSOR_LOCATION_LEFT_CRANK = 5 , /**<-- Left Crank */
|
|
||||||
BLE_SENSOR_LOCATION_RIGHT_CRANK = 6 , /**<-- Right Crank */
|
|
||||||
BLE_SENSOR_LOCATION_LEFT_PEDAL = 7 , /**<-- Left Pedal */
|
|
||||||
BLE_SENSOR_LOCATION_RIGHT_PEDAL = 8 , /**<-- Right Pedal */
|
|
||||||
BLE_SENSOR_LOCATION_FRONT_HUB = 9 , /**<-- Front Hub */
|
|
||||||
BLE_SENSOR_LOCATION_REAR_DROPOUT = 10, /**<-- Rear Dropout */
|
|
||||||
BLE_SENSOR_LOCATION_CHAINSTAY = 11, /**<-- Chainstay */
|
|
||||||
BLE_SENSOR_LOCATION_REAR_WHEEL = 12, /**<-- Rear Wheel */
|
|
||||||
BLE_SENSOR_LOCATION_REAR_HUB = 13, /**<-- Rear Hub */
|
|
||||||
}ble_sensor_location_t;
|
|
||||||
|
|
||||||
#define BLE_NB_MAX_SENSOR_LOCATIONS 14
|
|
||||||
|
|
||||||
#endif // BLE_SENSOR_LOCATION_H__
|
|
|
@ -1,217 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Attention!
|
|
||||||
* To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
|
|
||||||
* qualification listings, this section of source code must not be modified.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ble_srv_common.h"
|
|
||||||
#include <string.h>
|
|
||||||
#include "nordic_common.h"
|
|
||||||
#include "app_error.h"
|
|
||||||
#include "nrf_ble.h"
|
|
||||||
|
|
||||||
uint8_t ble_srv_report_ref_encode(uint8_t * p_encoded_buffer,
|
|
||||||
const ble_srv_report_ref_t * p_report_ref)
|
|
||||||
{
|
|
||||||
uint8_t len = 0;
|
|
||||||
|
|
||||||
p_encoded_buffer[len++] = p_report_ref->report_id;
|
|
||||||
p_encoded_buffer[len++] = p_report_ref->report_type;
|
|
||||||
|
|
||||||
APP_ERROR_CHECK_BOOL(len == BLE_SRV_ENCODED_REPORT_REF_LEN);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ble_srv_ascii_to_utf8(ble_srv_utf8_str_t * p_utf8, char * p_ascii)
|
|
||||||
{
|
|
||||||
p_utf8->length = (uint16_t)strlen(p_ascii);
|
|
||||||
p_utf8->p_str = (uint8_t *)p_ascii;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for setting security requirements of a characteristic.
|
|
||||||
*
|
|
||||||
* @param[in] level required security level.
|
|
||||||
* @param[out] p_perm Characteristic security requirements.
|
|
||||||
*
|
|
||||||
* @return encoded security level and security mode.
|
|
||||||
*/
|
|
||||||
static inline void set_security_req(security_req_t level, ble_gap_conn_sec_mode_t * p_perm)
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(p_perm);
|
|
||||||
switch (level)
|
|
||||||
{
|
|
||||||
case SEC_NO_ACCESS:
|
|
||||||
BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(p_perm);
|
|
||||||
break;
|
|
||||||
case SEC_OPEN:
|
|
||||||
BLE_GAP_CONN_SEC_MODE_SET_OPEN(p_perm);
|
|
||||||
break;
|
|
||||||
case SEC_JUST_WORKS:
|
|
||||||
BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(p_perm);
|
|
||||||
break;
|
|
||||||
case SEC_MITM:
|
|
||||||
BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(p_perm);
|
|
||||||
break;
|
|
||||||
case SEC_SIGNED:
|
|
||||||
BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(p_perm);
|
|
||||||
break;
|
|
||||||
case SEC_SIGNED_MITM:
|
|
||||||
BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(p_perm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t characteristic_add(uint16_t service_handle,
|
|
||||||
ble_add_char_params_t * p_char_props,
|
|
||||||
ble_gatts_char_handles_t * p_char_handle)
|
|
||||||
{
|
|
||||||
ble_gatts_char_md_t char_md;
|
|
||||||
ble_gatts_attr_t attr_char_value;
|
|
||||||
ble_uuid_t char_uuid;
|
|
||||||
ble_gatts_attr_md_t attr_md;
|
|
||||||
ble_gatts_attr_md_t user_descr_attr_md;
|
|
||||||
ble_gatts_attr_md_t cccd_md;
|
|
||||||
|
|
||||||
if (p_char_props->uuid_type == 0)
|
|
||||||
{
|
|
||||||
char_uuid.type = BLE_UUID_TYPE_BLE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char_uuid.type = p_char_props->uuid_type;
|
|
||||||
}
|
|
||||||
char_uuid.uuid = p_char_props->uuid;
|
|
||||||
|
|
||||||
memset(&attr_md, 0, sizeof(ble_gatts_attr_md_t));
|
|
||||||
set_security_req(p_char_props->read_access, &attr_md.read_perm);
|
|
||||||
set_security_req(p_char_props->write_access, & attr_md.write_perm);
|
|
||||||
attr_md.rd_auth = (p_char_props->is_defered_read ? 1 : 0);
|
|
||||||
attr_md.wr_auth = (p_char_props->is_defered_write ? 1 : 0);
|
|
||||||
attr_md.vlen = (p_char_props->is_var_len ? 1 : 0);
|
|
||||||
attr_md.vloc = (p_char_props->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);
|
|
||||||
|
|
||||||
|
|
||||||
memset(&char_md, 0, sizeof(ble_gatts_char_md_t));
|
|
||||||
if ((p_char_props->char_props.notify == 1)||(p_char_props->char_props.indicate == 1))
|
|
||||||
{
|
|
||||||
|
|
||||||
memset(&cccd_md, 0, sizeof(cccd_md));
|
|
||||||
set_security_req(p_char_props->cccd_write_access, &cccd_md.write_perm);
|
|
||||||
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
|
|
||||||
|
|
||||||
cccd_md.vloc = BLE_GATTS_VLOC_STACK;
|
|
||||||
|
|
||||||
char_md.p_cccd_md = &cccd_md;
|
|
||||||
}
|
|
||||||
char_md.char_props = p_char_props->char_props;
|
|
||||||
|
|
||||||
memset(&attr_char_value, 0, sizeof(ble_gatts_attr_t));
|
|
||||||
attr_char_value.p_uuid = &char_uuid;
|
|
||||||
attr_char_value.p_attr_md = &attr_md;
|
|
||||||
attr_char_value.max_len = p_char_props->max_len;
|
|
||||||
if (p_char_props->p_init_value != NULL)
|
|
||||||
{
|
|
||||||
attr_char_value.init_len = p_char_props->init_len;
|
|
||||||
attr_char_value.p_value = p_char_props->p_init_value;
|
|
||||||
}
|
|
||||||
if (p_char_props->p_user_descr != NULL)
|
|
||||||
{
|
|
||||||
memset(&user_descr_attr_md, 0, sizeof(ble_gatts_attr_md_t));
|
|
||||||
char_md.char_user_desc_max_size = p_char_props->p_user_descr->max_size;
|
|
||||||
char_md.char_user_desc_size = p_char_props->p_user_descr->size;
|
|
||||||
char_md.p_char_user_desc = p_char_props->p_user_descr->p_char_user_desc;
|
|
||||||
|
|
||||||
char_md.p_user_desc_md = &user_descr_attr_md;
|
|
||||||
|
|
||||||
set_security_req(p_char_props->p_user_descr->read_access, &user_descr_attr_md.read_perm);
|
|
||||||
set_security_req(p_char_props->p_user_descr->write_access, &user_descr_attr_md.write_perm);
|
|
||||||
|
|
||||||
user_descr_attr_md.rd_auth = (p_char_props->p_user_descr->is_defered_read ? 1 : 0);
|
|
||||||
user_descr_attr_md.wr_auth = (p_char_props->p_user_descr->is_defered_write ? 1 : 0);
|
|
||||||
user_descr_attr_md.vlen = (p_char_props->p_user_descr->is_var_len ? 1 : 0);
|
|
||||||
user_descr_attr_md.vloc = (p_char_props->p_user_descr->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);
|
|
||||||
}
|
|
||||||
if (p_char_props->p_presentation_format != NULL)
|
|
||||||
{
|
|
||||||
char_md.p_char_pf = p_char_props->p_presentation_format;
|
|
||||||
}
|
|
||||||
return sd_ble_gatts_characteristic_add(service_handle,
|
|
||||||
&char_md,
|
|
||||||
&attr_char_value,
|
|
||||||
p_char_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t descriptor_add(uint16_t char_handle,
|
|
||||||
ble_add_descr_params_t * p_descr_props,
|
|
||||||
uint16_t * p_descr_handle)
|
|
||||||
{
|
|
||||||
ble_gatts_attr_t descr_params;
|
|
||||||
ble_uuid_t desc_uuid;
|
|
||||||
ble_gatts_attr_md_t attr_md;
|
|
||||||
|
|
||||||
memset(&descr_params, 0, sizeof(descr_params));
|
|
||||||
if (p_descr_props->uuid_type == 0)
|
|
||||||
{
|
|
||||||
desc_uuid.type = BLE_UUID_TYPE_BLE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
desc_uuid.type = p_descr_props->uuid_type;
|
|
||||||
}
|
|
||||||
desc_uuid.uuid = p_descr_props->uuid;
|
|
||||||
descr_params.p_uuid = &desc_uuid;
|
|
||||||
|
|
||||||
set_security_req(p_descr_props->read_access, &attr_md.read_perm);
|
|
||||||
set_security_req(p_descr_props->write_access,&attr_md.write_perm);
|
|
||||||
|
|
||||||
attr_md.rd_auth = (p_descr_props->is_defered_read ? 1 : 0);
|
|
||||||
attr_md.wr_auth = (p_descr_props->is_defered_write ? 1 : 0);
|
|
||||||
attr_md.vlen = (p_descr_props->is_var_len ? 1 : 0);
|
|
||||||
attr_md.vloc = (p_descr_props->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);
|
|
||||||
descr_params.p_attr_md = &attr_md;
|
|
||||||
|
|
||||||
descr_params.init_len = p_descr_props->init_len;
|
|
||||||
descr_params.init_offs = p_descr_props->init_offs;
|
|
||||||
descr_params.max_len = p_descr_props->max_len;
|
|
||||||
descr_params.p_value = p_descr_props->p_value;
|
|
||||||
|
|
||||||
return sd_ble_gatts_descriptor_add(char_handle, &descr_params, p_descr_handle);
|
|
||||||
}
|
|
|
@ -1,368 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
*
|
|
||||||
* @defgroup ble_sdk_srv_common Common service definitions
|
|
||||||
* @{
|
|
||||||
* @ingroup ble_sdk_srv
|
|
||||||
* @brief Constants, type definitions, and functions that are common to all services.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BLE_SRV_COMMON_H__
|
|
||||||
#define BLE_SRV_COMMON_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "ble_types.h"
|
|
||||||
#include "app_util.h"
|
|
||||||
#include "nrf_ble.h"
|
|
||||||
#include "ble_gap.h"
|
|
||||||
#include "ble_gatt.h"
|
|
||||||
|
|
||||||
/** @defgroup UUID_SERVICES Service UUID definitions
|
|
||||||
* @{ */
|
|
||||||
#define BLE_UUID_ALERT_NOTIFICATION_SERVICE 0x1811 /**< Alert Notification service UUID. */
|
|
||||||
#define BLE_UUID_BATTERY_SERVICE 0x180F /**< Battery service UUID. */
|
|
||||||
#define BLE_UUID_BLOOD_PRESSURE_SERVICE 0x1810 /**< Blood Pressure service UUID. */
|
|
||||||
#define BLE_UUID_CURRENT_TIME_SERVICE 0x1805 /**< Current Time service UUID. */
|
|
||||||
#define BLE_UUID_CYCLING_SPEED_AND_CADENCE 0x1816 /**< Cycling Speed and Cadence service UUID. */
|
|
||||||
#define BLE_UUID_LOCATION_AND_NAVIGATION_SERVICE 0x1819 /**< Location and Navigation service UUID. */
|
|
||||||
#define BLE_UUID_DEVICE_INFORMATION_SERVICE 0x180A /**< Device Information service UUID. */
|
|
||||||
#define BLE_UUID_GLUCOSE_SERVICE 0x1808 /**< Glucose service UUID. */
|
|
||||||
#define BLE_UUID_HEALTH_THERMOMETER_SERVICE 0x1809 /**< Health Thermometer service UUID. */
|
|
||||||
#define BLE_UUID_HEART_RATE_SERVICE 0x180D /**< Heart Rate service UUID. */
|
|
||||||
#define BLE_UUID_HUMAN_INTERFACE_DEVICE_SERVICE 0x1812 /**< Human Interface Device service UUID. */
|
|
||||||
#define BLE_UUID_IMMEDIATE_ALERT_SERVICE 0x1802 /**< Immediate Alert service UUID. */
|
|
||||||
#define BLE_UUID_LINK_LOSS_SERVICE 0x1803 /**< Link Loss service UUID. */
|
|
||||||
#define BLE_UUID_NEXT_DST_CHANGE_SERVICE 0x1807 /**< Next Dst Change service UUID. */
|
|
||||||
#define BLE_UUID_PHONE_ALERT_STATUS_SERVICE 0x180E /**< Phone Alert Status service UUID. */
|
|
||||||
#define BLE_UUID_REFERENCE_TIME_UPDATE_SERVICE 0x1806 /**< Reference Time Update service UUID. */
|
|
||||||
#define BLE_UUID_RUNNING_SPEED_AND_CADENCE 0x1814 /**< Running Speed and Cadence service UUID. */
|
|
||||||
#define BLE_UUID_SCAN_PARAMETERS_SERVICE 0x1813 /**< Scan Parameters service UUID. */
|
|
||||||
#define BLE_UUID_TX_POWER_SERVICE 0x1804 /**< TX Power service UUID. */
|
|
||||||
#define BLE_UUID_IPSP_SERVICE 0x1820 /**< Internet Protocol Support service UUID. */
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/** @defgroup UUID_CHARACTERISTICS Characteristic UUID definitions
|
|
||||||
* @{ */
|
|
||||||
#define BLE_UUID_BATTERY_LEVEL_STATE_CHAR 0x2A1B /**< Battery Level State characteristic UUID. */
|
|
||||||
#define BLE_UUID_BATTERY_POWER_STATE_CHAR 0x2A1A /**< Battery Power State characteristic UUID. */
|
|
||||||
#define BLE_UUID_REMOVABLE_CHAR 0x2A3A /**< Removable characteristic UUID. */
|
|
||||||
#define BLE_UUID_SERVICE_REQUIRED_CHAR 0x2A3B /**< Service Required characteristic UUID. */
|
|
||||||
#define BLE_UUID_ALERT_CATEGORY_ID_CHAR 0x2A43 /**< Alert Category Id characteristic UUID. */
|
|
||||||
#define BLE_UUID_ALERT_CATEGORY_ID_BIT_MASK_CHAR 0x2A42 /**< Alert Category Id Bit Mask characteristic UUID. */
|
|
||||||
#define BLE_UUID_ALERT_LEVEL_CHAR 0x2A06 /**< Alert Level characteristic UUID. */
|
|
||||||
#define BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR 0x2A44 /**< Alert Notification Control Point characteristic UUID. */
|
|
||||||
#define BLE_UUID_ALERT_STATUS_CHAR 0x2A3F /**< Alert Status characteristic UUID. */
|
|
||||||
#define BLE_UUID_BATTERY_LEVEL_CHAR 0x2A19 /**< Battery Level characteristic UUID. */
|
|
||||||
#define BLE_UUID_BLOOD_PRESSURE_FEATURE_CHAR 0x2A49 /**< Blood Pressure Feature characteristic UUID. */
|
|
||||||
#define BLE_UUID_BLOOD_PRESSURE_MEASUREMENT_CHAR 0x2A35 /**< Blood Pressure Measurement characteristic UUID. */
|
|
||||||
#define BLE_UUID_BODY_SENSOR_LOCATION_CHAR 0x2A38 /**< Body Sensor Location characteristic UUID. */
|
|
||||||
#define BLE_UUID_BOOT_KEYBOARD_INPUT_REPORT_CHAR 0x2A22 /**< Boot Keyboard Input Report characteristic UUID. */
|
|
||||||
#define BLE_UUID_BOOT_KEYBOARD_OUTPUT_REPORT_CHAR 0x2A32 /**< Boot Keyboard Output Report characteristic UUID. */
|
|
||||||
#define BLE_UUID_BOOT_MOUSE_INPUT_REPORT_CHAR 0x2A33 /**< Boot Mouse Input Report characteristic UUID. */
|
|
||||||
#define BLE_UUID_CURRENT_TIME_CHAR 0x2A2B /**< Current Time characteristic UUID. */
|
|
||||||
#define BLE_UUID_DATE_TIME_CHAR 0x2A08 /**< Date Time characteristic UUID. */
|
|
||||||
#define BLE_UUID_DAY_DATE_TIME_CHAR 0x2A0A /**< Day Date Time characteristic UUID. */
|
|
||||||
#define BLE_UUID_DAY_OF_WEEK_CHAR 0x2A09 /**< Day Of Week characteristic UUID. */
|
|
||||||
#define BLE_UUID_DST_OFFSET_CHAR 0x2A0D /**< Dst Offset characteristic UUID. */
|
|
||||||
#define BLE_UUID_EXACT_TIME_256_CHAR 0x2A0C /**< Exact Time 256 characteristic UUID. */
|
|
||||||
#define BLE_UUID_FIRMWARE_REVISION_STRING_CHAR 0x2A26 /**< Firmware Revision String characteristic UUID. */
|
|
||||||
#define BLE_UUID_GLUCOSE_FEATURE_CHAR 0x2A51 /**< Glucose Feature characteristic UUID. */
|
|
||||||
#define BLE_UUID_GLUCOSE_MEASUREMENT_CHAR 0x2A18 /**< Glucose Measurement characteristic UUID. */
|
|
||||||
#define BLE_UUID_GLUCOSE_MEASUREMENT_CONTEXT_CHAR 0x2A34 /**< Glucose Measurement Context characteristic UUID. */
|
|
||||||
#define BLE_UUID_HARDWARE_REVISION_STRING_CHAR 0x2A27 /**< Hardware Revision String characteristic UUID. */
|
|
||||||
#define BLE_UUID_HEART_RATE_CONTROL_POINT_CHAR 0x2A39 /**< Heart Rate Control Point characteristic UUID. */
|
|
||||||
#define BLE_UUID_HEART_RATE_MEASUREMENT_CHAR 0x2A37 /**< Heart Rate Measurement characteristic UUID. */
|
|
||||||
#define BLE_UUID_HID_CONTROL_POINT_CHAR 0x2A4C /**< Hid Control Point characteristic UUID. */
|
|
||||||
#define BLE_UUID_HID_INFORMATION_CHAR 0x2A4A /**< Hid Information characteristic UUID. */
|
|
||||||
#define BLE_UUID_IEEE_REGULATORY_CERTIFICATION_DATA_LIST_CHAR 0x2A2A /**< IEEE Regulatory Certification Data List characteristic UUID. */
|
|
||||||
#define BLE_UUID_INTERMEDIATE_CUFF_PRESSURE_CHAR 0x2A36 /**< Intermediate Cuff Pressure characteristic UUID. */
|
|
||||||
#define BLE_UUID_INTERMEDIATE_TEMPERATURE_CHAR 0x2A1E /**< Intermediate Temperature characteristic UUID. */
|
|
||||||
#define BLE_UUID_LOCAL_TIME_INFORMATION_CHAR 0x2A0F /**< Local Time Information characteristic UUID. */
|
|
||||||
#define BLE_UUID_MANUFACTURER_NAME_STRING_CHAR 0x2A29 /**< Manufacturer Name String characteristic UUID. */
|
|
||||||
#define BLE_UUID_MEASUREMENT_INTERVAL_CHAR 0x2A21 /**< Measurement Interval characteristic UUID. */
|
|
||||||
#define BLE_UUID_MODEL_NUMBER_STRING_CHAR 0x2A24 /**< Model Number String characteristic UUID. */
|
|
||||||
#define BLE_UUID_UNREAD_ALERT_CHAR 0x2A45 /**< Unread Alert characteristic UUID. */
|
|
||||||
#define BLE_UUID_NEW_ALERT_CHAR 0x2A46 /**< New Alert characteristic UUID. */
|
|
||||||
#define BLE_UUID_PNP_ID_CHAR 0x2A50 /**< PNP Id characteristic UUID. */
|
|
||||||
#define BLE_UUID_PROTOCOL_MODE_CHAR 0x2A4E /**< Protocol Mode characteristic UUID. */
|
|
||||||
#define BLE_UUID_RECORD_ACCESS_CONTROL_POINT_CHAR 0x2A52 /**< Record Access Control Point characteristic UUID. */
|
|
||||||
#define BLE_UUID_REFERENCE_TIME_INFORMATION_CHAR 0x2A14 /**< Reference Time Information characteristic UUID. */
|
|
||||||
#define BLE_UUID_REPORT_CHAR 0x2A4D /**< Report characteristic UUID. */
|
|
||||||
#define BLE_UUID_REPORT_MAP_CHAR 0x2A4B /**< Report Map characteristic UUID. */
|
|
||||||
#define BLE_UUID_RINGER_CONTROL_POINT_CHAR 0x2A40 /**< Ringer Control Point characteristic UUID. */
|
|
||||||
#define BLE_UUID_RINGER_SETTING_CHAR 0x2A41 /**< Ringer Setting characteristic UUID. */
|
|
||||||
#define BLE_UUID_SCAN_INTERVAL_WINDOW_CHAR 0x2A4F /**< Scan Interval Window characteristic UUID. */
|
|
||||||
#define BLE_UUID_SCAN_REFRESH_CHAR 0x2A31 /**< Scan Refresh characteristic UUID. */
|
|
||||||
#define BLE_UUID_SERIAL_NUMBER_STRING_CHAR 0x2A25 /**< Serial Number String characteristic UUID. */
|
|
||||||
#define BLE_UUID_SOFTWARE_REVISION_STRING_CHAR 0x2A28 /**< Software Revision String characteristic UUID. */
|
|
||||||
#define BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR 0x2A47 /**< Supported New Alert Category characteristic UUID. */
|
|
||||||
#define BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR 0x2A48 /**< Supported Unread Alert Category characteristic UUID. */
|
|
||||||
#define BLE_UUID_SYSTEM_ID_CHAR 0x2A23 /**< System Id characteristic UUID. */
|
|
||||||
#define BLE_UUID_TEMPERATURE_MEASUREMENT_CHAR 0x2A1C /**< Temperature Measurement characteristic UUID. */
|
|
||||||
#define BLE_UUID_TEMPERATURE_TYPE_CHAR 0x2A1D /**< Temperature Type characteristic UUID. */
|
|
||||||
#define BLE_UUID_TIME_ACCURACY_CHAR 0x2A12 /**< Time Accuracy characteristic UUID. */
|
|
||||||
#define BLE_UUID_TIME_SOURCE_CHAR 0x2A13 /**< Time Source characteristic UUID. */
|
|
||||||
#define BLE_UUID_TIME_UPDATE_CONTROL_POINT_CHAR 0x2A16 /**< Time Update Control Point characteristic UUID. */
|
|
||||||
#define BLE_UUID_TIME_UPDATE_STATE_CHAR 0x2A17 /**< Time Update State characteristic UUID. */
|
|
||||||
#define BLE_UUID_TIME_WITH_DST_CHAR 0x2A11 /**< Time With Dst characteristic UUID. */
|
|
||||||
#define BLE_UUID_TIME_ZONE_CHAR 0x2A0E /**< Time Zone characteristic UUID. */
|
|
||||||
#define BLE_UUID_TX_POWER_LEVEL_CHAR 0x2A07 /**< TX Power Level characteristic UUID. */
|
|
||||||
#define BLE_UUID_CSC_FEATURE_CHAR 0x2A5C /**< Cycling Speed and Cadence Feature characteristic UUID. */
|
|
||||||
#define BLE_UUID_CSC_MEASUREMENT_CHAR 0x2A5B /**< Cycling Speed and Cadence Measurement characteristic UUID. */
|
|
||||||
#define BLE_UUID_RSC_FEATURE_CHAR 0x2A54 /**< Running Speed and Cadence Feature characteristic UUID. */
|
|
||||||
#define BLE_UUID_SC_CTRLPT_CHAR 0x2A55 /**< Speed and Cadence Control Point UUID. */
|
|
||||||
#define BLE_UUID_RSC_MEASUREMENT_CHAR 0x2A53 /**< Running Speed and Cadence Measurement characteristic UUID. */
|
|
||||||
#define BLE_UUID_SENSOR_LOCATION_CHAR 0x2A5D /**< Sensor Location characteristic UUID. */
|
|
||||||
#define BLE_UUID_EXTERNAL_REPORT_REF_DESCR 0x2907 /**< External Report Reference descriptor UUID. */
|
|
||||||
#define BLE_UUID_REPORT_REF_DESCR 0x2908 /**< Report Reference descriptor UUID. */
|
|
||||||
#define BLE_UUID_LN_FEATURE_CHAR 0x2A6A /**< Location Navigation Service, Feature characteristic UUID. */
|
|
||||||
#define BLE_UUID_LN_POSITION_QUALITY_CHAR 0x2A69 /**< Location Navigation Service, Position quality UUID. */
|
|
||||||
#define BLE_UUID_LN_LOCATION_AND_SPEED_CHAR 0x2A67 /**< Location Navigation Service, Location and Speed characteristic UUID. */
|
|
||||||
#define BLE_UUID_LN_NAVIGATION_CHAR 0x2A68 /**< Location Navigation Service, Navigation characteristic UUID. */
|
|
||||||
#define BLE_UUID_LN_CONTROL_POINT_CHAR 0x2A6B /**< Location Navigation Service, Control point characteristic UUID. */
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/** @defgroup ALERT_LEVEL_VALUES Definitions for the Alert Level characteristic values
|
|
||||||
* @{ */
|
|
||||||
#define BLE_CHAR_ALERT_LEVEL_NO_ALERT 0x00 /**< No Alert. */
|
|
||||||
#define BLE_CHAR_ALERT_LEVEL_MILD_ALERT 0x01 /**< Mild Alert. */
|
|
||||||
#define BLE_CHAR_ALERT_LEVEL_HIGH_ALERT 0x02 /**< High Alert. */
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#define BLE_SRV_ENCODED_REPORT_REF_LEN 2 /**< The length of an encoded Report Reference Descriptor. */
|
|
||||||
#define BLE_CCCD_VALUE_LEN 2 /**< The length of a CCCD value. */
|
|
||||||
|
|
||||||
/**@brief Type definition for error handler function that will be called in case of an error in
|
|
||||||
* a service or a service library module. */
|
|
||||||
typedef void (*ble_srv_error_handler_t) (uint32_t nrf_error);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Value of a Report Reference descriptor.
|
|
||||||
*
|
|
||||||
* @details This is mapping information that maps the parent characteristic to the Report ID(s) and
|
|
||||||
* Report Type(s) defined within a Report Map characteristic.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t report_id; /**< Non-zero value if there is more than one instance of the same Report Type */
|
|
||||||
uint8_t report_type; /**< Type of Report characteristic (see @ref BLE_HIDS_REPORT_TYPE) */
|
|
||||||
} ble_srv_report_ref_t;
|
|
||||||
|
|
||||||
/**@brief UTF-8 string data type.
|
|
||||||
*
|
|
||||||
* @note The type can only hold a pointer to the string data (i.e. not the actual data).
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t length; /**< String length. */
|
|
||||||
uint8_t * p_str; /**< String data. */
|
|
||||||
} ble_srv_utf8_str_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Security settings structure.
|
|
||||||
* @details This structure contains the security options needed during initialization of the
|
|
||||||
* service.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */
|
|
||||||
ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */
|
|
||||||
} ble_srv_security_mode_t;
|
|
||||||
|
|
||||||
/**@brief Security settings structure.
|
|
||||||
* @details This structure contains the security options needed during initialization of the
|
|
||||||
* service. It can be used when the characteristics contains a CCCD.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
ble_gap_conn_sec_mode_t cccd_write_perm; /**< Write permissions for Client Characteristic Configuration Descriptor. */
|
|
||||||
ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */
|
|
||||||
ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */
|
|
||||||
} ble_srv_cccd_security_mode_t;
|
|
||||||
|
|
||||||
/**@brief Function for decoding a CCCD value, and then testing if notification is
|
|
||||||
* enabled.
|
|
||||||
*
|
|
||||||
* @param[in] p_encoded_data Buffer where the encoded CCCD is stored.
|
|
||||||
*
|
|
||||||
* @retval TRUE If notification is enabled.
|
|
||||||
* @retval FALSE Otherwise.
|
|
||||||
*/
|
|
||||||
static __INLINE bool ble_srv_is_notification_enabled(uint8_t * p_encoded_data)
|
|
||||||
{
|
|
||||||
uint16_t cccd_value = uint16_decode(p_encoded_data);
|
|
||||||
return ((cccd_value & BLE_GATT_HVX_NOTIFICATION) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Function for decoding a CCCD value, and then testing if indication is
|
|
||||||
* enabled.
|
|
||||||
*
|
|
||||||
* @param[in] p_encoded_data Buffer where the encoded CCCD is stored.
|
|
||||||
*
|
|
||||||
* @retval TRUE If indication is enabled.
|
|
||||||
* @retval FALSE Otherwise.
|
|
||||||
*/
|
|
||||||
static __INLINE bool ble_srv_is_indication_enabled(uint8_t * p_encoded_data)
|
|
||||||
{
|
|
||||||
uint16_t cccd_value = uint16_decode(p_encoded_data);
|
|
||||||
return ((cccd_value & BLE_GATT_HVX_INDICATION) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Function for encoding a Report Reference Descriptor.
|
|
||||||
*
|
|
||||||
* @param[in] p_encoded_buffer The buffer of the encoded data.
|
|
||||||
* @param[in] p_report_ref Report Reference value to be encoded.
|
|
||||||
*
|
|
||||||
* @return Length of the encoded data.
|
|
||||||
*/
|
|
||||||
uint8_t ble_srv_report_ref_encode(uint8_t * p_encoded_buffer,
|
|
||||||
const ble_srv_report_ref_t * p_report_ref);
|
|
||||||
|
|
||||||
/**@brief Function for making a UTF-8 structure refer to an ASCII string.
|
|
||||||
*
|
|
||||||
* @param[out] p_utf8 UTF-8 structure to be set.
|
|
||||||
* @param[in] p_ascii ASCII string to be referred to.
|
|
||||||
*/
|
|
||||||
void ble_srv_ascii_to_utf8(ble_srv_utf8_str_t * p_utf8, char * p_ascii);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Security Access enumeration.
|
|
||||||
* @details This enumeration gives the possible requirements for accessing a characteristic value.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
SEC_NO_ACCESS = 0, /**< Not possible to access. */
|
|
||||||
SEC_OPEN = 1, /**< Access open. */
|
|
||||||
SEC_JUST_WORKS = 2, /**< Access possible with 'Just Works' security at least. */
|
|
||||||
SEC_MITM = 3, /**< Access possible with 'MITM' security at least. */
|
|
||||||
SEC_SIGNED = 4, /**< Access possible with 'signed' security at least. */
|
|
||||||
SEC_SIGNED_MITM = 5 /**< Access possible with 'signed and MITM' security at least. */
|
|
||||||
}security_req_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Characteristic User Descriptor parameters.
|
|
||||||
* @details This structure contains the parameters for User Descriptor.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t max_size; /**< Maximum size of the user descriptor*/
|
|
||||||
uint16_t size; /**< Size of the user descriptor*/
|
|
||||||
uint8_t *p_char_user_desc; /**< User descriptor content, pointer to a UTF-8 encoded string (non-NULL terminated)*/
|
|
||||||
bool is_var_len; /**< Indicates if the user descriptor has variable length.*/
|
|
||||||
ble_gatt_char_props_t char_props; /**< user descriptor properties.*/
|
|
||||||
bool is_defered_read; /**< Indicate if deferred read operations are supported.*/
|
|
||||||
bool is_defered_write; /**< Indicate if deferred write operations are supported.*/
|
|
||||||
security_req_t read_access; /**< Security requirement for reading the user descriptor.*/
|
|
||||||
security_req_t write_access; /**< Security requirement for writing the user descriptor.*/
|
|
||||||
bool is_value_user; /**< Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/
|
|
||||||
}ble_add_char_user_desc_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Add characteristic parameters structure.
|
|
||||||
* @details This structure contains the parameters needed to use the @ref characteristic_add function.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t uuid; /**< Characteristic UUID (16 bits UUIDs).*/
|
|
||||||
uint8_t uuid_type; /**< Base UUID. If 0, the Bluetooth SIG UUID will be used. Otherwise, this should be a value returned by @ref sd_ble_uuid_vs_add when adding the base UUID.*/
|
|
||||||
uint16_t max_len; /**< Maximum length of the characteristic value.*/
|
|
||||||
uint16_t init_len; /**< Initial length of the characteristic value.*/
|
|
||||||
uint8_t * p_init_value; /**< Initial encoded value of the characteristic.*/
|
|
||||||
bool is_var_len; /**< Indicates if the characteristic value has variable length.*/
|
|
||||||
ble_gatt_char_props_t char_props; /**< Characteristic properties.*/
|
|
||||||
bool is_defered_read; /**< Indicate if deferred read operations are supported.*/
|
|
||||||
bool is_defered_write; /**< Indicate if deferred write operations are supported.*/
|
|
||||||
security_req_t read_access; /**< Security requirement for reading the characteristic value.*/
|
|
||||||
security_req_t write_access; /**< Security requirement for writing the characteristic value.*/
|
|
||||||
security_req_t cccd_write_access; /**< Security requirement for writing the characteristic's CCCD.*/
|
|
||||||
bool is_value_user; /**< Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/
|
|
||||||
ble_add_char_user_desc_t *p_user_descr; /**< Pointer to user descriptor if needed*/
|
|
||||||
ble_gatts_char_pf_t *p_presentation_format; /**< Pointer to characteristic format if needed*/
|
|
||||||
} ble_add_char_params_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Add descriptor parameters structure.
|
|
||||||
* @details This structure contains the parameters needed to use the @ref descriptor_add function.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t uuid; /**< descriptor UUID (16 bits UUIDs).*/
|
|
||||||
uint8_t uuid_type; /**< Base UUID. If 0, the Bluetooth SIG UUID will be used. Otherwise, this should be a value returned by @ref sd_ble_uuid_vs_add when adding the base UUID.*/
|
|
||||||
bool is_defered_read; /**< Indicate if deferred read operations are supported.*/
|
|
||||||
bool is_defered_write; /**< Indicate if deferred write operations are supported.*/
|
|
||||||
bool is_var_len; /**< Indicates if the descriptor value has variable length.*/
|
|
||||||
security_req_t read_access; /**< Security requirement for reading the descriptor value.*/
|
|
||||||
security_req_t write_access; /**< Security requirement for writing the descriptor value.*/
|
|
||||||
bool is_value_user; /**< Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/
|
|
||||||
uint16_t init_len; /**< Initial descriptor value length in bytes. */
|
|
||||||
uint16_t init_offs; /**< Initial descriptor value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */
|
|
||||||
uint16_t max_len; /**< Maximum descriptor value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */
|
|
||||||
uint8_t* p_value; /**< Pointer to the value of the descriptor*/
|
|
||||||
} ble_add_descr_params_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for adding a characteristic to a given service.
|
|
||||||
*
|
|
||||||
* If no pointer is given for the initial value,
|
|
||||||
* the initial length parameter will be ignored and the initial length will be 0.
|
|
||||||
*
|
|
||||||
* @param[in] service_handle Handle of the service to which the characteristic is to be added.
|
|
||||||
* @param[in] p_char_props Information needed to add the characteristic.
|
|
||||||
* @param[out] p_char_handle Handle of the added characteristic.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS If the characteristic was added successfully. Otherwise, an error code is returned.
|
|
||||||
*/
|
|
||||||
uint32_t characteristic_add(uint16_t service_handle,
|
|
||||||
ble_add_char_params_t * p_char_props,
|
|
||||||
ble_gatts_char_handles_t * p_char_handle);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for adding a characteristic's descriptor to a given characteristic.
|
|
||||||
*
|
|
||||||
* @param[in] char_handle Handle of the characteristic to which the descriptor is to be added, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
|
|
||||||
* @param[in] p_descr_props Information needed to add the descriptor.
|
|
||||||
* @param[out] p_descr_handle Handle of the added descriptor.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS If the characteristic was added successfully. Otherwise, an error code is returned.
|
|
||||||
*/
|
|
||||||
uint32_t descriptor_add(uint16_t char_handle,
|
|
||||||
ble_add_descr_params_t * p_descr_props,
|
|
||||||
uint16_t * p_descr_handle);
|
|
||||||
|
|
||||||
|
|
||||||
#endif // BLE_SRV_COMMON_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,119 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file device_manager_cnfg.h
|
|
||||||
*
|
|
||||||
* @cond
|
|
||||||
* @defgroup device_manager_cnfg Device Manager Configuration
|
|
||||||
* @ingroup device_manager
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @brief Defines application specific configuration for Device Manager.
|
|
||||||
*
|
|
||||||
* @details All configurations that are specific to application have been defined
|
|
||||||
* here. Application should configuration that best suits its requirements.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DEVICE_MANAGER_CNFG_H__
|
|
||||||
#define DEVICE_MANAGER_CNFG_H__
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup device_manager_inst Device Manager Instances
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @brief Maximum applications that Device Manager can support.
|
|
||||||
*
|
|
||||||
* @details Maximum application that the Device Manager can support.
|
|
||||||
* Currently only one application can be supported.
|
|
||||||
* Minimum value : 1
|
|
||||||
* Maximum value : 1
|
|
||||||
* Dependencies : None.
|
|
||||||
*/
|
|
||||||
#define DEVICE_MANAGER_MAX_APPLICATIONS 1
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Maximum connections that Device Manager should simultaneously manage.
|
|
||||||
*
|
|
||||||
* @details Maximum connections that Device Manager should simultaneously manage.
|
|
||||||
* Minimum value : 1
|
|
||||||
* Maximum value : Maximum links supported by SoftDevice.
|
|
||||||
* Dependencies : None.
|
|
||||||
*/
|
|
||||||
#define DEVICE_MANAGER_MAX_CONNECTIONS 1
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Maximum bonds that Device Manager should manage.
|
|
||||||
*
|
|
||||||
* @details Maximum bonds that Device Manager should manage.
|
|
||||||
* Minimum value : 1
|
|
||||||
* Maximum value : 254.
|
|
||||||
* Dependencies : None.
|
|
||||||
* @note In case of GAP Peripheral role, the Device Manager will accept bonding procedure
|
|
||||||
* requests from peers even if this limit is reached, but bonding information will not
|
|
||||||
* be stored. In such cases, application will be notified with DM_DEVICE_CONTEXT_FULL
|
|
||||||
* as event result at the completion of the security procedure.
|
|
||||||
*/
|
|
||||||
#define DEVICE_MANAGER_MAX_BONDS 2
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Maximum Characteristic Client Descriptors used for GATT Server.
|
|
||||||
*
|
|
||||||
* @details Maximum Characteristic Client Descriptors used for GATT Server.
|
|
||||||
* Minimum value : 1
|
|
||||||
* Maximum value : 254.
|
|
||||||
* Dependencies : None.
|
|
||||||
*/
|
|
||||||
#define DM_GATT_CCCD_COUNT 2
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Size of application context.
|
|
||||||
*
|
|
||||||
* @details Size of application context that Device Manager should manage for each bonded device.
|
|
||||||
* Size had to be a multiple of word size.
|
|
||||||
* Minimum value : 4.
|
|
||||||
* Maximum value : 256.
|
|
||||||
* Dependencies : Needed only if Application Context saving is used by the application.
|
|
||||||
* @note If set to zero, its an indication that application context is not required to be managed
|
|
||||||
* by the module.
|
|
||||||
*/
|
|
||||||
#define DEVICE_MANAGER_APP_CONTEXT_SIZE 0
|
|
||||||
|
|
||||||
/* @} */
|
|
||||||
/* @} */
|
|
||||||
/** @endcond */
|
|
||||||
#endif // DEVICE_MANAGER_CNFG_H__
|
|
||||||
|
|
|
@ -1,909 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file device_manager.h
|
|
||||||
*
|
|
||||||
* @defgroup device_manager Device Manager
|
|
||||||
* @ingroup ble_sdk_lib
|
|
||||||
* @{
|
|
||||||
* @brief Device Manager Application Interface Abstraction.
|
|
||||||
*
|
|
||||||
* @details The Device Manager module manages Active and Bonded Peers. Management of peer includes
|
|
||||||
* book keeping of contextual information like the Security Keys, GATT
|
|
||||||
* configuration and any application specific information.
|
|
||||||
*
|
|
||||||
* Active Peers are devices which are connected, and may or may not be bonded.
|
|
||||||
* Bonded Peers are devices which are bonded, and may or may not be Active (Connected).
|
|
||||||
* Active Bonded Peer refers to a device which is connected and bonded.
|
|
||||||
*
|
|
||||||
* Paired Devices refers to peer devices that are connected and have necessary context
|
|
||||||
* establishment/exchange for the current connection session. On disconnect,
|
|
||||||
* all contextual information is flushed. For example, SMP Information Exchanged during
|
|
||||||
* pairing and GATT Configuration is not retained on disconnection.
|
|
||||||
*
|
|
||||||
* Note that this module allows management of contextual information but
|
|
||||||
* does not provide an interface for connection management. Therefore, entering connectible
|
|
||||||
* mode, connection establishment, or disconnection of a link with peer is not in scope
|
|
||||||
* of this module.
|
|
||||||
*
|
|
||||||
* For bonded peers, the contextual information is required to be retained on disconnection
|
|
||||||
* and power cycling. Persistent storage of contextual information is handled by the
|
|
||||||
* module. This module categorizes the contextual information into 3 categories:
|
|
||||||
* - <b>Bonding Information</b>
|
|
||||||
* Bond information is the information exchanged between local and peer device to
|
|
||||||
* establish a bond. It also includes peer identification information,
|
|
||||||
* like the peer address or the IRK or both. From here on this category of information
|
|
||||||
* is referred to as Device Context.
|
|
||||||
* - <b>Service/Protocol Information</b>
|
|
||||||
* Service/Protocol information is the information retained for the peer to save on one-time
|
|
||||||
* procedures like the GATT Service Discovery procedures and Service Configurations.
|
|
||||||
* It allows devices to resume data exchange on subsequent reconnection without having
|
|
||||||
* to perform initial set-up procedures each time. From here on this category is
|
|
||||||
* referred to as Service Context.
|
|
||||||
* - <b>Application Information</b>
|
|
||||||
* Application information is the context that the application would like to associate with
|
|
||||||
* each of the bonded device. For example, if the application chooses to rank its peers
|
|
||||||
* in order to manage them better, the rank information could be treated as
|
|
||||||
* Application Information. This storage space is provided to save the application from
|
|
||||||
* maintaining a mapping table with each Device Instance and Application Information.
|
|
||||||
* However, if the application have no use for this, it is possible to not
|
|
||||||
* use or employ this at compile time. From here on this category of information is
|
|
||||||
* referred to as Application Context.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef DEVICE_MANAGER_H__
|
|
||||||
#define DEVICE_MANAGER_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "sdk_common.h"
|
|
||||||
#include "nrf_ble.h"
|
|
||||||
#include "ble_gap.h"
|
|
||||||
#include "device_manager_cnfg.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup dm_service_cntext_types Service/Protocol Types
|
|
||||||
*
|
|
||||||
* @brief Describes the possible types of Service/Protocol Contexts for a bonded/peer device.
|
|
||||||
*
|
|
||||||
* @details Possible Service/Protocol context per peer device. The Device Manager provides the
|
|
||||||
* functionality of persistently storing the Service/Protocol context and can automatically
|
|
||||||
* load them when needed.
|
|
||||||
* For example system attributes for a GATT Server. Based on the nature of the application,
|
|
||||||
* not all service types may be needed. The application can specify
|
|
||||||
* only the service/protocol context it wants to use at the time of registration.
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#define DM_PROTOCOL_CNTXT_NONE 0x00 /**< No Service Context, this implies the application does not want to associate any service/protocol context with the peer device */
|
|
||||||
#define DM_PROTOCOL_CNTXT_GATT_SRVR_ID 0x01 /**< GATT Server Service Context, this implies the application does associate GATT Server with the peer device and this information will be loaded when needed for a bonded device */
|
|
||||||
#define DM_PROTOCOL_CNTXT_GATT_CLI_ID 0x02 /**< GATT Client Service Context, this implies the application does associate GATT Client with the peer device and this information will be loaded when needed for a bonded device */
|
|
||||||
#define DM_PROTOCOL_CNTXT_ALL \
|
|
||||||
(DM_PROTOCOL_CNTXT_GATT_SRVR_ID | DM_PROTOCOL_CNTXT_GATT_CLI_ID) /**< All Service/Protocol Context, this implies that the application wants to associate all Service/Protocol Information with the bonded device. This is configurable based on system requirements. If the application has only one type of service, this define could be altered to reflect the same. */
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup dm_events Device Manager Events
|
|
||||||
*
|
|
||||||
* @brief This section describes the device manager events that are notified to the application.
|
|
||||||
*
|
|
||||||
* @details The Device Manager notifies the application of various asynchronous events using the
|
|
||||||
* asynchronous event notification callback. All events has been categorized into:
|
|
||||||
* a. General.
|
|
||||||
* b. Link Status.
|
|
||||||
* c. Context Management.
|
|
||||||
*
|
|
||||||
* In the callback, these events are notified along with handle that uniquely identifies:
|
|
||||||
* application instance, active instance (if applicable), device instance
|
|
||||||
* bonding instance, (if applicable) and service instance.
|
|
||||||
* Not all events are pertaining to an active connection, for example a context deletion event could occur even if the peer
|
|
||||||
* is not connected. Also, general category of events may not be pertaining to any specific peer.
|
|
||||||
* See also \ref dm_event_cb_t and \ref dm_register.
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @defgroup general_events General Events
|
|
||||||
*
|
|
||||||
* @brief General or miscellaneous events.
|
|
||||||
*
|
|
||||||
* @details This category of events are general events not pertaining to a peer or context.
|
|
||||||
*
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#define DM_EVT_RFU 0x00 /**< Reserved for future use, is never notified. */
|
|
||||||
#define DM_EVT_ERROR 0x01 /**< Device Manager Event Error. */
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup link_status_events Link Status Events
|
|
||||||
*
|
|
||||||
* @brief Link Status Events.
|
|
||||||
*
|
|
||||||
* @details This category of events notify the application of the link status. Event result associated
|
|
||||||
* with the event is provided along with the event in the callback to provide more details of
|
|
||||||
* whether a procedure succeeded or failed and assist the application in decision making of
|
|
||||||
* how to proceed. For example if a DM_DEVICE_CONNECT_IND is indicated with NRF_SUCCESS
|
|
||||||
* result, the application may want to proceed with discovering and association with
|
|
||||||
* service of the peer. However, if indicated with a failure result, the application may
|
|
||||||
* want to take an alternate action such as reattempting to connect or go into a
|
|
||||||
* sleep mode.
|
|
||||||
*
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#define DM_EVT_CONNECTION 0x11 /**< Indicates that link with the peer is established. */
|
|
||||||
#define DM_EVT_DISCONNECTION 0x12 /**< Indicates that link with peer is torn down. */
|
|
||||||
#define DM_EVT_SECURITY_SETUP 0x13 /**< Security procedure for link started indication */
|
|
||||||
#define DM_EVT_SECURITY_SETUP_COMPLETE 0x14 /**< Security procedure for link completion indication. */
|
|
||||||
#define DM_EVT_LINK_SECURED 0x15 /**< Indicates that link with the peer is secured. For bonded devices, subsequent reconnections with bonded peer will result only in this event when the link is secured and setup procedures will not occur unless the bonding information is either lost or deleted on either or both sides. */
|
|
||||||
#define DM_EVT_SECURITY_SETUP_REFRESH 0x16 /**< Indicates that the security on the link was re-established. */
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup context_mgmt_events Context Management Events
|
|
||||||
*
|
|
||||||
* @brief Context Management Events.
|
|
||||||
*
|
|
||||||
* @details These events notify the application of the status of context loading and storing.
|
|
||||||
*
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
#define DM_EVT_DEVICE_CONTEXT_LOADED 0x21 /**< Indicates that device context for a peer is loaded. */
|
|
||||||
#define DM_EVT_DEVICE_CONTEXT_STORED 0x22 /**< Indicates that device context is stored persistently. */
|
|
||||||
#define DM_EVT_DEVICE_CONTEXT_DELETED 0x23 /**< Indicates that device context is deleted. */
|
|
||||||
#define DM_EVT_SERVICE_CONTEXT_LOADED 0x31 /**< Indicates that service context for a peer is loaded. */
|
|
||||||
#define DM_EVT_SERVICE_CONTEXT_STORED 0x32 /**< Indicates that service context is stored persistently. */
|
|
||||||
#define DM_EVT_SERVICE_CONTEXT_DELETED 0x33 /**< Indicates that service context is deleted. */
|
|
||||||
#define DM_EVT_APPL_CONTEXT_LOADED 0x41 /**< Indicates that application context for a peer is loaded. */
|
|
||||||
#define DM_EVT_APPL_CONTEXT_STORED 0x42 /**< Indicates that application context is stored persistently. */
|
|
||||||
#define DM_EVT_APPL_CONTEXT_DELETED 0x43 /**< Indicates that application context is deleted. */
|
|
||||||
/** @} */
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#define DM_INVALID_ID 0xFF /**< Invalid instance idenitifer. */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup dm_data_structure Device Manager Data Types
|
|
||||||
*
|
|
||||||
* @brief This section describes all the data types exposed by the module to the application.
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Application Instance.
|
|
||||||
*
|
|
||||||
* @details Application instance uniquely identifies an application. The identifier is allocated by
|
|
||||||
* the device manager when application registers with the module. The application is
|
|
||||||
* expected to identify itself with this instance identifier when initiating subsequent
|
|
||||||
* requests. Application should use the utility API \ref dm_application_instance_set in
|
|
||||||
* order to set its application instance in dm_handle_t needed for all subsequent APIs.
|
|
||||||
* See also \ref dm_register.
|
|
||||||
*/
|
|
||||||
typedef uint8_t dm_application_instance_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Connection Instance.
|
|
||||||
*
|
|
||||||
* @details Identifies connection instance for an active device. This instance is allocated by the
|
|
||||||
* device manager when a connection is established and is notified with DM_EVT_CONNECTION
|
|
||||||
* with the event result NRF_SUCCESS.
|
|
||||||
*/
|
|
||||||
typedef uint8_t dm_connection_instance_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Device Instance.
|
|
||||||
*
|
|
||||||
* @details Uniquely identifies a bonded peer device. The peer device may or may not be connected.
|
|
||||||
* In case of the central: The bonded device instance to identify the peer is allocated when bonding procedure is initiated by the central using dm_security_setup_req.
|
|
||||||
* In case of the peripheral: When the bonding procedure is successful, the DM_EVT_SECURITY_SETUP_COMPLETE event with success event result, is received.
|
|
||||||
* In case the module cannot add more bonded devices, no instance is allocated, this is indicated by an appropriate error code for the API/event as the case may be. Application can choose to disconnect the link.
|
|
||||||
*/
|
|
||||||
typedef uint8_t dm_device_instance_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Service Instance.
|
|
||||||
*
|
|
||||||
* @details Uniquely identifies a peer device. The peer device may or may not be connected. This
|
|
||||||
* instance is allocated by the device manager when a device is bonded and is notified
|
|
||||||
* when security procedures have been initiated.
|
|
||||||
* Security Procedures initiation is notified with DM_SECURITY_SETUP_IND with
|
|
||||||
* success event result. In case the event result indicates that the module cannot add more
|
|
||||||
* bonded devices, no instance is allocated. Application can chose to disconnect the link.
|
|
||||||
*/
|
|
||||||
typedef uint8_t dm_service_instance_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Service/Protocol Type Identifier.
|
|
||||||
*
|
|
||||||
* @details Uniquely identifies a service or a protocol type. Service/Protocol Type identification
|
|
||||||
* is needed as each service/protocol can have its own contextual data.
|
|
||||||
* This allows the peer to access more than one service at a time. \ref dm_service_cntext_types describes the
|
|
||||||
* list of services/protocols supported.
|
|
||||||
*/
|
|
||||||
typedef uint8_t service_type_t;
|
|
||||||
|
|
||||||
/**@brief Device Manager Master identification and encryption information. */
|
|
||||||
typedef struct dm_enc_key
|
|
||||||
{
|
|
||||||
ble_gap_enc_info_t enc_info; /**< GAP encryption information. */
|
|
||||||
ble_gap_master_id_t master_id; /**< Master identification. */
|
|
||||||
} dm_enc_key_t;
|
|
||||||
|
|
||||||
/** @brief Device Manager identity and address information. */
|
|
||||||
typedef struct dm_id_key
|
|
||||||
{
|
|
||||||
ble_gap_irk_t id_info; /**< Identity information. */
|
|
||||||
ble_gap_addr_t id_addr_info; /**< Identity address information. */
|
|
||||||
} dm_id_key_t;
|
|
||||||
|
|
||||||
/** @brief Device Manager signing information. */
|
|
||||||
typedef struct dm_sign_key
|
|
||||||
{
|
|
||||||
ble_gap_sign_info_t sign_key; /**< GAP signing information. */
|
|
||||||
} dm_sign_key_t;
|
|
||||||
|
|
||||||
/** @brief Security keys. */
|
|
||||||
typedef struct dm_sec_keyset
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
dm_enc_key_t * p_enc_key; /**< Pointer to Device Manager encryption information structure. */
|
|
||||||
} enc_key;
|
|
||||||
dm_id_key_t * p_id_key; /**< Identity key, or NULL. */
|
|
||||||
dm_sign_key_t * p_sign_key; /**< Signing key, or NULL. */
|
|
||||||
} dm_sec_keys_t;
|
|
||||||
|
|
||||||
/** @brief Device Manager security key set. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
dm_sec_keys_t keys_periph; /**< Keys distributed by the device in the Peripheral role. */
|
|
||||||
dm_sec_keys_t keys_central; /**< Keys distributed by the device in the Central role. */
|
|
||||||
} dm_sec_keyset_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Device Handle used for unique identification of each peer.
|
|
||||||
*
|
|
||||||
* @details This data type is used to uniquely identify each peer device. A peer device could be
|
|
||||||
* active and/or bonded. Therefore an instance for active and bonded is provided.
|
|
||||||
* However, the application is expected to treat this is an opaque structure and use this for
|
|
||||||
* all API interactions once stored on appropriate events.
|
|
||||||
* See \ref dm_events.
|
|
||||||
*/
|
|
||||||
typedef struct device_handle
|
|
||||||
{
|
|
||||||
dm_application_instance_t appl_id; /**< Identifies the application instances for the device that is being managed. */
|
|
||||||
dm_connection_instance_t connection_id; /**< Identifies the active connection instance. */
|
|
||||||
dm_device_instance_t device_id; /**< Identifies peer instance in the data base. */
|
|
||||||
dm_service_instance_t service_id; /**< Service instance identifier. */
|
|
||||||
} dm_handle_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Definition of Data Context.
|
|
||||||
*
|
|
||||||
* @details Defines contextual data format, it consists of context data length and pointer to data.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t flags; /**< Additional flags identifying data. */
|
|
||||||
uint32_t len; /**< Length of data. */
|
|
||||||
uint8_t * p_data; /**< Pointer to contextual data, a copy is made of the data. */
|
|
||||||
} dm_context_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Device Context.
|
|
||||||
*
|
|
||||||
* @details Defines "device context" type for a device managed by device manager.
|
|
||||||
*/
|
|
||||||
typedef dm_context_t dm_device_context_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Service Context.
|
|
||||||
*
|
|
||||||
* @details Service context data for a service identified by the 'service_type' field.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
service_type_t service_type; /**< Identifies the service/protocol to which the context data is related. */
|
|
||||||
dm_context_t context_data; /**< Contains length and pointer to context data */
|
|
||||||
} dm_service_context_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Application context.
|
|
||||||
*
|
|
||||||
* @details The application context can be used by the application to map any application level
|
|
||||||
* information that is to be mapped with a particular peer.
|
|
||||||
* For bonded peers, this information will be stored by the bond manager persistently.
|
|
||||||
* Note that the device manager treats this information as an
|
|
||||||
* opaque block of bytes.
|
|
||||||
* Necessary APIs to get and set this context for a peer have been provided.
|
|
||||||
*/
|
|
||||||
typedef dm_context_t dm_application_context_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Event parameters.
|
|
||||||
*
|
|
||||||
* @details Defines event parameters for each of the events notified by the module.
|
|
||||||
*/
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
ble_gap_evt_t * p_gap_param; /**< All events that are triggered in device manager as a result of GAP events, like connection, disconnection and security procedures are accompanied with GAP parameters. */
|
|
||||||
dm_application_context_t * p_app_context; /**< All events that are associated with application context procedures of store, load, and deletion have this as event parameter. */
|
|
||||||
dm_service_context_t * p_service_context; /**< All events that are associated with service context procedures of store, load and deletion have this as event parameter. */
|
|
||||||
dm_device_context_t * p_device_context; /**< All events that are associated with device context procedures of store, load and deletion have this as event parameter. */
|
|
||||||
} dm_event_param_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Asynchronous events details notified to the application by the module.
|
|
||||||
*
|
|
||||||
* @details Defines event type along with event parameters notified to the application by the
|
|
||||||
* module.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t event_id; /**< Identifies the event. See \ref dm_events for details on event types and their significance. */
|
|
||||||
dm_event_param_t event_param; /**< Event parameters. Can be NULL if the event does not have any parameters. */
|
|
||||||
uint16_t event_paramlen; /**< Length of the event parameters, is zero if the event does not have any parameters. */
|
|
||||||
} dm_event_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Event notification callback registered by application with the module.
|
|
||||||
*
|
|
||||||
* @details Event notification callback registered by application with the module when registering
|
|
||||||
* the module using \ref dm_register API.
|
|
||||||
*
|
|
||||||
* @param[in] p_handle Identifies the peer for which the event is being notified.
|
|
||||||
* @param[in] p_event Identifies the event, any associated parameters and parameter length.
|
|
||||||
* See \ref dm_events for details on event types and their significance.
|
|
||||||
* @param[in,out] event_result Provide additional information on the event.
|
|
||||||
* In addition to SDK error codes there is also a return value
|
|
||||||
* indicating if maximum number of connections has been reached when connecting or bonding.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS on success, or a failure to indicate if it could handle the event
|
|
||||||
* successfully. There is no action taken in case application returns a failure.
|
|
||||||
*/
|
|
||||||
typedef ret_code_t (*dm_event_cb_t)(dm_handle_t const * p_handle,
|
|
||||||
dm_event_t const * p_event,
|
|
||||||
ret_code_t event_result);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialization Parameters.
|
|
||||||
*
|
|
||||||
* @details Indicates the application parameters. Currently this only encompasses clearing
|
|
||||||
* all persistent data.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
bool clear_persistent_data; /**< Set to true in case the module should clear all persistent data. */
|
|
||||||
} dm_init_param_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Application Registration Parameters.
|
|
||||||
*
|
|
||||||
* @details Parameters needed by the module when registering with it.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
dm_event_cb_t evt_handler; /**< Event Handler to be registered. It will receive asynchronous notification from the module, see \ref dm_events for asynchronous events. */
|
|
||||||
uint8_t service_type; /**< Bit mask identifying services that the application intends to support for all peers. */
|
|
||||||
ble_gap_sec_params_t sec_param; /**< Security parameters to be used for the application. */
|
|
||||||
} dm_application_param_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Defines possible security status/states.
|
|
||||||
*
|
|
||||||
* @details Defines possible security status/states of a link when requested by application using
|
|
||||||
* the \ref dm_security_status_req.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NOT_ENCRYPTED, /**< The link is not secured. */
|
|
||||||
ENCRYPTION_IN_PROGRESS, /**< Link security is being established.*/
|
|
||||||
ENCRYPTED /**< The link is secure.*/
|
|
||||||
} dm_security_status_t;
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup dm_api Device Module APIs
|
|
||||||
*
|
|
||||||
* @brief This section describes APIs exposed by the module.
|
|
||||||
*
|
|
||||||
* @details This section describes APIs exposed by the module. The APIs have been categorized to provide
|
|
||||||
* better and specific look up for developers. Categories are:
|
|
||||||
* - Set up APIs.
|
|
||||||
* - Context Management APIs.
|
|
||||||
* - Utility APIs.
|
|
||||||
*
|
|
||||||
* MSCs describe usage of these APIs.
|
|
||||||
* See @ref dm_msc.
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @defgroup dm_setup_api Device Module Set-up APIs
|
|
||||||
*
|
|
||||||
* @brief Initialization & registration APIs that are pre-requisite for all other module procedures.
|
|
||||||
* @details This section describes the Module Initialization and Registration APIs needed to be set up by
|
|
||||||
* the application before device manager can start managing devices and device contexts
|
|
||||||
* for the application.
|
|
||||||
*
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Module Initialization Routine.
|
|
||||||
*
|
|
||||||
* @details Function for initializing the module. Must called before any other APIs of the module are used.
|
|
||||||
*
|
|
||||||
* @param[in] p_init_param Initialization parameters.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
|
|
||||||
*
|
|
||||||
* @note It is mandatory that pstorage is initialized before initializing this module.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_init(dm_init_param_t const * p_init_param);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for registering the application.
|
|
||||||
*
|
|
||||||
* @details This routine is used by the application to register for asynchronous events with the
|
|
||||||
* device manager. During registration the application also indicates the services that it
|
|
||||||
* intends to support on this instance. It is possible to register multiple times with the
|
|
||||||
* device manager. At least one instance shall be registered with the device manager after
|
|
||||||
* the module has been initialized.
|
|
||||||
* Maximum number of application instances device manager can support is determined
|
|
||||||
* by DM_MAX_APPLICATIONS.
|
|
||||||
*
|
|
||||||
* All applications must be registered before initiating or accepting connections from the peer.
|
|
||||||
*
|
|
||||||
* @param[in] p_appl_param Application parameters.
|
|
||||||
* @param[out] p_appl_instance Application Instance Identifier in case registration is successful.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization.
|
|
||||||
* @retval NRF_ERROR_NO_MEM If module cannot support more applications.
|
|
||||||
*
|
|
||||||
* @note Currently only one application instance is supported by the module.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_register(dm_application_instance_t * p_appl_instance,
|
|
||||||
dm_application_param_t const * p_appl_param);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for handling BLE events.
|
|
||||||
*
|
|
||||||
* @details BLE Event Handler for the module. This routine should be called from BLE stack event
|
|
||||||
* dispatcher for the module to work as expected.
|
|
||||||
*
|
|
||||||
* @param[in] p_ble_evt BLE stack event being dispatched to the function.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void dm_ble_evt_handler(ble_evt_t * p_ble_evt);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup dm_security_api APIs to set up or read status of security on a link.
|
|
||||||
*
|
|
||||||
* @brief This section describes APIs to set up Security. These APIs require that the peer is
|
|
||||||
* connected before the procedures can be requested.
|
|
||||||
*
|
|
||||||
* @details This group allows application to request security procedures
|
|
||||||
* or get the status of the security on a link.
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @brief Function for requesting setting up security on a link.
|
|
||||||
*
|
|
||||||
* @details This API initiates security procedures with a peer device.
|
|
||||||
* @note For the GAP Central role, in case peer is not bonded, request to bond/pair is
|
|
||||||
* initiated. If it is bonded, the link is re-encrypted using the existing bond information.
|
|
||||||
* For the GAP peripheral role, a Slave security request is sent.
|
|
||||||
* @details If a pairing procedure is initiated successfully, application is notified of
|
|
||||||
* @ref DM_EVT_SECURITY_SETUP_COMPLETE. A result indicating success or failure is notified along with the event.
|
|
||||||
* In case the link is re-encrypted using existing bond information, @ref DM_EVT_LINK_SECURED is
|
|
||||||
* notified to the application.
|
|
||||||
*
|
|
||||||
* @param[in] p_handle Identifies the link on which security is desired.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
|
||||||
* application registration.
|
|
||||||
* @retval NRF_ERROR_NULL If p_handle is NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR If the peer is not identified by the handle provided by the application
|
|
||||||
* or if the peer is not connected when this procedure is requested.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_security_setup_req(dm_handle_t * p_handle);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for reading the status of the security on a link.
|
|
||||||
*
|
|
||||||
* @details This API allows application to query status of security on a link.
|
|
||||||
*
|
|
||||||
* @param[in] p_handle Identifies the link on which security is desired.
|
|
||||||
* @param[out] p_status Pointer where security status is provided to the application.
|
|
||||||
* See \ref dm_security_status_t for possible statuses that can be expected.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Or appropriate error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
|
||||||
* application registration.
|
|
||||||
* @retval NRF_ERROR_NULL If p_handle or p_status is NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR If peer is not identified by the handle provided by the application
|
|
||||||
* or if peer is not connected when this procedure is requested.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_security_status_req(dm_handle_t const * p_handle, dm_security_status_t * p_status);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for creating the whitelist.
|
|
||||||
*
|
|
||||||
* @details This API allows application to create whitelist based on bonded peer devices in module
|
|
||||||
* data base.
|
|
||||||
*
|
|
||||||
* @param[in] p_handle Identifies the application requesting whitelist creation.
|
|
||||||
* @param[in,out] p_whitelist Pointer where created whitelist is provided to the application.
|
|
||||||
*
|
|
||||||
* @note 'addr_count' and 'irk_count' fields of the structure should be populated with the maximum
|
|
||||||
* number of devices that the application wishes to request in the whitelist.
|
|
||||||
* If the number of bonded devices is less than requested, the fields are updated with that number of devices.
|
|
||||||
* If the number of devices are more than requested, the module will populate the list
|
|
||||||
* with devices in the order the bond was established with the peer devices. Also, if this routine is
|
|
||||||
* called when a connection exists with one or more peer devices,
|
|
||||||
* those connected devices are not added to the whitelist.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
|
||||||
* application registration.
|
|
||||||
* @retval NRF_ERROR_NULL If p_handle or p_whitelist is NULL.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_whitelist_create(dm_application_instance_t const * p_handle,
|
|
||||||
ble_gap_whitelist_t * p_whitelist);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup dm_cntxt_mgmt_api Context Management APIs
|
|
||||||
*
|
|
||||||
* @brief Utility APIs offered by the device manager to get information about the peer if and
|
|
||||||
* when needed.
|
|
||||||
*
|
|
||||||
* @details This group of API allow the application to access information that is not required to be
|
|
||||||
* maintained by the application but may be needed. Hence it is possible to get the
|
|
||||||
* information from the module instead of mapping all the information with a device
|
|
||||||
* context.
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
ret_code_t dm_device_add(dm_handle_t * p_handle,
|
|
||||||
dm_device_context_t const * p_context);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for deleting a peer device context and all related information from the database.
|
|
||||||
*
|
|
||||||
* @details Delete peer device context and all related information from database. If
|
|
||||||
* this API returns NRF_SUCCESS, DM_EVT_DEVICE_CONTEXT_DELETED event is notified to the
|
|
||||||
* application. Event result notified along with the event indicates success or failure
|
|
||||||
* of this procedure.
|
|
||||||
*
|
|
||||||
* @param[in] p_handle Identifies the peer device to be deleted.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS on success, else an error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE In the API is called without module initialization and/or
|
|
||||||
* application registration.
|
|
||||||
* @retval NRF_ERROR_NULL If p_handle is NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR If peer is not identified the handle provided by the application.
|
|
||||||
*
|
|
||||||
* @note Deleting device context results in deleting service and application context for the
|
|
||||||
* bonded device. The respective events DM_EVT_SERVICE_CONTEXT_DELETED and
|
|
||||||
* DM_EVT_APPL_CONTEXT_DELETED are not notified to the application.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_device_delete(dm_handle_t const * p_handle);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for deleting all peer device context and all related information from the database.
|
|
||||||
*
|
|
||||||
* @details Delete peer device context and all related information from database. If
|
|
||||||
* this API returns NRF_SUCCESS, DM_EVT_DEVICE_CONTEXT_DELETED event is notified to the
|
|
||||||
* application for each device that is deleted from the data base. Event result
|
|
||||||
* notified along with the event indicates success or failure of this procedure.
|
|
||||||
*
|
|
||||||
* @param[in] p_handle Identifies application instance that is requesting
|
|
||||||
* the deletion of all bonded devices.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
|
||||||
* application registration.
|
|
||||||
* @retval NRF_ERROR_NULL If p_handle is NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR If peer is not identified the handle provided by the application.
|
|
||||||
*
|
|
||||||
* @note Deleting device context results in deleting both service and application context for the
|
|
||||||
* bonded device. The respective events DM_EVT_SERVICE_CONTEXT_DELETED and
|
|
||||||
* DM_EVT_APPL_CONTEXT_DELETED are not notified to the application.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_device_delete_all(dm_application_instance_t const * p_handle);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for setting Service Context for a peer device identified by 'p_handle' parameter.
|
|
||||||
*
|
|
||||||
* @details This API allows application to Set Service Context for a peer device identified by the
|
|
||||||
* 'p_handle' parameter. This API is useful when the Service Context cannot be requested
|
|
||||||
* from the SoftDevice, but needs to be assembled by the application or an another module.
|
|
||||||
* (or when service context is exchanged in an out of band way.)
|
|
||||||
* This API could also be used to trigger a storing of service context into persistent
|
|
||||||
* memory. If this is desired, a NULL pointer could be passed to the p_context.
|
|
||||||
*
|
|
||||||
* @param[in] p_handle Identifies peer device for which the procedure is requested.
|
|
||||||
* @param[in] p_context Service context being set. The context information includes length of
|
|
||||||
* data and pointer to the contextual data being set. The memory pointed to by
|
|
||||||
* the pointer to data is assumed to be resident when API is being called and
|
|
||||||
* can be freed or reused once the set procedure is complete. Set procedure
|
|
||||||
* completion is indicated by the event \ref DM_EVT_SERVICE_CONTEXT_STORED.
|
|
||||||
* The Event result is notified along with the event and indicates success or failure of
|
|
||||||
* this procedure.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
|
||||||
* application registration.
|
|
||||||
* @retval NRF_ERROR_NULL If p_handle is NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR If the peer is not identified by the handle provided by the application.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_service_context_set(dm_handle_t const * p_handle,
|
|
||||||
dm_service_context_t const * p_context);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for getting Service Context for a peer device identified by 'p_handle' parameter.
|
|
||||||
*
|
|
||||||
* @details Get Service Context for a peer device identified by the 'p_handle' parameter. If
|
|
||||||
* this API returns NRF_SUCCESS, DM_EVT_SERVICE_CONTEXT_LOADED event is notified to the
|
|
||||||
* application. The event result is notified along with the event indicates success or failure
|
|
||||||
* of this procedure.
|
|
||||||
*
|
|
||||||
* @param[in] p_handle Identifies peer device for which procedure is requested.
|
|
||||||
* @param[in] p_context Application context being requested. The context information includes length
|
|
||||||
* of the data and a pointer to the data. Note that requesting a 'get'
|
|
||||||
* of application does not need to provide memory, the pointer to data will be
|
|
||||||
* pointing to service data and hence no data movement is involved.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE In case API is called without module initialization and/or
|
|
||||||
* application registration.
|
|
||||||
* @retval NRF_ERROR_NULL If p_handle is NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR If the peer is not identified by the handle provided by the application.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_service_context_get(dm_handle_t const * p_handle,
|
|
||||||
dm_service_context_t * p_context);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for deleting a Service Context for a peer device identified by the 'p_handle' parameter.
|
|
||||||
*
|
|
||||||
* @details This API allows application to delete a Service Context identified for a peer device
|
|
||||||
* identified by the 'p_handle' parameter. If this API returns NRF_SUCCESS,
|
|
||||||
* DM_EVT_SERVICE_CONTEXT_DELETED event is notified to the application.
|
|
||||||
* Event result is notified along with the event and indicates success or failure of this
|
|
||||||
* procedure.
|
|
||||||
*
|
|
||||||
* @param[in] p_handle Identifies peer device for which procedure is requested.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
|
||||||
* application registration.
|
|
||||||
* @retval NRF_ERROR_NULL If p_handle is NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR If the peer is not identified by the handle provided by the application.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_service_context_delete(dm_handle_t const * p_handle);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for setting Application Context for a peer device identified by the 'p_handle' parameter.
|
|
||||||
*
|
|
||||||
* @details This application allows the setting of the application context for the peer device identified by
|
|
||||||
* the 'p_handle'. Application context is stored persistently by the module and can be
|
|
||||||
* requested by the application at any time using the \ref dm_application_context_get
|
|
||||||
* API. Note that this procedure is permitted only for bonded devices. If the
|
|
||||||
* device is not bonded, application context cannot be set. However, it is not mandatory
|
|
||||||
* that the bonded device is connected when requesting this procedure.
|
|
||||||
*
|
|
||||||
* @param[in] p_handle Identifies peer device for which procedure is requested.
|
|
||||||
*
|
|
||||||
* @param[in] p_context Application context being set. The context information includes length of the
|
|
||||||
* data and pointer to the contextual data being set. The memory pointed to by
|
|
||||||
* the data pointer is assumed to be resident when API is being called and
|
|
||||||
* can be freed or reused once the set procedure is complete. Set procedure
|
|
||||||
* completion is notified by the event \ref DM_EVT_APPL_CONTEXT_STORED.
|
|
||||||
* The event result is notified along with the event and indicates success or
|
|
||||||
* failure of this procedure.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
|
||||||
* application registration.
|
|
||||||
* @retval NRF_ERROR_NULL If p_handle and/or p_context is NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR If peer is not identified the handle provided by the application.
|
|
||||||
*
|
|
||||||
* @note The API returns FEATURE_NOT_ENABLED in case DEVICE_MANAGER_APP_CONTEXT_SIZE is set to zero.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_application_context_set(dm_handle_t const * p_handle,
|
|
||||||
dm_application_context_t const * p_context);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for getting Application Context for a peer device identified by the 'p_handle' parameter.
|
|
||||||
*
|
|
||||||
* @details Get Application Context for a peer device identified by the 'p_handle' parameter. If
|
|
||||||
* this API returns NRF_SUCCESS, DM_EVT_APPL_CONTEXT_LOADED event is notified to the
|
|
||||||
* application. Event result notified along with the event indicates success or failure
|
|
||||||
* of this procedure.
|
|
||||||
*
|
|
||||||
* @param[in] p_handle Identifies peer device for which procedure is requested.
|
|
||||||
* @param[in] p_context Application context being requested. The context information includes
|
|
||||||
* length of data and pointer to the contextual data is provided.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
|
||||||
* application registration.
|
|
||||||
* @retval NRF_ERROR_NULL If p_handle and/or p_context is NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR If the peer is not identified by the handle provided by the application.
|
|
||||||
* @retval DM_NO_APP_CONTEXT If no application context was set that can be fetched.
|
|
||||||
*
|
|
||||||
* @note The API returns FEATURE_NOT_ENABLED in case DEVICE_MANAGER_APP_CONTEXT_SIZE is set to
|
|
||||||
* zero.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_application_context_get(dm_handle_t const * p_handle,
|
|
||||||
dm_application_context_t * p_context);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for deleting Application Context for a peer device identified by the 'p_handle' parameter.
|
|
||||||
*
|
|
||||||
* @details Delete Application Context for a peer device identified by the 'p_handle' parameter. If
|
|
||||||
* this API returns NRF_SUCCESS, DM_EVT_APPL_CONTEXT_DELETED event is notified to the
|
|
||||||
* application. The event result notified along with the event and indicates success or failure
|
|
||||||
* of this procedure.
|
|
||||||
*
|
|
||||||
* @param[in] p_handle Identifies peer device for which procedure is requested.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
|
||||||
* application registration.
|
|
||||||
* @retval NRF_ERROR_NULL If the p_handle is NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR If peer is not identified the handle provided by the application.
|
|
||||||
* @retval DM_NO_APP_CONTEXT If no application context was set that can be deleted.
|
|
||||||
*
|
|
||||||
* @note The API returns FEATURE_NOT_ENABLED if the DEVICE_MANAGER_APP_CONTEXT_SIZE is set to zero.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_application_context_delete(dm_handle_t const * p_handle);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup utility_api Utility APIs
|
|
||||||
* @{
|
|
||||||
* @brief This section describes the utility APIs offered by the module.
|
|
||||||
*
|
|
||||||
* @details APIs defined in this section are utility or assisting/helper APIs.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @brief Function for Setting/Copying Application instance to Device Manager handle.
|
|
||||||
*
|
|
||||||
* @param[in] p_appl_instance Application instance to be set.
|
|
||||||
* @param[out] p_handle Device Manager handle for which the instance is to be copied.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
|
||||||
* application registration.
|
|
||||||
* @retval NRF_ERROR_NULL If p_handle and/or p_addr is NULL.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_application_instance_set(dm_application_instance_t const * p_appl_instance,
|
|
||||||
dm_handle_t * p_handle);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for getting a peer's device address.
|
|
||||||
*
|
|
||||||
* @param[in] p_handle Identifies the peer device whose address is requested. Can not be NULL.
|
|
||||||
* @param[out] p_addr Pointer where address is to be copied. Can not be NULL.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
|
||||||
* application registration.
|
|
||||||
* @retval NRF_ERROR_NULL If p_handle and/or p_addr is NULL.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND If the peer could not be identified.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_peer_addr_get(dm_handle_t const * p_handle,
|
|
||||||
ble_gap_addr_t * p_addr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for setting/updating a peer's device address.
|
|
||||||
*
|
|
||||||
* @param[in] p_handle Identifies the peer device whose address is requested to be set/updated.
|
|
||||||
* @param[out] p_addr Address to be set/updated.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
|
||||||
* application registration.
|
|
||||||
* @retval NRF_ERROR_NULL If p_handle and/or p_addr is NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR If the peer is not identified by the handle provided by the application.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM If this procedure is requested while connected to the peer or if the address
|
|
||||||
* type was set to BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE.
|
|
||||||
*
|
|
||||||
* @note Setting or updating a peer's device address is permitted
|
|
||||||
* only for a peer that is bonded and disconnected.
|
|
||||||
* @note Updated address is reflected only after DM_EVT_DEVICE_CONTEXT_STORED is notified to the
|
|
||||||
* application for this bonded device instance. In order to avoid abnormal behaviour, it is
|
|
||||||
* recommended to not invite/initiate connections on the updated address unless this event
|
|
||||||
* has been notified.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_peer_addr_set(dm_handle_t const * p_handle,
|
|
||||||
ble_gap_addr_t const * p_addr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for initializing Device Manager handle.
|
|
||||||
*
|
|
||||||
* @param[in] p_handle Device Manager handle to be initialized.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success.
|
|
||||||
* @retval NRF_ERROR_NULL If p_handle is NULL.
|
|
||||||
*
|
|
||||||
* @note This routine is permitted before initialization of the module.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_handle_initialize(dm_handle_t * p_handle);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for getting distributed keys for a device.
|
|
||||||
*
|
|
||||||
* @param[in] p_handle Device Manager handle identifying the peer.
|
|
||||||
* @param[out] p_key_dist Pointer to distributed keys.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or
|
|
||||||
* application registration.
|
|
||||||
* @retval NRF_ERROR_NULL If the p_handle and/or p_key_dist pointer is NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR If the peer is not identified by the handle provided by the application.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_distributed_keys_get(dm_handle_t const * p_handle,
|
|
||||||
dm_sec_keyset_t * p_key_dist);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for getting the corresponding dm_handle_t based on the connection handle.
|
|
||||||
*
|
|
||||||
* @param[in] conn_handle Connection handle as provided by the SoftDevice.
|
|
||||||
* @param[in,out] p_handle Pointer to the p_handle containg the application instance for the
|
|
||||||
* registered application. If the application instance is valid then
|
|
||||||
* the p_handle will be filled with requested data.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS On success, else an error code indicating reason for failure.
|
|
||||||
* @retval NRF_ERROR_NULL If the p_handle pointer is NULL.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND If no p_handle is found for the provided connection handle.
|
|
||||||
*/
|
|
||||||
ret_code_t dm_handle_get(uint16_t conn_handle, dm_handle_t * p_handle);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
/** @} */
|
|
||||||
/** @} */
|
|
||||||
#endif // DEVICE_MANAGER_H__
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,751 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "id_manager.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "nrf_soc.h"
|
|
||||||
#include "ble_gap.h"
|
|
||||||
#include "ble_conn_state.h"
|
|
||||||
#include "peer_manager_types.h"
|
|
||||||
#include "peer_database.h"
|
|
||||||
#include "nordic_common.h"
|
|
||||||
|
|
||||||
#define IM_MAX_CONN_HANDLES 8
|
|
||||||
#define IM_NO_INVALID_CONN_HANDLES 0xFF
|
|
||||||
#define MAX_REGISTRANTS 3
|
|
||||||
#define WHITELIST_MAX_COUNT MAX(BLE_GAP_WHITELIST_ADDR_MAX_COUNT, \
|
|
||||||
BLE_GAP_WHITELIST_IRK_MAX_COUNT)
|
|
||||||
#define IM_ADDR_CLEARTEXT_LENGTH 3
|
|
||||||
#define IM_ADDR_CIPHERTEXT_LENGTH 3
|
|
||||||
|
|
||||||
#define MODULE_INITIALIZED (m_im.n_registrants > 0)
|
|
||||||
|
|
||||||
#define VERIFY_MODULE_INITIALIZED() \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if (!MODULE_INITIALIZED) \
|
|
||||||
{ \
|
|
||||||
return NRF_ERROR_INVALID_STATE; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define VERIFY_PARAM_NOT_NULL(param) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if (param == NULL) \
|
|
||||||
{ \
|
|
||||||
return NRF_ERROR_NULL; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
pm_peer_id_t peer_id;
|
|
||||||
uint16_t conn_handle;
|
|
||||||
ble_gap_addr_t peer_address;
|
|
||||||
} im_connection_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
im_evt_handler_t evt_handlers[MAX_REGISTRANTS];
|
|
||||||
uint8_t n_registrants;
|
|
||||||
im_connection_t connections[8];
|
|
||||||
pm_peer_id_t whitelist_peer_ids[BLE_GAP_WHITELIST_IRK_MAX_COUNT];
|
|
||||||
ble_gap_irk_t whitelist_irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT];
|
|
||||||
ble_gap_addr_t whitelist_addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
|
|
||||||
uint8_t n_whitelist_peer_ids;
|
|
||||||
ble_conn_state_user_flag_id_t conn_state_user_flag_id;
|
|
||||||
} im_t;
|
|
||||||
|
|
||||||
static im_t m_im = {.n_registrants = 0};
|
|
||||||
|
|
||||||
static void internal_state_reset()
|
|
||||||
{
|
|
||||||
memset(&m_im, 0, sizeof(im_t));
|
|
||||||
m_im.n_registrants = 0;
|
|
||||||
m_im.n_whitelist_peer_ids = 0;
|
|
||||||
m_im.conn_state_user_flag_id = BLE_CONN_STATE_USER_FLAG_INVALID;
|
|
||||||
for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++)
|
|
||||||
{
|
|
||||||
m_im.connections[i].conn_handle = BLE_CONN_HANDLE_INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for sending an event to all registered event handlers.
|
|
||||||
*
|
|
||||||
* @param[in] p_event The event to distribute.
|
|
||||||
*/
|
|
||||||
static void evt_send(im_evt_t * p_event)
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < m_im.n_registrants; i++)
|
|
||||||
{
|
|
||||||
m_im.evt_handlers[i](p_event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Function finding a free position in m_im.connections.
|
|
||||||
*
|
|
||||||
* @detail All connection handles in the m_im.connections array are checked against the connection
|
|
||||||
* state module. The index of the first one that is not a connection handle for a current
|
|
||||||
* connection is returned. This position in the array can safely be used for a new connection.
|
|
||||||
*
|
|
||||||
* @return Either the index of a free position in the array or IM_NO_INVALID_CONN_HANDLES if no free
|
|
||||||
position exists.
|
|
||||||
*/
|
|
||||||
uint8_t get_free_connection()
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++)
|
|
||||||
{
|
|
||||||
// Query the connection state module to check if the connection handle does not belong to a
|
|
||||||
// valid connection.
|
|
||||||
if (!ble_conn_state_user_flag_get(m_im.connections[i].conn_handle, m_im.conn_state_user_flag_id))
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If all connection handles belong to a valid connection, return IM_NO_INVALID_CONN_HANDLES.
|
|
||||||
return IM_NO_INVALID_CONN_HANDLES;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function finding a particular connection handle m_im.connections.
|
|
||||||
*
|
|
||||||
* @param[in] conn_handle The handle to find.
|
|
||||||
*
|
|
||||||
* @return Either the index of the conn_handle in the array or IM_NO_INVALID_CONN_HANDLES if the
|
|
||||||
* handle was not found.
|
|
||||||
*/
|
|
||||||
uint8_t get_connection_by_conn_handle(uint16_t conn_handle)
|
|
||||||
{
|
|
||||||
if (ble_conn_state_user_flag_get(conn_handle, m_im.conn_state_user_flag_id))
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++)
|
|
||||||
{
|
|
||||||
if (m_im.connections[i].conn_handle == conn_handle)
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If all connection handles belong to a valid connection, return IM_NO_INVALID_CONN_HANDLES.
|
|
||||||
return IM_NO_INVALID_CONN_HANDLES;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for registering a new connection instance.
|
|
||||||
*
|
|
||||||
* @param[in] conn_handle The handle of the new connection.
|
|
||||||
* @param[in] p_ble_addr The address used to connect.
|
|
||||||
*
|
|
||||||
* @return Either the index of the new connection in the array or IM_NO_INVALID_CONN_HANDLES if no
|
|
||||||
* free position exists.
|
|
||||||
*/
|
|
||||||
uint8_t new_connection(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr)
|
|
||||||
{
|
|
||||||
uint8_t conn_index = IM_NO_INVALID_CONN_HANDLES;
|
|
||||||
|
|
||||||
if ((p_ble_addr != NULL) && (conn_handle != BLE_CONN_HANDLE_INVALID))
|
|
||||||
{
|
|
||||||
ble_conn_state_user_flag_set(conn_handle, m_im.conn_state_user_flag_id, true);
|
|
||||||
|
|
||||||
conn_index = get_connection_by_conn_handle(conn_handle);
|
|
||||||
if (conn_index == IM_NO_INVALID_CONN_HANDLES)
|
|
||||||
{
|
|
||||||
conn_index = get_free_connection();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (conn_index != IM_NO_INVALID_CONN_HANDLES)
|
|
||||||
{
|
|
||||||
m_im.connections[conn_index].conn_handle = conn_handle;
|
|
||||||
m_im.connections[conn_index].peer_id = PM_PEER_ID_INVALID;
|
|
||||||
m_im.connections[conn_index].peer_address = *p_ble_addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return conn_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function checking the validity of an IRK
|
|
||||||
*
|
|
||||||
* @detail An all-zero IRK is not valid. This function will check if a given IRK is valid.
|
|
||||||
*
|
|
||||||
* @param[in] irk The IRK for which the validity is going to be checked.
|
|
||||||
*
|
|
||||||
* @retval true The IRK is valid.
|
|
||||||
* @retval false The IRK is invalid.
|
|
||||||
*/
|
|
||||||
bool is_valid_irk(ble_gap_irk_t const * irk)
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < BLE_GAP_SEC_KEY_LEN; i++)
|
|
||||||
{
|
|
||||||
if (irk->irk[i] != 0)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for comparing two addresses to determine if they are identical
|
|
||||||
*
|
|
||||||
* @note The address type need to be identical, as well as every bit in the address itself.
|
|
||||||
*
|
|
||||||
* @param[in] p_addr1 The first address to be compared.
|
|
||||||
* @param[in] p_addr2 The second address to be compared.
|
|
||||||
*
|
|
||||||
* @retval true The addresses are identical.
|
|
||||||
* @retval false The addresses are not identical.
|
|
||||||
*/
|
|
||||||
bool addr_compare(ble_gap_addr_t const * p_addr1, ble_gap_addr_t const * p_addr2)
|
|
||||||
{
|
|
||||||
if ((p_addr1 == NULL) || (p_addr2 == NULL))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the addr type is identical, return false if it is not
|
|
||||||
if (p_addr1->addr_type != p_addr2->addr_type)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Check if the addr bytes are is identical
|
|
||||||
return (memcmp(p_addr1->addr, p_addr2->addr, BLE_GAP_ADDR_LEN) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void im_ble_evt_handler(ble_evt_t * ble_evt)
|
|
||||||
{
|
|
||||||
ret_code_t err_code;
|
|
||||||
switch (ble_evt->header.evt_id)
|
|
||||||
{
|
|
||||||
case BLE_GAP_EVT_CONNECTED:
|
|
||||||
{
|
|
||||||
pm_peer_id_t bonded_matching_peer_id = PM_PEER_ID_INVALID;
|
|
||||||
|
|
||||||
if (ble_evt->evt.gap_evt.params.connected.irk_match == 1)
|
|
||||||
{
|
|
||||||
// The peer was matched using a whitelist.
|
|
||||||
bonded_matching_peer_id
|
|
||||||
= m_im.whitelist_peer_ids[ble_evt->evt.gap_evt.params.connected.irk_match_idx];
|
|
||||||
}
|
|
||||||
else if ( ble_evt->evt.gap_evt.params.connected.peer_addr.addr_type
|
|
||||||
!= BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE)
|
|
||||||
{
|
|
||||||
/* Search the database for bonding data matching the one that triggered the event.
|
|
||||||
* Public and static addresses can be matched on address alone, while resolvable
|
|
||||||
* random addresses can be resolved agains known IRKs. Non-resolvable random addresses
|
|
||||||
* are never matching because they are not longterm form of identification.
|
|
||||||
*/
|
|
||||||
pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID);
|
|
||||||
while ( (compared_peer_id != PM_PEER_ID_INVALID)
|
|
||||||
&& (bonded_matching_peer_id == PM_PEER_ID_INVALID))
|
|
||||||
{
|
|
||||||
pm_peer_data_flash_t compared_data;
|
|
||||||
switch (ble_evt->evt.gap_evt.params.connected.peer_addr.addr_type)
|
|
||||||
{
|
|
||||||
case BLE_GAP_ADDR_TYPE_PUBLIC:
|
|
||||||
/* fall-through */
|
|
||||||
case BLE_GAP_ADDR_TYPE_RANDOM_STATIC:
|
|
||||||
err_code = pdb_read_buf_get(compared_peer_id,
|
|
||||||
PM_PEER_DATA_ID_BONDING,
|
|
||||||
&compared_data,
|
|
||||||
NULL);
|
|
||||||
if ((err_code == NRF_SUCCESS) &&
|
|
||||||
addr_compare(&ble_evt->evt.gap_evt.params.connected.peer_addr,
|
|
||||||
&compared_data.data.p_bonding_data->peer_id.id_addr_info)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
bonded_matching_peer_id = compared_peer_id;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE:
|
|
||||||
err_code = pdb_read_buf_get(compared_peer_id,
|
|
||||||
PM_PEER_DATA_ID_BONDING,
|
|
||||||
&compared_data,
|
|
||||||
NULL);
|
|
||||||
if (err_code == NRF_SUCCESS &&
|
|
||||||
im_address_resolve(&ble_evt->evt.gap_evt.params.connected.peer_addr,
|
|
||||||
&compared_data.data.p_bonding_data->peer_id.id_info)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
bonded_matching_peer_id = compared_peer_id;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE:
|
|
||||||
// Should not happen.
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
compared_peer_id = pdb_next_peer_id_get(compared_peer_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
new_connection(ble_evt->evt.gap_evt.conn_handle, &ble_evt->evt.gap_evt.params.connected.peer_addr);
|
|
||||||
|
|
||||||
if (bonded_matching_peer_id != PM_PEER_ID_INVALID)
|
|
||||||
{
|
|
||||||
im_new_peer_id(ble_evt->evt.gap_evt.conn_handle, bonded_matching_peer_id);
|
|
||||||
|
|
||||||
// Send a bonded peer event
|
|
||||||
im_evt_t im_evt;
|
|
||||||
im_evt.conn_handle = ble_evt->evt.gap_evt.conn_handle;
|
|
||||||
im_evt.evt_id = IM_EVT_BONDED_PEER_CONNECTED;
|
|
||||||
evt_send(&im_evt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to compare two sets of bonding data to check if they belong to the same device.
|
|
||||||
* @note Invalid irks will never match even though they are identical.
|
|
||||||
*
|
|
||||||
* @param[in] p_bonding_data1 First bonding data for comparison
|
|
||||||
* @param[in] p_bonding_data2 Second bonding data for comparison
|
|
||||||
*
|
|
||||||
* @return True if the input matches, false if it does not.
|
|
||||||
*/
|
|
||||||
bool is_duplicate_bonding_data(pm_peer_data_bonding_t const * p_bonding_data1,
|
|
||||||
pm_peer_data_bonding_t const * p_bonding_data2)
|
|
||||||
{
|
|
||||||
bool valid_irk = is_valid_irk(&p_bonding_data1->peer_id.id_info);
|
|
||||||
bool duplicate_irk = valid_irk &&
|
|
||||||
(memcmp(p_bonding_data1->peer_id.id_info.irk,
|
|
||||||
p_bonding_data2->peer_id.id_info.irk,
|
|
||||||
BLE_GAP_SEC_KEY_LEN) == 0
|
|
||||||
);
|
|
||||||
bool duplicate_addr = addr_compare(&p_bonding_data1->peer_id.id_addr_info,
|
|
||||||
&p_bonding_data2->peer_id.id_addr_info
|
|
||||||
);
|
|
||||||
return duplicate_irk || duplicate_addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Event handler for events from the peer_database module.
|
|
||||||
*
|
|
||||||
* @param[in] p_event The event that has happend with peer id and flags.
|
|
||||||
*/
|
|
||||||
static void pdb_evt_handler(pdb_evt_t const * p_event)
|
|
||||||
{
|
|
||||||
ret_code_t err_code;
|
|
||||||
if ((p_event != NULL) && (p_event->evt_id == PDB_EVT_WRITE_BUF_STORED))
|
|
||||||
{
|
|
||||||
// If new data about peer id has been stored it is compared to other peers peer ids in
|
|
||||||
// search of duplicates.
|
|
||||||
if (p_event->data_id == PM_PEER_DATA_ID_BONDING)
|
|
||||||
{
|
|
||||||
pm_peer_data_flash_t written_data;
|
|
||||||
err_code = pdb_read_buf_get(p_event->peer_id, PM_PEER_DATA_ID_BONDING, &written_data, NULL);
|
|
||||||
if (err_code == NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID);
|
|
||||||
while (compared_peer_id != PM_PEER_ID_INVALID)
|
|
||||||
{
|
|
||||||
pm_peer_data_flash_t compared_data;
|
|
||||||
err_code = pdb_read_buf_get(compared_peer_id,
|
|
||||||
PM_PEER_DATA_ID_BONDING,
|
|
||||||
&compared_data,
|
|
||||||
NULL);
|
|
||||||
if ( err_code == NRF_SUCCESS &&
|
|
||||||
p_event->peer_id != compared_peer_id &&
|
|
||||||
is_duplicate_bonding_data(written_data.data.p_bonding_data,
|
|
||||||
compared_data.data.p_bonding_data)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
im_evt_t im_evt;
|
|
||||||
im_evt.conn_handle = im_conn_handle_get(p_event->peer_id);
|
|
||||||
im_evt.evt_id = IM_EVT_DUPLICATE_ID;
|
|
||||||
im_evt.params.duplicate_id.peer_id_1 = p_event->peer_id;
|
|
||||||
im_evt.params.duplicate_id.peer_id_2 = compared_peer_id;
|
|
||||||
evt_send(&im_evt);
|
|
||||||
}
|
|
||||||
compared_peer_id = pdb_next_peer_id_get(compared_peer_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t im_register(im_evt_handler_t evt_handler)
|
|
||||||
{
|
|
||||||
VERIFY_PARAM_NOT_NULL(evt_handler);
|
|
||||||
ret_code_t err_code = NRF_SUCCESS;
|
|
||||||
|
|
||||||
if (!MODULE_INITIALIZED)
|
|
||||||
{
|
|
||||||
internal_state_reset();
|
|
||||||
m_im.conn_state_user_flag_id = ble_conn_state_user_flag_acquire();
|
|
||||||
if (m_im.conn_state_user_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID)
|
|
||||||
{
|
|
||||||
err_code = NRF_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err_code = pdb_register(pdb_evt_handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (err_code == NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
if ((m_im.n_registrants < MAX_REGISTRANTS))
|
|
||||||
{
|
|
||||||
m_im.evt_handlers[m_im.n_registrants++] = evt_handler;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err_code = NRF_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pm_peer_id_t im_peer_id_get_by_conn_handle(uint16_t conn_handle)
|
|
||||||
{
|
|
||||||
uint8_t conn_index = get_connection_by_conn_handle(conn_handle);
|
|
||||||
|
|
||||||
if (MODULE_INITIALIZED && (conn_index != IM_NO_INVALID_CONN_HANDLES))
|
|
||||||
{
|
|
||||||
return m_im.connections[conn_index].peer_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PM_PEER_ID_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t im_ble_addr_get(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr)
|
|
||||||
{
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
VERIFY_PARAM_NOT_NULL(p_ble_addr);
|
|
||||||
|
|
||||||
uint8_t conn_index = get_connection_by_conn_handle(conn_handle);
|
|
||||||
if (conn_index != IM_NO_INVALID_CONN_HANDLES)
|
|
||||||
{
|
|
||||||
*p_ble_addr = m_im.connections[conn_index].peer_address;
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NRF_ERROR_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for comparing two master ids
|
|
||||||
* @note Two invalid master IDs will not match.
|
|
||||||
*
|
|
||||||
* @param[in] p_master_id1 First master id for comparison
|
|
||||||
* @param[in] p_master_id2 Second master id for comparison
|
|
||||||
*
|
|
||||||
* @return True if the input matches, false if it does not.
|
|
||||||
*/
|
|
||||||
bool master_id_compare(ble_gap_master_id_t const * p_master_id1,
|
|
||||||
ble_gap_master_id_t const * p_master_id2)
|
|
||||||
{
|
|
||||||
if(!im_master_id_is_valid(p_master_id1))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (p_master_id1->ediv != p_master_id2->ediv)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return (memcmp(p_master_id1->rand, p_master_id2->rand, BLE_GAP_SEC_RAND_LEN) == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pm_peer_id_t im_peer_id_get_by_master_id(ble_gap_master_id_t * p_master_id)
|
|
||||||
{
|
|
||||||
ret_code_t err_code;
|
|
||||||
// For each stored peer, check if the master_id match p_master_id
|
|
||||||
pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID);
|
|
||||||
while (compared_peer_id != PM_PEER_ID_INVALID)
|
|
||||||
{
|
|
||||||
pm_peer_data_flash_t compared_data;
|
|
||||||
ble_gap_master_id_t const * p_compared_master_id;
|
|
||||||
|
|
||||||
err_code = pdb_read_buf_get(compared_peer_id, PM_PEER_DATA_ID_BONDING, &compared_data, NULL);
|
|
||||||
if (err_code == NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
p_compared_master_id = &compared_data.data.p_bonding_data->own_ltk.master_id;
|
|
||||||
if (compared_data.data.p_bonding_data->own_role == BLE_GAP_ROLE_CENTRAL)
|
|
||||||
{
|
|
||||||
p_compared_master_id = &compared_data.data.p_bonding_data->peer_ltk.master_id;
|
|
||||||
}
|
|
||||||
if (master_id_compare(p_master_id, p_compared_master_id))
|
|
||||||
{
|
|
||||||
// If a matching master_id is found return the peer_id
|
|
||||||
return compared_peer_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
compared_peer_id = pdb_next_peer_id_get(compared_peer_id);
|
|
||||||
}
|
|
||||||
// If no matching master_id is found return the PM_PEER_ID_INVALID
|
|
||||||
return PM_PEER_ID_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pm_peer_id_t im_peer_id_get_by_irk_match_idx(uint8_t irk_match_idx)
|
|
||||||
{
|
|
||||||
// Verify that the requested idx is within the list
|
|
||||||
if (irk_match_idx < m_im.n_whitelist_peer_ids)
|
|
||||||
{
|
|
||||||
// Return the peer_id from the white list
|
|
||||||
return m_im.whitelist_peer_ids[irk_match_idx];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Return PM_PEER_ID_INVALID to indicate that there was no peer with the requested idx
|
|
||||||
return PM_PEER_ID_INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t im_conn_handle_get(pm_peer_id_t peer_id)
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++)
|
|
||||||
{
|
|
||||||
if (peer_id == m_im.connections[i].peer_id)
|
|
||||||
{
|
|
||||||
return m_im.connections[i].conn_handle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return BLE_CONN_HANDLE_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool im_master_id_is_valid(ble_gap_master_id_t const * p_master_id)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (p_master_id->ediv != 0)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for (uint32_t i = 0; i < BLE_GAP_SEC_RAND_LEN; i++)
|
|
||||||
{
|
|
||||||
if (p_master_id->rand[i] != 0)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void im_new_peer_id(uint16_t conn_handle, pm_peer_id_t peer_id)
|
|
||||||
{
|
|
||||||
uint8_t conn_index = get_connection_by_conn_handle(conn_handle);
|
|
||||||
if (conn_index != IM_NO_INVALID_CONN_HANDLES)
|
|
||||||
{
|
|
||||||
m_im.connections[conn_index].peer_id = peer_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t im_wlist_create(pm_peer_id_t * p_peer_ids,
|
|
||||||
uint8_t n_peer_ids,
|
|
||||||
ble_gap_whitelist_t * p_whitelist)
|
|
||||||
{
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
VERIFY_PARAM_NOT_NULL(p_whitelist);
|
|
||||||
ret_code_t err_code;
|
|
||||||
p_whitelist->addr_count = 0;
|
|
||||||
p_whitelist->irk_count = 0;
|
|
||||||
m_im.n_whitelist_peer_ids = 0;
|
|
||||||
for (uint32_t peer_index = 0; peer_index < n_peer_ids; peer_index++)
|
|
||||||
{
|
|
||||||
bool peer_connected = false;
|
|
||||||
for (uint32_t conn_index = 0; conn_index < IM_MAX_CONN_HANDLES; conn_index++)
|
|
||||||
{
|
|
||||||
if (p_peer_ids[peer_index] == m_im.connections[conn_index].peer_id &&
|
|
||||||
ble_conn_state_user_flag_get(m_im.connections[conn_index].conn_handle, m_im.conn_state_user_flag_id)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
peer_connected = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!peer_connected)
|
|
||||||
{
|
|
||||||
pm_peer_data_flash_t peer_data;
|
|
||||||
err_code = pdb_read_buf_get(p_peer_ids[peer_index], PM_PEER_DATA_ID_BONDING, &peer_data, NULL);
|
|
||||||
if (err_code == NRF_ERROR_INVALID_PARAM || err_code == NRF_ERROR_NOT_FOUND)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
if (p_whitelist->pp_addrs != NULL &&
|
|
||||||
peer_data.data.p_bonding_data->peer_id.id_addr_info.addr_type
|
|
||||||
!= BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE &&
|
|
||||||
peer_data.data.p_bonding_data->peer_id.id_addr_info.addr_type
|
|
||||||
!= BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE
|
|
||||||
)
|
|
||||||
{
|
|
||||||
memcpy(m_im.whitelist_addrs[peer_index].addr,
|
|
||||||
peer_data.data.p_bonding_data->peer_id.id_addr_info.addr,
|
|
||||||
BLE_GAP_ADDR_LEN
|
|
||||||
);
|
|
||||||
m_im.whitelist_addrs[peer_index].addr_type =
|
|
||||||
peer_data.data.p_bonding_data->peer_id.id_addr_info.addr_type;
|
|
||||||
p_whitelist->pp_addrs[peer_index] = &m_im.whitelist_addrs[peer_index];
|
|
||||||
p_whitelist->addr_count++;
|
|
||||||
}
|
|
||||||
if (p_whitelist->pp_irks != NULL &&
|
|
||||||
is_valid_irk(&(peer_data.data.p_bonding_data->peer_id.id_info))
|
|
||||||
)
|
|
||||||
{
|
|
||||||
memcpy(m_im.whitelist_irks[peer_index].irk,
|
|
||||||
peer_data.data.p_bonding_data->peer_id.id_info.irk,
|
|
||||||
BLE_GAP_SEC_KEY_LEN
|
|
||||||
);
|
|
||||||
p_whitelist->pp_irks[peer_index] = &m_im.whitelist_irks[peer_index];
|
|
||||||
p_whitelist->irk_count++;
|
|
||||||
m_im.whitelist_peer_ids[peer_index] = p_peer_ids[peer_index];
|
|
||||||
m_im.n_whitelist_peer_ids++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t im_wlist_set(ble_gap_whitelist_t * p_whitelist)
|
|
||||||
{
|
|
||||||
pm_peer_id_t new_whitelist_peer_ids[BLE_GAP_WHITELIST_IRK_MAX_COUNT];
|
|
||||||
uint32_t n_new_whitelist_peer_ids = 0;
|
|
||||||
VERIFY_PARAM_NOT_NULL(p_whitelist);
|
|
||||||
for (uint32_t i = 0; i < BLE_GAP_WHITELIST_IRK_MAX_COUNT; i++)
|
|
||||||
{
|
|
||||||
new_whitelist_peer_ids[i] = PM_PEER_ID_INVALID;
|
|
||||||
}
|
|
||||||
pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID);
|
|
||||||
while (compared_peer_id != PM_PEER_ID_INVALID)
|
|
||||||
{
|
|
||||||
pm_peer_data_flash_t compared_data;
|
|
||||||
pdb_read_buf_get(compared_peer_id, PM_PEER_DATA_ID_BONDING, &compared_data, NULL);
|
|
||||||
for (uint32_t i = 0; i < p_whitelist->irk_count; i++)
|
|
||||||
{
|
|
||||||
bool valid_irk = is_valid_irk(&compared_data.data.p_bonding_data->peer_id.id_info);
|
|
||||||
bool duplicate_irk = valid_irk &&
|
|
||||||
(memcmp(p_whitelist->pp_irks[i]->irk,
|
|
||||||
compared_data.data.p_bonding_data->peer_id.id_info.irk,
|
|
||||||
BLE_GAP_SEC_KEY_LEN) == 0
|
|
||||||
);
|
|
||||||
if (duplicate_irk)
|
|
||||||
{
|
|
||||||
new_whitelist_peer_ids[i] = compared_peer_id;
|
|
||||||
n_new_whitelist_peer_ids++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
compared_peer_id = pdb_next_peer_id_get(compared_peer_id);
|
|
||||||
}
|
|
||||||
if (n_new_whitelist_peer_ids != p_whitelist->irk_count)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NOT_FOUND;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < n_new_whitelist_peer_ids; i++)
|
|
||||||
{
|
|
||||||
m_im.whitelist_peer_ids[i] = new_whitelist_peer_ids[i];
|
|
||||||
}
|
|
||||||
m_im.n_whitelist_peer_ids = n_new_whitelist_peer_ids;
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for calculating the ah() hash function described in Bluetooth core specification
|
|
||||||
* 4.2 section 3.H.2.2.2.
|
|
||||||
*
|
|
||||||
* @detail BLE uses a hash function to calculate the first half of a resolvable address
|
|
||||||
* from the second half of the address and an irk. This function will use the ECB
|
|
||||||
* periferal to hash these data acording to the Bluetooth core specification.
|
|
||||||
*
|
|
||||||
* @note The ECB expect little endian input and output.
|
|
||||||
* This function expect big endian and will reverse the data as necessary.
|
|
||||||
*
|
|
||||||
* @param[in] p_k The key used in the hash function.
|
|
||||||
* For address resolution this is should be the irk.
|
|
||||||
* The array must have a length of 16.
|
|
||||||
* @param[in] p_r The rand used in the hash function. For generating a new address
|
|
||||||
* this would be a random number. For resolving a resolvable address
|
|
||||||
* this would be the last half of the address being resolved.
|
|
||||||
* The array must have a length of 3.
|
|
||||||
* @param[out] p_local_hash The result of the hash operation. For address resolution this
|
|
||||||
* will match the first half of the address being resolved if and only
|
|
||||||
* if the irk used in the hash function is the same one used to generate
|
|
||||||
* the address.
|
|
||||||
* The array must have a length of 16.
|
|
||||||
*/
|
|
||||||
void ah(uint8_t const * p_k, uint8_t const * p_r, uint8_t * p_local_hash)
|
|
||||||
{
|
|
||||||
nrf_ecb_hal_data_t ecb_hal_data;
|
|
||||||
for (uint32_t i = 0; i < SOC_ECB_KEY_LENGTH; i++)
|
|
||||||
{
|
|
||||||
ecb_hal_data.key[i] = p_k[SOC_ECB_KEY_LENGTH - 1 - i];
|
|
||||||
}
|
|
||||||
memset(ecb_hal_data.cleartext, 0, SOC_ECB_KEY_LENGTH - IM_ADDR_CLEARTEXT_LENGTH);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < IM_ADDR_CLEARTEXT_LENGTH; i++)
|
|
||||||
{
|
|
||||||
ecb_hal_data.cleartext[SOC_ECB_KEY_LENGTH - 1 - i] = p_r[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
sd_ecb_block_encrypt(&ecb_hal_data);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < IM_ADDR_CIPHERTEXT_LENGTH; i++)
|
|
||||||
{
|
|
||||||
p_local_hash[i] = ecb_hal_data.ciphertext[SOC_ECB_KEY_LENGTH - 1 - i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool im_address_resolve(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk)
|
|
||||||
{
|
|
||||||
if (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
uint8_t hash[IM_ADDR_CIPHERTEXT_LENGTH];
|
|
||||||
uint8_t local_hash[IM_ADDR_CIPHERTEXT_LENGTH];
|
|
||||||
uint8_t prand[IM_ADDR_CLEARTEXT_LENGTH];
|
|
||||||
memcpy(hash, p_addr->addr, IM_ADDR_CIPHERTEXT_LENGTH);
|
|
||||||
memcpy(prand, &p_addr->addr[IM_ADDR_CIPHERTEXT_LENGTH], IM_ADDR_CLEARTEXT_LENGTH);
|
|
||||||
ah(p_irk->irk, prand, local_hash);
|
|
||||||
|
|
||||||
return (memcmp(hash, local_hash, IM_ADDR_CIPHERTEXT_LENGTH) == 0);
|
|
||||||
}
|
|
|
@ -1,266 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PEER_ID_MANAGER_H__
|
|
||||||
#define PEER_ID_MANAGER_H__
|
|
||||||
|
|
||||||
#include "stdint.h"
|
|
||||||
#include "sdk_errors.h"
|
|
||||||
#include "nrf_ble.h"
|
|
||||||
#include "ble_gap.h"
|
|
||||||
#include "peer_manager_types.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup id_manager ID Manager
|
|
||||||
* @ingroup peer_manager
|
|
||||||
* @{
|
|
||||||
* @brief An internal module of @ref peer_manager. A module for keeping track of peer identities
|
|
||||||
* (IRK and peer address).
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Events that can come from the ID Manager module.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
IM_EVT_DUPLICATE_ID, /**< The ID Manager module has detected that two stored peers represent the same peer. */
|
|
||||||
IM_EVT_BONDED_PEER_CONNECTED, /**< A connected peer has been identified as one of the bonded peers. This can happen immediately on connection, or at a later time. */
|
|
||||||
} im_evt_id_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
im_evt_id_t evt_id;
|
|
||||||
uint16_t conn_handle;
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
pm_peer_id_t peer_id_1;
|
|
||||||
pm_peer_id_t peer_id_2;
|
|
||||||
} duplicate_id;
|
|
||||||
} params;
|
|
||||||
} im_evt_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Event handler for events from the ID Manager module.
|
|
||||||
*
|
|
||||||
* @param[in] p_event The event that has happened.
|
|
||||||
*/
|
|
||||||
typedef void (*im_evt_handler_t)(im_evt_t const * p_event);
|
|
||||||
|
|
||||||
/**@brief Function for registering for events from the ID Manager module.
|
|
||||||
*
|
|
||||||
* @note This will also initialize the module if needed.
|
|
||||||
*
|
|
||||||
* @param[in] evt_handler Callback for events from the ID Manager module.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Registration was successful.
|
|
||||||
* @retval NRF_ERROR_NO_MEM No more registrations possible.
|
|
||||||
* @retval NRF_ERROR_NULL evt_handler was NULL.
|
|
||||||
*/
|
|
||||||
ret_code_t im_register(im_evt_handler_t evt_handler);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for dispatching SoftDevice events to the ID Manager module.
|
|
||||||
*
|
|
||||||
* @param[in] p_ble_evt The SoftDevice event.
|
|
||||||
*/
|
|
||||||
void im_ble_evt_handler(ble_evt_t * p_ble_evt);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for getting the corresponding peer ID from a connection handle.
|
|
||||||
*
|
|
||||||
* @param[in] conn_handle The connection handle.
|
|
||||||
*
|
|
||||||
* @return The corresponding peer ID, or @ref PM_PEER_ID_INVALID if none could be resolved.
|
|
||||||
*/
|
|
||||||
pm_peer_id_t im_peer_id_get_by_conn_handle(uint16_t conn_handle);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for getting the corresponding peer ID from a master ID (EDIV and rand).
|
|
||||||
*
|
|
||||||
* @param[in] p_master_id The master ID.
|
|
||||||
*
|
|
||||||
* @return The corresponding peer ID, or @ref PM_PEER_ID_INVALID if none could be resolved.
|
|
||||||
*/
|
|
||||||
pm_peer_id_t im_peer_id_get_by_master_id(ble_gap_master_id_t * p_master_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for getting the corresponding peer ID from an IRK match index, see @ref
|
|
||||||
* ble_gap_evt_connected_t.
|
|
||||||
*
|
|
||||||
* @param[in] irk_match_idx The IRK match index.
|
|
||||||
*
|
|
||||||
* @return The corresponding peer ID, or @ref PM_PEER_ID_INVALID if none could be resolved.
|
|
||||||
*/
|
|
||||||
pm_peer_id_t im_peer_id_get_by_irk_match_idx(uint8_t irk_match_idx);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for getting the corresponding connection handle from a peer ID.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id The peer ID.
|
|
||||||
*
|
|
||||||
* @return The corresponding connection handle, or @ref BLE_CONN_HANDLE_INVALID if none could be
|
|
||||||
* resolved.
|
|
||||||
*/
|
|
||||||
uint16_t im_conn_handle_get(pm_peer_id_t peer_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for getting the BLE address used by the peer when connecting.
|
|
||||||
*
|
|
||||||
* @param[in] conn_handle The connection handle.
|
|
||||||
* @param[out] p_ble_addr The BLE address used by the peer when the connection specified by
|
|
||||||
* conn_handle was established.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS The address was found and copied.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module not initialized.
|
|
||||||
* @retval BLE_ERROR_CONN_HANDLE_INVALID conn_handle does not refer to an active connection.
|
|
||||||
* @retval NRF_ERROR_NULL p_ble_addr was NULL.
|
|
||||||
*/
|
|
||||||
ret_code_t im_ble_addr_get(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for checking whether a master ID is valid or invalid
|
|
||||||
*
|
|
||||||
* @param[in] p_master_id The master ID.
|
|
||||||
*
|
|
||||||
* @retval true The master id is valid.
|
|
||||||
* @retval true The master id is invalid (i.e. all zeros).
|
|
||||||
*/
|
|
||||||
bool im_master_id_is_valid(ble_gap_master_id_t const * p_master_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for reporting that a new peer ID has been allocated for a specified connection.
|
|
||||||
*
|
|
||||||
* @param[in] conn_handle The connection.
|
|
||||||
* @param[in] peer_id The new peer ID.
|
|
||||||
*/
|
|
||||||
void im_new_peer_id(uint16_t conn_handle, pm_peer_id_t peer_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for informing this module of what whitelist will be used.
|
|
||||||
*
|
|
||||||
* @details This function is meant to be used when the app wants to use a custom whitelist.
|
|
||||||
* When using peer manager, this function must be used if a custom whitelist is used.
|
|
||||||
*
|
|
||||||
* @note When using a whitelist, always use the whitelist created/set by the most recent
|
|
||||||
* call to @ref im_wlist_create or to this function, whichever happened most recently.
|
|
||||||
* @note Do not call this function while scanning with another whitelist.
|
|
||||||
* @note Do not add any irks to the whitelist that are not present in the bonding data of a peer in
|
|
||||||
* the peer database.
|
|
||||||
*
|
|
||||||
* @param[in] p_whitelist The whitelist.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Whitelist successfully set.
|
|
||||||
* @retval NRF_ERROR_NULL p_whitelist was NULL.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND One or more of the whitelists irks was not found in the peer_database.
|
|
||||||
*/
|
|
||||||
ret_code_t im_wlist_set(ble_gap_whitelist_t * p_whitelist);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for constructing a whitelist for use when advertising.
|
|
||||||
*
|
|
||||||
* @note When advertising with whitelist, always use the whitelist created/set by the most recent
|
|
||||||
* call to this function or to @ref im_wlist_set, whichever happened most recently.
|
|
||||||
* @note Do not call this function while advertising with another whitelist.
|
|
||||||
*
|
|
||||||
* @param[in] p_peer_ids The ids of the peers to be added to the whitelist.
|
|
||||||
* @param[in] n_peer_ids The number of peer ids in p_peer_ids.
|
|
||||||
* @param[in,out] p_whitelist The constructed whitelist. Note that p_adv_whitelist->pp_addrs
|
|
||||||
* must be NULL or point to an array with size @ref
|
|
||||||
* BLE_GAP_WHITELIST_ADDR_MAX_COUNT and p_adv_whitelist->pp_irks
|
|
||||||
* must be NULL or point to an array with size @ref
|
|
||||||
* BLE_GAP_WHITELIST_IRK_MAX_COUNT.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Whitelist successfully created.
|
|
||||||
* @retval NRF_ERROR_NULL p_whitelist was NULL.
|
|
||||||
*/
|
|
||||||
ret_code_t im_wlist_create(pm_peer_id_t * p_peer_ids,
|
|
||||||
uint8_t n_peer_ids,
|
|
||||||
ble_gap_whitelist_t * p_whitelist);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for resolving a resolvable address with an identity resolution key (IRK).
|
|
||||||
*
|
|
||||||
* @details This function will use the ECB peripheral to resolve a resolvable address.
|
|
||||||
* This can be used to resolve the identity of a device distributing a random
|
|
||||||
* resolvable address based on any IRKs you have received earlier. If an address is
|
|
||||||
* resolved by an IRK, the device disributing the address must also know the IRK.
|
|
||||||
*
|
|
||||||
* @param[in] p_addr A random resolvable address.
|
|
||||||
* @param[in] p_irk An identity resolution key (IRK).
|
|
||||||
*
|
|
||||||
* @retval true The irk used matched the one used to create the address.
|
|
||||||
* @retval false The irk used did not match the one used to create the address, or an argument was
|
|
||||||
* NULL.
|
|
||||||
*/
|
|
||||||
bool im_address_resolve(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk);
|
|
||||||
|
|
||||||
/**@brief Function for calculating the ah() hash function described in Bluetooth core specification
|
|
||||||
* 4.2 section 3.H.2.2.2.
|
|
||||||
*
|
|
||||||
* @detail BLE uses a hash function to calculate the first half of a resolvable address
|
|
||||||
* from the second half of the address and an irk. This function will use the ECB
|
|
||||||
* periferal to hash these data acording to the Bluetooth core specification.
|
|
||||||
*
|
|
||||||
* @note The ECB expect little endian input and output.
|
|
||||||
* This function expect big endian and will reverse the data as necessary.
|
|
||||||
*
|
|
||||||
* @param[in] p_k The key used in the hash function.
|
|
||||||
* For address resolution this is should be the irk.
|
|
||||||
* The array must have a length of 16.
|
|
||||||
* @param[in] p_r The rand used in the hash function. For generating a new address
|
|
||||||
* this would be a random number. For resolving a resolvable address
|
|
||||||
* this would be the last half of the address being resolved.
|
|
||||||
* The array must have a length of 3.
|
|
||||||
* @param[out] p_local_hash The result of the hash operation. For address resolution this
|
|
||||||
* will match the first half of the address being resolved if and only
|
|
||||||
* if the irk used in the hash function is the same one used to generate
|
|
||||||
* the address.
|
|
||||||
* The array must have a length of 16.
|
|
||||||
*
|
|
||||||
* @note ====IMPORTANT====
|
|
||||||
* This is a special modification to the original nRF51 SDK required by the mbed BLE API
|
|
||||||
* to be able to generate BLE private resolvable addresses. This function is used by
|
|
||||||
* the BLE API implementation for nRF5xSecurityManager::getAddressFromBondTable() in the
|
|
||||||
* ble-nrf51822 yotta module.
|
|
||||||
* =================
|
|
||||||
*/
|
|
||||||
void ah(uint8_t const * p_k, uint8_t const * p_r, uint8_t * p_local_hash);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif /* PEER_ID_MANAGER_H__ */
|
|
|
@ -1,166 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "peer_data.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "peer_manager_types.h"
|
|
||||||
#include "fds.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void peer_data_parts_get(pm_peer_data_const_t const * p_peer_data, fds_record_chunk_t * p_chunks, uint16_t * p_n_chunks)
|
|
||||||
{
|
|
||||||
if (p_n_chunks == NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else if ((p_peer_data == NULL) || (p_chunks == NULL))
|
|
||||||
{
|
|
||||||
*p_n_chunks = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (p_peer_data->data_type)
|
|
||||||
{
|
|
||||||
case PM_PEER_DATA_ID_BONDING:
|
|
||||||
p_chunks[0].p_data = p_peer_data->data.p_bonding_data;
|
|
||||||
p_chunks[0].length_words = p_peer_data->length_words;
|
|
||||||
*p_n_chunks = 1;
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
|
|
||||||
p_chunks[0].p_data = p_peer_data->data.p_service_changed_pending;
|
|
||||||
p_chunks[0].length_words = p_peer_data->length_words;
|
|
||||||
*p_n_chunks = 1;
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_GATT_LOCAL:
|
|
||||||
p_chunks[0].p_data = p_peer_data->data.p_local_gatt_db;
|
|
||||||
p_chunks[0].length_words = PM_N_WORDS(PM_LOCAL_DB_LEN_OVERHEAD_BYTES);
|
|
||||||
p_chunks[1].p_data = p_peer_data->data.p_local_gatt_db->p_data;
|
|
||||||
p_chunks[1].length_words = p_peer_data->length_words - p_chunks[0].length_words;
|
|
||||||
*p_n_chunks = 2;
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_GATT_REMOTE:
|
|
||||||
p_chunks[0].p_data = p_peer_data->data.p_remote_gatt_db;
|
|
||||||
p_chunks[0].length_words = PM_N_WORDS(PM_REMOTE_DB_LEN_OVERHEAD_BYTES);
|
|
||||||
p_chunks[1].p_data = p_peer_data->data.p_remote_gatt_db->p_data;
|
|
||||||
p_chunks[1].length_words = p_peer_data->length_words - p_chunks[0].length_words;
|
|
||||||
*p_n_chunks = 2;
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_APPLICATION:
|
|
||||||
p_chunks[0].p_data = p_peer_data->data.p_application_data;
|
|
||||||
p_chunks[0].length_words = p_peer_data->length_words;
|
|
||||||
*p_n_chunks = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
*p_n_chunks = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t peer_data_deserialize(pm_peer_data_flash_t const * p_in_data, pm_peer_data_t * p_out_data)
|
|
||||||
{
|
|
||||||
if ((p_in_data == NULL) || (p_out_data == NULL))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (p_out_data->length_words < p_in_data->length_words)
|
|
||||||
{
|
|
||||||
p_out_data->length_words = p_in_data->length_words;
|
|
||||||
return NRF_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
p_out_data->length_words = p_in_data->length_words;
|
|
||||||
p_out_data->data_type = p_in_data->data_type;
|
|
||||||
|
|
||||||
switch (p_in_data->data_type)
|
|
||||||
{
|
|
||||||
case PM_PEER_DATA_ID_BONDING:
|
|
||||||
*p_out_data->data.p_bonding_data = *p_in_data->data.p_bonding_data;
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
|
|
||||||
*p_out_data->data.p_service_changed_pending = *p_in_data->data.p_service_changed_pending;
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_GATT_LOCAL:
|
|
||||||
if (p_out_data->data.p_local_gatt_db->p_data == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NULL;
|
|
||||||
}
|
|
||||||
if (p_out_data->data.p_local_gatt_db->len < p_in_data->data.p_local_gatt_db->len)
|
|
||||||
{
|
|
||||||
p_out_data->data.p_local_gatt_db->len = p_in_data->data.p_local_gatt_db->len;
|
|
||||||
return NRF_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p_out_data->data.p_local_gatt_db->flags = p_in_data->data.p_local_gatt_db->flags;
|
|
||||||
p_out_data->data.p_local_gatt_db->len = p_in_data->data.p_local_gatt_db->len;
|
|
||||||
memcpy(p_out_data->data.p_local_gatt_db->p_data,
|
|
||||||
p_in_data->data.p_local_gatt_db->p_data,
|
|
||||||
p_in_data->data.p_local_gatt_db->len);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_GATT_REMOTE:
|
|
||||||
if (p_out_data->data.p_remote_gatt_db->p_data == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NULL;
|
|
||||||
}
|
|
||||||
if (p_out_data->data.p_remote_gatt_db->service_count < p_in_data->data.p_remote_gatt_db->service_count)
|
|
||||||
{
|
|
||||||
p_out_data->data.p_remote_gatt_db->service_count = p_in_data->data.p_remote_gatt_db->service_count;
|
|
||||||
return NRF_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p_out_data->data.p_remote_gatt_db->service_count = p_in_data->data.p_remote_gatt_db->service_count;
|
|
||||||
memcpy(p_out_data->data.p_remote_gatt_db->p_data,
|
|
||||||
p_in_data->data.p_remote_gatt_db->p_data,
|
|
||||||
p_in_data->data.p_remote_gatt_db->service_count * sizeof(ble_gatt_db_srv_t));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_APPLICATION:
|
|
||||||
memcpy(p_out_data->data.p_application_data,
|
|
||||||
p_in_data->data.p_application_data,
|
|
||||||
p_in_data->length_words * 4);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PEER_DATA_H__
|
|
||||||
#define PEER_DATA_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "peer_manager_types.h"
|
|
||||||
#include "fds.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup peer_data Peer Data
|
|
||||||
* @ingroup peer_manager
|
|
||||||
* @{
|
|
||||||
* @brief An internal module of @ref peer_manager. This module defines the structure of the data
|
|
||||||
* that is managed by the @ref peer_manager. It also provides functions for parsing the data.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for enumerating the separate (non-contiguous) parts of the peer data.
|
|
||||||
*
|
|
||||||
* @param[in] p_peer_data The peer data to enumerate.
|
|
||||||
* @param[out] p_chunks The resulting chunks. This must be an array of at least 2 elements.
|
|
||||||
* @param[out] p_n_chunks The number of chunks. If this is 0, something went wrong.
|
|
||||||
*/
|
|
||||||
void peer_data_parts_get(pm_peer_data_const_t const * p_peer_data, fds_record_chunk_t * p_chunks, uint16_t * p_n_chunks);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for converting @ref pm_peer_data_flash_t into @ref pm_peer_data_t.
|
|
||||||
*
|
|
||||||
* @param[in] p_in_data The source data.
|
|
||||||
* @param[out] p_out_data The target data structure.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Successful conversion.
|
|
||||||
* @retval NRF_ERROR_NULL A parameter was NULL.
|
|
||||||
* @retval NRF_ERROR_NO_MEM A buffer was not large enough.
|
|
||||||
*/
|
|
||||||
ret_code_t peer_data_deserialize(pm_peer_data_flash_t const * p_in_data, pm_peer_data_t * p_out_data);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif /* PEER_DATA_H__ */
|
|
|
@ -1,688 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "peer_data_storage.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "sdk_errors.h"
|
|
||||||
#include "peer_manager_types.h"
|
|
||||||
#include "peer_id.h"
|
|
||||||
#include "peer_data.h"
|
|
||||||
#include "fds.h"
|
|
||||||
|
|
||||||
#define MAX_REGISTRANTS 6 /**< The number of user that can register with the module. */
|
|
||||||
|
|
||||||
#define MODULE_INITIALIZED (m_pds.n_registrants > 0) /**< Expression which is true when the module is initialized. */
|
|
||||||
|
|
||||||
/**@brief Macro for verifying that the module is initialized. It will cause the function to return
|
|
||||||
* @ref NRF_ERROR_INVALID_STATE if not.
|
|
||||||
*/
|
|
||||||
#define VERIFY_MODULE_INITIALIZED() \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if (!MODULE_INITIALIZED) \
|
|
||||||
{ \
|
|
||||||
return NRF_ERROR_INVALID_STATE; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for verifying that the module is initialized. It will cause the function to return
|
|
||||||
* if not.
|
|
||||||
*/
|
|
||||||
#define VERIFY_MODULE_INITIALIZED_VOID() \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if (!MODULE_INITIALIZED) \
|
|
||||||
{ \
|
|
||||||
return; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for verifying that the param is not NULL. It will cause the function to return
|
|
||||||
* if not.
|
|
||||||
*
|
|
||||||
* @param[in] param The variable to check if is NULL.
|
|
||||||
*/
|
|
||||||
#define VERIFY_PARAM_NOT_NULL(param) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if (param == NULL) \
|
|
||||||
{ \
|
|
||||||
return NRF_ERROR_NULL; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for verifying that param is not zero. It will cause the function to return
|
|
||||||
* if not.
|
|
||||||
*
|
|
||||||
* @param[in] param The variable to check if is zero.
|
|
||||||
*/
|
|
||||||
#define VERIFY_PARAM_NOT_ZERO(param) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if (param == 0) \
|
|
||||||
{ \
|
|
||||||
return NRF_ERROR_NULL; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for verifying that the peer id is within a valid range
|
|
||||||
*
|
|
||||||
* @param[in] id The peer data id to check.
|
|
||||||
*/
|
|
||||||
#define VERIFY_PEER_ID_IN_RANGE(id) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if ((id >= PM_PEER_ID_N_AVAILABLE_IDS)) \
|
|
||||||
{ \
|
|
||||||
return NRF_ERROR_INVALID_PARAM; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for verifying that the peer data id is withing a valid range
|
|
||||||
*
|
|
||||||
* @param[in] id The peer data id to check.
|
|
||||||
*/
|
|
||||||
#define VERIFY_PEER_DATA_ID_IN_RANGE(id) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if (!PM_PEER_DATA_ID_IS_VALID(id)) \
|
|
||||||
{ \
|
|
||||||
return NRF_ERROR_INVALID_PARAM; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
#define PEER_IDS_INITIALIZE() \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if (!m_pds.peer_ids_initialized) \
|
|
||||||
{ \
|
|
||||||
peer_ids_init(); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
bool peer_ids_initialized;
|
|
||||||
pds_evt_handler_t evt_handlers[MAX_REGISTRANTS];
|
|
||||||
uint8_t n_registrants;
|
|
||||||
} pds_t;
|
|
||||||
|
|
||||||
static pds_t m_pds = {.n_registrants = 0};
|
|
||||||
|
|
||||||
static void internal_state_reset(pds_t * p_pds)
|
|
||||||
{
|
|
||||||
memset(p_pds, 0, sizeof(pds_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Function for dispatching outbound events to all registered event handlers.
|
|
||||||
*
|
|
||||||
* @param[in] p_event The event to dispatch.
|
|
||||||
*/
|
|
||||||
static void pds_evt_send(pds_evt_t * p_event)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < m_pds.n_registrants; i++)
|
|
||||||
{
|
|
||||||
m_pds.evt_handlers[i](p_event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Function to convert peer id to instance id
|
|
||||||
*
|
|
||||||
* @param[in] peer_id Peer id to convert to instance id
|
|
||||||
*
|
|
||||||
* @return Value as instance id
|
|
||||||
*/
|
|
||||||
static fds_instance_id_t convert_peer_id_to_instance_id(pm_peer_id_t peer_id)
|
|
||||||
{
|
|
||||||
return (fds_instance_id_t)(peer_id + peer_id_to_instance_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Function to convert peer data id to type id
|
|
||||||
*
|
|
||||||
* @param[in] peer_data_id Peer data id to convert to type_id
|
|
||||||
*
|
|
||||||
* @return Value as type id
|
|
||||||
*/
|
|
||||||
static fds_type_id_t convert_peer_data_id_to_type_id(pm_peer_data_id_t peer_data_id)
|
|
||||||
{
|
|
||||||
return (fds_type_id_t)peer_data_id + (fds_type_id_t)peer_data_id_to_type_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to convert peer data id to type id
|
|
||||||
*
|
|
||||||
* @param[in] peer_data_id Peer data id to convert to type_id
|
|
||||||
*
|
|
||||||
* @return Value as type id
|
|
||||||
*/
|
|
||||||
static pm_peer_id_t convert_instance_id_to_peer_id(fds_instance_id_t instance_id)
|
|
||||||
{
|
|
||||||
return (pm_peer_id_t)(instance_id + instance_id_to_peer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to type id to peer data id
|
|
||||||
*
|
|
||||||
* @param[in] type_id Type id to convert to peer data id
|
|
||||||
*
|
|
||||||
* @return Value as peer data id
|
|
||||||
*/
|
|
||||||
static pm_peer_data_id_t convert_type_id_to_peer_data_id(fds_type_id_t type_id)
|
|
||||||
{
|
|
||||||
return (pm_peer_data_id_t)(type_id + instance_id_to_peer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static ret_code_t find_fds_item(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_id_t data_id,
|
|
||||||
fds_record_desc_t * const p_desc)
|
|
||||||
{
|
|
||||||
fds_find_token_t find_tok;
|
|
||||||
|
|
||||||
VERIFY_PEER_ID_IN_RANGE(peer_id);
|
|
||||||
VERIFY_PEER_DATA_ID_IN_RANGE(data_id);
|
|
||||||
// pp_record verified outside
|
|
||||||
|
|
||||||
fds_type_id_t type_id = convert_peer_data_id_to_type_id(data_id);
|
|
||||||
fds_instance_id_t instance_id = convert_peer_id_to_instance_id(peer_id);
|
|
||||||
|
|
||||||
return fds_find(type_id, instance_id, p_desc, &find_tok);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void peer_ids_init()
|
|
||||||
{
|
|
||||||
fds_record_t record;
|
|
||||||
fds_record_desc_t record_desc;
|
|
||||||
fds_find_token_t find_tok;
|
|
||||||
fds_type_id_t const type_id = convert_peer_data_id_to_type_id(PM_PEER_DATA_ID_BONDING);
|
|
||||||
pm_peer_id_t peer_id;
|
|
||||||
|
|
||||||
if (!m_pds.peer_ids_initialized)
|
|
||||||
{
|
|
||||||
while(fds_find_by_type(type_id, &record_desc, &find_tok) == NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
fds_open(&record_desc, &record);
|
|
||||||
fds_close(&record_desc);
|
|
||||||
peer_id = convert_instance_id_to_peer_id(record.header.ic.instance);
|
|
||||||
peer_id_allocate(peer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pds.peer_ids_initialized = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//uint32_t size_pad_to_mult_of_four(uint32_t unpadded_size)
|
|
||||||
//{
|
|
||||||
// return (unpadded_size + 3) & 3;
|
|
||||||
//}
|
|
||||||
|
|
||||||
static void fds_evt_handler(ret_code_t result,
|
|
||||||
fds_cmd_id_t cmd,
|
|
||||||
fds_record_id_t record_id,
|
|
||||||
fds_record_key_t record_key
|
|
||||||
/*fds_record_t const * const p_record*/)
|
|
||||||
{
|
|
||||||
pds_evt_t evt;
|
|
||||||
switch(cmd)
|
|
||||||
{
|
|
||||||
case FDS_CMD_INIT:
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FDS_CMD_UPDATE:
|
|
||||||
case FDS_CMD_WRITE:
|
|
||||||
evt.peer_id = convert_instance_id_to_peer_id(record_key.instance);
|
|
||||||
evt.evt_id = (result == NRF_SUCCESS) ? PDS_EVT_STORED : PDS_EVT_ERROR_STORE;
|
|
||||||
evt.data_id = convert_type_id_to_peer_data_id(record_key.type);
|
|
||||||
evt.store_token = record_id;
|
|
||||||
pds_evt_send(&evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FDS_CMD_CLEAR:
|
|
||||||
evt.peer_id = convert_instance_id_to_peer_id(record_key.instance);
|
|
||||||
evt.evt_id = (result == NRF_SUCCESS) ? PDS_EVT_CLEARED : PDS_EVT_ERROR_CLEAR;
|
|
||||||
evt.data_id = convert_type_id_to_peer_data_id(record_key.type);
|
|
||||||
evt.store_token = record_id;
|
|
||||||
pds_evt_send(&evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FDS_CMD_CLEAR_INST:
|
|
||||||
{
|
|
||||||
if ((record_key.type == FDS_TYPE_ID_INVALID) &&
|
|
||||||
(record_key.instance != FDS_TYPE_ID_INVALID))
|
|
||||||
{
|
|
||||||
pm_peer_id_t peer_id = convert_instance_id_to_peer_id(record_key.instance);
|
|
||||||
|
|
||||||
evt.peer_id = peer_id;
|
|
||||||
evt.data_id = PM_PEER_DATA_ID_INVALID;
|
|
||||||
if (result == NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
evt.evt_id = PDS_EVT_PEER_ID_CLEAR;
|
|
||||||
peer_id_free(peer_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
evt.evt_id = PDS_EVT_ERROR_PEER_ID_CLEAR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// TODO: Not supported yet (clear many without clearing peer_id)
|
|
||||||
}
|
|
||||||
|
|
||||||
pds_evt_send(&evt);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FDS_CMD_GC:
|
|
||||||
evt.peer_id = convert_instance_id_to_peer_id(record_key.instance);
|
|
||||||
evt.evt_id = PDS_EVT_COMPRESSED;
|
|
||||||
evt.data_id = convert_type_id_to_peer_data_id(record_key.type);
|
|
||||||
evt.store_token = record_id;
|
|
||||||
pds_evt_send(&evt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pds_register(pds_evt_handler_t evt_handler)
|
|
||||||
{
|
|
||||||
if (m_pds.n_registrants >= MAX_REGISTRANTS)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
VERIFY_PARAM_NOT_NULL(evt_handler);
|
|
||||||
|
|
||||||
if (!MODULE_INITIALIZED)
|
|
||||||
{
|
|
||||||
ret_code_t retval;
|
|
||||||
internal_state_reset(&m_pds);
|
|
||||||
peer_id_init();
|
|
||||||
|
|
||||||
fds_cb_t cb = fds_evt_handler;
|
|
||||||
retval = fds_register(cb);
|
|
||||||
if(retval != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
retval = fds_init();
|
|
||||||
if(retval != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pds.evt_handlers[m_pds.n_registrants] = evt_handler;
|
|
||||||
m_pds.n_registrants += 1;
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pds_peer_data_read_ptr_get(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_id_t data_id,
|
|
||||||
pm_peer_data_flash_t * p_data,
|
|
||||||
pm_store_token_t * p_token)
|
|
||||||
{
|
|
||||||
ret_code_t retval;
|
|
||||||
|
|
||||||
fds_record_t record;
|
|
||||||
fds_record_desc_t record_desc;
|
|
||||||
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
VERIFY_PEER_ID_IN_RANGE(peer_id);
|
|
||||||
VERIFY_PEER_DATA_ID_IN_RANGE(data_id);
|
|
||||||
|
|
||||||
retval = find_fds_item(peer_id, data_id, &record_desc);
|
|
||||||
if (retval != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shouldn't fail, unless record is cleared.
|
|
||||||
fds_open(&record_desc, &record);
|
|
||||||
// No need to keep it open, since we are not reading.
|
|
||||||
fds_close(&record_desc);
|
|
||||||
|
|
||||||
//NRF_LOG_PRINTF("Found item with peer_id: %d, data_id: %d, Address: %p\r\n", record.p_data);
|
|
||||||
|
|
||||||
if (p_data != NULL)
|
|
||||||
{
|
|
||||||
p_data->data_type = data_id;
|
|
||||||
p_data->length_words = record.header.tl.length_words;
|
|
||||||
|
|
||||||
p_data->data.p_application_data = (uint8_t const*)record.p_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_token != NULL)
|
|
||||||
{
|
|
||||||
*p_token = (uint32_t)record.header.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pds_peer_data_lock(pm_store_token_t store_token)
|
|
||||||
{
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
VERIFY_PARAM_NOT_ZERO(store_token);
|
|
||||||
|
|
||||||
// TODO: Not implemented yet in fds
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pds_peer_data_verify(pm_store_token_t store_token)
|
|
||||||
{
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
VERIFY_PARAM_NOT_ZERO(store_token);
|
|
||||||
|
|
||||||
// TODO: Not implemented yet in fds
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pds_peer_data_read(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_id_t data_id,
|
|
||||||
pm_peer_data_t * p_data,
|
|
||||||
fds_length_t * p_len_words)
|
|
||||||
{
|
|
||||||
VERIFY_PEER_ID_IN_RANGE(peer_id);
|
|
||||||
VERIFY_PEER_DATA_ID_IN_RANGE(data_id);
|
|
||||||
VERIFY_PARAM_NOT_NULL(p_len_words);
|
|
||||||
VERIFY_PARAM_NOT_NULL(p_data);
|
|
||||||
|
|
||||||
ret_code_t err_code;
|
|
||||||
pm_peer_data_flash_t peer_data_flash;
|
|
||||||
|
|
||||||
err_code = pds_peer_data_read_ptr_get(peer_id, data_id, &peer_data_flash, NULL);
|
|
||||||
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*p_len_words) == 0)
|
|
||||||
{
|
|
||||||
(*p_len_words) = peer_data_flash.length_words;
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
else if ((*p_len_words) < peer_data_flash.length_words)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
VERIFY_PARAM_NOT_NULL(p_data->data.p_application_data);
|
|
||||||
|
|
||||||
err_code = peer_data_deserialize(&peer_data_flash, p_data);
|
|
||||||
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pds_peer_data_write_prepare(pm_peer_data_const_t const * p_peer_data,
|
|
||||||
pm_prepare_token_t * p_prepare_token)
|
|
||||||
{
|
|
||||||
ret_code_t retval;
|
|
||||||
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
VERIFY_PARAM_NOT_NULL(p_peer_data);
|
|
||||||
VERIFY_PARAM_NOT_NULL(p_prepare_token);
|
|
||||||
VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_type);
|
|
||||||
|
|
||||||
retval = fds_reserve((fds_write_token_t*)p_prepare_token, p_peer_data->length_words);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pds_peer_data_write_prepare_cancel(pm_prepare_token_t prepare_token)
|
|
||||||
{
|
|
||||||
ret_code_t retval;
|
|
||||||
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
VERIFY_PARAM_NOT_ZERO(prepare_token);
|
|
||||||
|
|
||||||
retval = fds_reserve_cancel((fds_write_token_t*)&prepare_token);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pds_peer_data_write_prepared(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_const_t const * p_peer_data,
|
|
||||||
pm_prepare_token_t prepare_token,
|
|
||||||
pm_store_token_t * p_store_token)
|
|
||||||
{
|
|
||||||
ret_code_t retval;
|
|
||||||
fds_record_desc_t record_desc;
|
|
||||||
fds_record_key_t record_key;
|
|
||||||
fds_record_chunk_t chunks[2];
|
|
||||||
uint16_t n_chunks;
|
|
||||||
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
//VERIFY_PARAM_NOT_ZERO(prepare_token);
|
|
||||||
VERIFY_PARAM_NOT_NULL(p_peer_data);
|
|
||||||
VERIFY_PEER_ID_IN_RANGE(peer_id);
|
|
||||||
VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_type);
|
|
||||||
|
|
||||||
// Fill in the keys.
|
|
||||||
record_key.type = convert_peer_data_id_to_type_id(p_peer_data->data_type);
|
|
||||||
record_key.instance = convert_peer_id_to_instance_id(peer_id);
|
|
||||||
|
|
||||||
// Create chunks.
|
|
||||||
peer_data_parts_get(p_peer_data, chunks, &n_chunks);
|
|
||||||
|
|
||||||
retval = fds_write_reserved((fds_write_token_t*)&prepare_token, &record_desc,
|
|
||||||
record_key, n_chunks, chunks);
|
|
||||||
|
|
||||||
if ((retval == NRF_SUCCESS) && (p_store_token != NULL))
|
|
||||||
{
|
|
||||||
fds_record_id_from_desc(&record_desc, (fds_record_id_t*)p_store_token);
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pds_peer_data_write(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_const_t const * p_peer_data,
|
|
||||||
pm_store_token_t * p_store_token)
|
|
||||||
{
|
|
||||||
ret_code_t retval;
|
|
||||||
fds_record_desc_t record_desc;
|
|
||||||
fds_record_key_t record_key;
|
|
||||||
fds_record_chunk_t chunks[2];
|
|
||||||
uint16_t n_chunks;
|
|
||||||
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
VERIFY_PEER_ID_IN_RANGE(peer_id);
|
|
||||||
VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_type);
|
|
||||||
|
|
||||||
// Fill in the keys.
|
|
||||||
record_key.type = convert_peer_data_id_to_type_id(p_peer_data->data_type);
|
|
||||||
record_key.instance = convert_peer_id_to_instance_id(peer_id);
|
|
||||||
|
|
||||||
// Create chunks
|
|
||||||
peer_data_parts_get(p_peer_data, chunks, &n_chunks);
|
|
||||||
|
|
||||||
// Request write
|
|
||||||
retval = fds_write(&record_desc, record_key, n_chunks, chunks);
|
|
||||||
|
|
||||||
if ((retval == NRF_SUCCESS) && (p_store_token != NULL))
|
|
||||||
{
|
|
||||||
fds_record_id_from_desc(&record_desc, (fds_record_id_t*)p_store_token);
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pds_peer_data_update(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_const_t const * p_peer_data,
|
|
||||||
pm_store_token_t old_token,
|
|
||||||
pm_store_token_t * p_store_token)
|
|
||||||
{
|
|
||||||
ret_code_t retval;
|
|
||||||
fds_record_desc_t record_desc;
|
|
||||||
fds_record_key_t record_key;
|
|
||||||
fds_record_chunk_t chunks[2];
|
|
||||||
uint16_t n_chunks;
|
|
||||||
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_type);
|
|
||||||
VERIFY_PARAM_NOT_NULL(p_peer_data);
|
|
||||||
|
|
||||||
record_key.type = convert_peer_data_id_to_type_id(p_peer_data->data_type);
|
|
||||||
record_key.instance = convert_peer_id_to_instance_id(peer_id);
|
|
||||||
|
|
||||||
// Create chunks
|
|
||||||
peer_data_parts_get(p_peer_data, chunks, &n_chunks);
|
|
||||||
|
|
||||||
fds_descriptor_from_rec_id(&record_desc, (fds_record_id_t)old_token);
|
|
||||||
|
|
||||||
retval = fds_update(&record_desc, record_key, n_chunks, chunks);
|
|
||||||
|
|
||||||
if ((retval == NRF_SUCCESS) && (p_store_token != NULL))
|
|
||||||
{
|
|
||||||
fds_record_id_from_desc(&record_desc, (fds_record_id_t*)p_store_token);
|
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret_code_t pds_peer_data_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
|
|
||||||
{
|
|
||||||
ret_code_t retval;
|
|
||||||
fds_type_id_t type_id;
|
|
||||||
fds_instance_id_t instance_id;
|
|
||||||
fds_record_desc_t record_desc;
|
|
||||||
fds_find_token_t find_tok;
|
|
||||||
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
VERIFY_PEER_ID_IN_RANGE(peer_id);
|
|
||||||
VERIFY_PEER_DATA_ID_IN_RANGE(data_id);
|
|
||||||
|
|
||||||
type_id = convert_peer_data_id_to_type_id(data_id);
|
|
||||||
instance_id = convert_peer_id_to_instance_id(peer_id);
|
|
||||||
|
|
||||||
retval = fds_find(type_id, instance_id, &record_desc, &find_tok);
|
|
||||||
if(retval != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
retval = fds_clear(&record_desc);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pm_peer_id_t pds_peer_id_allocate(void)
|
|
||||||
{
|
|
||||||
if (!MODULE_INITIALIZED)
|
|
||||||
{
|
|
||||||
return PM_PEER_ID_INVALID;
|
|
||||||
}
|
|
||||||
PEER_IDS_INITIALIZE();
|
|
||||||
return peer_id_allocate(PM_PEER_ID_INVALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pds_peer_id_free(pm_peer_id_t peer_id)
|
|
||||||
{
|
|
||||||
ret_code_t retval;
|
|
||||||
fds_instance_id_t instance_id;
|
|
||||||
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
VERIFY_PEER_ID_IN_RANGE(peer_id);
|
|
||||||
PEER_IDS_INITIALIZE();
|
|
||||||
|
|
||||||
instance_id = convert_peer_id_to_instance_id(peer_id);
|
|
||||||
|
|
||||||
retval = fds_clear_by_instance(instance_id);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool pds_peer_id_is_allocated(pm_peer_id_t peer_id)
|
|
||||||
{
|
|
||||||
if (!MODULE_INITIALIZED)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
PEER_IDS_INITIALIZE();
|
|
||||||
|
|
||||||
return peer_id_is_allocated(peer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pm_peer_id_t pds_next_peer_id_get(pm_peer_id_t prev_peer_id)
|
|
||||||
{
|
|
||||||
if (!MODULE_INITIALIZED)
|
|
||||||
{
|
|
||||||
return PM_PEER_ID_INVALID;
|
|
||||||
}
|
|
||||||
PEER_IDS_INITIALIZE();
|
|
||||||
|
|
||||||
return peer_id_next_id_get(prev_peer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t pds_n_peers(void)
|
|
||||||
{
|
|
||||||
if (!MODULE_INITIALIZED)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
PEER_IDS_INITIALIZE();
|
|
||||||
return peer_id_n_ids();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,370 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PEER_DATA_STORAGE_H__
|
|
||||||
#define PEER_DATA_STORAGE_H__
|
|
||||||
|
|
||||||
|
|
||||||
#include "stdint.h"
|
|
||||||
#include "sdk_errors.h"
|
|
||||||
#include "ble_gap.h"
|
|
||||||
#include "peer_manager_types.h"
|
|
||||||
#include "fds.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup peer_data_storage Peer Data Storage
|
|
||||||
* @ingroup peer_manager
|
|
||||||
* @{
|
|
||||||
* @brief An internal module of @ref peer_manager. This module provides a Peer Manager-specific API
|
|
||||||
* to the persistent storage.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define PDS_PREPARE_TOKEN_INVALID 0
|
|
||||||
#define PDS_STORE_TOKEN_INVALID 0
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
peer_id_to_instance_id = 16384,
|
|
||||||
instance_id_to_peer_id = -peer_id_to_instance_id,
|
|
||||||
peer_data_id_to_type_id = 32768,
|
|
||||||
type_id_to_peer_data_id = -peer_data_id_to_type_id,
|
|
||||||
} pds_convert_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief The types of events that can come from the peer_data_storage module.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
PDS_EVT_STORED, /**< The specified data has been successfully stored. */
|
|
||||||
PDS_EVT_CLEARED, /**< The specified data has been successfully cleared. */
|
|
||||||
PDS_EVT_PEER_ID_CLEAR, /**< The peer id has been successfully cleared. */
|
|
||||||
PDS_EVT_ERROR_STORE, /**< The specified data could not be stored. */
|
|
||||||
PDS_EVT_ERROR_CLEAR, /**< The specified data could not be cleared. */
|
|
||||||
PDS_EVT_ERROR_PEER_ID_CLEAR, /**< The peer id has been successfully cleared. */
|
|
||||||
PDS_EVT_COMPRESSED, /**< A compress procedure has finished successfully. */
|
|
||||||
} pds_evt_id_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Events that can come from the peer_data_storage module.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
pds_evt_id_t evt_id; /**< The type of event. */
|
|
||||||
pm_peer_id_t peer_id; /**< The peer the event pertains to. */
|
|
||||||
pm_peer_data_id_t data_id; /**< The data the event pertains to. */
|
|
||||||
pm_store_token_t store_token;
|
|
||||||
} pds_evt_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Event handler for events from the peer_data_storage module.
|
|
||||||
*
|
|
||||||
* @param[in] event The event that has happened.
|
|
||||||
* @param[in] peer_id The id of the peer the event pertains to.
|
|
||||||
* @param[in] flags The data the event pertains to.
|
|
||||||
*/
|
|
||||||
typedef void (*pds_evt_handler_t)(pds_evt_t const * p_event);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for registering for events from the peer database.
|
|
||||||
*
|
|
||||||
* @note This function will initialize the module if it is not already initialized.
|
|
||||||
*
|
|
||||||
* @param[in] evt_handler Event handler to register.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Registration successful.
|
|
||||||
* @retval NRF_ERROR_NO_MEM No more event handlers can be registered.
|
|
||||||
* @retval NRF_ERROR_NULL evt_handler was NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Unexpected return code from @ref pm_buffer_init.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE FDS has not been initalized.
|
|
||||||
*/
|
|
||||||
ret_code_t pds_register(pds_evt_handler_t evt_handler);
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/**@brief Function for initializing Peer Data storage and registering a
|
|
||||||
* callback for its events.
|
|
||||||
*
|
|
||||||
* @param[in] evt_handler Event handler to register.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Registration successful.
|
|
||||||
* @retval NRF_ERROR_NO_MEM No more event handlers can be registered.
|
|
||||||
* @retval NRF_ERROR_NULL evt_handler was NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE FDS has not completed initialization.
|
|
||||||
*/
|
|
||||||
ret_code_t pds_init(pds_evt_handler_t evt_handler);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**@brief Function for retrieving a direct pointer to peer data in persistent storage.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id The id of the peer whose data to read.
|
|
||||||
* @param[in] data_id Which data to get.
|
|
||||||
* @param[out] p_data The peer data pointer.
|
|
||||||
* @param[out] p_token Token that can be used to lock data in flash and check data validity.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS The pointer was successfully retrieved.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Invalid data_id.
|
|
||||||
* @retval NRF_ERROR_NULL p_data was NULL.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND The requested data was not found in persistent storage.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pds_peer_data_read_ptr_get(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_id_t data_id,
|
|
||||||
pm_peer_data_flash_t * p_data,
|
|
||||||
pm_store_token_t * p_token);
|
|
||||||
|
|
||||||
/**@brief Function to lock the flash data (to defer compression from invalidating data)
|
|
||||||
*
|
|
||||||
* @param[in] store_token The token representing the item to lock
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
ret_code_t pds_peer_data_lock(pm_store_token_t store_token);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to verify flash data integrity
|
|
||||||
*
|
|
||||||
* @param[in] store_token The token representing the item to lock
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS The data integrity is valid.
|
|
||||||
* @retval NRF_ERROR_NULL The token is invalid.
|
|
||||||
* @retval NRF_ERROR_INVALID_DATA The data integrity is not valid.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pds_peer_data_verify(pm_store_token_t store_token);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for retrieving peer data from persistent storage by making a copy
|
|
||||||
*
|
|
||||||
* @param[in] peer_id The id of the peer whose data to read.
|
|
||||||
* @param[in] data_id Which piece of data to read.
|
|
||||||
* @param[out] p_data Pointer to the peer data.
|
|
||||||
* @param[in,out] p_len_words Length available to copy to (in words).
|
|
||||||
* If set to NULL, then no copy will be made and the
|
|
||||||
* length will be reflected in p_len_words after the call returns.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS The read was successful.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Invalid data_id.
|
|
||||||
* @retval NRF_ERROR_NULL data contained a NULL pointer.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND The requested data was not found in persistent storage.
|
|
||||||
* @retval NRF_ERROR_NO_MEM The length of stored data too large to copy out
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pds_peer_data_read(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_id_t data_id,
|
|
||||||
pm_peer_data_t * p_data,
|
|
||||||
fds_length_t * p_len_words);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for preparing persistent storage for a write.
|
|
||||||
*
|
|
||||||
* @details If this call succeeds, space is reserved in persistent storage, so the write will fit.
|
|
||||||
*
|
|
||||||
* @note If space has already been prepared for this peer_id/data_id pair, no new space will be
|
|
||||||
* reserved, unless the previous reservation had too small size.
|
|
||||||
*
|
|
||||||
* @param[in] p_peer_data Data to prepare for. The data needs not be ready, but length and type
|
|
||||||
* values must.
|
|
||||||
* @param[out] p_prepare_token A token identifying the prepared memory area.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS The call was successful.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Invalid data ID.
|
|
||||||
* @retval NRF_ERROR_INVALID_LENGTH Data length above the maximum allowed.
|
|
||||||
* @retval NRF_ERROR_NO_MEM No space available in persistent storage.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pds_peer_data_write_prepare(pm_peer_data_const_t const * p_peer_data,
|
|
||||||
pm_prepare_token_t * p_prepare_token);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for undoing a previous call to @ref pds_peer_data_write_prepare.
|
|
||||||
*
|
|
||||||
* @param[in] prepare_token A token identifying the prepared memory area to cancel.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS The call was successful.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND Invalid peer ID and/or prepare token.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pds_peer_data_write_prepare_cancel(pm_prepare_token_t prepare_token);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for writing prepared (reserved) peer data to persistent storage.
|
|
||||||
*
|
|
||||||
* @details Writing happens asynchronously. Expect a @ref PDS_EVT_STORED or @ref PDS_EVT_ERROR_STORE
|
|
||||||
* event.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id The id of the peer the data pertains to.
|
|
||||||
* @param[in] p_peer_data The peer data.
|
|
||||||
* @param[in] prepare_token A token identifying the prepared memory area to write into. If
|
|
||||||
* the prepare token is invalid, e.g. PDS_PREPARE_TOKEN_INVALID, the
|
|
||||||
* prepare/write sequence will happen atomically.
|
|
||||||
* @param[out] p_store_token A token identifying this particular store operation. The token can be
|
|
||||||
* used to identify events pertaining to this operation.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS The write was initiated successfully.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Invalid data ID or store_flags.
|
|
||||||
* @retval NRF_ERROR_INVALID_LENGTH Length of data longer than in prepare call.
|
|
||||||
* @retval NRF_ERROR_NULL data contained a NULL pointer.
|
|
||||||
* @retval NRF_ERROR_NO_MEM No space available in persistent storage. This can only happen
|
|
||||||
* if p_prepare_token is NULL.
|
|
||||||
* @retval NRF_ERROR_BUSY FDS or underlying modules are busy and can't take any
|
|
||||||
* more requests
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pds_peer_data_write_prepared(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_const_t const * p_peer_data,
|
|
||||||
pm_prepare_token_t prepare_token,
|
|
||||||
pm_store_token_t * p_store_token);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for writing peer data to persistent storage.
|
|
||||||
*
|
|
||||||
* @details Writing happens asynchronously. Expect a @ref PDS_EVT_STORED or @ref PDS_EVT_ERROR_STORE
|
|
||||||
* event.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id The id of the peer the data pertains to.
|
|
||||||
* @param[in] p_peer_data The peer data.
|
|
||||||
* @param[out] p_store_token A token identifying this particular store operation. The token can be
|
|
||||||
* used to identify events pertaining to this operation.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS The write was initiated successfully.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Invalid data ID or store_flags.
|
|
||||||
* @retval NRF_ERROR_NULL Data contained a NULL pointer.
|
|
||||||
* @retval NRF_ERROR_NO_MEM No space available in persistent storage. This can only happen
|
|
||||||
* if p_prepare_token is NULL.
|
|
||||||
* @retval NRF_ERROR_BUSY FDS or underlying modules are busy and can't take any
|
|
||||||
* more requests
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pds_peer_data_write(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_const_t const * p_peer_data,
|
|
||||||
pm_store_token_t * p_store_token);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for updating currently stored peer data to a new version
|
|
||||||
*
|
|
||||||
* @details Updating happens asynchronously.
|
|
||||||
* Expect a @ref PDS_EVT_STORED or @ref PDS_EVT_ERROR_STORE for the store token
|
|
||||||
* and a @ref PDS_EVT_ERROR_CLEAR or @ref PDS_EVT_ERROR_CLEAR for the old token
|
|
||||||
*
|
|
||||||
* @param[in] peer_id The peer which the data is associated to.
|
|
||||||
* @param[in] peer_data New data.
|
|
||||||
* @param[in] old_token Store token for the old data.
|
|
||||||
* @param[out] p_store_token Store token for the new data.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCESS The update was initiated successfully
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND The old store token was invalid.
|
|
||||||
* @retval NRF_ERROR_NULL Data contained a NULL pointer.
|
|
||||||
* @retval NRF_ERROR_NO_MEM No space available in persistent storage.
|
|
||||||
* @retval NRF_ERROR_BUSY FDS or underlying modules are busy and can't take any
|
|
||||||
* more requests
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pds_peer_data_update(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_const_t const * peer_data,
|
|
||||||
pm_store_token_t old_token,
|
|
||||||
pm_store_token_t * p_store_token);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for clearing peer data from persistent storage.
|
|
||||||
*
|
|
||||||
* @details Clearing happens asynchronously. Expect a @ref PDS_EVT_CLEARED or @ref PDS_EVT_ERROR_CLEAR
|
|
||||||
* event.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id The id of the peer the data pertains to.
|
|
||||||
* @param[in] data_id Which data to clear.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS The clear was initiated successfully.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Data ID or was invalid.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND Nothing to clear for this peer ID.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pds_peer_data_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for claiming an unused peer ID.
|
|
||||||
*
|
|
||||||
* @return The first unused peer ID.
|
|
||||||
* @retval PM_PEER_ID_INVALID If no peer ID is available or module is not initialized.
|
|
||||||
*/
|
|
||||||
pm_peer_id_t pds_peer_id_allocate(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for freeing a peer ID and clearing all data associated with it in persistent
|
|
||||||
* storage.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id Peer ID to free.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS The clear was initiated successfully
|
|
||||||
* @retval NRF_ERROR_BUSY Another peer_id clear was already requested or fds queue full
|
|
||||||
*/
|
|
||||||
ret_code_t pds_peer_id_free(pm_peer_id_t peer_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for finding out whether a peer ID is in use.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id The peer ID to inquire about.
|
|
||||||
*
|
|
||||||
* @retval true peer_id is in use.
|
|
||||||
* @retval false peer_id is free, or the module is not initialized.
|
|
||||||
*/
|
|
||||||
bool pds_peer_id_is_allocated(pm_peer_id_t peer_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for getting the next peer ID in the sequence of all used peer IDs. Can be
|
|
||||||
* used to loop through all used peer IDs.
|
|
||||||
*
|
|
||||||
* @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary
|
|
||||||
* peer ID.
|
|
||||||
*
|
|
||||||
* @param[in] prev_peer_id The previous peer ID.
|
|
||||||
*
|
|
||||||
* @return The next peer ID.
|
|
||||||
* @return The first ordinary peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID.
|
|
||||||
* @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID or the module
|
|
||||||
* is not initialized.
|
|
||||||
*/
|
|
||||||
pm_peer_id_t pds_next_peer_id_get(pm_peer_id_t prev_peer_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for querying the number of valid peer IDs available. I.E the number of peers
|
|
||||||
* in persistent storage.
|
|
||||||
*
|
|
||||||
* @return The number of valid peer IDs, or 0 if module is not initialized.
|
|
||||||
*/
|
|
||||||
uint32_t pds_n_peers(void);
|
|
||||||
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif /* PEER_DATA_STORAGE_H__ */
|
|
|
@ -1,768 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "peer_database.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "peer_manager_types.h"
|
|
||||||
#include "peer_data_storage.h"
|
|
||||||
#include "pm_buffer.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define MAX_REGISTRANTS 6 /**< The number of user that can register with the module. */
|
|
||||||
|
|
||||||
#define MODULE_INITIALIZED (m_pdb.n_registrants > 0) /**< Expression which is true when the module is initialized. */
|
|
||||||
|
|
||||||
#define N_WRITE_BUFFERS 8 /**< The number of write buffers available. */
|
|
||||||
#define N_WRITE_BUFFER_RECORDS (N_WRITE_BUFFERS) /**< The number of write buffer records. */
|
|
||||||
|
|
||||||
/**@brief Macro for verifying that the module is initialized. It will cause the function to return
|
|
||||||
* @ref NRF_ERROR_INVALID_STATE if not.
|
|
||||||
*/
|
|
||||||
#define VERIFY_MODULE_INITIALIZED() \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if (!MODULE_INITIALIZED) \
|
|
||||||
{ \
|
|
||||||
return NRF_ERROR_INVALID_STATE; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for verifying that the module is initialized. It will cause the function to return
|
|
||||||
* if not.
|
|
||||||
*/
|
|
||||||
#define VERIFY_MODULE_INITIALIZED_VOID()\
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if (!MODULE_INITIALIZED) \
|
|
||||||
{ \
|
|
||||||
return; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for verifying that the module is initialized. It will cause the function to return
|
|
||||||
* if not.
|
|
||||||
*
|
|
||||||
* @param[in] param The variable to check if is NULL.
|
|
||||||
*/
|
|
||||||
#define VERIFY_PARAM_NOT_NULL(param) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
if (param == NULL) \
|
|
||||||
{ \
|
|
||||||
return NRF_ERROR_NULL; \
|
|
||||||
} \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
pm_peer_id_t peer_id;
|
|
||||||
pm_peer_data_id_t data_id;
|
|
||||||
uint8_t buffer_block_id;
|
|
||||||
uint8_t store_busy : 1;
|
|
||||||
uint8_t store_flash_full : 1;
|
|
||||||
uint8_t store_requested : 1;
|
|
||||||
uint32_t n_bufs;
|
|
||||||
pm_prepare_token_t prepare_token;
|
|
||||||
pm_store_token_t store_token;
|
|
||||||
} pdb_buffer_record_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
pdb_evt_handler_t evt_handlers[MAX_REGISTRANTS];
|
|
||||||
uint8_t n_registrants;
|
|
||||||
pm_buffer_t write_buffer;
|
|
||||||
pdb_buffer_record_t write_buffer_records[N_WRITE_BUFFER_RECORDS];
|
|
||||||
uint32_t n_writes;
|
|
||||||
} pdb_t;
|
|
||||||
|
|
||||||
static pdb_t m_pdb = {.n_registrants = 0};
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for invalidating a record of a write buffer allocation.
|
|
||||||
*
|
|
||||||
* @param[in] p_record The record to invalidate.
|
|
||||||
*/
|
|
||||||
static void write_buffer_record_invalidate(pdb_buffer_record_t * p_record)
|
|
||||||
{
|
|
||||||
p_record->peer_id = PM_PEER_ID_INVALID;
|
|
||||||
p_record->data_id = PM_PEER_DATA_ID_INVALID;
|
|
||||||
p_record->buffer_block_id = BUFFER_INVALID_ID;
|
|
||||||
p_record->store_busy = false;
|
|
||||||
p_record->store_flash_full = false;
|
|
||||||
p_record->store_requested = false;
|
|
||||||
p_record->n_bufs = 0;
|
|
||||||
p_record->prepare_token = PDS_PREPARE_TOKEN_INVALID;
|
|
||||||
p_record->store_token = PDS_STORE_TOKEN_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for finding a record of a write buffer allocation.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id The peer ID in the record.
|
|
||||||
* @param[in] data_id The data ID in the record.
|
|
||||||
*
|
|
||||||
* @return A pointer to the matching record, or NULL if none was found.
|
|
||||||
*/
|
|
||||||
static pdb_buffer_record_t * write_buffer_record_find(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_id_t data_id)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < N_WRITE_BUFFER_RECORDS; i++)
|
|
||||||
{
|
|
||||||
if ((m_pdb.write_buffer_records[i].peer_id == peer_id)
|
|
||||||
&& (m_pdb.write_buffer_records[i].data_id == data_id))
|
|
||||||
{
|
|
||||||
return &m_pdb.write_buffer_records[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for finding an available record for write buffer allocation.
|
|
||||||
*
|
|
||||||
* @return A pointer to the available record, or NULL if none was found.
|
|
||||||
*/
|
|
||||||
static pdb_buffer_record_t * write_buffer_record_find_unused(void)
|
|
||||||
{
|
|
||||||
return write_buffer_record_find(PM_PEER_ID_INVALID, PM_PEER_DATA_ID_INVALID);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for gracefully deactivating a write buffer record.
|
|
||||||
*
|
|
||||||
* @details This function will first release any buffers, then invalidate the record.
|
|
||||||
*
|
|
||||||
* @param[inout] p_write_buffer_record The record to release.
|
|
||||||
*
|
|
||||||
* @return A pointer to the matching record, or NULL if none was found.
|
|
||||||
*/
|
|
||||||
static void write_buffer_record_release(pdb_buffer_record_t * p_write_buffer_record)
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < p_write_buffer_record->n_bufs; i++)
|
|
||||||
{
|
|
||||||
pm_buffer_release(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
write_buffer_record_invalidate(p_write_buffer_record);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void write_buffer_record_get(pdb_buffer_record_t ** pp_write_buffer_record, pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
|
|
||||||
{
|
|
||||||
if (pp_write_buffer_record == NULL)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*pp_write_buffer_record = write_buffer_record_find_unused();
|
|
||||||
if (*pp_write_buffer_record == NULL)
|
|
||||||
{
|
|
||||||
// This also means the buffer is full.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
(*pp_write_buffer_record)->peer_id = peer_id;
|
|
||||||
(*pp_write_buffer_record)->data_id = data_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for dispatching outbound events to all registered event handlers.
|
|
||||||
*
|
|
||||||
* @param[in] p_event The event to dispatch.
|
|
||||||
*/
|
|
||||||
static void pdb_evt_send(pdb_evt_t * p_event)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < m_pdb.n_registrants; i++)
|
|
||||||
{
|
|
||||||
m_pdb.evt_handlers[i](p_event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for resetting the internal state of the Peer Database module.
|
|
||||||
*
|
|
||||||
* @param[out] p_event The event to dispatch.
|
|
||||||
*/
|
|
||||||
static void internal_state_reset(pdb_t * pdb)
|
|
||||||
{
|
|
||||||
memset(pdb, 0, sizeof(pdb_t));
|
|
||||||
for (int i = 0; i < N_WRITE_BUFFER_RECORDS; i++)
|
|
||||||
{
|
|
||||||
write_buffer_record_invalidate(&pdb->write_buffer_records[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for handling events from the Peer Data Storage module.
|
|
||||||
*
|
|
||||||
* @param[in] p_event The event to handle.
|
|
||||||
*/
|
|
||||||
static void pds_evt_handler(pds_evt_t const * p_event)
|
|
||||||
{
|
|
||||||
ret_code_t err_code;
|
|
||||||
pdb_buffer_record_t * p_write_buffer_record;
|
|
||||||
bool retry_flash_full = false;
|
|
||||||
pdb_evt_t event =
|
|
||||||
{
|
|
||||||
.peer_id = p_event->peer_id,
|
|
||||||
.data_id = p_event->data_id,
|
|
||||||
};
|
|
||||||
|
|
||||||
p_write_buffer_record = write_buffer_record_find(p_event->peer_id, p_event->data_id);
|
|
||||||
|
|
||||||
switch (p_event->evt_id)
|
|
||||||
{
|
|
||||||
case PDS_EVT_STORED:
|
|
||||||
if ( (p_write_buffer_record != NULL)
|
|
||||||
//&& (p_write_buffer_record->store_token == p_event->store_token)
|
|
||||||
&& (p_write_buffer_record->store_requested))
|
|
||||||
{
|
|
||||||
write_buffer_record_release(p_write_buffer_record);
|
|
||||||
event.evt_id = PDB_EVT_WRITE_BUF_STORED;
|
|
||||||
pdb_evt_send(&event);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
event.evt_id = PDB_EVT_RAW_STORED;
|
|
||||||
pdb_evt_send(&event);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PDS_EVT_ERROR_STORE:
|
|
||||||
if ( (p_write_buffer_record != NULL)
|
|
||||||
&& (p_write_buffer_record->store_token == p_event->store_token)
|
|
||||||
&& (p_write_buffer_record->store_requested))
|
|
||||||
{
|
|
||||||
// Retry if internal buffer.
|
|
||||||
m_pdb.n_writes++;
|
|
||||||
p_write_buffer_record->store_requested = false;
|
|
||||||
p_write_buffer_record->store_busy = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
event.evt_id = PDB_EVT_RAW_STORE_FAILED;
|
|
||||||
pdb_evt_send(&event);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PDS_EVT_CLEARED:
|
|
||||||
event.evt_id = PDB_EVT_CLEARED;
|
|
||||||
pdb_evt_send(&event);
|
|
||||||
break;
|
|
||||||
case PDS_EVT_ERROR_CLEAR:
|
|
||||||
event.evt_id = PDB_EVT_CLEAR_FAILED;
|
|
||||||
pdb_evt_send(&event);
|
|
||||||
break;
|
|
||||||
case PDS_EVT_COMPRESSED:
|
|
||||||
retry_flash_full = true;
|
|
||||||
event.evt_id = PDB_EVT_COMPRESSED;
|
|
||||||
pdb_evt_send(&event);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_pdb.n_writes > 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < N_WRITE_BUFFER_RECORDS; i++)
|
|
||||||
{
|
|
||||||
if ((m_pdb.write_buffer_records[i].store_busy)
|
|
||||||
|| (m_pdb.write_buffer_records[i].store_flash_full && retry_flash_full))
|
|
||||||
{
|
|
||||||
err_code = pdb_write_buf_store(m_pdb.write_buffer_records[i].peer_id,
|
|
||||||
m_pdb.write_buffer_records[i].data_id);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
event.peer_id = m_pdb.write_buffer_records[i].peer_id;
|
|
||||||
event.data_id = m_pdb.write_buffer_records[i].data_id;
|
|
||||||
if (err_code == NRF_ERROR_NO_MEM)
|
|
||||||
{
|
|
||||||
event.evt_id = PDB_EVT_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
event.evt_id = PDB_EVT_ERROR_UNEXPECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
pdb_evt_send(&event);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pdb_register(pdb_evt_handler_t evt_handler)
|
|
||||||
{
|
|
||||||
if (m_pdb.n_registrants >= MAX_REGISTRANTS)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
VERIFY_PARAM_NOT_NULL(evt_handler);
|
|
||||||
|
|
||||||
if (!MODULE_INITIALIZED)
|
|
||||||
{
|
|
||||||
ret_code_t err_code;
|
|
||||||
|
|
||||||
internal_state_reset(&m_pdb);
|
|
||||||
err_code = pds_register(pds_evt_handler);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
PM_BUFFER_INIT(&m_pdb.write_buffer, N_WRITE_BUFFERS, PDB_WRITE_BUF_SIZE, err_code);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pdb.evt_handlers[m_pdb.n_registrants] = evt_handler;
|
|
||||||
m_pdb.n_registrants += 1;
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pm_peer_id_t pdb_peer_allocate(void)
|
|
||||||
{
|
|
||||||
if (!MODULE_INITIALIZED)
|
|
||||||
{
|
|
||||||
return PM_PEER_ID_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pds_peer_id_allocate();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pdb_peer_free(pm_peer_id_t peer_id)
|
|
||||||
{
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
|
|
||||||
return pds_peer_id_free(peer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pdb_read_buf_get(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_id_t data_id,
|
|
||||||
pm_peer_data_flash_t * p_peer_data,
|
|
||||||
pm_store_token_t * p_token)
|
|
||||||
{
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
|
|
||||||
return pds_peer_data_read_ptr_get(peer_id, data_id, p_peer_data, p_token);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void peer_data_point_to_buffer(pm_peer_data_t * p_peer_data, pm_peer_data_id_t data_id, uint8_t * p_buffer_memory, uint16_t n_bufs)
|
|
||||||
{
|
|
||||||
uint16_t n_bytes = n_bufs * PDB_WRITE_BUF_SIZE;
|
|
||||||
p_peer_data->data_type = data_id;
|
|
||||||
|
|
||||||
switch(p_peer_data->data_type)
|
|
||||||
{
|
|
||||||
case PM_PEER_DATA_ID_BONDING:
|
|
||||||
p_peer_data->data.p_bonding_data = (pm_peer_data_bonding_t *)p_buffer_memory;
|
|
||||||
p_peer_data->length_words = PM_BONDING_DATA_N_WORDS();
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
|
|
||||||
p_peer_data->data.p_service_changed_pending = (bool *)p_buffer_memory;
|
|
||||||
p_peer_data->length_words = PM_SC_STATE_N_WORDS();
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_GATT_LOCAL:
|
|
||||||
p_peer_data->data.p_local_gatt_db = (pm_peer_data_local_gatt_db_t *)p_buffer_memory;
|
|
||||||
p_peer_data->length_words = PM_LOCAL_DB_N_WORDS(n_bytes);
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_GATT_REMOTE:
|
|
||||||
p_peer_data->data.p_remote_gatt_db = (pm_peer_data_remote_gatt_db_t *)p_buffer_memory;
|
|
||||||
p_peer_data->length_words = PM_REMOTE_DB_N_WORDS(n_bytes / sizeof(ble_gatt_db_srv_t));
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_APPLICATION:
|
|
||||||
p_peer_data->data.p_application_data = p_buffer_memory;
|
|
||||||
p_peer_data->length_words = PM_N_WORDS(n_bytes);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
p_peer_data->length_words = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void peer_data_const_point_to_buffer(pm_peer_data_const_t * p_peer_data, pm_peer_data_id_t data_id, uint8_t * p_buffer_memory, uint32_t n_bufs)
|
|
||||||
{
|
|
||||||
peer_data_point_to_buffer((pm_peer_data_t*)p_peer_data, data_id, p_buffer_memory, n_bufs);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pdb_write_buf_get(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_id_t data_id,
|
|
||||||
uint32_t n_bufs,
|
|
||||||
pm_peer_data_t * p_peer_data)
|
|
||||||
{
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
VERIFY_PARAM_NOT_NULL(p_peer_data);
|
|
||||||
if ( !PM_PEER_DATA_ID_IS_VALID(data_id)
|
|
||||||
|| (n_bufs == 0)
|
|
||||||
|| (n_bufs > N_WRITE_BUFFERS)
|
|
||||||
|| !pds_peer_id_is_allocated(peer_id))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
pdb_buffer_record_t * write_buffer_record;
|
|
||||||
uint8_t * p_buffer_memory;
|
|
||||||
|
|
||||||
write_buffer_record = write_buffer_record_find(peer_id, data_id);
|
|
||||||
|
|
||||||
if ((write_buffer_record != NULL) && (write_buffer_record->n_bufs < n_bufs))
|
|
||||||
{
|
|
||||||
// @TODO: Copy?
|
|
||||||
// Existing buffer is too small.
|
|
||||||
for (uint8_t i = 0; i < write_buffer_record->n_bufs; i++)
|
|
||||||
{
|
|
||||||
pm_buffer_release(&m_pdb.write_buffer, write_buffer_record->buffer_block_id + i);
|
|
||||||
}
|
|
||||||
write_buffer_record_invalidate(write_buffer_record);
|
|
||||||
write_buffer_record = NULL;
|
|
||||||
}
|
|
||||||
else if ((write_buffer_record != NULL) && write_buffer_record->n_bufs > n_bufs)
|
|
||||||
{
|
|
||||||
// Release excess blocks.
|
|
||||||
for (uint8_t i = n_bufs; i < write_buffer_record->n_bufs; i++)
|
|
||||||
{
|
|
||||||
pm_buffer_release(&m_pdb.write_buffer, write_buffer_record->buffer_block_id + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (write_buffer_record == NULL)
|
|
||||||
{
|
|
||||||
write_buffer_record_get(&write_buffer_record, peer_id, data_id);
|
|
||||||
if (write_buffer_record == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_BUSY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (write_buffer_record->buffer_block_id == BUFFER_INVALID_ID)
|
|
||||||
{
|
|
||||||
write_buffer_record->buffer_block_id = pm_buffer_block_acquire(&m_pdb.write_buffer, n_bufs);
|
|
||||||
|
|
||||||
if (write_buffer_record->buffer_block_id == BUFFER_INVALID_ID)
|
|
||||||
{
|
|
||||||
write_buffer_record_invalidate(write_buffer_record);
|
|
||||||
return NRF_ERROR_BUSY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
write_buffer_record->n_bufs = n_bufs;
|
|
||||||
|
|
||||||
p_buffer_memory = pm_buffer_ptr_get(&m_pdb.write_buffer, write_buffer_record->buffer_block_id);
|
|
||||||
|
|
||||||
if (p_buffer_memory == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INTERNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
peer_data_point_to_buffer(p_peer_data, data_id, p_buffer_memory, n_bufs);
|
|
||||||
switch(data_id)
|
|
||||||
{
|
|
||||||
case PM_PEER_DATA_ID_BONDING:
|
|
||||||
/* No action needed. */
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
|
|
||||||
/* No action needed. */
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_GATT_LOCAL:
|
|
||||||
{
|
|
||||||
uint32_t size_offset = sizeof(pm_peer_data_local_gatt_db_t);
|
|
||||||
p_peer_data->data.p_local_gatt_db->p_data = &p_buffer_memory[size_offset];
|
|
||||||
p_peer_data->data.p_local_gatt_db->len = (PDB_WRITE_BUF_SIZE*n_bufs)-size_offset;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_GATT_REMOTE:
|
|
||||||
{
|
|
||||||
uint32_t size_offset = sizeof(pm_peer_data_remote_gatt_db_t);
|
|
||||||
p_peer_data->data.p_remote_gatt_db->p_data = (ble_gatt_db_srv_t*)&(p_buffer_memory[size_offset]);
|
|
||||||
p_peer_data->data.p_remote_gatt_db->service_count
|
|
||||||
= ((PDB_WRITE_BUF_SIZE*n_bufs)-size_offset)/sizeof(ble_gatt_db_srv_t);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_APPLICATION:
|
|
||||||
{
|
|
||||||
p_peer_data->data.p_application_data = p_buffer_memory;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// Invalid data_id. This should have been picked up earlier.
|
|
||||||
return NRF_ERROR_INTERNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pdb_write_buf_release(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
|
|
||||||
{
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
|
|
||||||
ret_code_t err_code = NRF_SUCCESS;
|
|
||||||
pdb_buffer_record_t * p_write_buffer_record;
|
|
||||||
p_write_buffer_record = write_buffer_record_find(peer_id, data_id);
|
|
||||||
|
|
||||||
if (p_write_buffer_record == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_write_buffer_record->prepare_token != PDS_PREPARE_TOKEN_INVALID)
|
|
||||||
{
|
|
||||||
err_code = pds_peer_data_write_prepare_cancel(p_write_buffer_record->prepare_token);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
err_code = NRF_ERROR_INTERNAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
write_buffer_record_release(p_write_buffer_record);
|
|
||||||
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pdb_write_buf_store_prepare(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
|
|
||||||
{
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
|
|
||||||
ret_code_t err_code = NRF_SUCCESS;
|
|
||||||
pdb_buffer_record_t * p_write_buffer_record;
|
|
||||||
p_write_buffer_record = write_buffer_record_find(peer_id, data_id);
|
|
||||||
|
|
||||||
if (p_write_buffer_record == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_write_buffer_record->prepare_token == PDS_PREPARE_TOKEN_INVALID)
|
|
||||||
{
|
|
||||||
uint8_t * p_buffer_memory = pm_buffer_ptr_get(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id);
|
|
||||||
pm_peer_data_const_t peer_data = {.data_type = data_id};
|
|
||||||
|
|
||||||
if (p_buffer_memory == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INTERNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
peer_data_const_point_to_buffer(&peer_data, data_id, p_buffer_memory, p_write_buffer_record->n_bufs);
|
|
||||||
|
|
||||||
err_code = pds_peer_data_write_prepare(&peer_data, &p_write_buffer_record->prepare_token);
|
|
||||||
if (err_code == NRF_ERROR_INVALID_LENGTH)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INTERNAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static ret_code_t write_or_update(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_id_t data_id,
|
|
||||||
pm_peer_data_const_t * p_peer_data,
|
|
||||||
pm_store_token_t * p_store_token,
|
|
||||||
pm_prepare_token_t prepare_token)
|
|
||||||
{
|
|
||||||
pm_peer_data_flash_t old_peer_data;
|
|
||||||
pm_store_token_t old_store_token;
|
|
||||||
ret_code_t err_code = pds_peer_data_read_ptr_get(peer_id, data_id, &old_peer_data, &old_store_token);
|
|
||||||
|
|
||||||
if (err_code == NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
pds_peer_data_write_prepare_cancel(prepare_token);
|
|
||||||
err_code = pds_peer_data_update(peer_id, p_peer_data, old_store_token, p_store_token);
|
|
||||||
}
|
|
||||||
else if (err_code == NRF_ERROR_NOT_FOUND)
|
|
||||||
{
|
|
||||||
if (prepare_token == PDS_PREPARE_TOKEN_INVALID)
|
|
||||||
{
|
|
||||||
err_code = pds_peer_data_write(peer_id, p_peer_data, p_store_token);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err_code = pds_peer_data_write_prepared(peer_id, p_peer_data, prepare_token, p_store_token);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pdb_write_buf_store(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_id_t data_id)
|
|
||||||
{
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
|
|
||||||
ret_code_t err_code = NRF_SUCCESS;
|
|
||||||
pdb_buffer_record_t * p_write_buffer_record;
|
|
||||||
uint8_t * p_buffer_memory;
|
|
||||||
pm_peer_data_const_t peer_data = {.data_type = data_id};
|
|
||||||
|
|
||||||
|
|
||||||
p_write_buffer_record = write_buffer_record_find(peer_id, data_id);
|
|
||||||
|
|
||||||
if (p_write_buffer_record == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_write_buffer_record->store_requested)
|
|
||||||
{
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
p_buffer_memory = pm_buffer_ptr_get(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id);
|
|
||||||
|
|
||||||
if (p_buffer_memory == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INTERNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
peer_data_const_point_to_buffer(&peer_data, data_id, p_buffer_memory, p_write_buffer_record->n_bufs);
|
|
||||||
|
|
||||||
switch (data_id)
|
|
||||||
{
|
|
||||||
case PM_PEER_DATA_ID_BONDING:
|
|
||||||
peer_data.length_words = PM_BONDING_DATA_N_WORDS();
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
|
|
||||||
peer_data.length_words = PM_SC_STATE_N_WORDS();
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_GATT_LOCAL:
|
|
||||||
peer_data.length_words = PM_LOCAL_DB_N_WORDS(peer_data.data.p_local_gatt_db->len);
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_GATT_REMOTE:
|
|
||||||
peer_data.length_words = PM_REMOTE_DB_N_WORDS(peer_data.data.p_remote_gatt_db->service_count);
|
|
||||||
break;
|
|
||||||
case PM_PEER_DATA_ID_APPLICATION:
|
|
||||||
peer_data.length_words = PM_N_WORDS(p_write_buffer_record->n_bufs * PDB_WRITE_BUF_SIZE);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return NRF_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_code = write_or_update(peer_id, data_id, &peer_data, &p_write_buffer_record->store_token, p_write_buffer_record->prepare_token);
|
|
||||||
|
|
||||||
if (p_write_buffer_record->store_busy && p_write_buffer_record->store_flash_full)
|
|
||||||
{
|
|
||||||
m_pdb.n_writes--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err_code == NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
p_write_buffer_record->store_requested = true;
|
|
||||||
p_write_buffer_record->store_busy = false;
|
|
||||||
p_write_buffer_record->store_flash_full = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (err_code == NRF_ERROR_BUSY)
|
|
||||||
{
|
|
||||||
m_pdb.n_writes++;
|
|
||||||
p_write_buffer_record->store_busy = true;
|
|
||||||
p_write_buffer_record->store_flash_full = false;
|
|
||||||
err_code = NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
else if (err_code == NRF_ERROR_NO_MEM)
|
|
||||||
{
|
|
||||||
m_pdb.n_writes++;
|
|
||||||
p_write_buffer_record->store_busy = false;
|
|
||||||
p_write_buffer_record->store_flash_full = true;
|
|
||||||
}
|
|
||||||
else if ((err_code != NRF_ERROR_NO_MEM) && (err_code != NRF_ERROR_INVALID_PARAM))
|
|
||||||
{
|
|
||||||
err_code = NRF_ERROR_INTERNAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pdb_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
|
|
||||||
{
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
|
|
||||||
return pds_peer_data_clear(peer_id, data_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t pdb_n_peers(void)
|
|
||||||
{
|
|
||||||
if (!MODULE_INITIALIZED)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pds_n_peers();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pm_peer_id_t pdb_next_peer_id_get(pm_peer_id_t prev_peer_id)
|
|
||||||
{
|
|
||||||
if (!MODULE_INITIALIZED)
|
|
||||||
{
|
|
||||||
return PM_PEER_ID_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
return pds_next_peer_id_get(prev_peer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pdb_raw_read(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_id_t data_id,
|
|
||||||
pm_peer_data_t * p_peer_data)
|
|
||||||
{
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
return pds_peer_data_read(peer_id, data_id, p_peer_data, &p_peer_data->length_words);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pdb_raw_store(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_const_t * p_peer_data,
|
|
||||||
pm_store_token_t * p_store_token)
|
|
||||||
{
|
|
||||||
VERIFY_MODULE_INITIALIZED();
|
|
||||||
|
|
||||||
return write_or_update(peer_id, p_peer_data->data_type, p_peer_data, p_store_token, PDS_PREPARE_TOKEN_INVALID);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,354 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PEER_DATABASE_H__
|
|
||||||
#define PEER_DATABASE_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "peer_manager_types.h"
|
|
||||||
#include "sdk_errors.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup peer_database Peer Database
|
|
||||||
* @ingroup peer_manager
|
|
||||||
* @{
|
|
||||||
* @brief An internal module of @ref peer_manager. A module for simple management of reading and
|
|
||||||
* writing of peer data into persistent storage.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define PDB_WRITE_BUF_SIZE (sizeof(pm_peer_data_bonding_t))
|
|
||||||
|
|
||||||
/**@brief Events that can come from the peer_database module.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
PDB_EVT_WRITE_BUF_STORED, /**< A pdb_write_buf_store operation has completed successfully. */
|
|
||||||
PDB_EVT_RAW_STORED, /**< A pdb_raw_store operation has completed successfully. */
|
|
||||||
PDB_EVT_RAW_STORE_FAILED, /**< A pdb_raw_store operation has failed. */
|
|
||||||
PDB_EVT_CLEARED, /**< A pdb_clear operation has completed successfully. */
|
|
||||||
PDB_EVT_CLEAR_FAILED, /**< A pdb_clear operation has failed. */
|
|
||||||
PDB_EVT_COMPRESSED, /**< A compress procedure has completed. */
|
|
||||||
PDB_EVT_ERROR_NO_MEM, /**< An operation is blocked because the flash is full. It will be reattempted automatically after the next compress procedure. */
|
|
||||||
PDB_EVT_ERROR_UNEXPECTED, /**< An unexpected error occurred. This is a fatal error. */
|
|
||||||
} pdb_evt_id_t;
|
|
||||||
|
|
||||||
/**@brief Events that can come from the peer_database module.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
pdb_evt_id_t evt_id; /**< The event that has happened. */
|
|
||||||
pm_peer_id_t peer_id; /**< The id of the peer the event pertains to. */
|
|
||||||
pm_peer_data_id_t data_id; /**< The data the event pertains to. */
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
pm_store_token_t store_token; /**< A token identifying the store operation this event pertains to. */
|
|
||||||
} raw_stored_evt;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
pm_store_token_t store_token; /**< A token identifying the store operation this event pertains to. */
|
|
||||||
} error_raw_store_evt;
|
|
||||||
} params;
|
|
||||||
} pdb_evt_t;
|
|
||||||
|
|
||||||
/**@brief Event handler for events from the peer_data_storage module.
|
|
||||||
*
|
|
||||||
* @param[in] p_event The event that has happened.
|
|
||||||
*/
|
|
||||||
typedef void (*pdb_evt_handler_t)(pdb_evt_t const * p_event);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for registering for events from the peer database.
|
|
||||||
*
|
|
||||||
* @note This function will initialize the module if it is not already initialized.
|
|
||||||
*
|
|
||||||
* @param[in] evt_handler Event handler to register.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Registration successful.
|
|
||||||
* @retval NRF_ERROR_NO_MEM No more event handlers can be registered.
|
|
||||||
* @retval NRF_ERROR_NULL evt_handler was NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Unexpected return code from @ref pm_buffer_init.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE FDS has not been initalized.
|
|
||||||
*/
|
|
||||||
ret_code_t pdb_register(pdb_evt_handler_t evt_handler);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for allocating persistent bond storage for a peer.
|
|
||||||
*
|
|
||||||
* @return The ID of the newly allocated storage.
|
|
||||||
* @retval PM_PEER_ID_INVALID If no peer ID is available.
|
|
||||||
*/
|
|
||||||
pm_peer_id_t pdb_peer_allocate(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for freeing a peer's persistent bond storage.
|
|
||||||
*
|
|
||||||
* @note This function will call @ref pdb_write_buf_release on the data for this peer.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id ID to be freed.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Peer ID was released and clear operation was initiated successfully.
|
|
||||||
* @retval NRF_ERROR_BUSY Another peer_id clear was already requested or could not be started.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pdb_peer_free(pm_peer_id_t peer_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for retrieving pointers to read-only peer data.
|
|
||||||
*
|
|
||||||
* @note Reading this pointer is not safe in the strictest sense. If a safe read is required:
|
|
||||||
* - Disable interrupts
|
|
||||||
* - Call this function. If the return code is @ref NRF_SUCCESS, the following read is safe.
|
|
||||||
* - Read memory.
|
|
||||||
* - Enable interrupts.
|
|
||||||
* @note This buffer does not need to be released. It is a pointer directly to flash.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id ID of peer to retrieve data for.
|
|
||||||
* @param[in] data_id Which piece of data to get.
|
|
||||||
* @param[out] p_peer_data Pointer to immutable peer data.
|
|
||||||
* @param[out] p_token Token that can be used to lock data in flash and check data validity.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Data retrieved successfully.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated.
|
|
||||||
* @retval NRF_ERROR_NULL p_peer_data was NULL.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND This data was not found for this peer ID.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pdb_read_buf_get(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_id_t data_id,
|
|
||||||
pm_peer_data_flash_t * p_peer_data,
|
|
||||||
pm_store_token_t * p_token);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for retrieving pointers to a write buffer for peer data.
|
|
||||||
*
|
|
||||||
* @details This function will provide pointers to a buffer of the data. The data buffer will not be
|
|
||||||
* written to persistent storage until @ref pdb_write_buf_store is called. The buffer is
|
|
||||||
* released by calling either @ref pdb_write_buf_release, @ref pdb_write_buf_store, or
|
|
||||||
* @ref pdb_peer_free.
|
|
||||||
*
|
|
||||||
* When the data_id refers to a variable length data type, the available size is written
|
|
||||||
* to the data, both the top-level, and any internal length fields.
|
|
||||||
*
|
|
||||||
* @note Calling this function on a peer_id/data_id pair that already has a buffer created will
|
|
||||||
* give the same buffer, not create a new one. If n_bufs was increased since last time, the
|
|
||||||
* buffer might be relocated to be able to provide additional room. In this case, the data
|
|
||||||
* will be copied. If n_bufs was increased since last time, this function might return @ref
|
|
||||||
* NRF_ERROR_BUSY. In that case, the buffer is automatically released.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id ID of peer to get a write buffer for.
|
|
||||||
* @param[in] data_id Which piece of data to get.
|
|
||||||
* @param[in] n_bufs The number of contiguous buffers needed.
|
|
||||||
* @param[out] p_peer_data Pointers to mutable peer data.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Data retrieved successfully.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated, or n_bufs was 0
|
|
||||||
* or more than the total available buffers.
|
|
||||||
* @retval NRF_ERROR_NULL p_peer_data was NULL.
|
|
||||||
* @retval NRF_ERROR_BUSY Not enough buffer(s) available.
|
|
||||||
* @retval NRF_ERROR_INTERNAL Unexpected internal error.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pdb_write_buf_get(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_id_t data_id,
|
|
||||||
uint32_t n_bufs,
|
|
||||||
pm_peer_data_t * p_peer_data);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for freeing a write buffer allocated with @ref pdb_write_buf_get.
|
|
||||||
*
|
|
||||||
* @note This function will not write peer data to persistent memory. Data in released buffer will
|
|
||||||
* be lost.
|
|
||||||
*
|
|
||||||
* @note This function will undo any previous call to @ref pdb_write_buf_store_prepare for this
|
|
||||||
* piece of data.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id ID of peer to release buffer for.
|
|
||||||
* @param[in] data_id Which piece of data to release buffer for.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Successfully released buffer.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND No buffer was allocated for this peer ID/data ID pair.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
* @retval NRF_ERROR_INTERNAL Unexpected internal error.
|
|
||||||
*/
|
|
||||||
ret_code_t pdb_write_buf_release(pm_peer_id_t peer_id, pm_peer_data_id_t data_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for reserving space in persistent storage for data in a buffer.
|
|
||||||
*
|
|
||||||
* @note This function only works for data which has a write buffer allocated. If the write buffer
|
|
||||||
* is released, this prepare is undone.
|
|
||||||
*
|
|
||||||
* @note If space has already been reserved for this data, nothing is done.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id The peer whose data to reserve space for.
|
|
||||||
* @param[in] data_id The type of data to reserve space for.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Successfully reserved space in persistent storage.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Not enough room in persistent storage.
|
|
||||||
* @retval NRF_ERROR_BUSY Could not process request at this time. Reattempt later.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND No buffer has been allocated for this peer ID/data ID pair.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pdb_write_buf_store_prepare(pm_peer_id_t peer_id, pm_peer_data_id_t data_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for writing data into persistent storage. Writing happens asynchronously.
|
|
||||||
*
|
|
||||||
* @note This will unlock the data after it has been written.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id ID of peer to store data for.
|
|
||||||
* @param[in] data_id Which piece of data to store.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Data storing was successfully started.
|
|
||||||
* @retval NRF_ERROR_NO_MEM No space available in persistent storage. Please clear some
|
|
||||||
* space, the operation will be reattempted after the next compress
|
|
||||||
* procedure. This error will not happen if
|
|
||||||
* @ref pdb_write_buf_store_prepare is called beforehand.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Data ID was invalid.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND No buffer has been allocated for this peer ID/data ID pair.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
* @retval NRF_ERROR_INTERNAL Unexpected internal error.
|
|
||||||
*/
|
|
||||||
ret_code_t pdb_write_buf_store(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_id_t data_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for clearing data from persistent storage.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id ID of peer to clear data for.
|
|
||||||
* @param[in] data_id Which piece of data to clear.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Data clear was successfully started.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Data ID was invalid.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND Nothing to clear for this data for this peer ID.
|
|
||||||
* @retval NRF_ERROR_BUSY Could not process request at this time. Reattempt later.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pdb_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for querying the number of valid peer IDs available. I.E the number of peers
|
|
||||||
* in persistent storage.
|
|
||||||
*
|
|
||||||
* @return The number of valid peer IDs.
|
|
||||||
*/
|
|
||||||
uint32_t pdb_n_peers(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for getting the next peer ID in the sequence of all used peer IDs. Can be
|
|
||||||
* used to loop through all used peer IDs.
|
|
||||||
*
|
|
||||||
* @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary
|
|
||||||
* peer ID.
|
|
||||||
*
|
|
||||||
* @param[in] prev_peer_id The previous peer ID.
|
|
||||||
*
|
|
||||||
* @return The next peer ID.
|
|
||||||
* @return The first ordinary peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID.
|
|
||||||
* @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID.
|
|
||||||
*/
|
|
||||||
pm_peer_id_t pdb_next_peer_id_get(pm_peer_id_t prev_peer_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for updating currently stored peer data to a new version
|
|
||||||
*
|
|
||||||
* @details Updating happens asynchronously.
|
|
||||||
* Expect a @ref PDS_EVT_STORED or @ref PDS_EVT_ERROR_STORE for the store token
|
|
||||||
* and a @ref PDS_EVT_ERROR_CLEAR or @ref PDS_EVT_ERROR_CLEAR for the old token
|
|
||||||
*
|
|
||||||
* @param[in] peer_data New data
|
|
||||||
* @param[in] old_token Store token for the old data
|
|
||||||
* @param[out] p_store_token Store token for the new data
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCESS The update was initiated successfully
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND The old store token was invalid.
|
|
||||||
* @retval NRF_ERROR_NULL Data contained a NULL pointer.
|
|
||||||
* @retval NRF_ERROR_NO_MEM No space available in persistent storage.
|
|
||||||
* @retval NRF_ERROR_BUSY FDS or underlying modules are busy and can't take any
|
|
||||||
* more requests
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pdb_peer_data_update(pm_peer_data_const_t peer_data,
|
|
||||||
pm_store_token_t old_token,
|
|
||||||
pm_store_token_t * p_store_token);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for reading data directly from persistent storage to external memory.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id ID of peer to read data for.
|
|
||||||
* @param[in] data_id Which piece of data to read.
|
|
||||||
* @param[inout] p_peer_data Where to store the data. If the data to be read has variable length,
|
|
||||||
* the appropriate length field needs to reflect the available buffer
|
|
||||||
* space. On a successful read, the length field is updated to match the
|
|
||||||
* length of the read data.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Data successfully read.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated.
|
|
||||||
* @retval NRF_ERROR_NULL p_peer_data contained a NULL pointer.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND This data was not found for this peer ID.
|
|
||||||
* @retval NRF_ERROR_DATA_SIZE The provided buffer was not large enough.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pdb_raw_read(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_id_t data_id,
|
|
||||||
pm_peer_data_t * p_peer_data);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for writing data directly to persistent storage from external memory.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id ID of peer to write data for.
|
|
||||||
* @param[in] p_peer_data Data to store.
|
|
||||||
* @param[out] p_store_token A token identifying this particular store operation. The token can be
|
|
||||||
* used to identify events pertaining to this operation.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Data successfully written.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated.
|
|
||||||
* @retval NRF_ERROR_NULL p_peer_data contained a NULL pointer.
|
|
||||||
* @retval NRF_ERROR_NO_MEM No space available in persistent storage.
|
|
||||||
* @retval NRF_ERROR_INVALID_LENGTH Data length above the maximum allowed.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Module is not initialized.
|
|
||||||
*/
|
|
||||||
ret_code_t pdb_raw_store(pm_peer_id_t peer_id,
|
|
||||||
pm_peer_data_const_t * p_peer_data,
|
|
||||||
pm_store_token_t * p_store_token);
|
|
||||||
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif /* PEER_DATABASE_H__ */
|
|
||||||
|
|
||||||
|
|
|
@ -1,131 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "peer_id.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "sdk_errors.h"
|
|
||||||
#include "peer_manager_types.h"
|
|
||||||
#include "pm_mutex.h"
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t peer_ids[MUTEX_STORAGE_SIZE(PM_PEER_ID_N_AVAILABLE_IDS)]; /*< bitmap. */
|
|
||||||
} pi_t;
|
|
||||||
|
|
||||||
|
|
||||||
static pi_t m_pi = {.peer_ids = {0}};
|
|
||||||
|
|
||||||
|
|
||||||
static void internal_state_reset(pi_t * p_pi)
|
|
||||||
{
|
|
||||||
memset(p_pi, 0, sizeof(pi_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void peer_id_init(void)
|
|
||||||
{
|
|
||||||
internal_state_reset(&m_pi);
|
|
||||||
pm_mutex_init(m_pi.peer_ids, PM_PEER_ID_N_AVAILABLE_IDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pm_peer_id_t peer_id_allocate(pm_peer_id_t peer_id)
|
|
||||||
{
|
|
||||||
pm_peer_id_t allocated_peer_id = PM_PEER_ID_INVALID;
|
|
||||||
if (peer_id == PM_PEER_ID_INVALID)
|
|
||||||
{
|
|
||||||
allocated_peer_id = pm_mutex_lock_first_available(m_pi.peer_ids, PM_PEER_ID_N_AVAILABLE_IDS);
|
|
||||||
if (allocated_peer_id == PM_PEER_ID_N_AVAILABLE_IDS)
|
|
||||||
{
|
|
||||||
allocated_peer_id = PM_PEER_ID_INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS)
|
|
||||||
{
|
|
||||||
bool lock_success = pm_mutex_lock(m_pi.peer_ids, peer_id);
|
|
||||||
allocated_peer_id = lock_success ? peer_id : PM_PEER_ID_INVALID;
|
|
||||||
}
|
|
||||||
return allocated_peer_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void peer_id_free(pm_peer_id_t peer_id)
|
|
||||||
{
|
|
||||||
if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS)
|
|
||||||
{
|
|
||||||
pm_mutex_unlock(m_pi.peer_ids, peer_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool peer_id_is_allocated(pm_peer_id_t peer_id)
|
|
||||||
{
|
|
||||||
if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS)
|
|
||||||
{
|
|
||||||
return pm_mutex_lock_status_get(m_pi.peer_ids, peer_id);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pm_peer_id_t peer_id_next_id_get(pm_peer_id_t prev_peer_id)
|
|
||||||
{
|
|
||||||
pm_peer_id_t i = (prev_peer_id == PM_PEER_ID_INVALID) ? 0 : (prev_peer_id + 1);
|
|
||||||
for (; i < PM_PEER_ID_N_AVAILABLE_IDS; i++)
|
|
||||||
{
|
|
||||||
if (pm_mutex_lock_status_get(m_pi.peer_ids, i))
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return PM_PEER_ID_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t peer_id_n_ids(void)
|
|
||||||
{
|
|
||||||
uint32_t n_ids = 0;
|
|
||||||
|
|
||||||
for (pm_peer_id_t i = 0; i < PM_PEER_ID_N_AVAILABLE_IDS; i++)
|
|
||||||
{
|
|
||||||
n_ids += pm_mutex_lock_status_get(m_pi.peer_ids, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return n_ids;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,112 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PEER_ID_H__
|
|
||||||
#define PEER_ID_H__
|
|
||||||
|
|
||||||
|
|
||||||
#include "stdint.h"
|
|
||||||
#include "sdk_errors.h"
|
|
||||||
#include "ble_gap.h"
|
|
||||||
#include "peer_manager_types.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup peer_id Peer IDs
|
|
||||||
* @ingroup peer_manager
|
|
||||||
* @{
|
|
||||||
* @brief An internal module of @ref peer_manager. This module keeps track of which peer IDs are in
|
|
||||||
* use and which are free.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for initializing the module.
|
|
||||||
*/
|
|
||||||
void peer_id_init(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for claiming an unused peer ID.
|
|
||||||
*
|
|
||||||
* @param peer_id The peer ID to allocate. If this is @ref PM_PEER_ID_INVALID, the first available
|
|
||||||
* will be allocated.
|
|
||||||
*
|
|
||||||
* @return The allocated peer ID.
|
|
||||||
* @retval PM_PEER_ID_INVALID If no peer ID could be allocated or module is not initialized.
|
|
||||||
*/
|
|
||||||
pm_peer_id_t peer_id_allocate(pm_peer_id_t peer_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for freeing a peer ID and clearing all data associated with it in persistent
|
|
||||||
* storage.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id Peer ID to free.
|
|
||||||
*/
|
|
||||||
void peer_id_free(pm_peer_id_t peer_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for finding out whether a peer ID is in use.
|
|
||||||
*
|
|
||||||
* @param[in] peer_id The peer ID to inquire about.
|
|
||||||
*
|
|
||||||
* @retval true peer_id is in use.
|
|
||||||
* @retval false peer_id is free, or the module is not initialized.
|
|
||||||
*/
|
|
||||||
bool peer_id_is_allocated(pm_peer_id_t peer_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for getting the next peer ID in the sequence of all used peer IDs. Can be
|
|
||||||
* used to loop through all used peer IDs.
|
|
||||||
*
|
|
||||||
* @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary
|
|
||||||
* peer ID.
|
|
||||||
*
|
|
||||||
* @param[in] prev_peer_id The previous peer ID.
|
|
||||||
*
|
|
||||||
* @return The next peer ID.
|
|
||||||
* @return The first used peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID.
|
|
||||||
* @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID or the module is
|
|
||||||
* not initialized.
|
|
||||||
*/
|
|
||||||
pm_peer_id_t peer_id_next_id_get(pm_peer_id_t prev_peer_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for querying the number of valid peer IDs available. I.E the number of peers
|
|
||||||
* in persistent storage.
|
|
||||||
*
|
|
||||||
* @return The number of valid peer IDs, or 0 if module is not initialized.
|
|
||||||
*/
|
|
||||||
uint32_t peer_id_n_ids(void);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif /* PEER_ID_H__ */
|
|
|
@ -1,301 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PEER_MANAGER_TYPES_H__
|
|
||||||
#define PEER_MANAGER_TYPES_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file peer_manager_types.h
|
|
||||||
*
|
|
||||||
* @addtogroup peer_manager
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include "ble_gap.h"
|
|
||||||
#include "ble_hci.h"
|
|
||||||
#include "ble_gatt_db.h"
|
|
||||||
#include "compiler_abstraction.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Handle to uniquely identify a peer for which we have persistently stored data.
|
|
||||||
*/
|
|
||||||
typedef uint16_t pm_peer_id_t;
|
|
||||||
|
|
||||||
#define PM_PEER_ID_INVALID 0xFFFF /**< Invalid value for @ref pm_peer_id_t. */
|
|
||||||
#define PM_PEER_ID_N_AVAILABLE_IDS 256 /**< The number of available peer IDs. */
|
|
||||||
#define PM_LOCAL_DB_LEN_OVERHEAD_BYTES offsetof(pm_peer_data_local_gatt_db_flash_t, p_data)
|
|
||||||
#define PM_REMOTE_DB_LEN_OVERHEAD_BYTES offsetof(pm_peer_data_remote_gatt_db_flash_t, p_data)
|
|
||||||
|
|
||||||
static __INLINE uint16_t PM_N_WORDS(uint16_t n_bytes)
|
|
||||||
{
|
|
||||||
return ((n_bytes + 3) >> 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Errors originating from the Peer Manager module.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
PM_SEC_ERROR_CODE_PIN_OR_KEY_MISSING = BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING, /**< Encryption failed because the peripheral has lost the LTK for this bond. */
|
|
||||||
PM_SEC_ERROR_CODE_MIC_FAILURE = BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE, /**< Pairing ended with disconnection because of mismatching keys. */
|
|
||||||
PM_SEC_ERROR_SMP_TIMEOUT, /**< Pairing/bonding could not start because an SMP timeout has already happened on this link. This means that no more pairing or bonding can happen on this link. To be able to pair or bond, the link must be disconnected and then reconnected. See Bluetooth specification 4.2 section 3.H.3.4 */
|
|
||||||
} pm_sec_error_code_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Enumeration describing the different procedures that can lead to an encrypted link.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
PM_LINK_SECURED_PROCEDURE_ENCRYPTION, /**< Using an LTK shared during a previous bonding procedure to encrypt the link. */
|
|
||||||
PM_LINK_SECURED_PROCEDURE_BONDING, /**< A pairing procedure, followed by a bonding procedure. */
|
|
||||||
PM_LINK_SECURED_PROCEDURE_PAIRING, /**< A pairing procedure with no bonding. */
|
|
||||||
} pm_sec_procedure_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Data associated with a bond to a peer.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t own_role; /**< The role of the local device during bonding. */
|
|
||||||
ble_gap_id_key_t peer_id; /**< The peer's peer address and identity resolution key. */
|
|
||||||
ble_gap_enc_key_t peer_ltk; /**< The peer's long term encryption key. */
|
|
||||||
ble_gap_enc_key_t own_ltk; /**< Locally generated long term encryption key, distributed to the peer. */
|
|
||||||
} pm_peer_data_bonding_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for calculating the flash size of bonding data.
|
|
||||||
*
|
|
||||||
* @return The number of words the data will take in flash.
|
|
||||||
*/
|
|
||||||
static __INLINE uint16_t PM_BONDING_DATA_N_WORDS(void)
|
|
||||||
{
|
|
||||||
return PM_N_WORDS(sizeof(pm_peer_data_bonding_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for calculating the flash size of service changed pending state.
|
|
||||||
*
|
|
||||||
* @return The number of words the data will take in flash.
|
|
||||||
*/
|
|
||||||
static __INLINE uint16_t PM_SC_STATE_N_WORDS(void)
|
|
||||||
{
|
|
||||||
return PM_N_WORDS(sizeof(bool));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Data on a local GATT database.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t flags; /**< Flags describing the database attributes. */
|
|
||||||
uint16_t len; /**< Size of attribute array. */
|
|
||||||
uint8_t * p_data; /**< Array to hold the database attributes. */
|
|
||||||
} pm_peer_data_local_gatt_db_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Data on a local GATT database, as formatted in flash.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t flags;
|
|
||||||
uint16_t len;
|
|
||||||
uint16_t _padding;
|
|
||||||
uint8_t p_data[];
|
|
||||||
} pm_peer_data_local_gatt_db_flash_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for calculating the flash size of local GATT database data.
|
|
||||||
*
|
|
||||||
* @param[in] local_db_len The length of the database as reported by the SoftDevice.
|
|
||||||
*
|
|
||||||
* @return The number of words the data will take in flash.
|
|
||||||
*/
|
|
||||||
static __INLINE uint16_t PM_LOCAL_DB_N_WORDS(uint16_t local_db_len)
|
|
||||||
{
|
|
||||||
return PM_N_WORDS(local_db_len + PM_LOCAL_DB_LEN_OVERHEAD_BYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for calculating the length of a local GATT database attribute array.
|
|
||||||
*
|
|
||||||
* @param[in] n_words The number of words the data takes in flash.
|
|
||||||
*
|
|
||||||
* @return The length of the database attribute array.
|
|
||||||
*/
|
|
||||||
static __INLINE uint16_t PM_LOCAL_DB_LEN(uint16_t n_words)
|
|
||||||
{
|
|
||||||
return ((n_words * 4) - PM_LOCAL_DB_LEN_OVERHEAD_BYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Data on a remote GATT database.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t service_count; /**< Number of stored services. */
|
|
||||||
ble_gatt_db_srv_t * p_data; /**< Array to hold the database attributes. */
|
|
||||||
} pm_peer_data_remote_gatt_db_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Data on a remote GATT database, as formatted in flash.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t service_count;
|
|
||||||
ble_gatt_db_srv_t p_data[];
|
|
||||||
} pm_peer_data_remote_gatt_db_flash_t;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for calculating the flash size of remote GATT database data.
|
|
||||||
*
|
|
||||||
* @param[in] service_count The number of services in the service array.
|
|
||||||
*
|
|
||||||
* @return The number of words the data will take in flash.
|
|
||||||
*/
|
|
||||||
static __INLINE uint16_t PM_REMOTE_DB_N_WORDS(uint16_t service_count)
|
|
||||||
{
|
|
||||||
return PM_N_WORDS((sizeof(ble_gatt_db_srv_t) * service_count) + PM_REMOTE_DB_LEN_OVERHEAD_BYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Union of all data associated with one peer.
|
|
||||||
*/
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
pm_peer_data_bonding_t * p_bonding_data; /**< The exchanged bond information in addition to metadata of the bonding. */
|
|
||||||
bool * p_service_changed_pending; /**< Whether a service changed indication should be sent to the peer. */
|
|
||||||
pm_peer_data_local_gatt_db_t * p_local_gatt_db; /**< Persistent information pertaining to a peer GATT client. */
|
|
||||||
pm_peer_data_remote_gatt_db_t * p_remote_gatt_db; /**< Persistent information pertaining to a peer GATT server. */
|
|
||||||
uint8_t * p_application_data; /**< Arbitrary data to associate with the peer. This data can be freely used by the application. */
|
|
||||||
} pm_peer_data_unit_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Immutable version of @ref pm_peer_data_unit_t.
|
|
||||||
*/
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
pm_peer_data_bonding_t const * p_bonding_data;
|
|
||||||
bool const * p_service_changed_pending;
|
|
||||||
pm_peer_data_local_gatt_db_t const * p_local_gatt_db;
|
|
||||||
pm_peer_data_remote_gatt_db_t const * p_remote_gatt_db;
|
|
||||||
uint8_t const * p_application_data;
|
|
||||||
} pm_peer_data_unit_const_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Data from @ref pm_peer_data_unit_t, as mapped in flash.
|
|
||||||
*/
|
|
||||||
typedef union
|
|
||||||
{
|
|
||||||
pm_peer_data_bonding_t const * p_bonding_data;
|
|
||||||
bool const * p_service_changed_pending;
|
|
||||||
pm_peer_data_local_gatt_db_flash_t const * p_local_gatt_db;
|
|
||||||
pm_peer_data_remote_gatt_db_flash_t const * p_remote_gatt_db;
|
|
||||||
uint8_t const * p_application_data;
|
|
||||||
} pm_peer_data_unit_flash_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief The different types of data associated with a peer.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
PM_PEER_DATA_ID_BONDING,
|
|
||||||
PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING,
|
|
||||||
PM_PEER_DATA_ID_GATT_LOCAL,
|
|
||||||
PM_PEER_DATA_ID_GATT_REMOTE,
|
|
||||||
PM_PEER_DATA_ID_APPLICATION,
|
|
||||||
PM_PEER_DATA_ID_INVALID,
|
|
||||||
} pm_peer_data_id_t;
|
|
||||||
|
|
||||||
|
|
||||||
//STATIC_ASSERT_MSG(sizeof(pm_peer_data_t) == sizeof(pm_peer_data_const_t), "Size of pm_peer_data_t different from immutable version.");
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro saying whether a data_id is valid, i.e. one of the valid enum values.
|
|
||||||
*
|
|
||||||
* @param[in] data_id The data_id to check.
|
|
||||||
*/
|
|
||||||
static __INLINE bool PM_PEER_DATA_ID_IS_VALID(pm_peer_data_id_t data_id)
|
|
||||||
{
|
|
||||||
return ((data_id - PM_PEER_DATA_ID_BONDING) < (PM_PEER_DATA_ID_INVALID - PM_PEER_DATA_ID_BONDING));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief One piece of data associated with a peer, together with the type.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t length_words;
|
|
||||||
pm_peer_data_id_t data_type;
|
|
||||||
pm_peer_data_unit_t data;
|
|
||||||
} pm_peer_data_t;
|
|
||||||
|
|
||||||
/**@brief Immutable version of @ref pm_peer_data_t.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t length_words;
|
|
||||||
pm_peer_data_id_t data_type;
|
|
||||||
pm_peer_data_unit_const_t data;
|
|
||||||
} pm_peer_data_const_t;
|
|
||||||
|
|
||||||
/**@brief Data from @ref pm_peer_data_t, as mapped in flash.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t length_words;
|
|
||||||
pm_peer_data_id_t data_type;
|
|
||||||
pm_peer_data_unit_flash_t data;
|
|
||||||
} pm_peer_data_flash_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Typedef for type used for write prepares. Used to reserve space in flash
|
|
||||||
*/
|
|
||||||
typedef uint32_t pm_prepare_token_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Typedef for type used to hold reference to stored item in flash.
|
|
||||||
* this token can be used for locking and validity check
|
|
||||||
*/
|
|
||||||
typedef uint32_t pm_store_token_t;
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif /* PEER_MANAGER_TYPES_H__ */
|
|
|
@ -1,142 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "pm_buffer.h"
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "nrf_error.h"
|
|
||||||
#include "pm_mutex.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define BUFFER_IS_VALID(p_buffer) ((p_buffer != NULL) \
|
|
||||||
&& (p_buffer->p_memory != NULL) \
|
|
||||||
&& (p_buffer->p_mutex != NULL))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t pm_buffer_init(pm_buffer_t * p_buffer,
|
|
||||||
uint8_t * p_buffer_memory,
|
|
||||||
uint32_t buffer_memory_size,
|
|
||||||
uint8_t * p_mutex_memory,
|
|
||||||
uint32_t mutex_memory_size,
|
|
||||||
uint32_t n_blocks,
|
|
||||||
uint32_t block_size)
|
|
||||||
{
|
|
||||||
if ( (p_buffer != NULL)
|
|
||||||
&& (p_buffer_memory != NULL)
|
|
||||||
&& (p_mutex_memory != NULL)
|
|
||||||
&& (buffer_memory_size >= (n_blocks*block_size))
|
|
||||||
&& (mutex_memory_size >= MUTEX_STORAGE_SIZE(n_blocks))
|
|
||||||
&& (n_blocks != 0)
|
|
||||||
&& (block_size != 0))
|
|
||||||
{
|
|
||||||
p_buffer->p_memory = p_buffer_memory;
|
|
||||||
p_buffer->p_mutex = p_mutex_memory;
|
|
||||||
p_buffer->n_blocks = n_blocks;
|
|
||||||
p_buffer->block_size = block_size;
|
|
||||||
pm_mutex_init(p_buffer->p_mutex, n_blocks);
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t pm_buffer_block_acquire(pm_buffer_t * p_buffer, uint32_t n_blocks)
|
|
||||||
{
|
|
||||||
if (!BUFFER_IS_VALID(p_buffer))
|
|
||||||
{
|
|
||||||
return ( BUFFER_INVALID_ID );
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t first_locked_mutex = BUFFER_INVALID_ID;
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < p_buffer->n_blocks; i++)
|
|
||||||
{
|
|
||||||
if (pm_mutex_lock(p_buffer->p_mutex, i))
|
|
||||||
{
|
|
||||||
if (first_locked_mutex == BUFFER_INVALID_ID)
|
|
||||||
{
|
|
||||||
first_locked_mutex = i;
|
|
||||||
}
|
|
||||||
if ((i - first_locked_mutex + 1) >= 0 && ((uint32_t)(i - first_locked_mutex + 1)) == n_blocks)
|
|
||||||
{
|
|
||||||
return first_locked_mutex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (first_locked_mutex != BUFFER_INVALID_ID)
|
|
||||||
{
|
|
||||||
for (uint8_t j = first_locked_mutex; j < i; j++)
|
|
||||||
{
|
|
||||||
pm_buffer_release(p_buffer, j);
|
|
||||||
}
|
|
||||||
first_locked_mutex = BUFFER_INVALID_ID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ( BUFFER_INVALID_ID );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t * pm_buffer_ptr_get(pm_buffer_t * p_buffer, uint8_t id)
|
|
||||||
{
|
|
||||||
if (!BUFFER_IS_VALID(p_buffer))
|
|
||||||
{
|
|
||||||
return ( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (id != BUFFER_INVALID_ID)
|
|
||||||
&& pm_mutex_lock_status_get(p_buffer->p_mutex, id) )
|
|
||||||
{
|
|
||||||
return ( &p_buffer->p_memory[id*p_buffer->block_size] );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ( NULL );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void pm_buffer_release(pm_buffer_t * p_buffer, uint8_t id)
|
|
||||||
{
|
|
||||||
if ( BUFFER_IS_VALID(p_buffer)
|
|
||||||
&& (id != BUFFER_INVALID_ID)
|
|
||||||
&& pm_mutex_lock_status_get(p_buffer->p_mutex, id))
|
|
||||||
{
|
|
||||||
pm_mutex_unlock(p_buffer->p_mutex, id);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,133 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef BUFFER_H__
|
|
||||||
#define BUFFER_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "sdk_errors.h"
|
|
||||||
#include "pm_mutex.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup pm_buffer Buffer
|
|
||||||
* @ingroup peer_manager
|
|
||||||
* @{
|
|
||||||
* @brief An internal module of @ref peer_manager. This module provides a simple buffer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define BUFFER_INVALID_ID 0xFF
|
|
||||||
|
|
||||||
#define PM_BUFFER_INIT(p_buffer, n_blocks, block_size, err_code) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
static uint8_t buffer_memory[(n_blocks) * (block_size)]; \
|
|
||||||
static uint8_t mutex_memory[MUTEX_STORAGE_SIZE(n_blocks)]; \
|
|
||||||
err_code = pm_buffer_init((p_buffer), \
|
|
||||||
buffer_memory, \
|
|
||||||
(n_blocks) * (block_size), \
|
|
||||||
mutex_memory, \
|
|
||||||
MUTEX_STORAGE_SIZE(n_blocks), \
|
|
||||||
(n_blocks), \
|
|
||||||
(block_size)); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t * p_memory; /**< The storage for all buffer entries. The size of the buffer must be n_blocks*block_size. */
|
|
||||||
uint8_t * p_mutex; /**< A mutex group with one mutex for each buffer entry. */
|
|
||||||
uint32_t n_blocks; /**< The number of allocatable blocks in the buffer. */
|
|
||||||
uint32_t block_size; /**< The size of each block in the buffer. */
|
|
||||||
} pm_buffer_t;
|
|
||||||
|
|
||||||
/**@brief Function for initializing a buffer instance.
|
|
||||||
*
|
|
||||||
* @param[out] p_buffer The buffer instance to initialize.
|
|
||||||
* @param[in] p_buffer_memory The memory this buffer will use.
|
|
||||||
* @param[in] buffer_memory_size The size of p_buffer_memory. This must be at least
|
|
||||||
* n_blocks*block_size.
|
|
||||||
* @param[in] p_mutex_memory The memory for the mutexes. This must be at least
|
|
||||||
* @ref MUTEX_STORAGE_SIZE(n_blocks).
|
|
||||||
* @param[in] mutex_memory_size The size of p_mutex_memory.
|
|
||||||
* @param[in] n_blocks The number of blocks in the buffer.
|
|
||||||
* @param[in] block_size The size of each block.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Successfully initialized buffer instance.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM A parameter was 0 or NULL or a size was too small.
|
|
||||||
*/
|
|
||||||
ret_code_t pm_buffer_init(pm_buffer_t * p_buffer,
|
|
||||||
uint8_t * p_buffer_memory,
|
|
||||||
uint32_t buffer_memory_size,
|
|
||||||
uint8_t * p_mutex_memory,
|
|
||||||
uint32_t mutex_memory_size,
|
|
||||||
uint32_t n_blocks,
|
|
||||||
uint32_t block_size);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for acquiring a buffer block in a buffer.
|
|
||||||
*
|
|
||||||
* @param[in] p_buffer The buffer instance acquire from.
|
|
||||||
* @param[in] n_blocks The number of contiguous blocks to acquire.
|
|
||||||
*
|
|
||||||
* @return The id of the acquired block, if successful.
|
|
||||||
* @retval BUFFER_INVALID_ID If unsuccessful.
|
|
||||||
*/
|
|
||||||
uint8_t pm_buffer_block_acquire(pm_buffer_t * p_buffer, uint32_t n_blocks);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for getting a pointer to a specific buffer block.
|
|
||||||
*
|
|
||||||
* @param[in] p_buffer The buffer instance get from.
|
|
||||||
* @param[in] id The id of the buffer to get the pointer for.
|
|
||||||
*
|
|
||||||
* @return A pointer to the buffer for the specified id, if the id is valid.
|
|
||||||
* @retval NULL If the id is invalid.
|
|
||||||
*/
|
|
||||||
uint8_t * pm_buffer_ptr_get(pm_buffer_t * p_buffer, uint8_t id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for releasing a buffer block.
|
|
||||||
*
|
|
||||||
* @param[in] p_buffer The buffer instance containing the block to release.
|
|
||||||
* @param[in] id The id of the block to release.
|
|
||||||
*/
|
|
||||||
void pm_buffer_release(pm_buffer_t * p_buffer, uint8_t id);
|
|
||||||
|
|
||||||
|
|
||||||
#endif // BUFFER_H__
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
|
@ -1,135 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "pm_mutex.h"
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "nrf_error.h"
|
|
||||||
#include "app_util_platform.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Locks the mutex defined by the mask.
|
|
||||||
*
|
|
||||||
* @param p_mutex pointer to the mutex storage.
|
|
||||||
* @param mutex_mask the mask identifying the mutex position.
|
|
||||||
*
|
|
||||||
* @retval true if the mutex could be locked.
|
|
||||||
* @retval false if the mutex was already locked.
|
|
||||||
*/
|
|
||||||
static bool lock_by_mask(uint8_t * p_mutex, uint8_t mutex_mask)
|
|
||||||
{
|
|
||||||
bool success = false;
|
|
||||||
|
|
||||||
if ( (*p_mutex & mutex_mask) == 0 )
|
|
||||||
{
|
|
||||||
CRITICAL_REGION_ENTER();
|
|
||||||
if ( (*p_mutex & mutex_mask) == 0 )
|
|
||||||
{
|
|
||||||
*p_mutex |= mutex_mask;
|
|
||||||
|
|
||||||
success = true;
|
|
||||||
}
|
|
||||||
CRITICAL_REGION_EXIT();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ( success );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void pm_mutex_init(uint8_t * p_mutex, uint16_t mutex_size)
|
|
||||||
{
|
|
||||||
if (p_mutex != NULL)
|
|
||||||
{
|
|
||||||
memset(&p_mutex[0], 0, MUTEX_STORAGE_SIZE(mutex_size));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool pm_mutex_lock(uint8_t * p_mutex, uint16_t mutex_id)
|
|
||||||
{
|
|
||||||
if (p_mutex != NULL)
|
|
||||||
{
|
|
||||||
return ( lock_by_mask(&(p_mutex[mutex_id >> 3]), (1 << (mutex_id & 0x07))) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void pm_mutex_unlock(uint8_t * p_mutex, uint16_t mutex_id)
|
|
||||||
{
|
|
||||||
uint8_t mutex_base = mutex_id >> 3;
|
|
||||||
uint8_t mutex_mask = (1 << (mutex_id & 0x07));
|
|
||||||
|
|
||||||
if ((p_mutex != NULL)
|
|
||||||
&& (p_mutex[mutex_base] & mutex_mask))
|
|
||||||
{
|
|
||||||
CRITICAL_REGION_ENTER();
|
|
||||||
p_mutex[mutex_base] &= ~mutex_mask;
|
|
||||||
CRITICAL_REGION_EXIT();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t pm_mutex_lock_first_available(uint8_t * p_mutex, uint16_t mutex_size)
|
|
||||||
{
|
|
||||||
if (p_mutex != NULL)
|
|
||||||
{
|
|
||||||
for ( uint16_t i = 0; i < mutex_size; i++ )
|
|
||||||
{
|
|
||||||
if ( lock_by_mask(&(p_mutex[i >> 3]), 1 << (i & 0x07)) )
|
|
||||||
{
|
|
||||||
return ( i );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ( mutex_size );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool pm_mutex_lock_status_get(uint8_t * p_mutex, uint16_t mutex_id)
|
|
||||||
{
|
|
||||||
if (p_mutex != NULL)
|
|
||||||
{
|
|
||||||
return ( (p_mutex[mutex_id >> 3] & (1 << (mutex_id & 0x07))) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,108 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef MUTEX_H__
|
|
||||||
#define MUTEX_H__
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup pm_mutex Mutex
|
|
||||||
* @ingroup peer_manager
|
|
||||||
* @{
|
|
||||||
* @brief An internal module of @ref peer_manager. This module provides thread-safe mutexes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Defines the storage size of a specified mutex group.
|
|
||||||
*
|
|
||||||
* @param number_of_mutexes the number of mutexes in the group.
|
|
||||||
*/
|
|
||||||
#define MUTEX_STORAGE_SIZE(number_of_mutexes) ((7 + (number_of_mutexes)) >> 3)
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Initializes a mutex group.
|
|
||||||
*
|
|
||||||
* @param[in] p_mutex Pointer to the mutex group. See @ref MUTEX_STORAGE_SIZE().
|
|
||||||
* @param[in] mutex_size The size of the mutex group in number of mutexes.
|
|
||||||
*/
|
|
||||||
void pm_mutex_init(uint8_t * p_mutex, uint16_t mutex_size);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Locks the mutex specified by the bit id.
|
|
||||||
*
|
|
||||||
* @param[inout] p_mutex Pointer to the mutex group.
|
|
||||||
* @param[in] mutex_bit_id The bit id of the mutex.
|
|
||||||
*
|
|
||||||
* @retval true if it was possible to lock the mutex.
|
|
||||||
* @retval false otherwise.
|
|
||||||
*/
|
|
||||||
bool pm_mutex_lock(uint8_t * p_mutex, uint16_t mutex_bit_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Locks the first unlocked mutex within the mutex group.
|
|
||||||
*
|
|
||||||
* @param[in, out] p_mutex Pointer to the mutex group.
|
|
||||||
* @param[in] mutex_size The size of the mutex group.
|
|
||||||
*
|
|
||||||
* @return The first unlocked mutex id in the group.
|
|
||||||
* @retval group-size if there was no unlocked mutex available.
|
|
||||||
*/
|
|
||||||
uint16_t pm_mutex_lock_first_available(uint8_t * p_mutex, uint16_t mutex_size);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Unlocks the mutex specified by the bit id.
|
|
||||||
*
|
|
||||||
* @param[in, out] p_mutex Pointer to the mutex group.
|
|
||||||
* @param[in] mutex_bit_id The bit id of the mutex.
|
|
||||||
*/
|
|
||||||
void pm_mutex_unlock(uint8_t * p_mutex, uint16_t mutex_bit_id);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Gets the locking status of the specified mutex.
|
|
||||||
*
|
|
||||||
* @param[in, out] p_mutex Pointer to the mutex group.
|
|
||||||
* @param[in] mutex_bit_id The bit id of the mutex.
|
|
||||||
*
|
|
||||||
* @retval true if the mutex was locked.
|
|
||||||
* @retval false otherwise.
|
|
||||||
*/
|
|
||||||
bool pm_mutex_lock_status_get(uint8_t * p_mutex, uint16_t mutex_bit_id);
|
|
||||||
|
|
||||||
|
|
||||||
#endif // MUTEX_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,107 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifndef _COMPILER_ABSTRACTION_H
|
|
||||||
#define _COMPILER_ABSTRACTION_H
|
|
||||||
|
|
||||||
/*lint ++flb "Enter library region" */
|
|
||||||
|
|
||||||
#if defined ( __ICCARM__ )
|
|
||||||
#ifndef __ASM
|
|
||||||
#define __ASM __asm
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __INLINE
|
|
||||||
#define __INLINE inline
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __WEAK
|
|
||||||
#define __WEAK __weak
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Not defined for IAR since it requires a new line to work, and C preprocessor does not allow that. */
|
|
||||||
#ifndef __ALIGN
|
|
||||||
#define __ALIGN(n)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GET_SP() __get_SP()
|
|
||||||
|
|
||||||
#elif defined ( __GNUC__ )
|
|
||||||
|
|
||||||
#ifndef __ASM
|
|
||||||
#define __ASM __asm
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __INLINE
|
|
||||||
#define __INLINE inline
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __WEAK
|
|
||||||
#define __WEAK __attribute__((weak))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __ALIGN
|
|
||||||
#define __ALIGN(n) __attribute__((aligned(n)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GET_SP() gcc_current_sp()
|
|
||||||
|
|
||||||
static inline unsigned int gcc_current_sp(void)
|
|
||||||
{
|
|
||||||
register unsigned sp __ASM("sp");
|
|
||||||
return sp;
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined ( __TASKING__ )
|
|
||||||
|
|
||||||
#ifndef __ASM
|
|
||||||
#define __ASM __asm
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __INLINE
|
|
||||||
#define __INLINE inline
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __WEAK
|
|
||||||
#define __WEAK __attribute__((weak))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __ALIGN
|
|
||||||
#define __ALIGN(n) __align(n)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GET_SP() __get_MSP()
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*lint --flb "Leave library region" */
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NRF_H
|
|
||||||
#define NRF_H
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
/* Do not include nrf51 specific files when building for PC host */
|
|
||||||
#elif defined(__unix)
|
|
||||||
/* Do not include nrf51 specific files when building for PC host */
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
/* Do not include nrf51 specific files when building for PC host */
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* Family selection for family includes. */
|
|
||||||
#if defined (NRF51)
|
|
||||||
#include "nrf51.h"
|
|
||||||
#include "nrf51_bitfields.h"
|
|
||||||
#include "nrf51_deprecated.h"
|
|
||||||
#elif defined (NRF52)
|
|
||||||
#include "nrf52.h"
|
|
||||||
#include "nrf52_bitfields.h"
|
|
||||||
#include "nrf51_to_nrf52.h"
|
|
||||||
#else
|
|
||||||
#error "Device family must be defined. See nrf.h."
|
|
||||||
#endif /* NRF51, NRF52 */
|
|
||||||
|
|
||||||
#include "compiler_abstraction.h"
|
|
||||||
|
|
||||||
#endif /* _WIN32 || __unix || __APPLE__ */
|
|
||||||
|
|
||||||
#endif /* NRF_H */
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,440 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NRF51_DEPRECATED_H
|
|
||||||
#define NRF51_DEPRECATED_H
|
|
||||||
|
|
||||||
/*lint ++flb "Enter library region */
|
|
||||||
|
|
||||||
/* This file is given to prevent your SW from not compiling with the updates made to nrf51.h and
|
|
||||||
* nrf51_bitfields.h. The macros defined in this file were available previously. Do not use these
|
|
||||||
* macros on purpose. Use the ones defined in nrf51.h and nrf51_bitfields.h instead.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* NVMC */
|
|
||||||
/* The register ERASEPROTECTEDPAGE is called ERASEPCR0 in the documentation. */
|
|
||||||
#define ERASEPROTECTEDPAGE ERASEPCR0
|
|
||||||
|
|
||||||
|
|
||||||
/* LPCOMP */
|
|
||||||
/* The interrupt ISR was renamed. Adding old name to the macros. */
|
|
||||||
#define LPCOMP_COMP_IRQHandler LPCOMP_IRQHandler
|
|
||||||
#define LPCOMP_COMP_IRQn LPCOMP_IRQn
|
|
||||||
|
|
||||||
|
|
||||||
/* MPU */
|
|
||||||
/* The field MPU.PERR0.LPCOMP_COMP was renamed. Added into deprecated in case somebody was using the macros defined for it. */
|
|
||||||
#define MPU_PERR0_LPCOMP_COMP_Pos MPU_PERR0_LPCOMP_Pos
|
|
||||||
#define MPU_PERR0_LPCOMP_COMP_Msk MPU_PERR0_LPCOMP_Msk
|
|
||||||
#define MPU_PERR0_LPCOMP_COMP_InRegion1 MPU_PERR0_LPCOMP_InRegion1
|
|
||||||
#define MPU_PERR0_LPCOMP_COMP_InRegion0 MPU_PERR0_LPCOMP_InRegion0
|
|
||||||
|
|
||||||
|
|
||||||
/* POWER */
|
|
||||||
/* The field POWER.RAMON.OFFRAM3 was eliminated. Added into deprecated in case somebody was using the macros defined for it. */
|
|
||||||
#define POWER_RAMON_OFFRAM3_Pos (19UL)
|
|
||||||
#define POWER_RAMON_OFFRAM3_Msk (0x1UL << POWER_RAMON_OFFRAM3_Pos)
|
|
||||||
#define POWER_RAMON_OFFRAM3_RAM3Off (0UL)
|
|
||||||
#define POWER_RAMON_OFFRAM3_RAM3On (1UL)
|
|
||||||
/* The field POWER.RAMON.OFFRAM2 was eliminated. Added into deprecated in case somebody was using the macros defined for it. */
|
|
||||||
#define POWER_RAMON_OFFRAM2_Pos (18UL)
|
|
||||||
#define POWER_RAMON_OFFRAM2_Msk (0x1UL << POWER_RAMON_OFFRAM2_Pos)
|
|
||||||
#define POWER_RAMON_OFFRAM2_RAM2Off (0UL)
|
|
||||||
#define POWER_RAMON_OFFRAM2_RAM2On (1UL)
|
|
||||||
/* The field POWER.RAMON.ONRAM3 was eliminated. Added into deprecated in case somebody was using the macros defined for it. */
|
|
||||||
#define POWER_RAMON_ONRAM3_Pos (3UL)
|
|
||||||
#define POWER_RAMON_ONRAM3_Msk (0x1UL << POWER_RAMON_ONRAM3_Pos)
|
|
||||||
#define POWER_RAMON_ONRAM3_RAM3Off (0UL)
|
|
||||||
#define POWER_RAMON_ONRAM3_RAM3On (1UL)
|
|
||||||
/* The field POWER.RAMON.ONRAM2 was eliminated. Added into deprecated in case somebody was using the macros defined for it. */
|
|
||||||
#define POWER_RAMON_ONRAM2_Pos (2UL)
|
|
||||||
#define POWER_RAMON_ONRAM2_Msk (0x1UL << POWER_RAMON_ONRAM2_Pos)
|
|
||||||
#define POWER_RAMON_ONRAM2_RAM2Off (0UL)
|
|
||||||
#define POWER_RAMON_ONRAM2_RAM2On (1UL)
|
|
||||||
|
|
||||||
|
|
||||||
/* RADIO */
|
|
||||||
/* The enumerated value RADIO.TXPOWER.TXPOWER.Neg40dBm was renamed. Added into deprecated with the new macro name. */
|
|
||||||
#define RADIO_TXPOWER_TXPOWER_Neg40dBm RADIO_TXPOWER_TXPOWER_Neg30dBm
|
|
||||||
/* The name of the field SKIPADDR was corrected. Old macros added for compatibility. */
|
|
||||||
#define RADIO_CRCCNF_SKIP_ADDR_Pos RADIO_CRCCNF_SKIPADDR_Pos
|
|
||||||
#define RADIO_CRCCNF_SKIP_ADDR_Msk RADIO_CRCCNF_SKIPADDR_Msk
|
|
||||||
#define RADIO_CRCCNF_SKIP_ADDR_Include RADIO_CRCCNF_SKIPADDR_Include
|
|
||||||
#define RADIO_CRCCNF_SKIP_ADDR_Skip RADIO_CRCCNF_SKIPADDR_Skip
|
|
||||||
/* The name of the field PLLLOCK was corrected. Old macros added for compatibility. */
|
|
||||||
#define RADIO_TEST_PLL_LOCK_Pos RADIO_TEST_PLLLOCK_Pos
|
|
||||||
#define RADIO_TEST_PLL_LOCK_Msk RADIO_TEST_PLLLOCK_Msk
|
|
||||||
#define RADIO_TEST_PLL_LOCK_Disabled RADIO_TEST_PLLLOCK_Disabled
|
|
||||||
#define RADIO_TEST_PLL_LOCK_Enabled RADIO_TEST_PLLLOCK_Enabled
|
|
||||||
/* The name of the field CONSTCARRIER was corrected. Old macros added for compatibility. */
|
|
||||||
#define RADIO_TEST_CONST_CARRIER_Pos RADIO_TEST_CONSTCARRIER_Pos
|
|
||||||
#define RADIO_TEST_CONST_CARRIER_Msk RADIO_TEST_CONSTCARRIER_Msk
|
|
||||||
#define RADIO_TEST_CONST_CARRIER_Disabled RADIO_TEST_CONSTCARRIER_Disabled
|
|
||||||
#define RADIO_TEST_CONST_CARRIER_Enabled RADIO_TEST_CONSTCARRIER_Enabled
|
|
||||||
|
|
||||||
|
|
||||||
/* FICR */
|
|
||||||
/* The registers FICR.SIZERAMBLOCK0, FICR.SIZERAMBLOCK1, FICR.SIZERAMBLOCK2 and FICR.SIZERAMBLOCK3 were renamed into an array. */
|
|
||||||
#define SIZERAMBLOCK0 SIZERAMBLOCKS
|
|
||||||
#define SIZERAMBLOCK1 SIZERAMBLOCKS
|
|
||||||
#define SIZERAMBLOCK2 SIZERAMBLOCK[2] /*!< Note that this macro will disapear when SIZERAMBLOCK array is eliminated. SIZERAMBLOCK is a deprecated array. */
|
|
||||||
#define SIZERAMBLOCK3 SIZERAMBLOCK[3] /*!< Note that this macro will disapear when SIZERAMBLOCK array is eliminated. SIZERAMBLOCK is a deprecated array. */
|
|
||||||
/* The registers FICR.DEVICEID0 and FICR.DEVICEID1 were renamed into an array. */
|
|
||||||
#define DEVICEID0 DEVICEID[0]
|
|
||||||
#define DEVICEID1 DEVICEID[1]
|
|
||||||
/* The registers FICR.ER0, FICR.ER1, FICR.ER2 and FICR.ER3 were renamed into an array. */
|
|
||||||
#define ER0 ER[0]
|
|
||||||
#define ER1 ER[1]
|
|
||||||
#define ER2 ER[2]
|
|
||||||
#define ER3 ER[3]
|
|
||||||
/* The registers FICR.IR0, FICR.IR1, FICR.IR2 and FICR.IR3 were renamed into an array. */
|
|
||||||
#define IR0 IR[0]
|
|
||||||
#define IR1 IR[1]
|
|
||||||
#define IR2 IR[2]
|
|
||||||
#define IR3 IR[3]
|
|
||||||
/* The registers FICR.DEVICEADDR0 and FICR.DEVICEADDR1 were renamed into an array. */
|
|
||||||
#define DEVICEADDR0 DEVICEADDR[0]
|
|
||||||
#define DEVICEADDR1 DEVICEADDR[1]
|
|
||||||
|
|
||||||
|
|
||||||
/* PPI */
|
|
||||||
/* The tasks PPI.TASKS_CHGxEN and PPI.TASKS_CHGxDIS were renamed into an array of structs. */
|
|
||||||
#define TASKS_CHG0EN TASKS_CHG[0].EN
|
|
||||||
#define TASKS_CHG0DIS TASKS_CHG[0].DIS
|
|
||||||
#define TASKS_CHG1EN TASKS_CHG[1].EN
|
|
||||||
#define TASKS_CHG1DIS TASKS_CHG[1].DIS
|
|
||||||
#define TASKS_CHG2EN TASKS_CHG[2].EN
|
|
||||||
#define TASKS_CHG2DIS TASKS_CHG[2].DIS
|
|
||||||
#define TASKS_CHG3EN TASKS_CHG[3].EN
|
|
||||||
#define TASKS_CHG3DIS TASKS_CHG[3].DIS
|
|
||||||
/* The registers PPI.CHx_EEP and PPI.CHx_TEP were renamed into an array of structs. */
|
|
||||||
#define CH0_EEP CH[0].EEP
|
|
||||||
#define CH0_TEP CH[0].TEP
|
|
||||||
#define CH1_EEP CH[1].EEP
|
|
||||||
#define CH1_TEP CH[1].TEP
|
|
||||||
#define CH2_EEP CH[2].EEP
|
|
||||||
#define CH2_TEP CH[2].TEP
|
|
||||||
#define CH3_EEP CH[3].EEP
|
|
||||||
#define CH3_TEP CH[3].TEP
|
|
||||||
#define CH4_EEP CH[4].EEP
|
|
||||||
#define CH4_TEP CH[4].TEP
|
|
||||||
#define CH5_EEP CH[5].EEP
|
|
||||||
#define CH5_TEP CH[5].TEP
|
|
||||||
#define CH6_EEP CH[6].EEP
|
|
||||||
#define CH6_TEP CH[6].TEP
|
|
||||||
#define CH7_EEP CH[7].EEP
|
|
||||||
#define CH7_TEP CH[7].TEP
|
|
||||||
#define CH8_EEP CH[8].EEP
|
|
||||||
#define CH8_TEP CH[8].TEP
|
|
||||||
#define CH9_EEP CH[9].EEP
|
|
||||||
#define CH9_TEP CH[9].TEP
|
|
||||||
#define CH10_EEP CH[10].EEP
|
|
||||||
#define CH10_TEP CH[10].TEP
|
|
||||||
#define CH11_EEP CH[11].EEP
|
|
||||||
#define CH11_TEP CH[11].TEP
|
|
||||||
#define CH12_EEP CH[12].EEP
|
|
||||||
#define CH12_TEP CH[12].TEP
|
|
||||||
#define CH13_EEP CH[13].EEP
|
|
||||||
#define CH13_TEP CH[13].TEP
|
|
||||||
#define CH14_EEP CH[14].EEP
|
|
||||||
#define CH14_TEP CH[14].TEP
|
|
||||||
#define CH15_EEP CH[15].EEP
|
|
||||||
#define CH15_TEP CH[15].TEP
|
|
||||||
/* The registers PPI.CHG0, PPI.CHG1, PPI.CHG2 and PPI.CHG3 were renamed into an array. */
|
|
||||||
#define CHG0 CHG[0]
|
|
||||||
#define CHG1 CHG[1]
|
|
||||||
#define CHG2 CHG[2]
|
|
||||||
#define CHG3 CHG[3]
|
|
||||||
/* All bitfield macros for the CHGx registers therefore changed name. */
|
|
||||||
#define PPI_CHG0_CH15_Pos PPI_CHG_CH15_Pos
|
|
||||||
#define PPI_CHG0_CH15_Msk PPI_CHG_CH15_Msk
|
|
||||||
#define PPI_CHG0_CH15_Excluded PPI_CHG_CH15_Excluded
|
|
||||||
#define PPI_CHG0_CH15_Included PPI_CHG_CH15_Included
|
|
||||||
#define PPI_CHG0_CH14_Pos PPI_CHG_CH14_Pos
|
|
||||||
#define PPI_CHG0_CH14_Msk PPI_CHG_CH14_Msk
|
|
||||||
#define PPI_CHG0_CH14_Excluded PPI_CHG_CH14_Excluded
|
|
||||||
#define PPI_CHG0_CH14_Included PPI_CHG_CH14_Included
|
|
||||||
#define PPI_CHG0_CH13_Pos PPI_CHG_CH13_Pos
|
|
||||||
#define PPI_CHG0_CH13_Msk PPI_CHG_CH13_Msk
|
|
||||||
#define PPI_CHG0_CH13_Excluded PPI_CHG_CH13_Excluded
|
|
||||||
#define PPI_CHG0_CH13_Included PPI_CHG_CH13_Included
|
|
||||||
#define PPI_CHG0_CH12_Pos PPI_CHG_CH12_Pos
|
|
||||||
#define PPI_CHG0_CH12_Msk PPI_CHG_CH12_Msk
|
|
||||||
#define PPI_CHG0_CH12_Excluded PPI_CHG_CH12_Excluded
|
|
||||||
#define PPI_CHG0_CH12_Included PPI_CHG_CH12_Included
|
|
||||||
#define PPI_CHG0_CH11_Pos PPI_CHG_CH11_Pos
|
|
||||||
#define PPI_CHG0_CH11_Msk PPI_CHG_CH11_Msk
|
|
||||||
#define PPI_CHG0_CH11_Excluded PPI_CHG_CH11_Excluded
|
|
||||||
#define PPI_CHG0_CH11_Included PPI_CHG_CH11_Included
|
|
||||||
#define PPI_CHG0_CH10_Pos PPI_CHG_CH10_Pos
|
|
||||||
#define PPI_CHG0_CH10_Msk PPI_CHG_CH10_Msk
|
|
||||||
#define PPI_CHG0_CH10_Excluded PPI_CHG_CH10_Excluded
|
|
||||||
#define PPI_CHG0_CH10_Included PPI_CHG_CH10_Included
|
|
||||||
#define PPI_CHG0_CH9_Pos PPI_CHG_CH9_Pos
|
|
||||||
#define PPI_CHG0_CH9_Msk PPI_CHG_CH9_Msk
|
|
||||||
#define PPI_CHG0_CH9_Excluded PPI_CHG_CH9_Excluded
|
|
||||||
#define PPI_CHG0_CH9_Included PPI_CHG_CH9_Included
|
|
||||||
#define PPI_CHG0_CH8_Pos PPI_CHG_CH8_Pos
|
|
||||||
#define PPI_CHG0_CH8_Msk PPI_CHG_CH8_Msk
|
|
||||||
#define PPI_CHG0_CH8_Excluded PPI_CHG_CH8_Excluded
|
|
||||||
#define PPI_CHG0_CH8_Included PPI_CHG_CH8_Included
|
|
||||||
#define PPI_CHG0_CH7_Pos PPI_CHG_CH7_Pos
|
|
||||||
#define PPI_CHG0_CH7_Msk PPI_CHG_CH7_Msk
|
|
||||||
#define PPI_CHG0_CH7_Excluded PPI_CHG_CH7_Excluded
|
|
||||||
#define PPI_CHG0_CH7_Included PPI_CHG_CH7_Included
|
|
||||||
#define PPI_CHG0_CH6_Pos PPI_CHG_CH6_Pos
|
|
||||||
#define PPI_CHG0_CH6_Msk PPI_CHG_CH6_Msk
|
|
||||||
#define PPI_CHG0_CH6_Excluded PPI_CHG_CH6_Excluded
|
|
||||||
#define PPI_CHG0_CH6_Included PPI_CHG_CH6_Included
|
|
||||||
#define PPI_CHG0_CH5_Pos PPI_CHG_CH5_Pos
|
|
||||||
#define PPI_CHG0_CH5_Msk PPI_CHG_CH5_Msk
|
|
||||||
#define PPI_CHG0_CH5_Excluded PPI_CHG_CH5_Excluded
|
|
||||||
#define PPI_CHG0_CH5_Included PPI_CHG_CH5_Included
|
|
||||||
#define PPI_CHG0_CH4_Pos PPI_CHG_CH4_Pos
|
|
||||||
#define PPI_CHG0_CH4_Msk PPI_CHG_CH4_Msk
|
|
||||||
#define PPI_CHG0_CH4_Excluded PPI_CHG_CH4_Excluded
|
|
||||||
#define PPI_CHG0_CH4_Included PPI_CHG_CH4_Included
|
|
||||||
#define PPI_CHG0_CH3_Pos PPI_CHG_CH3_Pos
|
|
||||||
#define PPI_CHG0_CH3_Msk PPI_CHG_CH3_Msk
|
|
||||||
#define PPI_CHG0_CH3_Excluded PPI_CHG_CH3_Excluded
|
|
||||||
#define PPI_CHG0_CH3_Included PPI_CHG_CH3_Included
|
|
||||||
#define PPI_CHG0_CH2_Pos PPI_CHG_CH2_Pos
|
|
||||||
#define PPI_CHG0_CH2_Msk PPI_CHG_CH2_Msk
|
|
||||||
#define PPI_CHG0_CH2_Excluded PPI_CHG_CH2_Excluded
|
|
||||||
#define PPI_CHG0_CH2_Included PPI_CHG_CH2_Included
|
|
||||||
#define PPI_CHG0_CH1_Pos PPI_CHG_CH1_Pos
|
|
||||||
#define PPI_CHG0_CH1_Msk PPI_CHG_CH1_Msk
|
|
||||||
#define PPI_CHG0_CH1_Excluded PPI_CHG_CH1_Excluded
|
|
||||||
#define PPI_CHG0_CH1_Included PPI_CHG_CH1_Included
|
|
||||||
#define PPI_CHG0_CH0_Pos PPI_CHG_CH0_Pos
|
|
||||||
#define PPI_CHG0_CH0_Msk PPI_CHG_CH0_Msk
|
|
||||||
#define PPI_CHG0_CH0_Excluded PPI_CHG_CH0_Excluded
|
|
||||||
#define PPI_CHG0_CH0_Included PPI_CHG_CH0_Included
|
|
||||||
#define PPI_CHG1_CH15_Pos PPI_CHG_CH15_Pos
|
|
||||||
#define PPI_CHG1_CH15_Msk PPI_CHG_CH15_Msk
|
|
||||||
#define PPI_CHG1_CH15_Excluded PPI_CHG_CH15_Excluded
|
|
||||||
#define PPI_CHG1_CH15_Included PPI_CHG_CH15_Included
|
|
||||||
#define PPI_CHG1_CH14_Pos PPI_CHG_CH14_Pos
|
|
||||||
#define PPI_CHG1_CH14_Msk PPI_CHG_CH14_Msk
|
|
||||||
#define PPI_CHG1_CH14_Excluded PPI_CHG_CH14_Excluded
|
|
||||||
#define PPI_CHG1_CH14_Included PPI_CHG_CH14_Included
|
|
||||||
#define PPI_CHG1_CH13_Pos PPI_CHG_CH13_Pos
|
|
||||||
#define PPI_CHG1_CH13_Msk PPI_CHG_CH13_Msk
|
|
||||||
#define PPI_CHG1_CH13_Excluded PPI_CHG_CH13_Excluded
|
|
||||||
#define PPI_CHG1_CH13_Included PPI_CHG_CH13_Included
|
|
||||||
#define PPI_CHG1_CH12_Pos PPI_CHG_CH12_Pos
|
|
||||||
#define PPI_CHG1_CH12_Msk PPI_CHG_CH12_Msk
|
|
||||||
#define PPI_CHG1_CH12_Excluded PPI_CHG_CH12_Excluded
|
|
||||||
#define PPI_CHG1_CH12_Included PPI_CHG_CH12_Included
|
|
||||||
#define PPI_CHG1_CH11_Pos PPI_CHG_CH11_Pos
|
|
||||||
#define PPI_CHG1_CH11_Msk PPI_CHG_CH11_Msk
|
|
||||||
#define PPI_CHG1_CH11_Excluded PPI_CHG_CH11_Excluded
|
|
||||||
#define PPI_CHG1_CH11_Included PPI_CHG_CH11_Included
|
|
||||||
#define PPI_CHG1_CH10_Pos PPI_CHG_CH10_Pos
|
|
||||||
#define PPI_CHG1_CH10_Msk PPI_CHG_CH10_Msk
|
|
||||||
#define PPI_CHG1_CH10_Excluded PPI_CHG_CH10_Excluded
|
|
||||||
#define PPI_CHG1_CH10_Included PPI_CHG_CH10_Included
|
|
||||||
#define PPI_CHG1_CH9_Pos PPI_CHG_CH9_Pos
|
|
||||||
#define PPI_CHG1_CH9_Msk PPI_CHG_CH9_Msk
|
|
||||||
#define PPI_CHG1_CH9_Excluded PPI_CHG_CH9_Excluded
|
|
||||||
#define PPI_CHG1_CH9_Included PPI_CHG_CH9_Included
|
|
||||||
#define PPI_CHG1_CH8_Pos PPI_CHG_CH8_Pos
|
|
||||||
#define PPI_CHG1_CH8_Msk PPI_CHG_CH8_Msk
|
|
||||||
#define PPI_CHG1_CH8_Excluded PPI_CHG_CH8_Excluded
|
|
||||||
#define PPI_CHG1_CH8_Included PPI_CHG_CH8_Included
|
|
||||||
#define PPI_CHG1_CH7_Pos PPI_CHG_CH7_Pos
|
|
||||||
#define PPI_CHG1_CH7_Msk PPI_CHG_CH7_Msk
|
|
||||||
#define PPI_CHG1_CH7_Excluded PPI_CHG_CH7_Excluded
|
|
||||||
#define PPI_CHG1_CH7_Included PPI_CHG_CH7_Included
|
|
||||||
#define PPI_CHG1_CH6_Pos PPI_CHG_CH6_Pos
|
|
||||||
#define PPI_CHG1_CH6_Msk PPI_CHG_CH6_Msk
|
|
||||||
#define PPI_CHG1_CH6_Excluded PPI_CHG_CH6_Excluded
|
|
||||||
#define PPI_CHG1_CH6_Included PPI_CHG_CH6_Included
|
|
||||||
#define PPI_CHG1_CH5_Pos PPI_CHG_CH5_Pos
|
|
||||||
#define PPI_CHG1_CH5_Msk PPI_CHG_CH5_Msk
|
|
||||||
#define PPI_CHG1_CH5_Excluded PPI_CHG_CH5_Excluded
|
|
||||||
#define PPI_CHG1_CH5_Included PPI_CHG_CH5_Included
|
|
||||||
#define PPI_CHG1_CH4_Pos PPI_CHG_CH4_Pos
|
|
||||||
#define PPI_CHG1_CH4_Msk PPI_CHG_CH4_Msk
|
|
||||||
#define PPI_CHG1_CH4_Excluded PPI_CHG_CH4_Excluded
|
|
||||||
#define PPI_CHG1_CH4_Included PPI_CHG_CH4_Included
|
|
||||||
#define PPI_CHG1_CH3_Pos PPI_CHG_CH3_Pos
|
|
||||||
#define PPI_CHG1_CH3_Msk PPI_CHG_CH3_Msk
|
|
||||||
#define PPI_CHG1_CH3_Excluded PPI_CHG_CH3_Excluded
|
|
||||||
#define PPI_CHG1_CH3_Included PPI_CHG_CH3_Included
|
|
||||||
#define PPI_CHG1_CH2_Pos PPI_CHG_CH2_Pos
|
|
||||||
#define PPI_CHG1_CH2_Msk PPI_CHG_CH2_Msk
|
|
||||||
#define PPI_CHG1_CH2_Excluded PPI_CHG_CH2_Excluded
|
|
||||||
#define PPI_CHG1_CH2_Included PPI_CHG_CH2_Included
|
|
||||||
#define PPI_CHG1_CH1_Pos PPI_CHG_CH1_Pos
|
|
||||||
#define PPI_CHG1_CH1_Msk PPI_CHG_CH1_Msk
|
|
||||||
#define PPI_CHG1_CH1_Excluded PPI_CHG_CH1_Excluded
|
|
||||||
#define PPI_CHG1_CH1_Included PPI_CHG_CH1_Included
|
|
||||||
#define PPI_CHG1_CH0_Pos PPI_CHG_CH0_Pos
|
|
||||||
#define PPI_CHG1_CH0_Msk PPI_CHG_CH0_Msk
|
|
||||||
#define PPI_CHG1_CH0_Excluded PPI_CHG_CH0_Excluded
|
|
||||||
#define PPI_CHG1_CH0_Included PPI_CHG_CH0_Included
|
|
||||||
#define PPI_CHG2_CH15_Pos PPI_CHG_CH15_Pos
|
|
||||||
#define PPI_CHG2_CH15_Msk PPI_CHG_CH15_Msk
|
|
||||||
#define PPI_CHG2_CH15_Excluded PPI_CHG_CH15_Excluded
|
|
||||||
#define PPI_CHG2_CH15_Included PPI_CHG_CH15_Included
|
|
||||||
#define PPI_CHG2_CH14_Pos PPI_CHG_CH14_Pos
|
|
||||||
#define PPI_CHG2_CH14_Msk PPI_CHG_CH14_Msk
|
|
||||||
#define PPI_CHG2_CH14_Excluded PPI_CHG_CH14_Excluded
|
|
||||||
#define PPI_CHG2_CH14_Included PPI_CHG_CH14_Included
|
|
||||||
#define PPI_CHG2_CH13_Pos PPI_CHG_CH13_Pos
|
|
||||||
#define PPI_CHG2_CH13_Msk PPI_CHG_CH13_Msk
|
|
||||||
#define PPI_CHG2_CH13_Excluded PPI_CHG_CH13_Excluded
|
|
||||||
#define PPI_CHG2_CH13_Included PPI_CHG_CH13_Included
|
|
||||||
#define PPI_CHG2_CH12_Pos PPI_CHG_CH12_Pos
|
|
||||||
#define PPI_CHG2_CH12_Msk PPI_CHG_CH12_Msk
|
|
||||||
#define PPI_CHG2_CH12_Excluded PPI_CHG_CH12_Excluded
|
|
||||||
#define PPI_CHG2_CH12_Included PPI_CHG_CH12_Included
|
|
||||||
#define PPI_CHG2_CH11_Pos PPI_CHG_CH11_Pos
|
|
||||||
#define PPI_CHG2_CH11_Msk PPI_CHG_CH11_Msk
|
|
||||||
#define PPI_CHG2_CH11_Excluded PPI_CHG_CH11_Excluded
|
|
||||||
#define PPI_CHG2_CH11_Included PPI_CHG_CH11_Included
|
|
||||||
#define PPI_CHG2_CH10_Pos PPI_CHG_CH10_Pos
|
|
||||||
#define PPI_CHG2_CH10_Msk PPI_CHG_CH10_Msk
|
|
||||||
#define PPI_CHG2_CH10_Excluded PPI_CHG_CH10_Excluded
|
|
||||||
#define PPI_CHG2_CH10_Included PPI_CHG_CH10_Included
|
|
||||||
#define PPI_CHG2_CH9_Pos PPI_CHG_CH9_Pos
|
|
||||||
#define PPI_CHG2_CH9_Msk PPI_CHG_CH9_Msk
|
|
||||||
#define PPI_CHG2_CH9_Excluded PPI_CHG_CH9_Excluded
|
|
||||||
#define PPI_CHG2_CH9_Included PPI_CHG_CH9_Included
|
|
||||||
#define PPI_CHG2_CH8_Pos PPI_CHG_CH8_Pos
|
|
||||||
#define PPI_CHG2_CH8_Msk PPI_CHG_CH8_Msk
|
|
||||||
#define PPI_CHG2_CH8_Excluded PPI_CHG_CH8_Excluded
|
|
||||||
#define PPI_CHG2_CH8_Included PPI_CHG_CH8_Included
|
|
||||||
#define PPI_CHG2_CH7_Pos PPI_CHG_CH7_Pos
|
|
||||||
#define PPI_CHG2_CH7_Msk PPI_CHG_CH7_Msk
|
|
||||||
#define PPI_CHG2_CH7_Excluded PPI_CHG_CH7_Excluded
|
|
||||||
#define PPI_CHG2_CH7_Included PPI_CHG_CH7_Included
|
|
||||||
#define PPI_CHG2_CH6_Pos PPI_CHG_CH6_Pos
|
|
||||||
#define PPI_CHG2_CH6_Msk PPI_CHG_CH6_Msk
|
|
||||||
#define PPI_CHG2_CH6_Excluded PPI_CHG_CH6_Excluded
|
|
||||||
#define PPI_CHG2_CH6_Included PPI_CHG_CH6_Included
|
|
||||||
#define PPI_CHG2_CH5_Pos PPI_CHG_CH5_Pos
|
|
||||||
#define PPI_CHG2_CH5_Msk PPI_CHG_CH5_Msk
|
|
||||||
#define PPI_CHG2_CH5_Excluded PPI_CHG_CH5_Excluded
|
|
||||||
#define PPI_CHG2_CH5_Included PPI_CHG_CH5_Included
|
|
||||||
#define PPI_CHG2_CH4_Pos PPI_CHG_CH4_Pos
|
|
||||||
#define PPI_CHG2_CH4_Msk PPI_CHG_CH4_Msk
|
|
||||||
#define PPI_CHG2_CH4_Excluded PPI_CHG_CH4_Excluded
|
|
||||||
#define PPI_CHG2_CH4_Included PPI_CHG_CH4_Included
|
|
||||||
#define PPI_CHG2_CH3_Pos PPI_CHG_CH3_Pos
|
|
||||||
#define PPI_CHG2_CH3_Msk PPI_CHG_CH3_Msk
|
|
||||||
#define PPI_CHG2_CH3_Excluded PPI_CHG_CH3_Excluded
|
|
||||||
#define PPI_CHG2_CH3_Included PPI_CHG_CH3_Included
|
|
||||||
#define PPI_CHG2_CH2_Pos PPI_CHG_CH2_Pos
|
|
||||||
#define PPI_CHG2_CH2_Msk PPI_CHG_CH2_Msk
|
|
||||||
#define PPI_CHG2_CH2_Excluded PPI_CHG_CH2_Excluded
|
|
||||||
#define PPI_CHG2_CH2_Included PPI_CHG_CH2_Included
|
|
||||||
#define PPI_CHG2_CH1_Pos PPI_CHG_CH1_Pos
|
|
||||||
#define PPI_CHG2_CH1_Msk PPI_CHG_CH1_Msk
|
|
||||||
#define PPI_CHG2_CH1_Excluded PPI_CHG_CH1_Excluded
|
|
||||||
#define PPI_CHG2_CH1_Included PPI_CHG_CH1_Included
|
|
||||||
#define PPI_CHG2_CH0_Pos PPI_CHG_CH0_Pos
|
|
||||||
#define PPI_CHG2_CH0_Msk PPI_CHG_CH0_Msk
|
|
||||||
#define PPI_CHG2_CH0_Excluded PPI_CHG_CH0_Excluded
|
|
||||||
#define PPI_CHG2_CH0_Included PPI_CHG_CH0_Included
|
|
||||||
#define PPI_CHG3_CH15_Pos PPI_CHG_CH15_Pos
|
|
||||||
#define PPI_CHG3_CH15_Msk PPI_CHG_CH15_Msk
|
|
||||||
#define PPI_CHG3_CH15_Excluded PPI_CHG_CH15_Excluded
|
|
||||||
#define PPI_CHG3_CH15_Included PPI_CHG_CH15_Included
|
|
||||||
#define PPI_CHG3_CH14_Pos PPI_CHG_CH14_Pos
|
|
||||||
#define PPI_CHG3_CH14_Msk PPI_CHG_CH14_Msk
|
|
||||||
#define PPI_CHG3_CH14_Excluded PPI_CHG_CH14_Excluded
|
|
||||||
#define PPI_CHG3_CH14_Included PPI_CHG_CH14_Included
|
|
||||||
#define PPI_CHG3_CH13_Pos PPI_CHG_CH13_Pos
|
|
||||||
#define PPI_CHG3_CH13_Msk PPI_CHG_CH13_Msk
|
|
||||||
#define PPI_CHG3_CH13_Excluded PPI_CHG_CH13_Excluded
|
|
||||||
#define PPI_CHG3_CH13_Included PPI_CHG_CH13_Included
|
|
||||||
#define PPI_CHG3_CH12_Pos PPI_CHG_CH12_Pos
|
|
||||||
#define PPI_CHG3_CH12_Msk PPI_CHG_CH12_Msk
|
|
||||||
#define PPI_CHG3_CH12_Excluded PPI_CHG_CH12_Excluded
|
|
||||||
#define PPI_CHG3_CH12_Included PPI_CHG_CH12_Included
|
|
||||||
#define PPI_CHG3_CH11_Pos PPI_CHG_CH11_Pos
|
|
||||||
#define PPI_CHG3_CH11_Msk PPI_CHG_CH11_Msk
|
|
||||||
#define PPI_CHG3_CH11_Excluded PPI_CHG_CH11_Excluded
|
|
||||||
#define PPI_CHG3_CH11_Included PPI_CHG_CH11_Included
|
|
||||||
#define PPI_CHG3_CH10_Pos PPI_CHG_CH10_Pos
|
|
||||||
#define PPI_CHG3_CH10_Msk PPI_CHG_CH10_Msk
|
|
||||||
#define PPI_CHG3_CH10_Excluded PPI_CHG_CH10_Excluded
|
|
||||||
#define PPI_CHG3_CH10_Included PPI_CHG_CH10_Included
|
|
||||||
#define PPI_CHG3_CH9_Pos PPI_CHG_CH9_Pos
|
|
||||||
#define PPI_CHG3_CH9_Msk PPI_CHG_CH9_Msk
|
|
||||||
#define PPI_CHG3_CH9_Excluded PPI_CHG_CH9_Excluded
|
|
||||||
#define PPI_CHG3_CH9_Included PPI_CHG_CH9_Included
|
|
||||||
#define PPI_CHG3_CH8_Pos PPI_CHG_CH8_Pos
|
|
||||||
#define PPI_CHG3_CH8_Msk PPI_CHG_CH8_Msk
|
|
||||||
#define PPI_CHG3_CH8_Excluded PPI_CHG_CH8_Excluded
|
|
||||||
#define PPI_CHG3_CH8_Included PPI_CHG_CH8_Included
|
|
||||||
#define PPI_CHG3_CH7_Pos PPI_CHG_CH7_Pos
|
|
||||||
#define PPI_CHG3_CH7_Msk PPI_CHG_CH7_Msk
|
|
||||||
#define PPI_CHG3_CH7_Excluded PPI_CHG_CH7_Excluded
|
|
||||||
#define PPI_CHG3_CH7_Included PPI_CHG_CH7_Included
|
|
||||||
#define PPI_CHG3_CH6_Pos PPI_CHG_CH6_Pos
|
|
||||||
#define PPI_CHG3_CH6_Msk PPI_CHG_CH6_Msk
|
|
||||||
#define PPI_CHG3_CH6_Excluded PPI_CHG_CH6_Excluded
|
|
||||||
#define PPI_CHG3_CH6_Included PPI_CHG_CH6_Included
|
|
||||||
#define PPI_CHG3_CH5_Pos PPI_CHG_CH5_Pos
|
|
||||||
#define PPI_CHG3_CH5_Msk PPI_CHG_CH5_Msk
|
|
||||||
#define PPI_CHG3_CH5_Excluded PPI_CHG_CH5_Excluded
|
|
||||||
#define PPI_CHG3_CH5_Included PPI_CHG_CH5_Included
|
|
||||||
#define PPI_CHG3_CH4_Pos PPI_CHG_CH4_Pos
|
|
||||||
#define PPI_CHG3_CH4_Msk PPI_CHG_CH4_Msk
|
|
||||||
#define PPI_CHG3_CH4_Excluded PPI_CHG_CH4_Excluded
|
|
||||||
#define PPI_CHG3_CH4_Included PPI_CHG_CH4_Included
|
|
||||||
#define PPI_CHG3_CH3_Pos PPI_CHG_CH3_Pos
|
|
||||||
#define PPI_CHG3_CH3_Msk PPI_CHG_CH3_Msk
|
|
||||||
#define PPI_CHG3_CH3_Excluded PPI_CHG_CH3_Excluded
|
|
||||||
#define PPI_CHG3_CH3_Included PPI_CHG_CH3_Included
|
|
||||||
#define PPI_CHG3_CH2_Pos PPI_CHG_CH2_Pos
|
|
||||||
#define PPI_CHG3_CH2_Msk PPI_CHG_CH2_Msk
|
|
||||||
#define PPI_CHG3_CH2_Excluded PPI_CHG_CH2_Excluded
|
|
||||||
#define PPI_CHG3_CH2_Included PPI_CHG_CH2_Included
|
|
||||||
#define PPI_CHG3_CH1_Pos PPI_CHG_CH1_Pos
|
|
||||||
#define PPI_CHG3_CH1_Msk PPI_CHG_CH1_Msk
|
|
||||||
#define PPI_CHG3_CH1_Excluded PPI_CHG_CH1_Excluded
|
|
||||||
#define PPI_CHG3_CH1_Included PPI_CHG_CH1_Included
|
|
||||||
#define PPI_CHG3_CH0_Pos PPI_CHG_CH0_Pos
|
|
||||||
#define PPI_CHG3_CH0_Msk PPI_CHG_CH0_Msk
|
|
||||||
#define PPI_CHG3_CH0_Excluded PPI_CHG_CH0_Excluded
|
|
||||||
#define PPI_CHG3_CH0_Included PPI_CHG_CH0_Included
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*lint --flb "Leave library region" */
|
|
||||||
|
|
||||||
#endif /* NRF51_DEPRECATED_H */
|
|
||||||
|
|
|
@ -1,306 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "ble_flash.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "nrf_soc.h"
|
|
||||||
#include "nordic_common.h"
|
|
||||||
#include "nrf_error.h"
|
|
||||||
#include "nrf.h"
|
|
||||||
#include "app_util.h"
|
|
||||||
|
|
||||||
|
|
||||||
static volatile bool m_radio_active = false; /**< TRUE if radio is active (or about to become active), FALSE otherwise. */
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t ble_flash_crc16_compute(uint8_t * p_data, uint16_t size, uint16_t * p_crc)
|
|
||||||
{
|
|
||||||
uint16_t i;
|
|
||||||
uint16_t crc = (p_crc == NULL) ? 0xffff : *p_crc;
|
|
||||||
|
|
||||||
for (i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
crc = (unsigned char)(crc >> 8) | (crc << 8);
|
|
||||||
crc ^= p_data[i];
|
|
||||||
crc ^= (unsigned char)(crc & 0xff) >> 4;
|
|
||||||
crc ^= (crc << 8) << 4;
|
|
||||||
crc ^= ((crc & 0xff) << 4) << 1;
|
|
||||||
}
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for erasing a page in flash.
|
|
||||||
*
|
|
||||||
* @param[in] p_page Pointer to first word in page to be erased.
|
|
||||||
*/
|
|
||||||
static void flash_page_erase(uint32_t * p_page)
|
|
||||||
{
|
|
||||||
// Turn on flash erase enable and wait until the NVMC is ready.
|
|
||||||
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Een << NVMC_CONFIG_WEN_Pos);
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Erase page.
|
|
||||||
NRF_NVMC->ERASEPAGE = (uint32_t)p_page;
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Turn off flash erase enable and wait until the NVMC is ready.
|
|
||||||
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for writing one word to flash. Unprotected write, which can interfere with radio communication.
|
|
||||||
*
|
|
||||||
* @details This function DOES NOT use the m_radio_active variable, but will force the write even
|
|
||||||
* when the radio is active. To be used only from @ref ble_flash_page_write.
|
|
||||||
*
|
|
||||||
* @note Flash location to be written must have been erased previously.
|
|
||||||
*
|
|
||||||
* @param[in] p_address Pointer to flash location to be written.
|
|
||||||
* @param[in] value Value to write to flash.
|
|
||||||
*/
|
|
||||||
static void flash_word_unprotected_write(uint32_t * p_address, uint32_t value)
|
|
||||||
{
|
|
||||||
// Turn on flash write enable and wait until the NVMC is ready.
|
|
||||||
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
*p_address = value;
|
|
||||||
|
|
||||||
// Wait flash write to finish
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Turn off flash write enable and wait until the NVMC is ready.
|
|
||||||
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for writing one word to flash.
|
|
||||||
*
|
|
||||||
* @note Flash location to be written must have been erased previously.
|
|
||||||
*
|
|
||||||
* @param[in] p_address Pointer to flash location to be written.
|
|
||||||
* @param[in] value Value to write to flash.
|
|
||||||
*/
|
|
||||||
static void flash_word_write(uint32_t * p_address, uint32_t value)
|
|
||||||
{
|
|
||||||
// If radio is active, wait for it to become inactive.
|
|
||||||
while (m_radio_active)
|
|
||||||
{
|
|
||||||
// Do nothing (just wait for radio to become inactive).
|
|
||||||
(void) sd_app_evt_wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Turn on flash write enable and wait until the NVMC is ready.
|
|
||||||
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
|
|
||||||
*p_address = value;
|
|
||||||
// Wait flash write to finish
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
// Do nothing.
|
|
||||||
}
|
|
||||||
// Turn off flash write enable and wait until the NVMC is ready.
|
|
||||||
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_flash_word_write(uint32_t * p_address, uint32_t value)
|
|
||||||
{
|
|
||||||
flash_word_write(p_address, value);
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_flash_block_write(uint32_t * p_address, uint32_t * p_in_array, uint16_t word_count)
|
|
||||||
{
|
|
||||||
uint16_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < word_count; i++)
|
|
||||||
{
|
|
||||||
flash_word_write(p_address, p_in_array[i]);
|
|
||||||
p_address++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_flash_page_erase(uint8_t page_num)
|
|
||||||
{
|
|
||||||
uint32_t * p_page = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num);
|
|
||||||
flash_page_erase(p_page);
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_flash_page_write(uint8_t page_num, uint32_t * p_in_array, uint8_t word_count)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
uint32_t * p_page;
|
|
||||||
uint32_t * p_curr_addr;
|
|
||||||
uint16_t in_data_crc;
|
|
||||||
uint16_t flash_crc;
|
|
||||||
uint32_t flash_header;
|
|
||||||
|
|
||||||
p_page = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num);
|
|
||||||
p_curr_addr = p_page;
|
|
||||||
|
|
||||||
// Calculate CRC of the data to write.
|
|
||||||
in_data_crc = ble_flash_crc16_compute((uint8_t *)p_in_array,
|
|
||||||
word_count * sizeof(uint32_t),
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
// Compare the calculated to the one in flash.
|
|
||||||
flash_header = *p_curr_addr;
|
|
||||||
flash_crc = (uint16_t)flash_header;
|
|
||||||
|
|
||||||
if (flash_crc == in_data_crc)
|
|
||||||
{
|
|
||||||
// Data is the same as the data already stored in flash, return without modifying flash.
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Erase flash page
|
|
||||||
flash_page_erase(p_page);
|
|
||||||
|
|
||||||
// Reserve space for magic number (for detecting if flash content is valid).
|
|
||||||
p_curr_addr++;
|
|
||||||
|
|
||||||
// Reserve space for saving word_count.
|
|
||||||
p_curr_addr++;
|
|
||||||
|
|
||||||
// Write data
|
|
||||||
for (i = 0; i < word_count; i++)
|
|
||||||
{
|
|
||||||
flash_word_unprotected_write(p_curr_addr, p_in_array[i]);
|
|
||||||
p_curr_addr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write number of elements.
|
|
||||||
flash_word_write(p_page + 1, (uint32_t)(word_count));
|
|
||||||
|
|
||||||
// Write magic number and CRC to indicate that flash content is valid.
|
|
||||||
flash_header = BLE_FLASH_MAGIC_NUMBER | (uint32_t)in_data_crc;
|
|
||||||
flash_word_write(p_page, flash_header);
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_flash_page_read(uint8_t page_num, uint32_t * p_out_array, uint8_t * p_word_count)
|
|
||||||
{
|
|
||||||
int byte_count;
|
|
||||||
uint32_t * p_page;
|
|
||||||
uint32_t * p_curr_addr;
|
|
||||||
uint32_t flash_header;
|
|
||||||
uint32_t calc_header;
|
|
||||||
uint16_t calc_crc;
|
|
||||||
uint32_t tmp;
|
|
||||||
|
|
||||||
p_page = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num);
|
|
||||||
p_curr_addr = p_page;
|
|
||||||
|
|
||||||
// Check if block is valid
|
|
||||||
flash_header = *p_curr_addr;
|
|
||||||
tmp = flash_header & 0xFFFF0000;
|
|
||||||
if (tmp != BLE_FLASH_MAGIC_NUMBER)
|
|
||||||
{
|
|
||||||
*p_word_count = 0;
|
|
||||||
return NRF_ERROR_NOT_FOUND;
|
|
||||||
}
|
|
||||||
p_curr_addr++;
|
|
||||||
|
|
||||||
// Read number of elements
|
|
||||||
*p_word_count = (uint8_t)(*(p_curr_addr));
|
|
||||||
p_curr_addr++;
|
|
||||||
|
|
||||||
// Read data
|
|
||||||
byte_count = (*p_word_count) * sizeof(uint32_t);
|
|
||||||
memcpy(p_out_array, p_curr_addr, byte_count);
|
|
||||||
|
|
||||||
// Check CRC
|
|
||||||
calc_crc = ble_flash_crc16_compute((uint8_t *)p_out_array,
|
|
||||||
(*p_word_count) * sizeof(uint32_t),
|
|
||||||
NULL);
|
|
||||||
calc_header = BLE_FLASH_MAGIC_NUMBER | (uint32_t)calc_crc;
|
|
||||||
|
|
||||||
if (calc_header != flash_header)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t ble_flash_page_addr(uint8_t page_num, uint32_t ** pp_page_addr)
|
|
||||||
{
|
|
||||||
*pp_page_addr = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num);
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ble_flash_on_radio_active_evt(bool radio_active)
|
|
||||||
{
|
|
||||||
m_radio_active = radio_active;
|
|
||||||
}
|
|
|
@ -1,162 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
*
|
|
||||||
* @defgroup ble_flash_module Flash Manager
|
|
||||||
* @{
|
|
||||||
* @ingroup ble_sdk_lib
|
|
||||||
* @brief Module for accessing flash memory.
|
|
||||||
*
|
|
||||||
* @details It contains functions for reading, writing and erasing one page in flash.
|
|
||||||
*
|
|
||||||
* The module uses the first 32 bits of the flash page to write a magic number in order to
|
|
||||||
* determine if the page has been written or not.
|
|
||||||
*
|
|
||||||
* @note Be careful not to use a page number in the SoftDevice area (which currently occupies the
|
|
||||||
* range 0 to 127), or in your application space! In both cases, this would end up
|
|
||||||
* with a hard fault.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BLE_FLASH_H__
|
|
||||||
#define BLE_FLASH_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "nrf.h"
|
|
||||||
|
|
||||||
#define BLE_FLASH_PAGE_SIZE ((uint16_t)NRF_FICR->CODEPAGESIZE) /**< Size of one flash page. */
|
|
||||||
#define BLE_FLASH_MAGIC_NUMBER 0x45DE0000 /**< Magic value to identify if flash contains valid data. */
|
|
||||||
#define BLE_FLASH_EMPTY_MASK 0xFFFFFFFF /**< Bit mask that defines an empty address in flash. */
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for getting the end of the flash available for application.
|
|
||||||
*
|
|
||||||
* @details The result flash page number indicates the end boundary of the flash available
|
|
||||||
* to the application. If a bootloader is used, the end will be the start of the
|
|
||||||
* bootloader region. Otherwise, the end will be the size of the flash.
|
|
||||||
*/
|
|
||||||
#define BLE_FLASH_PAGE_END \
|
|
||||||
((NRF_UICR->BOOTLOADERADDR != BLE_FLASH_EMPTY_MASK) \
|
|
||||||
? (NRF_UICR->BOOTLOADERADDR / BLE_FLASH_PAGE_SIZE) \
|
|
||||||
: NRF_FICR->CODESIZE)
|
|
||||||
|
|
||||||
/**@brief Function for erasing the specified flash page, and then writes the given data to this page.
|
|
||||||
*
|
|
||||||
* @warning This operation blocks the CPU. DO NOT use while in a connection!
|
|
||||||
*
|
|
||||||
* @param[in] page_num Page number to update.
|
|
||||||
* @param[in] p_in_array Pointer to a RAM area containing the elements to write in flash.
|
|
||||||
* This area has to be 32 bits aligned.
|
|
||||||
* @param[in] word_count Number of 32 bits words to write in flash.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on successful flash write, otherwise an error code.
|
|
||||||
*/
|
|
||||||
uint32_t ble_flash_page_write(uint8_t page_num, uint32_t * p_in_array, uint8_t word_count);
|
|
||||||
|
|
||||||
/**@brief Function for reading data from flash to RAM.
|
|
||||||
*
|
|
||||||
* @param[in] page_num Page number to read.
|
|
||||||
* @param[out] p_out_array Pointer to a RAM area where the found data will be written.
|
|
||||||
* This area has to be 32 bits aligned.
|
|
||||||
* @param[out] p_word_count Number of 32 bits words read.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on successful upload, NRF_ERROR_NOT_FOUND if no valid data has been found
|
|
||||||
* in flash (first 32 bits not equal to the MAGIC_NUMBER+CRC).
|
|
||||||
*/
|
|
||||||
uint32_t ble_flash_page_read(uint8_t page_num, uint32_t * p_out_array, uint8_t * p_word_count);
|
|
||||||
|
|
||||||
/**@brief Function for erasing a flash page.
|
|
||||||
*
|
|
||||||
* @note This operation blocks the CPU, so it should not be done while the radio is running!
|
|
||||||
*
|
|
||||||
* @param[in] page_num Page number to erase.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on success, an error_code otherwise.
|
|
||||||
*/
|
|
||||||
uint32_t ble_flash_page_erase(uint8_t page_num);
|
|
||||||
|
|
||||||
/**@brief Function for writing one word to flash.
|
|
||||||
*
|
|
||||||
* @note Flash location to be written must have been erased previously.
|
|
||||||
*
|
|
||||||
* @param[in] p_address Pointer to flash location to be written.
|
|
||||||
* @param[in] value Value to write to flash.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS.
|
|
||||||
*/
|
|
||||||
uint32_t ble_flash_word_write(uint32_t * p_address, uint32_t value);
|
|
||||||
|
|
||||||
/**@brief Function for writing a data block to flash.
|
|
||||||
*
|
|
||||||
* @note Flash locations to be written must have been erased previously.
|
|
||||||
*
|
|
||||||
* @param[in] p_address Pointer to start of flash location to be written.
|
|
||||||
* @param[in] p_in_array Pointer to start of flash block to be written.
|
|
||||||
* @param[in] word_count Number of words to be written.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS.
|
|
||||||
*/
|
|
||||||
uint32_t ble_flash_block_write(uint32_t * p_address, uint32_t * p_in_array, uint16_t word_count);
|
|
||||||
|
|
||||||
/**@brief Function for computing pointer to start of specified flash page.
|
|
||||||
*
|
|
||||||
* @param[in] page_num Page number.
|
|
||||||
* @param[out] pp_page_addr Pointer to start of flash page.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS.
|
|
||||||
*/
|
|
||||||
uint32_t ble_flash_page_addr(uint8_t page_num, uint32_t ** pp_page_addr);
|
|
||||||
|
|
||||||
/**@brief Function for calculating a 16 bit CRC using the CRC-16-CCITT scheme.
|
|
||||||
*
|
|
||||||
* @param[in] p_data Pointer to data on which the CRC is to be calulated.
|
|
||||||
* @param[in] size Number of bytes on which the CRC is to be calulated.
|
|
||||||
* @param[in] p_crc Initial CRC value (if NULL, a preset value is used as the initial value).
|
|
||||||
*
|
|
||||||
* @return Calculated CRC.
|
|
||||||
*/
|
|
||||||
uint16_t ble_flash_crc16_compute(uint8_t * p_data, uint16_t size, uint16_t * p_crc);
|
|
||||||
|
|
||||||
/**@brief Function for handling flashing module Radio Notification event.
|
|
||||||
*
|
|
||||||
* @note For flash writing to work safely while in a connection or while advertising, this function
|
|
||||||
* MUST be called from the Radio Notification module's event handler (see
|
|
||||||
* @ref ble_radio_notification for details).
|
|
||||||
*
|
|
||||||
* @param[in] radio_active TRUE if radio is active (or about to become active), FALSE otherwise.
|
|
||||||
*/
|
|
||||||
void ble_flash_on_radio_active_evt(bool radio_active);
|
|
||||||
|
|
||||||
#endif // BLE_FLASH_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,46 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "compiler_abstraction.h"
|
|
||||||
#include "nrf.h"
|
|
||||||
#include "nrf_delay.h"
|
|
||||||
|
|
||||||
/*lint --e{438} "Variable not used" */
|
|
||||||
void nrf_delay_ms(uint32_t volatile number_of_ms)
|
|
||||||
{
|
|
||||||
while(number_of_ms != 0)
|
|
||||||
{
|
|
||||||
number_of_ms--;
|
|
||||||
nrf_delay_us(999);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,207 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NRF_DELAY_H
|
|
||||||
#define _NRF_DELAY_H
|
|
||||||
|
|
||||||
#include "nrf.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for delaying execution for number of microseconds.
|
|
||||||
*
|
|
||||||
* @note NRF52 has instruction cache and because of that delay is not precise.
|
|
||||||
*
|
|
||||||
* @param number_of_ms
|
|
||||||
*/
|
|
||||||
/*lint --e{438, 522} "Variable not used" "Function lacks side-effects" */
|
|
||||||
|
|
||||||
#if defined ( __ICCARM__ )
|
|
||||||
|
|
||||||
static void __INLINE nrf_delay_us(uint32_t volatile number_of_us)
|
|
||||||
{
|
|
||||||
__ASM (
|
|
||||||
"loop:\n\t"
|
|
||||||
" SUBS R0, R0, #1\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
#ifdef NRF52
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
" NOP\n\t"
|
|
||||||
#endif
|
|
||||||
" BNE.n loop\n\t");
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined ( _WIN32 ) || defined ( __unix ) || defined( __APPLE__ )
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_delay_us(uint32_t volatile number_of_us);
|
|
||||||
|
|
||||||
#ifndef CUSTOM_NRF_DELAY_US
|
|
||||||
__STATIC_INLINE void nrf_delay_us(uint32_t volatile number_of_us)
|
|
||||||
{}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif defined ( __GNUC__ )
|
|
||||||
|
|
||||||
static __INLINE void nrf_delay_us(uint32_t volatile number_of_us) __attribute__((always_inline));
|
|
||||||
static __INLINE void nrf_delay_us(uint32_t volatile number_of_us)
|
|
||||||
{
|
|
||||||
register uint32_t delay __ASM ("r0") = number_of_us;
|
|
||||||
__ASM volatile (
|
|
||||||
#ifdef NRF51
|
|
||||||
".syntax unified\n"
|
|
||||||
#endif
|
|
||||||
"1:\n"
|
|
||||||
" SUBS %0, %0, #1\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
#ifdef NRF52
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
" NOP\n"
|
|
||||||
#endif
|
|
||||||
" BNE 1b\n"
|
|
||||||
#ifdef NRF51
|
|
||||||
".syntax divided\n"
|
|
||||||
#endif
|
|
||||||
: "+r" (delay));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void nrf_delay_ms(uint32_t volatile number_of_ms);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,93 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief Implementation of AES ECB driver
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
//lint -e438
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "nrf.h"
|
|
||||||
#include "nrf_ecb.h"
|
|
||||||
|
|
||||||
static uint8_t ecb_data[48]; ///< ECB data structure for RNG peripheral to access.
|
|
||||||
static uint8_t* ecb_key; ///< Key: Starts at ecb_data
|
|
||||||
static uint8_t* ecb_cleartext; ///< Cleartext: Starts at ecb_data + 16 bytes.
|
|
||||||
static uint8_t* ecb_ciphertext; ///< Ciphertext: Starts at ecb_data + 32 bytes.
|
|
||||||
|
|
||||||
bool nrf_ecb_init(void)
|
|
||||||
{
|
|
||||||
ecb_key = ecb_data;
|
|
||||||
ecb_cleartext = ecb_data + 16;
|
|
||||||
ecb_ciphertext = ecb_data + 32;
|
|
||||||
|
|
||||||
NRF_ECB->ECBDATAPTR = (uint32_t)ecb_data;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool nrf_ecb_crypt(uint8_t * dest_buf, const uint8_t * src_buf)
|
|
||||||
{
|
|
||||||
uint32_t counter = 0x1000000;
|
|
||||||
if(src_buf != ecb_cleartext)
|
|
||||||
{
|
|
||||||
memcpy(ecb_cleartext,src_buf,16);
|
|
||||||
}
|
|
||||||
NRF_ECB->EVENTS_ENDECB = 0;
|
|
||||||
NRF_ECB->TASKS_STARTECB = 1;
|
|
||||||
while(NRF_ECB->EVENTS_ENDECB == 0)
|
|
||||||
{
|
|
||||||
counter--;
|
|
||||||
if(counter == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NRF_ECB->EVENTS_ENDECB = 0;
|
|
||||||
if(dest_buf != ecb_ciphertext)
|
|
||||||
{
|
|
||||||
memcpy(dest_buf,ecb_ciphertext,16);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nrf_ecb_set_key(const uint8_t * key)
|
|
||||||
{
|
|
||||||
memcpy(ecb_key,key,16);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,85 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief ECB driver API.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NRF_ECB_H__
|
|
||||||
#define NRF_ECB_H__
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup nrf_ecb AES ECB encryption
|
|
||||||
* @{
|
|
||||||
* @ingroup nrf_drivers
|
|
||||||
* @brief Driver for the AES Electronic Code Book (ECB) peripheral.
|
|
||||||
*
|
|
||||||
* To encrypt and decrypt data, the peripheral must first be powered on
|
|
||||||
* using @ref nrf_ecb_init. Next, the key must be set using @ref nrf_ecb_set_key.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for initializing and powering on the ECB peripheral.
|
|
||||||
*
|
|
||||||
* This function allocates memory for the ECBDATAPTR.
|
|
||||||
* @retval true If initialization was successful.
|
|
||||||
* @retval false If powering on failed.
|
|
||||||
*/
|
|
||||||
bool nrf_ecb_init(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for encrypting and decrypting 16-byte data using current key.
|
|
||||||
*
|
|
||||||
* This function avoids unnecessary copying of data if the parameters point to the
|
|
||||||
* correct locations in the ECB data structure.
|
|
||||||
*
|
|
||||||
* @param dst Result of encryption/decryption. 16 bytes will be written.
|
|
||||||
* @param src Source with 16-byte data to be encrypted/decrypted.
|
|
||||||
*
|
|
||||||
* @retval true If the encryption operation completed.
|
|
||||||
* @retval false If the encryption operation did not complete.
|
|
||||||
*/
|
|
||||||
bool nrf_ecb_crypt(uint8_t * dst, const uint8_t * src);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for setting the key to be used for encryption and decryption.
|
|
||||||
*
|
|
||||||
* @param key Pointer to the key. 16 bytes will be read.
|
|
||||||
*/
|
|
||||||
void nrf_ecb_set_key(const uint8_t * key);
|
|
||||||
|
|
||||||
#endif // NRF_ECB_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,667 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifndef NRF_GPIO_H__
|
|
||||||
#define NRF_GPIO_H__
|
|
||||||
|
|
||||||
#include "nrf.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup nrf_gpio GPIO abstraction
|
|
||||||
* @{
|
|
||||||
* @ingroup nrf_drivers
|
|
||||||
* @brief GPIO pin abstraction and port abstraction for reading and writing byte-wise to GPIO ports.
|
|
||||||
*
|
|
||||||
* Here, the GPIO ports are defined as follows:
|
|
||||||
* - Port 0 -> pin 0-7
|
|
||||||
* - Port 1 -> pin 8-15
|
|
||||||
* - Port 2 -> pin 16-23
|
|
||||||
* - Port 3 -> pin 24-31
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define NUMBER_OF_PINS 32
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enumerator used for selecting between port 0 - 3.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NRF_GPIO_PORT_SELECT_PORT0 = 0, ///< Port 0 (GPIO pin 0-7)
|
|
||||||
NRF_GPIO_PORT_SELECT_PORT1, ///< Port 1 (GPIO pin 8-15)
|
|
||||||
NRF_GPIO_PORT_SELECT_PORT2, ///< Port 2 (GPIO pin 16-23)
|
|
||||||
NRF_GPIO_PORT_SELECT_PORT3, ///< Port 3 (GPIO pin 24-31)
|
|
||||||
} nrf_gpio_port_select_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enumerator used for setting the direction of a GPIO port.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NRF_GPIO_PORT_DIR_OUTPUT, ///< Output
|
|
||||||
NRF_GPIO_PORT_DIR_INPUT ///< Input
|
|
||||||
} nrf_gpio_port_dir_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Pin direction definitions.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NRF_GPIO_PIN_DIR_INPUT = GPIO_PIN_CNF_DIR_Input, ///< Input
|
|
||||||
NRF_GPIO_PIN_DIR_OUTPUT = GPIO_PIN_CNF_DIR_Output ///< Output
|
|
||||||
} nrf_gpio_pin_dir_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Connection of input buffer
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NRF_GPIO_PIN_INPUT_CONNECT = GPIO_PIN_CNF_INPUT_Connect, ///< Connect input buffer
|
|
||||||
NRF_GPIO_PIN_INPUT_DISCONNECT = GPIO_PIN_CNF_INPUT_Disconnect ///< Disconnect input buffer
|
|
||||||
} nrf_gpio_pin_input_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enumerator used for selecting the pin to be pulled down or up at the time of pin configuration
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NRF_GPIO_PIN_NOPULL = GPIO_PIN_CNF_PULL_Disabled, ///< Pin pullup resistor disabled
|
|
||||||
NRF_GPIO_PIN_PULLDOWN = GPIO_PIN_CNF_PULL_Pulldown, ///< Pin pulldown resistor enabled
|
|
||||||
NRF_GPIO_PIN_PULLUP = GPIO_PIN_CNF_PULL_Pullup, ///< Pin pullup resistor enabled
|
|
||||||
} nrf_gpio_pin_pull_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enumerator used for selecting output drive mode
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NRF_GPIO_PIN_S0S1 = GPIO_PIN_CNF_DRIVE_S0S1, ///< !< Standard '0', standard '1'
|
|
||||||
NRF_GPIO_PIN_H0S1 = GPIO_PIN_CNF_DRIVE_H0S1, ///< !< High drive '0', standard '1'
|
|
||||||
NRF_GPIO_PIN_S0H1 = GPIO_PIN_CNF_DRIVE_S0H1, ///< !< Standard '0', high drive '1'
|
|
||||||
NRF_GPIO_PIN_H0H1 = GPIO_PIN_CNF_DRIVE_H0H1, ///< !< High drive '0', high 'drive '1''
|
|
||||||
NRF_GPIO_PIN_D0S1 = GPIO_PIN_CNF_DRIVE_D0S1, ///< !< Disconnect '0' standard '1'
|
|
||||||
NRF_GPIO_PIN_D0H1 = GPIO_PIN_CNF_DRIVE_D0H1, ///< !< Disconnect '0', high drive '1'
|
|
||||||
NRF_GPIO_PIN_S0D1 = GPIO_PIN_CNF_DRIVE_S0D1, ///< !< Standard '0'. disconnect '1'
|
|
||||||
NRF_GPIO_PIN_H0D1 = GPIO_PIN_CNF_DRIVE_H0D1, ///< !< High drive '0', disconnect '1'
|
|
||||||
} nrf_gpio_pin_drive_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enumerator used for selecting the pin to sense high or low level on the pin input.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NRF_GPIO_PIN_NOSENSE = GPIO_PIN_CNF_SENSE_Disabled, ///< Pin sense level disabled.
|
|
||||||
NRF_GPIO_PIN_SENSE_LOW = GPIO_PIN_CNF_SENSE_Low, ///< Pin sense low level.
|
|
||||||
NRF_GPIO_PIN_SENSE_HIGH = GPIO_PIN_CNF_SENSE_High, ///< Pin sense high level.
|
|
||||||
} nrf_gpio_pin_sense_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for configuring the GPIO pin range as outputs with normal drive strength.
|
|
||||||
* This function can be used to configure pin range as simple output with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
|
|
||||||
*
|
|
||||||
* @param pin_range_start specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30)
|
|
||||||
*
|
|
||||||
* @param pin_range_end specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30)
|
|
||||||
*
|
|
||||||
* @note For configuring only one pin as output use @ref nrf_gpio_cfg_output
|
|
||||||
* Sense capability on the pin is disabled, and input is disconnected from the buffer as the pins are configured as output.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for configuring the GPIO pin range as inputs with given initial value set, hiding inner details.
|
|
||||||
* This function can be used to configure pin range as simple input.
|
|
||||||
*
|
|
||||||
* @param pin_range_start specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30)
|
|
||||||
*
|
|
||||||
* @param pin_range_end specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30)
|
|
||||||
*
|
|
||||||
* @param pull_config State of the pin range pull resistor (no pull, pulled down or pulled high)
|
|
||||||
*
|
|
||||||
* @note For configuring only one pin as input use @ref nrf_gpio_cfg_input
|
|
||||||
* Sense capability on the pin is disabled, and input is connected to buffer so that the GPIO->IN register is readable
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, uint32_t pin_range_end, nrf_gpio_pin_pull_t pull_config);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Pin configuration function
|
|
||||||
*
|
|
||||||
* The main pin configuration function.
|
|
||||||
* This function allows to set any aspect in PIN_CNF register.
|
|
||||||
* @param pin_number Specifies the pin number (allowed values 0-31).
|
|
||||||
* @param dir Pin direction
|
|
||||||
* @param input Connect or disconnect input buffer
|
|
||||||
* @param pull Pull configuration
|
|
||||||
* @param drive Drive configuration
|
|
||||||
* @param sense Pin sensing mechanism
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_cfg(
|
|
||||||
uint32_t pin_number,
|
|
||||||
nrf_gpio_pin_dir_t dir,
|
|
||||||
nrf_gpio_pin_input_t input,
|
|
||||||
nrf_gpio_pin_pull_t pull,
|
|
||||||
nrf_gpio_pin_drive_t drive,
|
|
||||||
nrf_gpio_pin_sense_t sense);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for configuring the given GPIO pin number as output with given initial value set, hiding inner details.
|
|
||||||
* This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
|
|
||||||
*
|
|
||||||
* @param pin_number specifies the pin number (allowed values 0-31)
|
|
||||||
*
|
|
||||||
* @note Sense capability on the pin is disabled, and input is disconnected from the buffer as the pins are configured as output.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for configuring the given GPIO pin number as input with given initial value set, hiding inner details.
|
|
||||||
* This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
|
|
||||||
*
|
|
||||||
* @param pin_number Specifies the pin number (allowed values 0-30).
|
|
||||||
* @param pull_config State of the pin range pull resistor (no pull, pulled down or pulled high).
|
|
||||||
*
|
|
||||||
* @note Sense capability on the pin is disabled, and input is connected to buffer so that the GPIO->IN register is readable
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for reseting pin configuration to its default state.
|
|
||||||
*
|
|
||||||
* @param pin_number Specifies the pin number (allowed values 0-31).
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for configuring the given GPIO pin number as a watcher. Only input is connected.
|
|
||||||
*
|
|
||||||
* @param pin_number Specifies the pin number (allowed values 0-31).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for disconnecting input for the given GPIO.
|
|
||||||
*
|
|
||||||
* @param pin_number Specifies the pin number (allowed values 0-31).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for configuring the given GPIO pin number as input with given initial value set, hiding inner details.
|
|
||||||
* This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases).
|
|
||||||
* Sense capability on the pin is configurable, and input is connected to buffer so that the GPIO->IN register is readable.
|
|
||||||
*
|
|
||||||
* @param pin_number Specifies the pin number (allowed values 0-30).
|
|
||||||
* @param pull_config State of the pin pull resistor (no pull, pulled down or pulled high).
|
|
||||||
* @param sense_config Sense level of the pin (no sense, sense low or sense high).
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config, nrf_gpio_pin_sense_t sense_config);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for configuring sense level for the given GPIO.
|
|
||||||
*
|
|
||||||
* @param pin_number Specifies the pin number of gpio pin numbers to be configured (allowed values 0-30).
|
|
||||||
* @param sense_config Sense configuration.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_cfg_sense_set(uint32_t pin_number, nrf_gpio_pin_sense_t sense_config);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for setting the direction for a GPIO pin.
|
|
||||||
*
|
|
||||||
* @param pin_number specifies the pin number [0:31] for which to
|
|
||||||
* set the direction.
|
|
||||||
*
|
|
||||||
* @param direction specifies the direction
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for setting a GPIO pin.
|
|
||||||
*
|
|
||||||
* Note that the pin must be configured as an output for this
|
|
||||||
* function to have any effect.
|
|
||||||
*
|
|
||||||
* @param pin_number specifies the pin number [0:31] to
|
|
||||||
* set.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for setting GPIO pins.
|
|
||||||
*
|
|
||||||
* Note that pins must be configured as an output for this
|
|
||||||
* function to have any effect.
|
|
||||||
*
|
|
||||||
* @param pin_mask Specifies the pins to set.
|
|
||||||
* set.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_pins_set(uint32_t pin_mask);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for clearing a GPIO pin.
|
|
||||||
*
|
|
||||||
* Note that the pin must be configured as an output for this
|
|
||||||
* function to have any effect.
|
|
||||||
*
|
|
||||||
* @param pin_number specifies the pin number [0:31] to
|
|
||||||
* clear.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for clearing GPIO pins.
|
|
||||||
*
|
|
||||||
* Note that pins must be configured as an output for this
|
|
||||||
* function to have any effect.
|
|
||||||
*
|
|
||||||
* @param pin_mask Specifies the pins to clear.
|
|
||||||
* set.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_pins_clear(uint32_t pin_mask);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for toggling a GPIO pin.
|
|
||||||
*
|
|
||||||
* Note that the pin must be configured as an output for this
|
|
||||||
* function to have any effect.
|
|
||||||
*
|
|
||||||
* @param pin_number specifies the pin number [0:31] to
|
|
||||||
* toggle.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for writing a value to a GPIO pin.
|
|
||||||
*
|
|
||||||
* Note that the pin must be configured as an output for this
|
|
||||||
* function to have any effect.
|
|
||||||
*
|
|
||||||
* @param pin_number specifies the pin number [0:31] to
|
|
||||||
* write.
|
|
||||||
*
|
|
||||||
* @param value specifies the value to be written to the pin.
|
|
||||||
* @arg 0 clears the pin
|
|
||||||
* @arg >=1 sets the pin.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for reading the input level of a GPIO pin.
|
|
||||||
*
|
|
||||||
* Note that the pin must have input connected for the value
|
|
||||||
* returned from this function to be valid.
|
|
||||||
*
|
|
||||||
* @param pin_number specifies the pin number [0:31] to
|
|
||||||
* read.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* @retval 0 if the pin input level is low.
|
|
||||||
* @retval 1 if the pin input level is high.
|
|
||||||
* @retval > 1 should never occur.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for reading the input level of all GPIO pins.
|
|
||||||
*
|
|
||||||
* Note that the pin must have input connected for the value
|
|
||||||
* returned from this function to be valid.
|
|
||||||
*
|
|
||||||
* @retval Status of input of all pins
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE uint32_t nrf_gpio_pins_read(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for reading the sense configuration of a GPIO pin.
|
|
||||||
*
|
|
||||||
* @param pin_number specifies the pin number [0:31] to
|
|
||||||
* read.
|
|
||||||
*
|
|
||||||
* @retval Sense configuration
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Generic function for writing a single byte of a 32 bit word at a given
|
|
||||||
* address.
|
|
||||||
*
|
|
||||||
* This function should not be called from outside the nrf_gpio
|
|
||||||
* abstraction layer.
|
|
||||||
*
|
|
||||||
* @param word_address is the address of the word to be written.
|
|
||||||
*
|
|
||||||
* @param byte_no is the word byte number (0-3) to be written.
|
|
||||||
*
|
|
||||||
* @param value is the value to be written to byte "byte_no" of word
|
|
||||||
* at address "word_address"
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_word_byte_write(volatile uint32_t * word_address, uint8_t byte_no, uint8_t value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Generic function for reading a single byte of a 32 bit word at a given
|
|
||||||
* address.
|
|
||||||
*
|
|
||||||
* This function should not be called from outside the nrf_gpio
|
|
||||||
* abstraction layer.
|
|
||||||
*
|
|
||||||
* @param word_address is the address of the word to be read.
|
|
||||||
*
|
|
||||||
* @param byte_no is the byte number (0-3) of the word to be read.
|
|
||||||
*
|
|
||||||
* @return byte "byte_no" of word at address "word_address".
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE uint8_t nrf_gpio_word_byte_read(const volatile uint32_t* word_address, uint8_t byte_no);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for setting the direction of a port.
|
|
||||||
*
|
|
||||||
* @param port is the port for which to set the direction.
|
|
||||||
*
|
|
||||||
* @param dir direction to be set for this port.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_port_dir_set(nrf_gpio_port_select_t port, nrf_gpio_port_dir_t dir);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for reading a GPIO port.
|
|
||||||
*
|
|
||||||
* @param port is the port to read.
|
|
||||||
*
|
|
||||||
* @return the input value on this port.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE uint8_t nrf_gpio_port_read(nrf_gpio_port_select_t port);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for writing to a GPIO port.
|
|
||||||
*
|
|
||||||
* @param port is the port to write.
|
|
||||||
*
|
|
||||||
* @param value is the value to write to this port.
|
|
||||||
*
|
|
||||||
* @sa nrf_gpio_port_dir_set()
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_port_write(nrf_gpio_port_select_t port, uint8_t value);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for setting individual pins on GPIO port.
|
|
||||||
*
|
|
||||||
* @param port is the port for which to set the pins.
|
|
||||||
*
|
|
||||||
* @param set_mask is a mask specifying which pins to set. A bit
|
|
||||||
* set to 1 indicates that the corresponding port pin shall be
|
|
||||||
* set.
|
|
||||||
*
|
|
||||||
* @sa nrf_gpio_port_dir_set()
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_port_set(nrf_gpio_port_select_t port, uint8_t set_mask);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for clearing individual pins on GPIO port.
|
|
||||||
*
|
|
||||||
* @param port is the port for which to clear the pins.
|
|
||||||
*
|
|
||||||
* @param clr_mask is a mask specifying which pins to clear. A bit
|
|
||||||
* set to 1 indicates that the corresponding port pin shall be
|
|
||||||
* cleared.
|
|
||||||
*
|
|
||||||
* @sa nrf_gpio_port_dir_set()
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpio_port_clear(nrf_gpio_port_select_t port, uint8_t clr_mask);
|
|
||||||
|
|
||||||
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
|
|
||||||
__STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end)
|
|
||||||
{
|
|
||||||
/*lint -e{845} // A zero has been given as right argument to operator '|'" */
|
|
||||||
for (; pin_range_start <= pin_range_end; pin_range_start++)
|
|
||||||
{
|
|
||||||
nrf_gpio_cfg_output(pin_range_start);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, uint32_t pin_range_end, nrf_gpio_pin_pull_t pull_config)
|
|
||||||
{
|
|
||||||
/*lint -e{845} // A zero has been given as right argument to operator '|'" */
|
|
||||||
for (; pin_range_start <= pin_range_end; pin_range_start++)
|
|
||||||
{
|
|
||||||
nrf_gpio_cfg_input(pin_range_start, pull_config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_cfg(
|
|
||||||
uint32_t pin_number,
|
|
||||||
nrf_gpio_pin_dir_t dir,
|
|
||||||
nrf_gpio_pin_input_t input,
|
|
||||||
nrf_gpio_pin_pull_t pull,
|
|
||||||
nrf_gpio_pin_drive_t drive,
|
|
||||||
nrf_gpio_pin_sense_t sense)
|
|
||||||
{
|
|
||||||
NRF_GPIO->PIN_CNF[pin_number] = ((uint32_t)dir << GPIO_PIN_CNF_DIR_Pos)
|
|
||||||
| ((uint32_t)input << GPIO_PIN_CNF_INPUT_Pos)
|
|
||||||
| ((uint32_t)pull << GPIO_PIN_CNF_PULL_Pos)
|
|
||||||
| ((uint32_t)drive << GPIO_PIN_CNF_DRIVE_Pos)
|
|
||||||
| ((uint32_t)sense << GPIO_PIN_CNF_SENSE_Pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number)
|
|
||||||
{
|
|
||||||
nrf_gpio_cfg(
|
|
||||||
pin_number,
|
|
||||||
NRF_GPIO_PIN_DIR_OUTPUT,
|
|
||||||
NRF_GPIO_PIN_INPUT_DISCONNECT,
|
|
||||||
NRF_GPIO_PIN_NOPULL,
|
|
||||||
NRF_GPIO_PIN_S0S1,
|
|
||||||
NRF_GPIO_PIN_NOSENSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config)
|
|
||||||
{
|
|
||||||
nrf_gpio_cfg(
|
|
||||||
pin_number,
|
|
||||||
NRF_GPIO_PIN_DIR_INPUT,
|
|
||||||
NRF_GPIO_PIN_INPUT_CONNECT,
|
|
||||||
pull_config,
|
|
||||||
NRF_GPIO_PIN_S0S1,
|
|
||||||
NRF_GPIO_PIN_NOSENSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number)
|
|
||||||
{
|
|
||||||
nrf_gpio_cfg(
|
|
||||||
pin_number,
|
|
||||||
NRF_GPIO_PIN_DIR_INPUT,
|
|
||||||
NRF_GPIO_PIN_INPUT_DISCONNECT,
|
|
||||||
NRF_GPIO_PIN_NOPULL,
|
|
||||||
NRF_GPIO_PIN_S0S1,
|
|
||||||
NRF_GPIO_PIN_NOSENSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number)
|
|
||||||
{
|
|
||||||
/*lint -e{845} // A zero has been given as right argument to operator '|'" */
|
|
||||||
uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk;
|
|
||||||
NRF_GPIO->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number)
|
|
||||||
{
|
|
||||||
/*lint -e{845} // A zero has been given as right argument to operator '|'" */
|
|
||||||
uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk;
|
|
||||||
NRF_GPIO->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config, nrf_gpio_pin_sense_t sense_config)
|
|
||||||
{
|
|
||||||
nrf_gpio_cfg(
|
|
||||||
pin_number,
|
|
||||||
NRF_GPIO_PIN_DIR_INPUT,
|
|
||||||
NRF_GPIO_PIN_INPUT_CONNECT,
|
|
||||||
pull_config,
|
|
||||||
NRF_GPIO_PIN_S0S1,
|
|
||||||
sense_config);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_cfg_sense_set(uint32_t pin_number, nrf_gpio_pin_sense_t sense_config)
|
|
||||||
{
|
|
||||||
/*lint -e{845} // A zero has been given as right argument to operator '|'" */
|
|
||||||
//uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_SENSE_Msk;
|
|
||||||
NRF_GPIO->PIN_CNF[pin_number] &= ~GPIO_PIN_CNF_SENSE_Msk;
|
|
||||||
NRF_GPIO->PIN_CNF[pin_number] |= (sense_config << GPIO_PIN_CNF_SENSE_Pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction)
|
|
||||||
{
|
|
||||||
if(direction == NRF_GPIO_PIN_DIR_INPUT)
|
|
||||||
{
|
|
||||||
nrf_gpio_cfg(
|
|
||||||
pin_number,
|
|
||||||
NRF_GPIO_PIN_DIR_INPUT,
|
|
||||||
NRF_GPIO_PIN_INPUT_CONNECT,
|
|
||||||
NRF_GPIO_PIN_NOPULL,
|
|
||||||
NRF_GPIO_PIN_S0S1,
|
|
||||||
NRF_GPIO_PIN_NOSENSE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NRF_GPIO->DIRSET = (1UL << pin_number);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number)
|
|
||||||
{
|
|
||||||
NRF_GPIO->OUTSET = (1UL << pin_number);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_pins_set(uint32_t pin_mask)
|
|
||||||
{
|
|
||||||
NRF_GPIO->OUTSET = pin_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number)
|
|
||||||
{
|
|
||||||
NRF_GPIO->OUTCLR = (1UL << pin_number);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_pins_clear(uint32_t pin_mask)
|
|
||||||
{
|
|
||||||
NRF_GPIO->OUTCLR = pin_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number)
|
|
||||||
{
|
|
||||||
const uint32_t pin_bit = 1UL << pin_number;
|
|
||||||
const uint32_t pin_state = ((NRF_GPIO->OUT >> pin_number) & 1UL);
|
|
||||||
|
|
||||||
if (pin_state == 0)
|
|
||||||
{
|
|
||||||
// Current state low, set high.
|
|
||||||
NRF_GPIO->OUTSET = pin_bit;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Current state high, set low.
|
|
||||||
NRF_GPIO->OUTCLR = pin_bit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value)
|
|
||||||
{
|
|
||||||
if (value == 0)
|
|
||||||
{
|
|
||||||
nrf_gpio_pin_clear(pin_number);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nrf_gpio_pin_set(pin_number);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number)
|
|
||||||
{
|
|
||||||
return ((NRF_GPIO->IN >> pin_number) & 1UL);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE uint32_t nrf_gpio_pins_read(void)
|
|
||||||
{
|
|
||||||
return NRF_GPIO->IN;
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number)
|
|
||||||
{
|
|
||||||
return (nrf_gpio_pin_sense_t)((NRF_GPIO->PIN_CNF[pin_number] & GPIO_PIN_CNF_SENSE_Msk) >> GPIO_PIN_CNF_SENSE_Pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_word_byte_write(volatile uint32_t * word_address, uint8_t byte_no, uint8_t value)
|
|
||||||
{
|
|
||||||
*((volatile uint8_t*)(word_address) + byte_no) = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE uint8_t nrf_gpio_word_byte_read(const volatile uint32_t* word_address, uint8_t byte_no)
|
|
||||||
{
|
|
||||||
return (*((const volatile uint8_t*)(word_address) + byte_no));
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_port_dir_set(nrf_gpio_port_select_t port, nrf_gpio_port_dir_t dir)
|
|
||||||
{
|
|
||||||
if (dir == NRF_GPIO_PORT_DIR_OUTPUT)
|
|
||||||
{
|
|
||||||
nrf_gpio_word_byte_write(&NRF_GPIO->DIRSET, port, 0xFF);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nrf_gpio_range_cfg_input(port*8, (port+1)*8-1, NRF_GPIO_PIN_NOPULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE uint8_t nrf_gpio_port_read(nrf_gpio_port_select_t port)
|
|
||||||
{
|
|
||||||
return nrf_gpio_word_byte_read(&NRF_GPIO->IN, port);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_port_write(nrf_gpio_port_select_t port, uint8_t value)
|
|
||||||
{
|
|
||||||
nrf_gpio_word_byte_write(&NRF_GPIO->OUT, port, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_port_set(nrf_gpio_port_select_t port, uint8_t set_mask)
|
|
||||||
{
|
|
||||||
nrf_gpio_word_byte_write(&NRF_GPIO->OUTSET, port, set_mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpio_port_clear(nrf_gpio_port_select_t port, uint8_t clr_mask)
|
|
||||||
{
|
|
||||||
nrf_gpio_word_byte_write(&NRF_GPIO->OUTCLR, port, clr_mask);
|
|
||||||
}
|
|
||||||
#endif //SUPPRESS_INLINE_IMPLEMENTATION
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,366 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifndef NRF_GPIOTE_H__
|
|
||||||
#define NRF_GPIOTE_H__
|
|
||||||
|
|
||||||
#include "nrf.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup nrf_gpiote_abs GPIOTE abstraction
|
|
||||||
* @{
|
|
||||||
* @ingroup nrf_gpiote
|
|
||||||
* @brief GPIOTE abstraction for configuration of channels.
|
|
||||||
*/
|
|
||||||
#ifdef NRF51
|
|
||||||
#define NUMBER_OF_GPIO_TE 4
|
|
||||||
#elif defined NRF52
|
|
||||||
#define NUMBER_OF_GPIO_TE 8
|
|
||||||
#else
|
|
||||||
#error "Chip family not specified"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @enum nrf_gpiote_polarity_t
|
|
||||||
* @brief Polarity for the GPIOTE channel.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NRF_GPIOTE_POLARITY_LOTOHI = GPIOTE_CONFIG_POLARITY_LoToHi, ///< Low to high.
|
|
||||||
NRF_GPIOTE_POLARITY_HITOLO = GPIOTE_CONFIG_POLARITY_HiToLo, ///< High to low.
|
|
||||||
NRF_GPIOTE_POLARITY_TOGGLE = GPIOTE_CONFIG_POLARITY_Toggle ///< Toggle.
|
|
||||||
} nrf_gpiote_polarity_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @enum nrf_gpiote_outinit_t
|
|
||||||
* @brief Initial output value for the GPIOTE channel.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NRF_GPIOTE_INITIAL_VALUE_LOW = GPIOTE_CONFIG_OUTINIT_Low, ///< Low to high.
|
|
||||||
NRF_GPIOTE_INITIAL_VALUE_HIGH = GPIOTE_CONFIG_OUTINIT_High ///< High to low.
|
|
||||||
} nrf_gpiote_outinit_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Tasks.
|
|
||||||
*/
|
|
||||||
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
|
|
||||||
{
|
|
||||||
NRF_GPIOTE_TASKS_OUT_0 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[0]), /**< Out task 0.*/
|
|
||||||
NRF_GPIOTE_TASKS_OUT_1 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[1]), /**< Out task 1.*/
|
|
||||||
NRF_GPIOTE_TASKS_OUT_2 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[2]), /**< Out task 2.*/
|
|
||||||
NRF_GPIOTE_TASKS_OUT_3 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[3]), /**< Out task 3.*/
|
|
||||||
/*lint -restore*/
|
|
||||||
} nrf_gpiote_tasks_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Events.
|
|
||||||
*/
|
|
||||||
typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */
|
|
||||||
{
|
|
||||||
NRF_GPIOTE_EVENTS_IN_0 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[0]), /**< In event 0.*/
|
|
||||||
NRF_GPIOTE_EVENTS_IN_1 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[1]), /**< In event 1.*/
|
|
||||||
NRF_GPIOTE_EVENTS_IN_2 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[2]), /**< In event 2.*/
|
|
||||||
NRF_GPIOTE_EVENTS_IN_3 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[3]), /**< In event 3.*/
|
|
||||||
NRF_GPIOTE_EVENTS_PORT = offsetof(NRF_GPIOTE_Type, EVENTS_PORT), /**< Port event.*/
|
|
||||||
/*lint -restore*/
|
|
||||||
} nrf_gpiote_events_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @enum nrf_gpiote_int_t
|
|
||||||
* @brief GPIOTE interrupts.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NRF_GPIOTE_INT_IN0_MASK = GPIOTE_INTENSET_IN0_Msk, /**< GPIOTE interrupt from IN0. */
|
|
||||||
NRF_GPIOTE_INT_IN1_MASK = GPIOTE_INTENSET_IN1_Msk, /**< GPIOTE interrupt from IN1. */
|
|
||||||
NRF_GPIOTE_INT_IN2_MASK = GPIOTE_INTENSET_IN2_Msk, /**< GPIOTE interrupt from IN2. */
|
|
||||||
NRF_GPIOTE_INT_IN3_MASK = GPIOTE_INTENSET_IN3_Msk, /**< GPIOTE interrupt from IN3. */
|
|
||||||
NRF_GPIOTE_INT_PORT_MASK = (int)GPIOTE_INTENSET_PORT_Msk, /**< GPIOTE interrupt from PORT event. */
|
|
||||||
} nrf_gpiote_int_t;
|
|
||||||
|
|
||||||
#define NRF_GPIOTE_INT_IN_MASK (NRF_GPIOTE_INT_IN0_MASK | NRF_GPIOTE_INT_IN1_MASK |\
|
|
||||||
NRF_GPIOTE_INT_IN2_MASK | NRF_GPIOTE_INT_IN3_MASK)
|
|
||||||
/**
|
|
||||||
* @brief Function for activating a specific GPIOTE task.
|
|
||||||
*
|
|
||||||
* @param[in] task Task.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpiote_task_set(nrf_gpiote_tasks_t task);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for getting the address of a specific GPIOTE task.
|
|
||||||
*
|
|
||||||
* @param[in] task Task.
|
|
||||||
*
|
|
||||||
* @returns Address.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE uint32_t nrf_gpiote_task_addr_get(nrf_gpiote_tasks_t task);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for getting the state of a specific GPIOTE event.
|
|
||||||
*
|
|
||||||
* @param[in] event Event.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE bool nrf_gpiote_event_is_set(nrf_gpiote_events_t event);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for clearing a specific GPIOTE event.
|
|
||||||
*
|
|
||||||
* @param[in] event Event.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpiote_event_clear(nrf_gpiote_events_t event);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for getting the address of a specific GPIOTE event.
|
|
||||||
*
|
|
||||||
* @param[in] event Event.
|
|
||||||
*
|
|
||||||
* @return Address
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE uint32_t nrf_gpiote_event_addr_get(nrf_gpiote_events_t event);
|
|
||||||
|
|
||||||
/**@brief Function for enabling interrupts.
|
|
||||||
*
|
|
||||||
* @param[in] mask Interrupt mask to be enabled.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpiote_int_enable(uint32_t mask);
|
|
||||||
|
|
||||||
/**@brief Function for disabling interrupts.
|
|
||||||
*
|
|
||||||
* @param[in] mask Interrupt mask to be disabled.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpiote_int_disable(uint32_t mask);
|
|
||||||
|
|
||||||
/**@brief Function for checking if interrupts are enabled.
|
|
||||||
*
|
|
||||||
* @param[in] mask Mask of interrupt flags to check.
|
|
||||||
*
|
|
||||||
* @return Mask with enabled interrupts.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE uint32_t nrf_gpiote_int_is_enabled(uint32_t mask);
|
|
||||||
|
|
||||||
/**@brief Function for enabling a GPIOTE event.
|
|
||||||
*
|
|
||||||
* @param[in] idx Task-Event index.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpiote_event_enable(uint32_t idx);
|
|
||||||
|
|
||||||
/**@brief Function for disabling a GPIOTE event.
|
|
||||||
*
|
|
||||||
* @param[in] idx Task-Event index.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpiote_event_disable(uint32_t idx);
|
|
||||||
|
|
||||||
/**@brief Function for configuring a GPIOTE event.
|
|
||||||
*
|
|
||||||
* @param[in] idx Task-Event index.
|
|
||||||
* @param[in] pin Pin associated with event.
|
|
||||||
* @param[in] polarity Transition that should generate an event.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpiote_event_configure(uint32_t idx, uint32_t pin,
|
|
||||||
nrf_gpiote_polarity_t polarity);
|
|
||||||
|
|
||||||
/**@brief Function for getting the pin associated with a GPIOTE event.
|
|
||||||
*
|
|
||||||
* @param[in] idx Task-Event index.
|
|
||||||
*
|
|
||||||
* @return Pin number.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE uint32_t nrf_gpiote_event_pin_get(uint32_t idx);
|
|
||||||
|
|
||||||
/**@brief Function for getting the polarity associated with a GPIOTE event.
|
|
||||||
*
|
|
||||||
* @param[in] idx Task-Event index.
|
|
||||||
*
|
|
||||||
* @return Polarity.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE nrf_gpiote_polarity_t nrf_gpiote_event_polarity_get(uint32_t idx);
|
|
||||||
|
|
||||||
/**@brief Function for enabling a GPIOTE task.
|
|
||||||
*
|
|
||||||
* @param[in] idx Task-Event index.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpiote_task_enable(uint32_t idx);
|
|
||||||
|
|
||||||
/**@brief Function for disabling a GPIOTE task.
|
|
||||||
*
|
|
||||||
* @param[in] idx Task-Event index.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpiote_task_disable(uint32_t idx);
|
|
||||||
|
|
||||||
/**@brief Function for configuring a GPIOTE task.
|
|
||||||
* @note Function is not configuring mode field so task is disabled after this function is called.
|
|
||||||
*
|
|
||||||
* @param[in] idx Task-Event index.
|
|
||||||
* @param[in] pin Pin associated with event.
|
|
||||||
* @param[in] polarity Transition that should generate an event.
|
|
||||||
* @param[in] init_val Initial value of pin.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpiote_task_configure(uint32_t idx, uint32_t pin,
|
|
||||||
nrf_gpiote_polarity_t polarity,
|
|
||||||
nrf_gpiote_outinit_t init_val);
|
|
||||||
|
|
||||||
/**@brief Function for forcing a specific state on the pin connected to GPIOTE.
|
|
||||||
*
|
|
||||||
* @param[in] idx Task-Event index.
|
|
||||||
* @param[in] init_val Pin state.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpiote_task_force(uint32_t idx, nrf_gpiote_outinit_t init_val);
|
|
||||||
|
|
||||||
/**@brief Function for resetting a GPIOTE task event configuration to the default state.
|
|
||||||
*
|
|
||||||
* @param[in] idx Task-Event index.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_gpiote_te_default(uint32_t idx);
|
|
||||||
|
|
||||||
#ifndef SUPPRESS_INLINE_IMPLEMENTATION
|
|
||||||
__STATIC_INLINE void nrf_gpiote_task_set(nrf_gpiote_tasks_t task)
|
|
||||||
{
|
|
||||||
*(__IO uint32_t *)((uint32_t)NRF_GPIOTE + task) = 0x1UL;
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE uint32_t nrf_gpiote_task_addr_get(nrf_gpiote_tasks_t task)
|
|
||||||
{
|
|
||||||
return ((uint32_t)NRF_GPIOTE + task);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE bool nrf_gpiote_event_is_set(nrf_gpiote_events_t event)
|
|
||||||
{
|
|
||||||
return (*(uint32_t *)nrf_gpiote_event_addr_get(event) == 0x1UL) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpiote_event_clear(nrf_gpiote_events_t event)
|
|
||||||
{
|
|
||||||
*(uint32_t *)nrf_gpiote_event_addr_get(event) = 0;
|
|
||||||
#if __CORTEX_M == 0x04
|
|
||||||
volatile uint32_t dummy = *((volatile uint32_t *)nrf_gpiote_event_addr_get(event));
|
|
||||||
(void)dummy;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE uint32_t nrf_gpiote_event_addr_get(nrf_gpiote_events_t event)
|
|
||||||
{
|
|
||||||
return ((uint32_t)NRF_GPIOTE + event);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpiote_int_enable(uint32_t mask)
|
|
||||||
{
|
|
||||||
NRF_GPIOTE->INTENSET = mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpiote_int_disable(uint32_t mask)
|
|
||||||
{
|
|
||||||
NRF_GPIOTE->INTENCLR = mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE uint32_t nrf_gpiote_int_is_enabled(uint32_t mask)
|
|
||||||
{
|
|
||||||
return (NRF_GPIOTE->INTENSET & mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpiote_event_enable(uint32_t idx)
|
|
||||||
{
|
|
||||||
NRF_GPIOTE->CONFIG[idx] |= GPIOTE_CONFIG_MODE_Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpiote_event_disable(uint32_t idx)
|
|
||||||
{
|
|
||||||
NRF_GPIOTE->CONFIG[idx] &= ~GPIOTE_CONFIG_MODE_Event;
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpiote_event_configure(uint32_t idx, uint32_t pin, nrf_gpiote_polarity_t polarity)
|
|
||||||
{
|
|
||||||
NRF_GPIOTE->CONFIG[idx] &= ~(GPIOTE_CONFIG_PSEL_Msk | GPIOTE_CONFIG_POLARITY_Msk);
|
|
||||||
NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk) |
|
|
||||||
((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE uint32_t nrf_gpiote_event_pin_get(uint32_t idx)
|
|
||||||
{
|
|
||||||
return ((NRF_GPIOTE->CONFIG[idx] & GPIOTE_CONFIG_PSEL_Msk) >> GPIOTE_CONFIG_PSEL_Pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE nrf_gpiote_polarity_t nrf_gpiote_event_polarity_get(uint32_t idx)
|
|
||||||
{
|
|
||||||
return (nrf_gpiote_polarity_t)((NRF_GPIOTE->CONFIG[idx] & GPIOTE_CONFIG_POLARITY_Msk) >> GPIOTE_CONFIG_POLARITY_Pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpiote_task_enable(uint32_t idx)
|
|
||||||
{
|
|
||||||
uint32_t final_config = NRF_GPIOTE->CONFIG[idx] | GPIOTE_CONFIG_MODE_Task;
|
|
||||||
/* Workaround for the OUTINIT PAN. When nrf_gpiote_task_config() is called a glitch happens
|
|
||||||
on the GPIO if the GPIO in question is already assigned to GPIOTE and the pin is in the
|
|
||||||
correct state in GPIOTE but not in the OUT register. */
|
|
||||||
/* Configure channel to Pin31, not connected to the pin, and configure as a tasks that will set it to proper level */
|
|
||||||
NRF_GPIOTE->CONFIG[idx] = final_config | ((31 << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk);
|
|
||||||
__NOP();
|
|
||||||
__NOP();
|
|
||||||
__NOP();
|
|
||||||
NRF_GPIOTE->CONFIG[idx] = final_config;
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpiote_task_disable(uint32_t idx)
|
|
||||||
{
|
|
||||||
NRF_GPIOTE->CONFIG[idx] &= ~GPIOTE_CONFIG_MODE_Task;
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpiote_task_configure(uint32_t idx, uint32_t pin,
|
|
||||||
nrf_gpiote_polarity_t polarity,
|
|
||||||
nrf_gpiote_outinit_t init_val)
|
|
||||||
{
|
|
||||||
NRF_GPIOTE->CONFIG[idx] &= ~(GPIOTE_CONFIG_PSEL_Msk |
|
|
||||||
GPIOTE_CONFIG_POLARITY_Msk |
|
|
||||||
GPIOTE_CONFIG_OUTINIT_Msk);
|
|
||||||
|
|
||||||
NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk) |
|
|
||||||
((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk) |
|
|
||||||
((init_val << GPIOTE_CONFIG_OUTINIT_Pos) & GPIOTE_CONFIG_OUTINIT_Msk);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpiote_task_force(uint32_t idx, nrf_gpiote_outinit_t init_val)
|
|
||||||
{
|
|
||||||
NRF_GPIOTE->CONFIG[idx] = (NRF_GPIOTE->CONFIG[idx] & ~GPIOTE_CONFIG_OUTINIT_Msk)
|
|
||||||
| ((init_val << GPIOTE_CONFIG_OUTINIT_Pos) & GPIOTE_CONFIG_OUTINIT_Msk);
|
|
||||||
}
|
|
||||||
|
|
||||||
__STATIC_INLINE void nrf_gpiote_te_default(uint32_t idx)
|
|
||||||
{
|
|
||||||
NRF_GPIOTE->CONFIG[idx] = 0;
|
|
||||||
}
|
|
||||||
#endif //SUPPRESS_INLINE_IMPLEMENTATION
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,136 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
*@file
|
|
||||||
*@brief NMVC driver implementation
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "stdbool.h"
|
|
||||||
#include "nrf.h"
|
|
||||||
#include "nrf_nvmc.h"
|
|
||||||
|
|
||||||
|
|
||||||
void nrf_nvmc_page_erase(uint32_t address)
|
|
||||||
{
|
|
||||||
// Enable erase.
|
|
||||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een;
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Erase the page
|
|
||||||
NRF_NVMC->ERASEPAGE = address;
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void nrf_nvmc_write_byte(uint32_t address, uint8_t value)
|
|
||||||
{
|
|
||||||
uint32_t byte_shift = address & (uint32_t)0x03;
|
|
||||||
uint32_t address32 = address & ~byte_shift; // Address to the word this byte is in.
|
|
||||||
uint32_t value32 = (*(uint32_t*)address32 & ~((uint32_t)0xFF << (byte_shift << (uint32_t)3)));
|
|
||||||
value32 = value32 + ((uint32_t)value << (byte_shift << 3));
|
|
||||||
|
|
||||||
// Enable write.
|
|
||||||
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
*(uint32_t*)address32 = value32;
|
|
||||||
while(NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nrf_nvmc_write_word(uint32_t address, uint32_t value)
|
|
||||||
{
|
|
||||||
// Enable write.
|
|
||||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){
|
|
||||||
}
|
|
||||||
|
|
||||||
*(uint32_t*)address = value;
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy){
|
|
||||||
}
|
|
||||||
|
|
||||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_bytes)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
for(i=0;i<num_bytes;i++)
|
|
||||||
{
|
|
||||||
nrf_nvmc_write_byte(address+i,src[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nrf_nvmc_write_words(uint32_t address, const uint32_t * src, uint32_t num_words)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
|
|
||||||
// Enable write.
|
|
||||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i=0;i<num_words;i++)
|
|
||||||
{
|
|
||||||
((uint32_t*)address)[i] = src[i];
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
|
|
||||||
while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,109 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
* @brief NMVC driver API.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NRF_NVMC_H__
|
|
||||||
#define NRF_NVMC_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup nrf_nvmc Non-volatile memory controller
|
|
||||||
* @{
|
|
||||||
* @ingroup nrf_drivers
|
|
||||||
* @brief Driver for the NVMC peripheral.
|
|
||||||
*
|
|
||||||
* This driver allows writing to the non-volatile memory (NVM) regions
|
|
||||||
* of the chip. In order to write to NVM the controller must be powered
|
|
||||||
* on and the relevant page must be erased.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Erase a page in flash. This is required before writing to any
|
|
||||||
* address in the page.
|
|
||||||
*
|
|
||||||
* @param address Start address of the page.
|
|
||||||
*/
|
|
||||||
void nrf_nvmc_page_erase(uint32_t address);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write a single byte to flash.
|
|
||||||
*
|
|
||||||
* The function reads the word containing the byte, and then
|
|
||||||
* rewrites the entire word.
|
|
||||||
*
|
|
||||||
* @param address Address to write to.
|
|
||||||
* @param value Value to write.
|
|
||||||
*/
|
|
||||||
void nrf_nvmc_write_byte(uint32_t address , uint8_t value);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write a 32-bit word to flash.
|
|
||||||
* @param address Address to write to.
|
|
||||||
* @param value Value to write.
|
|
||||||
*/
|
|
||||||
void nrf_nvmc_write_word(uint32_t address, uint32_t value);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write consecutive bytes to flash.
|
|
||||||
*
|
|
||||||
* @param address Address to write to.
|
|
||||||
* @param src Pointer to data to copy from.
|
|
||||||
* @param num_bytes Number of bytes in src to write.
|
|
||||||
*/
|
|
||||||
void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_bytes);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write consecutive words to flash.
|
|
||||||
*
|
|
||||||
* @param address Address to write to.
|
|
||||||
* @param src Pointer to data to copy from.
|
|
||||||
* @param num_words Number of bytes in src to write.
|
|
||||||
*/
|
|
||||||
void nrf_nvmc_write_words(uint32_t address, const uint32_t * src, uint32_t num_words);
|
|
||||||
|
|
||||||
|
|
||||||
#endif // NRF_NVMC_H__
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NRF_TEMP_H__
|
|
||||||
#define NRF_TEMP_H__
|
|
||||||
|
|
||||||
#include "nrf.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup nrf_temperature TEMP (temperature) abstraction
|
|
||||||
* @{
|
|
||||||
* @ingroup nrf_drivers temperature_example
|
|
||||||
* @brief Temperature module init and read functions.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**@cond NO_DOXYGEN */
|
|
||||||
#define MASK_SIGN (0x00000200UL)
|
|
||||||
#define MASK_SIGN_EXTENSION (0xFFFFFC00UL)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for preparing the temp module for temperature measurement.
|
|
||||||
*
|
|
||||||
* This function initializes the TEMP module and writes to the hidden configuration register.
|
|
||||||
*/
|
|
||||||
static __INLINE void nrf_temp_init(void)
|
|
||||||
{
|
|
||||||
/**@note Workaround for PAN_028 rev2.0A anomaly 31 - TEMP: Temperature offset value has to be manually loaded to the TEMP module */
|
|
||||||
*(uint32_t *) 0x4000C504 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for reading temperature measurement.
|
|
||||||
*
|
|
||||||
* The function reads the 10 bit 2's complement value and transforms it to a 32 bit 2's complement value.
|
|
||||||
*/
|
|
||||||
static __INLINE int32_t nrf_temp_read(void)
|
|
||||||
{
|
|
||||||
/**@note Workaround for PAN_028 rev2.0A anomaly 28 - TEMP: Negative measured values are not represented correctly */
|
|
||||||
return ((NRF_TEMP->TEMP & MASK_SIGN) != 0) ? (NRF_TEMP->TEMP | MASK_SIGN_EXTENSION) : (NRF_TEMP->TEMP);
|
|
||||||
}
|
|
||||||
/**@endcond */
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,319 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup nrf_wdt_hal WDT HAL
|
|
||||||
* @{
|
|
||||||
* @ingroup nrf_wdt
|
|
||||||
*
|
|
||||||
* @brief Hardware access layer for accessing the watchdog timer (WDT) peripheral.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef NRF_WDT_H__
|
|
||||||
#define NRF_WDT_H__
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "nrf.h"
|
|
||||||
|
|
||||||
#define NRF_WDT_CHANNEL_NUMBER 0x8UL
|
|
||||||
#define NRF_WDT_RR_VALUE 0x6E524635UL /* Fixed value, shouldn't be modified.*/
|
|
||||||
|
|
||||||
#define NRF_WDT_TASK_SET 1UL
|
|
||||||
#define NRF_WDT_EVENT_CLEAR 0UL
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @enum nrf_wdt_task_t
|
|
||||||
* @brief WDT tasks.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
/*lint -save -e30 -esym(628,__INTADDR__)*/
|
|
||||||
NRF_WDT_TASK_START = offsetof(NRF_WDT_Type, TASKS_START), /**< Task for starting WDT. */
|
|
||||||
/*lint -restore*/
|
|
||||||
} nrf_wdt_task_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @enum nrf_wdt_event_t
|
|
||||||
* @brief WDT events.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
/*lint -save -e30*/
|
|
||||||
NRF_WDT_EVENT_TIMEOUT = offsetof(NRF_WDT_Type, EVENTS_TIMEOUT), /**< Event from WDT time-out. */
|
|
||||||
/*lint -restore*/
|
|
||||||
} nrf_wdt_event_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @enum nrf_wdt_behaviour_t
|
|
||||||
* @brief WDT behavior in CPU SLEEP or HALT mode.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NRF_WDT_BEHAVIOUR_RUN_SLEEP = WDT_CONFIG_SLEEP_Msk, /**< WDT will run when CPU is in SLEEP mode. */
|
|
||||||
NRF_WDT_BEHAVIOUR_RUN_HALT = WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in HALT mode. */
|
|
||||||
NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT = WDT_CONFIG_SLEEP_Msk | WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in SLEEP or HALT mode. */
|
|
||||||
NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT = 0, /**< WDT will be paused when CPU is in SLEEP or HALT mode. */
|
|
||||||
} nrf_wdt_behaviour_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @enum nrf_wdt_rr_register_t
|
|
||||||
* @brief WDT reload request registers.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NRF_WDT_RR0 = 0, /**< Reload request register 0. */
|
|
||||||
NRF_WDT_RR1, /**< Reload request register 1. */
|
|
||||||
NRF_WDT_RR2, /**< Reload request register 2. */
|
|
||||||
NRF_WDT_RR3, /**< Reload request register 3. */
|
|
||||||
NRF_WDT_RR4, /**< Reload request register 4. */
|
|
||||||
NRF_WDT_RR5, /**< Reload request register 5. */
|
|
||||||
NRF_WDT_RR6, /**< Reload request register 6. */
|
|
||||||
NRF_WDT_RR7 /**< Reload request register 7. */
|
|
||||||
} nrf_wdt_rr_register_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @enum nrf_wdt_int_mask_t
|
|
||||||
* @brief WDT interrupts.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NRF_WDT_INT_TIMEOUT_MASK = WDT_INTENSET_TIMEOUT_Msk, /**< WDT interrupt from time-out event. */
|
|
||||||
} nrf_wdt_int_mask_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for configuring the watchdog behavior when the CPU is sleeping or halted.
|
|
||||||
*
|
|
||||||
* @param behaviour Watchdog behavior when CPU is in SLEEP or HALT mode.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_wdt_behaviour_set(nrf_wdt_behaviour_t behaviour)
|
|
||||||
{
|
|
||||||
NRF_WDT->CONFIG = behaviour;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for starting the watchdog.
|
|
||||||
*
|
|
||||||
* @param[in] task Task.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_wdt_task_trigger(nrf_wdt_task_t task)
|
|
||||||
{
|
|
||||||
*((volatile uint32_t *)((uint8_t *)NRF_WDT + task)) = NRF_WDT_TASK_SET;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for clearing the WDT event.
|
|
||||||
*
|
|
||||||
* @param[in] event Event.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_wdt_event_clear(nrf_wdt_event_t event)
|
|
||||||
{
|
|
||||||
*((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event)) = NRF_WDT_EVENT_CLEAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for retrieving the state of the WDT event.
|
|
||||||
*
|
|
||||||
* @param[in] event Event.
|
|
||||||
*
|
|
||||||
* @retval true If the event is set.
|
|
||||||
* @retval false If the event is not set.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE bool nrf_wdt_event_check(nrf_wdt_event_t event)
|
|
||||||
{
|
|
||||||
return (bool)*((volatile uint32_t *)((uint8_t *)NRF_WDT + event));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for enabling a specific interrupt.
|
|
||||||
*
|
|
||||||
* @param[in] int_mask Interrupt.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_wdt_int_enable(uint32_t int_mask)
|
|
||||||
{
|
|
||||||
NRF_WDT->INTENSET = int_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for retrieving the state of given interrupt.
|
|
||||||
*
|
|
||||||
* @param[in] int_mask Interrupt.
|
|
||||||
*
|
|
||||||
* @retval true Interrupt is enabled.
|
|
||||||
* @retval false Interrupt is not enabled.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE bool nrf_wdt_int_enable_check(uint32_t int_mask)
|
|
||||||
{
|
|
||||||
return (bool)(NRF_WDT->INTENSET & int_mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for disabling a specific interrupt.
|
|
||||||
*
|
|
||||||
* @param[in] int_mask Interrupt.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_wdt_int_disable(uint32_t int_mask)
|
|
||||||
{
|
|
||||||
NRF_WDT->INTENCLR = int_mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for returning the address of a specific WDT task register.
|
|
||||||
*
|
|
||||||
* @param[in] task Task.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE uint32_t nrf_wdt_task_address_get(nrf_wdt_task_t task)
|
|
||||||
{
|
|
||||||
return ((uint32_t)NRF_WDT + task);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for returning the address of a specific WDT event register.
|
|
||||||
*
|
|
||||||
* @param[in] event Event.
|
|
||||||
*
|
|
||||||
* @retval address of requested event register
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE uint32_t nrf_wdt_event_address_get(nrf_wdt_event_t event)
|
|
||||||
{
|
|
||||||
return ((uint32_t)NRF_WDT + event);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for retrieving the watchdog status.
|
|
||||||
*
|
|
||||||
* @retval true If the watchdog is started.
|
|
||||||
* @retval false If the watchdog is not started.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE bool nrf_wdt_started(void)
|
|
||||||
{
|
|
||||||
return (bool)(NRF_WDT->RUNSTATUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for retrieving the watchdog reload request status.
|
|
||||||
*
|
|
||||||
* @param[in] rr_register Reload request register to check.
|
|
||||||
*
|
|
||||||
* @retval true If a reload request is running.
|
|
||||||
* @retval false If no reload request is running.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE bool nrf_wdt_request_status(nrf_wdt_rr_register_t rr_register)
|
|
||||||
{
|
|
||||||
return (bool)(((NRF_WDT->REQSTATUS) >> rr_register) & 0x1UL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for setting the watchdog reload value.
|
|
||||||
*
|
|
||||||
* @param[in] reload_value Watchdog counter initial value.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_wdt_reload_value_set(uint32_t reload_value)
|
|
||||||
{
|
|
||||||
NRF_WDT->CRV = reload_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for retrieving the watchdog reload value.
|
|
||||||
*
|
|
||||||
* @retval Reload value.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE uint32_t nrf_wdt_reload_value_get(void)
|
|
||||||
{
|
|
||||||
return (uint32_t)NRF_WDT->CRV;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for enabling a specific reload request register.
|
|
||||||
*
|
|
||||||
* @param[in] rr_register Reload request register to enable.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_wdt_reload_request_enable(nrf_wdt_rr_register_t rr_register)
|
|
||||||
{
|
|
||||||
NRF_WDT->RREN |= 0x1UL << rr_register;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for disabling a specific reload request register.
|
|
||||||
*
|
|
||||||
* @param[in] rr_register Reload request register to disable.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_wdt_reload_request_disable(nrf_wdt_rr_register_t rr_register)
|
|
||||||
{
|
|
||||||
NRF_WDT->RREN &= ~(0x1UL << rr_register);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for retrieving the status of a specific reload request register.
|
|
||||||
*
|
|
||||||
* @param[in] rr_register Reload request register to check.
|
|
||||||
*
|
|
||||||
* @retval true If the reload request register is enabled.
|
|
||||||
* @retval false If the reload request register is not enabled.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE bool nrf_wdt_reload_request_is_enabled(nrf_wdt_rr_register_t rr_register)
|
|
||||||
{
|
|
||||||
return (bool)(NRF_WDT->RREN & (0x1UL << rr_register));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for setting a specific reload request register.
|
|
||||||
*
|
|
||||||
* @param[in] rr_register Reload request register to set.
|
|
||||||
*/
|
|
||||||
__STATIC_INLINE void nrf_wdt_reload_request_set(nrf_wdt_rr_register_t rr_register)
|
|
||||||
{
|
|
||||||
NRF_WDT->RR[rr_register] = NRF_WDT_RR_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,101 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @cond To make doxygen skip this file */
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
* This header contains defines with respect persistent storage that are specific to
|
|
||||||
* persistent storage implementation and application use case.
|
|
||||||
*/
|
|
||||||
#ifndef PSTORAGE_PL_H__
|
|
||||||
#define PSTORAGE_PL_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "nrf.h"
|
|
||||||
|
|
||||||
static __INLINE uint16_t pstorage_flash_page_size()
|
|
||||||
{
|
|
||||||
return (uint16_t)NRF_FICR->CODEPAGESIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PSTORAGE_FLASH_PAGE_SIZE pstorage_flash_page_size() /**< Size of one flash page. */
|
|
||||||
#define PSTORAGE_FLASH_EMPTY_MASK 0xFFFFFFFF /**< Bit mask that defines an empty address in flash. */
|
|
||||||
|
|
||||||
#ifdef NRF51
|
|
||||||
#define BOOTLOADER_ADDRESS (NRF_UICR->BOOTLOADERADDR)
|
|
||||||
#elif defined NRF52
|
|
||||||
#define BOOTLOADER_ADDRESS (PSTORAGE_FLASH_EMPTY_MASK)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static __INLINE uint32_t pstorage_flash_page_end()
|
|
||||||
{
|
|
||||||
uint32_t bootloader_addr = BOOTLOADER_ADDRESS;
|
|
||||||
|
|
||||||
return ((bootloader_addr != PSTORAGE_FLASH_EMPTY_MASK) ?
|
|
||||||
(bootloader_addr/ PSTORAGE_FLASH_PAGE_SIZE) : NRF_FICR->CODESIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define PSTORAGE_FLASH_PAGE_END pstorage_flash_page_end()
|
|
||||||
|
|
||||||
#ifndef PSTORAGE_NUM_OF_PAGES
|
|
||||||
#define PSTORAGE_NUM_OF_PAGES 1 /**< Number of flash pages allocated for the pstorage module excluding the swap page, configurable based on system requirements. */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PSTORAGE_MIN_BLOCK_SIZE 0x0010 /**< Minimum size of block that can be registered with the module. Should be configured based on system requirements, recommendation is not have this value to be at least size of word. */
|
|
||||||
|
|
||||||
#define PSTORAGE_DATA_START_ADDR ((PSTORAGE_FLASH_PAGE_END - PSTORAGE_NUM_OF_PAGES - 1) \
|
|
||||||
* PSTORAGE_FLASH_PAGE_SIZE) /**< Start address for persistent data, configurable according to system requirements. */
|
|
||||||
#define PSTORAGE_DATA_END_ADDR ((PSTORAGE_FLASH_PAGE_END - 1) * PSTORAGE_FLASH_PAGE_SIZE) /**< End address for persistent data, configurable according to system requirements. */
|
|
||||||
#define PSTORAGE_SWAP_ADDR PSTORAGE_DATA_END_ADDR /**< Top-most page is used as swap area for clear and update. */
|
|
||||||
|
|
||||||
#define PSTORAGE_MAX_BLOCK_SIZE PSTORAGE_FLASH_PAGE_SIZE /**< Maximum size of block that can be registered with the module. Should be configured based on system requirements. And should be greater than or equal to the minimum size. */
|
|
||||||
#define PSTORAGE_CMD_QUEUE_SIZE 2 /**< Maximum number of flash access commands that can be maintained by the module for all applications. Configurable. */
|
|
||||||
|
|
||||||
|
|
||||||
/** Abstracts persistently memory block identifier. */
|
|
||||||
typedef uint32_t pstorage_block_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t module_id; /**< Module ID.*/
|
|
||||||
pstorage_block_t block_id; /**< Block ID.*/
|
|
||||||
} pstorage_handle_t;
|
|
||||||
|
|
||||||
typedef uint16_t pstorage_size_t; /** Size of length and offset fields. */
|
|
||||||
|
|
||||||
/**@brief Handles Flash Access Result Events. To be called in the system event dispatcher of the application. */
|
|
||||||
void pstorage_sys_event_handler (uint32_t sys_evt);
|
|
||||||
|
|
||||||
#endif // PSTORAGE_PL_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
/** @endcond */
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,401 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**@file
|
|
||||||
*
|
|
||||||
* @defgroup persistent_storage Persistent Storage Interface
|
|
||||||
* @{
|
|
||||||
* @ingroup app_common
|
|
||||||
* @brief Abstracted flash interface.
|
|
||||||
*
|
|
||||||
* @details An abstracted interface is provided by the module to easily port the application and
|
|
||||||
* SDK modules to an alternate option. This ensures that the SDK and application are moved
|
|
||||||
* to alternate persistent storage instead of the one provided by default.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PSTORAGE_H__
|
|
||||||
#define PSTORAGE_H__
|
|
||||||
|
|
||||||
#include "pstorage_platform.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**@defgroup ps_opcode Persistent Storage Access Operation Codes
|
|
||||||
* @{
|
|
||||||
* @brief Persistent Storage Access Operation Codes.
|
|
||||||
*
|
|
||||||
* @details Persistent Storage Access Operation Codes are used by Persistent storage operation
|
|
||||||
* completion callback @ref pstorage_ntf_cb_t to identify the operation type requested by
|
|
||||||
* the application.
|
|
||||||
*/
|
|
||||||
#define PSTORAGE_STORE_OP_CODE 0x01 /**< Store Operation type. */
|
|
||||||
#define PSTORAGE_LOAD_OP_CODE 0x02 /**< Load Operation type. */
|
|
||||||
#define PSTORAGE_CLEAR_OP_CODE 0x03 /**< Clear Operation type. */
|
|
||||||
#define PSTORAGE_UPDATE_OP_CODE 0x04 /**< Update Operation type. */
|
|
||||||
|
|
||||||
/**@} */
|
|
||||||
|
|
||||||
/**@defgroup pstorage_data_types Persistent Memory Interface Data Types
|
|
||||||
* @{
|
|
||||||
* @brief Data Types needed for interfacing with persistent memory.
|
|
||||||
*
|
|
||||||
* @details Data Types needed for interfacing with persistent memory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**@brief Persistent storage operation completion callback function type.
|
|
||||||
*
|
|
||||||
* @details The persistent storage operation completion callback is used by the interface to report
|
|
||||||
* success or failure of a flash operation. Since data is not copied for a store operation,
|
|
||||||
* a callback is an indication that the resident memory can now be reused or freed.
|
|
||||||
*
|
|
||||||
* @param[in] handle Identifies the module and block for the callback that is received.
|
|
||||||
* @param[in] op_code Identifies the operation for the event that is notified.
|
|
||||||
* @param[in] result Identifies the result of a flash access operation. NRF_SUCCESS implies
|
|
||||||
* operation succeeded.
|
|
||||||
*
|
|
||||||
* @note Unmanaged (abnormal behaviour) error codes from the SoftDevice flash
|
|
||||||
* access API are forwarded as is and are expected to be handled by the
|
|
||||||
* application. For details refer to the implementation file and corresponding
|
|
||||||
* SoftDevice flash API documentation.
|
|
||||||
*
|
|
||||||
* @param[in] p_data Identifies the application data pointer. For a store operation, this points
|
|
||||||
* to the resident source of application memory that the application can now
|
|
||||||
* free or reuse. When there is a clear operation, this is NULL since no
|
|
||||||
* application pointer is needed for this operation.
|
|
||||||
* @param[in] data_len Length data the application provided for the operation.
|
|
||||||
*/
|
|
||||||
typedef void (*pstorage_ntf_cb_t)(pstorage_handle_t * p_handle,
|
|
||||||
uint8_t op_code,
|
|
||||||
uint32_t result,
|
|
||||||
uint8_t * p_data,
|
|
||||||
uint32_t data_len);
|
|
||||||
|
|
||||||
/**@brief Struct containing module registration context. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
pstorage_ntf_cb_t cb; /**< Persistent storage operation completion callback function @ref pstorage_ntf_cb_t. */
|
|
||||||
pstorage_size_t block_size; /**< Desired block size for persistent memory storage. For example, if a module has a table with 10 entries, and each entry is 64 bytes in size,
|
|
||||||
* it can request 10 blocks with a block size of 64 bytes. The module can also request one block that is 640 bytes depending
|
|
||||||
* on how it would like to access or alter the memory in persistent memory.
|
|
||||||
* The first option is preferred when it is a single entry that needs to be updated often and doesn't impact the other entries.
|
|
||||||
* The second option is preferred when table entries are not changed individually but have a common point of loading and storing
|
|
||||||
* data. */
|
|
||||||
pstorage_size_t block_count; /** Number of blocks requested by the module; minimum values is 1. */
|
|
||||||
} pstorage_module_param_t;
|
|
||||||
|
|
||||||
/**@} */
|
|
||||||
|
|
||||||
/**@defgroup pstorage_routines Persistent Storage Access Routines
|
|
||||||
* @{
|
|
||||||
* @brief Functions/Interface SDK modules used to persistently store data.
|
|
||||||
*
|
|
||||||
* @details Interface for the Application and SDK modules to load/store information persistently.
|
|
||||||
* Note: While implementation of each of the persistent storage access functions
|
|
||||||
* depends on the system and is specific to system/solution, the signature of the
|
|
||||||
* interface routines should not be altered.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**@brief Function for initializing the module.
|
|
||||||
*
|
|
||||||
* @details Function for initializing the module. This function is called once before any other APIs
|
|
||||||
* of the module are used.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
*/
|
|
||||||
uint32_t pstorage_init(void);
|
|
||||||
|
|
||||||
/**@brief Function for registering with persistent storage interface.
|
|
||||||
*
|
|
||||||
* @param[in] p_module_param Module registration parameter.
|
|
||||||
* @param[out] p_block_id Block identifier to identify persistent memory blocks when
|
|
||||||
* registration succeeds. Application is expected to use the block IDs
|
|
||||||
* for subsequent operations on requested persistent memory. Maximum
|
|
||||||
* registrations permitted is determined by the configuration of the
|
|
||||||
* parameter PSTORAGE_NUM_OF_PAGES. If more than one memory block is
|
|
||||||
* requested, the identifier provided here is the base identifier for the
|
|
||||||
* first block and used to identify the subsequent block. The application
|
|
||||||
* uses \@ref pstorage_block_identifier_get with this base identifier and
|
|
||||||
* block number. Therefore if 10 blocks of size 64 are requested and the
|
|
||||||
* application wishes to store memory in the 6th block, it shall use
|
|
||||||
* \@ref pstorage_block_identifier_get with the base ID and provide a
|
|
||||||
* block number of 5. This way the application is only expected to
|
|
||||||
* remember the base block identifier.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module
|
|
||||||
* initialization.
|
|
||||||
* @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Operation failure. Additional registrations can't be
|
|
||||||
* supported.
|
|
||||||
*/
|
|
||||||
uint32_t pstorage_register(pstorage_module_param_t * p_module_param,
|
|
||||||
pstorage_handle_t * p_block_id);
|
|
||||||
|
|
||||||
/**@brief Function for getting block ID with reference to base block identifier provided at the time
|
|
||||||
* of registration.
|
|
||||||
*
|
|
||||||
* @details Function to get the block ID with reference to base block identifier provided at the
|
|
||||||
* time of registration.
|
|
||||||
* If more than one memory block was requested when registering, the identifier provided
|
|
||||||
* here is the base identifier for the first block which is used to identify subsequent
|
|
||||||
* blocks. The application shall use this routine to get the block identifier, providing
|
|
||||||
* input as base identifier and block number. Therefore, if 10 blocks of size 64 are
|
|
||||||
* requested and the application wishes to store memory in the 6th block, it shall use
|
|
||||||
* \@ref pstorage_block_identifier_get with the base ID and provide a block number of 5.
|
|
||||||
* This way the application is only expected to remember the base block identifier.
|
|
||||||
*
|
|
||||||
* @param[in] p_base_id Base block ID received at the time of registration.
|
|
||||||
* @param[in] block_num Block Number, with first block numbered zero.
|
|
||||||
* @param[out] p_block_id Block identifier for the block number requested when the API succeeds.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module
|
|
||||||
* initialization.
|
|
||||||
* @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
|
|
||||||
*/
|
|
||||||
uint32_t pstorage_block_identifier_get(pstorage_handle_t * p_base_id,
|
|
||||||
pstorage_size_t block_num,
|
|
||||||
pstorage_handle_t * p_block_id);
|
|
||||||
|
|
||||||
/**@brief Function for persistently storing data of length 'size' contained in the 'p_src' address
|
|
||||||
* in the storage module at 'p_dest' address. Equivalent to Storage Write.
|
|
||||||
*
|
|
||||||
* @param[in] p_dest Destination address where data is to be stored persistently.
|
|
||||||
* @param[in] p_src Source address containing data to be stored. API assumes this to be resident
|
|
||||||
* memory and no intermediate copy of data is made by the API. Must be word
|
|
||||||
* aligned.
|
|
||||||
* @param[in] size Size of data to be stored expressed in bytes. Must be word aligned and size +
|
|
||||||
* offset must be <= block size.
|
|
||||||
* @param[in] offset Offset in bytes to be applied when writing to the block.
|
|
||||||
* For example, if within a block of 100 bytes, the application wishes to
|
|
||||||
* write 20 bytes at an offset of 12, then this field should be set to 12.
|
|
||||||
* Must be word aligned.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module
|
|
||||||
* initialization.
|
|
||||||
* @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR Operation failure. Parameter is not aligned.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Operation failure. No storage space available.
|
|
||||||
*
|
|
||||||
* @warning No copy of the data is made, meaning memory provided for the data source that is to
|
|
||||||
* be written to flash cannot be freed or reused by the application until this procedure
|
|
||||||
* is complete. The application is notified when the procedure is finished using the
|
|
||||||
* notification callback registered by the application.
|
|
||||||
*/
|
|
||||||
uint32_t pstorage_store(pstorage_handle_t * p_dest,
|
|
||||||
uint8_t * p_src,
|
|
||||||
pstorage_size_t size,
|
|
||||||
pstorage_size_t offset);
|
|
||||||
|
|
||||||
/**@brief Function for updating persistently stored data of length 'size' contained in the 'p_src'
|
|
||||||
* address in the storage module at 'p_dest' address.
|
|
||||||
*
|
|
||||||
* @param[in] p_dest Destination address where data is to be updated.
|
|
||||||
* @param[in] p_src Source address containing data to be stored. API assumes this to be resident
|
|
||||||
* memory and no intermediate copy of data is made by the API.
|
|
||||||
* @param[in] size Size of data to be stored expressed in bytes. Must be word aligned and size +
|
|
||||||
* offset must be <= block size.
|
|
||||||
* @param[in] offset Offset in bytes to be applied when writing to the block.
|
|
||||||
* For example, if within a block of 100 bytes, the application wishes to
|
|
||||||
* write 20 bytes at an offset of 12 bytes, then this field should be set to 12.
|
|
||||||
* Must be word aligned.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module
|
|
||||||
* initialization.
|
|
||||||
* @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR Operation failure. Parameter is not aligned.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Operation failure. No storage space available.
|
|
||||||
*
|
|
||||||
* @warning No copy of the data is made, meaning memory provided for the data source that is to
|
|
||||||
* be written to flash cannot be freed or reused by the application until this procedure
|
|
||||||
* is complete. The application is notified when the procedure is finished using the
|
|
||||||
* notification callback registered by the application.
|
|
||||||
*/
|
|
||||||
uint32_t pstorage_update(pstorage_handle_t * p_dest,
|
|
||||||
uint8_t * p_src,
|
|
||||||
pstorage_size_t size,
|
|
||||||
pstorage_size_t offset);
|
|
||||||
|
|
||||||
/**@brief Function for loading persistently stored data of length 'size' from 'p_src' address
|
|
||||||
* to 'p_dest' address. Equivalent to Storage Read.
|
|
||||||
*
|
|
||||||
* @param[in] p_dest Destination address where persistently stored data is to be loaded.
|
|
||||||
* @param[in] p_src Source where data is loaded from persistent memory.
|
|
||||||
* @param[in] size Size of data to be loaded from persistent memory expressed in bytes.
|
|
||||||
* Should be word aligned.
|
|
||||||
* @param[in] offset Offset in bytes, to be applied when loading from the block.
|
|
||||||
* For example, if within a block of 100 bytes, the application wishes to
|
|
||||||
* load 20 bytes from offset of 12 bytes, then this field should be set to 12.
|
|
||||||
* Should be word aligned.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module
|
|
||||||
* initialization.
|
|
||||||
* @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR Operation failure. Parameter is not aligned.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Operation failure. No storage space available.
|
|
||||||
*/
|
|
||||||
uint32_t pstorage_load(uint8_t * p_dest,
|
|
||||||
pstorage_handle_t * p_src,
|
|
||||||
pstorage_size_t size,
|
|
||||||
pstorage_size_t offset);
|
|
||||||
|
|
||||||
/**@brief Function for clearing data in persistent memory.
|
|
||||||
*
|
|
||||||
* @param[in] p_base_id Base block identifier in persistent memory that needs to be cleared;
|
|
||||||
* equivalent to an Erase Operation.
|
|
||||||
* @param[in] size Size of data to be cleared from persistent memory expressed in bytes.
|
|
||||||
* This parameter is to provision for clearing of certain blocks
|
|
||||||
* of memory, or all memory blocks in a registered module. If the total size
|
|
||||||
* of the application module is used (blocks * block size) in combination with
|
|
||||||
* the identifier for the first block in the module, all blocks in the
|
|
||||||
* module will be erased. Must be multiple of block size.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module
|
|
||||||
* initialization.
|
|
||||||
* @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR Operation failure. Parameter is not aligned.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Operation failure. No storage space available.
|
|
||||||
*
|
|
||||||
* @note Clear operations may take time. This API however, does not block until the clear
|
|
||||||
* procedure is complete. The application is notified of procedure completion using
|
|
||||||
* a notification callback registered by the application. The 'result' parameter of the
|
|
||||||
* callback indicates if the procedure was successful or not.
|
|
||||||
*/
|
|
||||||
uint32_t pstorage_clear(pstorage_handle_t * p_base_id, pstorage_size_t size);
|
|
||||||
|
|
||||||
/**@brief Function for getting the number of pending operations with the module.
|
|
||||||
*
|
|
||||||
* @param[out] p_count Number of storage operations pending with the module. If 0, there are no
|
|
||||||
* outstanding requests.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module
|
|
||||||
* initialization.
|
|
||||||
* @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed.
|
|
||||||
*/
|
|
||||||
uint32_t pstorage_access_status_get(uint32_t * p_count);
|
|
||||||
|
|
||||||
#ifdef PSTORAGE_RAW_MODE_ENABLE
|
|
||||||
|
|
||||||
/**@brief Function for registering with the persistent storage interface.
|
|
||||||
*
|
|
||||||
* @param[in] p_module_param Module registration parameter.
|
|
||||||
* @param[out] p_block_id Block identifier used to identify persistent memory blocks upon
|
|
||||||
* successful registration. The application is expected to use the block
|
|
||||||
* IDs for subsequent operations on requested persistent memory. When
|
|
||||||
* more than one memory block is requested, this identifier is the base
|
|
||||||
* identifier for the first block and used to identify subsequent blocks.
|
|
||||||
* The application shall use \@ref pstorage_block_identifier_get with
|
|
||||||
* this base identifier and block number. Therefore if 10 blocks of size
|
|
||||||
* 64 are requested and the application wishes to store memory in the 6th
|
|
||||||
* block, it shall use \@ref pstorage_block_identifier_get with the base
|
|
||||||
* ID and provide a block number of 5. Therefore, the application is only
|
|
||||||
* expected to remember the base block identifier.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module
|
|
||||||
* initialization.
|
|
||||||
* @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Operation failure. No storage space available.
|
|
||||||
*/
|
|
||||||
uint32_t pstorage_raw_register(pstorage_module_param_t * p_module_param,
|
|
||||||
pstorage_handle_t * p_block_id);
|
|
||||||
|
|
||||||
/**@brief Function for persistently storing data of length 'size' contained in 'p_src' address in
|
|
||||||
* storage module at 'p_dest' address. Equivalent to Storage Write.
|
|
||||||
*
|
|
||||||
* @param[in] p_dest Destination address where data is to be stored persistently.
|
|
||||||
* @param[in] p_src Source address containing data to be stored. The API assumes this is resident
|
|
||||||
* memory and no intermediate copy of data is made by the API. Must be word
|
|
||||||
* aligned.
|
|
||||||
* @param[in] size Size of data to be stored expressed in bytes. Must be word aligned.
|
|
||||||
* @param[in] offset Offset in bytes to be applied when writing to the block.
|
|
||||||
* For example, if within a block of 100 bytes, the application wishes to
|
|
||||||
* write 20 bytes at an offset of 12 bytes, this field should be set to 12.
|
|
||||||
* Must be word aligned.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module
|
|
||||||
* initialization.
|
|
||||||
* @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR Operation failure. Parameter is not aligned.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Operation failure. No storage space available.
|
|
||||||
*
|
|
||||||
* @warning No copy of the data is made, meaning memory provided for data source that is to be
|
|
||||||
* written to flash cannot be freed or reused by the application until this procedure
|
|
||||||
* is complete. The application is notified when the procedure is finished using the
|
|
||||||
* notification callback registered by the application.
|
|
||||||
*/
|
|
||||||
uint32_t pstorage_raw_store(pstorage_handle_t * p_dest,
|
|
||||||
uint8_t * p_src,
|
|
||||||
pstorage_size_t size,
|
|
||||||
pstorage_size_t offset);
|
|
||||||
|
|
||||||
/**@brief Function for clearing data in persistent memory in raw mode.
|
|
||||||
*
|
|
||||||
* @param[in] p_dest Base block identifier in persistent memory that needs to be cleared.
|
|
||||||
* Equivalent to an Erase Operation.
|
|
||||||
* @param[in] size Size of data to be cleared from persistent memory expressed in bytes.
|
|
||||||
* Not used.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module
|
|
||||||
* initialization.
|
|
||||||
* @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Operation failure. No storage space available.
|
|
||||||
*
|
|
||||||
* @note Clear operations may take time. This API, however, does not block until the clear
|
|
||||||
* procedure is complete. The application is notified of procedure completion using
|
|
||||||
* a notification callback registered by the application. The 'result' parameter of the
|
|
||||||
* callback indicates if the procedure was successful or not.
|
|
||||||
*/
|
|
||||||
uint32_t pstorage_raw_clear(pstorage_handle_t * p_dest, pstorage_size_t size);
|
|
||||||
|
|
||||||
#endif // PSTORAGE_RAW_MODE_ENABLE
|
|
||||||
|
|
||||||
/**@} */
|
|
||||||
/**@} */
|
|
||||||
|
|
||||||
#endif // PSTORAGE_H__
|
|
||||||
|
|
|
@ -1,117 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**@file
|
|
||||||
*
|
|
||||||
* @defgroup nrf_bootloader Bootloader API.
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @brief Bootloader module interface.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOTLOADER_H__
|
|
||||||
#define BOOTLOADER_H__
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "bootloader_types.h"
|
|
||||||
#include <dfu_types.h>
|
|
||||||
|
|
||||||
/**@brief Function for initializing the Bootloader.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS If bootloader was succesfully initialized.
|
|
||||||
*/
|
|
||||||
uint32_t bootloader_init(void);
|
|
||||||
|
|
||||||
/**@brief Function for validating application region in flash.
|
|
||||||
*
|
|
||||||
* @param[in] app_addr Address to the region in flash where the application is stored.
|
|
||||||
*
|
|
||||||
* @retval true If Application region is valid.
|
|
||||||
* @retval false If Application region is not valid.
|
|
||||||
*/
|
|
||||||
bool bootloader_app_is_valid(uint32_t app_addr);
|
|
||||||
|
|
||||||
/**@brief Function for starting the Device Firmware Update.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS If new application image was successfully transferred.
|
|
||||||
*/
|
|
||||||
uint32_t bootloader_dfu_start(void);
|
|
||||||
|
|
||||||
/**@brief Function for exiting bootloader and booting into application.
|
|
||||||
*
|
|
||||||
* @details This function will disable SoftDevice and all interrupts before jumping to application.
|
|
||||||
* The SoftDevice vector table base for interrupt forwarding will be set the application
|
|
||||||
* address.
|
|
||||||
*
|
|
||||||
* @param[in] app_addr Address to the region where the application is stored.
|
|
||||||
*/
|
|
||||||
void bootloader_app_start(uint32_t app_addr);
|
|
||||||
|
|
||||||
/**@brief Function for retrieving the bootloader settings.
|
|
||||||
*
|
|
||||||
* @param[out] p_settings A copy of the current bootloader settings is returned in the structure
|
|
||||||
* provided.
|
|
||||||
*/
|
|
||||||
void bootloader_settings_get(bootloader_settings_t * const p_settings);
|
|
||||||
|
|
||||||
/**@brief Function for processing DFU status update.
|
|
||||||
*
|
|
||||||
* @param[in] update_status DFU update status.
|
|
||||||
*/
|
|
||||||
void bootloader_dfu_update_process(dfu_update_status_t update_status);
|
|
||||||
|
|
||||||
/**@brief Function getting state of SoftDevice update in progress.
|
|
||||||
* After a successfull SoftDevice transfer the system restarts in orderto disable SoftDevice
|
|
||||||
* and complete the update.
|
|
||||||
*
|
|
||||||
* @retval true A SoftDevice update is in progress. This indicates that second stage
|
|
||||||
* of a SoftDevice update procedure can be initiated.
|
|
||||||
* @retval false No SoftDevice update is in progress.
|
|
||||||
*/
|
|
||||||
bool bootloader_dfu_sd_in_progress(void);
|
|
||||||
|
|
||||||
/**@brief Function for continuing the Device Firmware Update of a SoftDevice.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS If the final stage of SoftDevice update was successful.
|
|
||||||
*/
|
|
||||||
uint32_t bootloader_dfu_sd_update_continue(void);
|
|
||||||
|
|
||||||
/**@brief Function for finalizing the Device Firmware Update of a SoftDevice.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS If the final stage of SoftDevice update was successful.
|
|
||||||
*/
|
|
||||||
uint32_t bootloader_dfu_sd_update_finalize(void);
|
|
||||||
|
|
||||||
#endif // BOOTLOADER_H__
|
|
||||||
|
|
||||||
/**@} */
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**@file
|
|
||||||
*
|
|
||||||
* @defgroup nrf_bootloader_types Types and definitions.
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @ingroup nrf_bootloader
|
|
||||||
*
|
|
||||||
* @brief Bootloader module type and definitions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOTLOADER_TYPES_H__
|
|
||||||
#define BOOTLOADER_TYPES_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define BOOTLOADER_DFU_START 0xB1
|
|
||||||
|
|
||||||
#define BOOTLOADER_SVC_APP_DATA_PTR_GET 0x02
|
|
||||||
|
|
||||||
/**@brief DFU Bank state code, which indicates wether the bank contains: A valid image, invalid image, or an erased flash.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
BANK_VALID_APP = 0x01,
|
|
||||||
BANK_VALID_SD = 0xA5,
|
|
||||||
BANK_VALID_BOOT = 0xAA,
|
|
||||||
BANK_ERASED = 0xFE,
|
|
||||||
BANK_INVALID_APP = 0xFF,
|
|
||||||
} bootloader_bank_code_t;
|
|
||||||
|
|
||||||
/**@brief Structure holding bootloader settings for application and bank data.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
bootloader_bank_code_t bank_0; /**< Variable to store if bank 0 contains a valid application. */
|
|
||||||
uint16_t bank_0_crc; /**< If bank is valid, this field will contain a valid CRC of the total image. */
|
|
||||||
bootloader_bank_code_t bank_1; /**< Variable to store if bank 1 has been erased/prepared for new image. Bank 1 is only used in Banked Update scenario. */
|
|
||||||
uint32_t bank_0_size; /**< Size of active image in bank0 if present, otherwise 0. */
|
|
||||||
uint32_t sd_image_size; /**< Size of SoftDevice image in bank0 if bank_0 code is BANK_VALID_SD. */
|
|
||||||
uint32_t bl_image_size; /**< Size of Bootloader image in bank0 if bank_0 code is BANK_VALID_SD. */
|
|
||||||
uint32_t app_image_size; /**< Size of Application image in bank0 if bank_0 code is BANK_VALID_SD. */
|
|
||||||
uint32_t sd_image_start; /**< Location in flash where SoftDevice image is stored for SoftDevice update. */
|
|
||||||
} bootloader_settings_t;
|
|
||||||
|
|
||||||
#endif // BOOTLOADER_TYPES_H__
|
|
||||||
|
|
||||||
/**@} */
|
|
|
@ -1,137 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "bootloader_util.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Function for aborting current application/bootloader jump to to other app/bootloader.
|
|
||||||
*
|
|
||||||
* @details This functions will use the address provide to swap the stack pointer and then load
|
|
||||||
* the address of the reset handler to be executed. It will check current system mode
|
|
||||||
* (thread/handler) and if in thread mode it will reset into other application.
|
|
||||||
* If in handler mode \ref isr_abort will be executed to ensure correct exit of handler
|
|
||||||
* mode and jump into reset handler of other application.
|
|
||||||
*
|
|
||||||
* @param[in] start_addr Start address of other application. This address must point to the
|
|
||||||
initial stack pointer of the application.
|
|
||||||
*
|
|
||||||
* @note This function will never return but issue a reset into provided application.
|
|
||||||
*/
|
|
||||||
#if defined ( __GNUC__ )
|
|
||||||
static inline void bootloader_util_reset(uint32_t start_addr)
|
|
||||||
{
|
|
||||||
__asm volatile(
|
|
||||||
"ldr r0, [%0]\t\n" // Get App initial MSP for bootloader.
|
|
||||||
"msr msp, r0\t\n" // Set the main stack pointer to the applications MSP.
|
|
||||||
"ldr r0, [%0, #0x04]\t\n" // Load Reset handler into R0.
|
|
||||||
|
|
||||||
"movs r4, #0xFF\t\n" // Move ones to R4.
|
|
||||||
"sxtb r4, r4\t\n" // Sign extend R4 to obtain 0xFFFFFFFF instead of 0xFF.
|
|
||||||
|
|
||||||
"mrs r5, IPSR\t\n" // Load IPSR to R5 to check for handler or thread mode.
|
|
||||||
"cmp r5, #0x00\t\n" // Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader.
|
|
||||||
"bne isr_abort\t\n" // If not zero we need to exit current ISR and jump to reset handler of bootloader.
|
|
||||||
|
|
||||||
"mov lr, r4\t\n" // Clear the link register and set to ones to ensure no return.
|
|
||||||
"bx r0\t\n" // Branch to reset handler of bootloader.
|
|
||||||
|
|
||||||
"isr_abort: \t\n"
|
|
||||||
|
|
||||||
"mov r5, r4\t\n" // Fill with ones before jumping to reset handling. Will be popped as LR when exiting ISR. Ensures no return to application.
|
|
||||||
"mov r6, r0\t\n" // Move address of reset handler to R6. Will be popped as PC when exiting ISR. Ensures the reset handler will be executed when exist ISR.
|
|
||||||
"movs r7, #0x21\t\n" // Move MSB reset value of xPSR to R7. Will be popped as xPSR when exiting ISR. xPSR is 0x21000000 thus MSB is 0x21.
|
|
||||||
"rev r7, r7\t\n" // Reverse byte order to put 0x21 as MSB.
|
|
||||||
"push {r4-r7}\t\n" // Push everything to new stack to allow interrupt handler to fetch it on exiting the ISR.
|
|
||||||
|
|
||||||
"movs r4, #0x00\t\n" // Fill with zeros before jumping to reset handling. We be popped as R0 when exiting ISR (Cleaning up of the registers).
|
|
||||||
"movs r5, #0x00\t\n" // Fill with zeros before jumping to reset handling. We be popped as R1 when exiting ISR (Cleaning up of the registers).
|
|
||||||
"movs r6, #0x00\t\n" // Fill with zeros before jumping to reset handling. We be popped as R2 when exiting ISR (Cleaning up of the registers).
|
|
||||||
"movs r7, #0x00\t\n" // Fill with zeros before jumping to reset handling. We be popped as R3 when exiting ISR (Cleaning up of the registers).
|
|
||||||
"push {r4-r7}\t\n" // Push zeros (R4-R7) to stack to prepare for exiting the interrupt routine.
|
|
||||||
|
|
||||||
"movs r0, #0xF9\t\n" // Move the execution return command into register, 0xFFFFFFF9.
|
|
||||||
"sxtb r0, r0\t\n" // Sign extend R0 to obtain 0xFFFFFFF9 instead of 0xF9.
|
|
||||||
"bx r0\t\n" // No return - Handler mode will be exited. Stack will be popped and execution will continue in reset handler initializing other application.
|
|
||||||
".align\t\n"
|
|
||||||
:: "r" (start_addr) // Argument list for the gcc assembly. start_addr is %0.
|
|
||||||
: "r0", "r4", "r5", "r6", "r7" // List of register maintained manually.
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#elif defined ( __ICCARM__ )
|
|
||||||
static inline void bootloader_util_reset(uint32_t start_addr)
|
|
||||||
{
|
|
||||||
asm("ldr r5, [%0]\n" // Get App initial MSP for bootloader.
|
|
||||||
"msr msp, r5\n" // Set the main stack pointer to the applications MSP.
|
|
||||||
"ldr r0, [%0, #0x04]\n" // Load Reset handler into R0.
|
|
||||||
|
|
||||||
"movs r4, #0x00\n" // Load zero into R4.
|
|
||||||
"mvns r4, r4\n" // Invert R4 to ensure it contain ones.
|
|
||||||
|
|
||||||
"mrs r5, IPSR\n" // Load IPSR to R5 to check for handler or thread mode
|
|
||||||
"cmp r5, #0x00\n" // Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader.
|
|
||||||
"bne isr_abort\n" // If not zero we need to exit current ISR and jump to reset handler of bootloader.
|
|
||||||
|
|
||||||
"mov lr, r4\n" // Clear the link register and set to ones to ensure no return.
|
|
||||||
"bx r0\n" // Branch to reset handler of bootloader.
|
|
||||||
|
|
||||||
"isr_abort: \n"
|
|
||||||
// R4 contains ones from line above. We be popped as R12 when exiting ISR (Cleaning up the registers).
|
|
||||||
"mov r5, r4\n" // Fill with ones before jumping to reset handling. Will be popped as LR when exiting ISR. Ensures no return to application.
|
|
||||||
"mov r6, r0\n" // Move address of reset handler to R6. Will be popped as PC when exiting ISR. Ensures the reset handler will be executed when exist ISR.
|
|
||||||
"movs r7, #0x21\n" // Move MSB reset value of xPSR to R7. Will be popped as xPSR when exiting ISR. xPSR is 0x21000000 thus MSB is 0x21.
|
|
||||||
"rev r7, r7\n" // Reverse byte order to put 0x21 as MSB.
|
|
||||||
"push {r4-r7}\n" // Push everything to new stack to allow interrupt handler to fetch it on exiting the ISR.
|
|
||||||
|
|
||||||
"movs r4, #0x00\n" // Fill with zeros before jumping to reset handling. We be popped as R0 when exiting ISR (Cleaning up of the registers).
|
|
||||||
"movs r5, #0x00\n" // Fill with zeros before jumping to reset handling. We be popped as R1 when exiting ISR (Cleaning up of the registers).
|
|
||||||
"movs r6, #0x00\n" // Fill with zeros before jumping to reset handling. We be popped as R2 when exiting ISR (Cleaning up of the registers).
|
|
||||||
"movs r7, #0x00\n" // Fill with zeros before jumping to reset handling. We be popped as R3 when exiting ISR (Cleaning up of the registers).
|
|
||||||
"push {r4-r7}\n" // Push zeros (R4-R7) to stack to prepare for exiting the interrupt routine.
|
|
||||||
|
|
||||||
"movs r0, #0x06\n" // Load 0x06 into R6 to prepare for exec return command.
|
|
||||||
"mvns r0, r0\n" // Invert 0x06 to obtain EXEC_RETURN, 0xFFFFFFF9.
|
|
||||||
"bx r0\n" // No return - Handler mode will be exited. Stack will be popped and execution will continue in reset handler initializing other application.
|
|
||||||
:: "r" (start_addr) // Argument list for the IAR assembly. start_addr is %0.
|
|
||||||
: "r0", "r4", "r5", "r6", "r7"); // List of register maintained manually.
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#error Compiler not supported.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void bootloader_util_app_start(uint32_t start_addr)
|
|
||||||
{
|
|
||||||
bootloader_util_reset(start_addr);
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**@file
|
|
||||||
*
|
|
||||||
* @defgroup nrf_bootloader_util Bootloader util API.
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @brief Bootloader util module interface.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BOOTLOADER_UTIL_H__
|
|
||||||
#define BOOTLOADER_UTIL_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "bootloader_types.h"
|
|
||||||
|
|
||||||
/**@brief Function for starting the application (or bootloader) at the provided address.
|
|
||||||
*
|
|
||||||
* @param[in] start_addr Start address.
|
|
||||||
*
|
|
||||||
* @note This function will never retrun. Instead it will reset into the application of the
|
|
||||||
* provided address.
|
|
||||||
*/
|
|
||||||
void bootloader_util_app_start(uint32_t start_addr);
|
|
||||||
|
|
||||||
#endif // BOOTLOADER_UTIL_H__
|
|
||||||
|
|
||||||
/**@} */
|
|
|
@ -1,154 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**@file
|
|
||||||
*
|
|
||||||
* @defgroup nrf_dfu Device Firmware Update API.
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @brief Device Firmware Update module interface.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DFU_H__
|
|
||||||
#define DFU_H__
|
|
||||||
|
|
||||||
#include <dfu_types.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief DFU event callback for asynchronous calls.
|
|
||||||
*
|
|
||||||
* @param[in] packet Packet type for which this callback is related. START_PACKET, DATA_PACKET.
|
|
||||||
* @param[in] result Operation result code. NRF_SUCCESS when a queued operation was successful.
|
|
||||||
* @param[in] p_data Pointer to the data to which the operation is related.
|
|
||||||
*/
|
|
||||||
typedef void (*dfu_callback_t)(uint32_t packet, uint32_t result, uint8_t * p_data);
|
|
||||||
|
|
||||||
/**@brief Function for initializing the Device Firmware Update module.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on success, an error_code otherwise.
|
|
||||||
*/
|
|
||||||
uint32_t dfu_init(void);
|
|
||||||
|
|
||||||
/**@brief Function for registering a callback listener for \ref dfu_data_pkt_handle callbacks.
|
|
||||||
*
|
|
||||||
* @param[in] callback_handler Callback handler for receiving DFU events on completed operations
|
|
||||||
* of DFU packets.
|
|
||||||
*/
|
|
||||||
void dfu_register_callback(dfu_callback_t callback_handler);
|
|
||||||
|
|
||||||
/**@brief Function for setting the DFU image size.
|
|
||||||
*
|
|
||||||
* @details Function sets the DFU image size. This function must be called when an update is started
|
|
||||||
* in order to notify the DFU of the new image size. If multiple images are to be
|
|
||||||
* transferred within the same update context then this function must be called with size
|
|
||||||
* information for each image being transfered.
|
|
||||||
* If an image type is not being transfered, e.g. SoftDevice but no Application , then the
|
|
||||||
* image size for application must be zero.
|
|
||||||
*
|
|
||||||
* @param[in] p_packet Pointer to the DFU packet containing information on DFU update process to
|
|
||||||
* be started.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on success, an error_code otherwise.
|
|
||||||
*/
|
|
||||||
uint32_t dfu_start_pkt_handle(dfu_update_packet_t * p_packet);
|
|
||||||
|
|
||||||
/**@brief Function for handling DFU data packets.
|
|
||||||
*
|
|
||||||
* @param[in] p_packet Pointer to the DFU packet.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on success, an error_code otherwise.
|
|
||||||
*/
|
|
||||||
uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet);
|
|
||||||
|
|
||||||
/**@brief Function for handling DFU init packets.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on success, an error_code otherwise.
|
|
||||||
*/
|
|
||||||
uint32_t dfu_init_pkt_handle(dfu_update_packet_t * p_packet);
|
|
||||||
|
|
||||||
/**@brief Function for validating a transferred image after the transfer has completed.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on success, an error_code otherwise.
|
|
||||||
*/
|
|
||||||
uint32_t dfu_image_validate(void);
|
|
||||||
|
|
||||||
/**@brief Function for activating the transfered image after validation has successfully completed.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on success, an error_code otherwise.
|
|
||||||
*/
|
|
||||||
uint32_t dfu_image_activate(void);
|
|
||||||
|
|
||||||
/**@brief Function for reseting the current update procedure and return to initial state.
|
|
||||||
*
|
|
||||||
* @details This function call will result in a system reset to ensure correct system behavior.
|
|
||||||
* The reset will might be scheduled to execute at a later point in time to ensure pending
|
|
||||||
* flash operations has completed.
|
|
||||||
*/
|
|
||||||
void dfu_reset(void);
|
|
||||||
|
|
||||||
/**@brief Function for validating that new bootloader has been correctly installed.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS if install was successful. NRF_ERROR_NULL if the images differs.
|
|
||||||
*/
|
|
||||||
uint32_t dfu_bl_image_validate(void);
|
|
||||||
|
|
||||||
/**@brief Function for validating that new SoftDevicehas been correctly installed.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS if install was successful. NRF_ERROR_NULL if the images differs.
|
|
||||||
*/
|
|
||||||
uint32_t dfu_sd_image_validate(void);
|
|
||||||
|
|
||||||
/**@brief Function for swapping existing bootloader with newly received.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on succesfull swapping. For error code please refer to
|
|
||||||
* \ref sd_mbr_command_copy_bl_t.
|
|
||||||
*/
|
|
||||||
uint32_t dfu_bl_image_swap(void);
|
|
||||||
|
|
||||||
/**@brief Function for swapping existing SoftDevice with newly received.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on succesfull swapping. For error code please refer to
|
|
||||||
* \ref sd_mbr_command_copy_sd_t.
|
|
||||||
*/
|
|
||||||
uint32_t dfu_sd_image_swap(void);
|
|
||||||
|
|
||||||
/**@brief Function for handling DFU init packet complete.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on success, an error_code otherwise.
|
|
||||||
*/
|
|
||||||
uint32_t dfu_init_pkt_complete(void);
|
|
||||||
|
|
||||||
#endif // DFU_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,212 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "dfu_app_handler.h"
|
|
||||||
#include <string.h>
|
|
||||||
#include "bootloader_util.h"
|
|
||||||
#include "nrf.h"
|
|
||||||
#include "nrf_sdm.h"
|
|
||||||
#include "ble_gatt.h"
|
|
||||||
#include "ble_gatts.h"
|
|
||||||
#include "app_error.h"
|
|
||||||
#include "dfu_ble_svc.h"
|
|
||||||
#include "device_manager.h"
|
|
||||||
#include "nrf_delay.h"
|
|
||||||
|
|
||||||
#define IRQ_ENABLED 0x01 /**< Field that identifies if an interrupt is enabled. */
|
|
||||||
#define MAX_NUMBER_INTERRUPTS 32 /**< Maximum number of interrupts available. */
|
|
||||||
|
|
||||||
static void dfu_app_reset_prepare(void); /**< Forward declaration of default reset handler. */
|
|
||||||
static dfu_app_reset_prepare_t m_reset_prepare = dfu_app_reset_prepare; /**< Callback function to application to prepare for system reset. Allows application to clean up service and memory before reset. */
|
|
||||||
static dfu_ble_peer_data_t m_peer_data; /**< Peer data to be used for data exchange when resetting into DFU mode. */
|
|
||||||
static dm_handle_t m_dm_handle; /**< Device Manager handle with instance IDs of current BLE connection. */
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for reset_prepare handler if the application has not registered a handler.
|
|
||||||
*/
|
|
||||||
static void dfu_app_reset_prepare(void)
|
|
||||||
{
|
|
||||||
// Reset prepare should be handled by application.
|
|
||||||
// This function can be extended to include default handling if application does not implement
|
|
||||||
// own handler.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for disabling all interrupts before jumping from bootloader to application.
|
|
||||||
*/
|
|
||||||
static void interrupts_disable(void)
|
|
||||||
{
|
|
||||||
uint32_t interrupt_setting_mask;
|
|
||||||
uint32_t irq;
|
|
||||||
|
|
||||||
// Fetch the current interrupt settings.
|
|
||||||
interrupt_setting_mask = NVIC->ISER[0];
|
|
||||||
|
|
||||||
// Loop from interrupt 0 for disabling of all interrupts.
|
|
||||||
for (irq = 0; irq < MAX_NUMBER_INTERRUPTS; irq++)
|
|
||||||
{
|
|
||||||
if (interrupt_setting_mask & (IRQ_ENABLED << irq))
|
|
||||||
{
|
|
||||||
// The interrupt was enabled, hence disable it.
|
|
||||||
NVIC_DisableIRQ((IRQn_Type)irq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for providing peer information to DFU for re-establishing a bonded connection in
|
|
||||||
* DFU mode.
|
|
||||||
*
|
|
||||||
* @param[in] conn_handle Connection handle for the connection requesting DFU mode.
|
|
||||||
*/
|
|
||||||
static void dfu_app_peer_data_set(uint16_t conn_handle)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
dm_sec_keyset_t key_set;
|
|
||||||
uint32_t app_context_data = 0;
|
|
||||||
dm_application_context_t app_context;
|
|
||||||
|
|
||||||
|
|
||||||
/** [DFU bond sharing] */
|
|
||||||
err_code = dm_handle_get(conn_handle, &m_dm_handle);
|
|
||||||
if (err_code == NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
err_code = dm_distributed_keys_get(&m_dm_handle, &key_set);
|
|
||||||
if (err_code == NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
|
|
||||||
m_peer_data.addr = key_set.keys_central.p_id_key->id_addr_info;
|
|
||||||
m_peer_data.irk = key_set.keys_central.p_id_key->id_info;
|
|
||||||
m_peer_data.enc_key.enc_info = key_set.keys_periph.enc_key.p_enc_key->enc_info;
|
|
||||||
m_peer_data.enc_key.master_id = key_set.keys_periph.enc_key.p_enc_key->master_id;
|
|
||||||
|
|
||||||
err_code = dfu_ble_svc_peer_data_set(&m_peer_data);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
|
|
||||||
app_context_data = (DFU_APP_ATT_TABLE_CHANGED << DFU_APP_ATT_TABLE_POS);
|
|
||||||
app_context.len = sizeof(app_context_data);
|
|
||||||
app_context.p_data = (uint8_t *)&app_context_data;
|
|
||||||
app_context.flags = 0;
|
|
||||||
|
|
||||||
err_code = dm_application_context_set(&m_dm_handle, &app_context);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Keys were not available, thus we have a non-encrypted connection.
|
|
||||||
err_code = dm_peer_addr_get(&m_dm_handle, &m_peer_data.addr);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
|
|
||||||
err_code = dfu_ble_svc_peer_data_set(&m_peer_data);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/** [DFU bond sharing] */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for preparing the reset, disabling SoftDevice, and jumping to the bootloader.
|
|
||||||
*
|
|
||||||
* @param[in] conn_handle Connection handle for peer requesting to enter DFU mode.
|
|
||||||
*/
|
|
||||||
static void bootloader_start(uint16_t conn_handle)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
uint16_t sys_serv_attr_len = sizeof(m_peer_data.sys_serv_attr);
|
|
||||||
|
|
||||||
err_code = sd_ble_gatts_sys_attr_get(conn_handle,
|
|
||||||
m_peer_data.sys_serv_attr,
|
|
||||||
&sys_serv_attr_len,
|
|
||||||
BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);
|
|
||||||
if (err_code != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
// Any error at this stage means the system service attributes could not be fetched.
|
|
||||||
// This means the service changed indication cannot be sent in DFU mode, but connection
|
|
||||||
// is still possible to establish.
|
|
||||||
}
|
|
||||||
|
|
||||||
m_reset_prepare();
|
|
||||||
|
|
||||||
err_code = sd_power_gpregret_set(BOOTLOADER_DFU_START);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
|
|
||||||
err_code = sd_softdevice_disable();
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
|
|
||||||
err_code = sd_softdevice_vector_table_base_set(NRF_UICR->BOOTLOADERADDR);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
|
|
||||||
dfu_app_peer_data_set(conn_handle);
|
|
||||||
|
|
||||||
NVIC_ClearPendingIRQ(SWI2_IRQn);
|
|
||||||
interrupts_disable();
|
|
||||||
bootloader_util_app_start(NRF_UICR->BOOTLOADERADDR);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dfu_app_on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
|
|
||||||
{
|
|
||||||
switch (p_evt->ble_dfu_evt_type)
|
|
||||||
{
|
|
||||||
case BLE_DFU_START:
|
|
||||||
// Starting the bootloader - will cause reset.
|
|
||||||
bootloader_start(p_dfu->conn_handle);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
// Unsupported event received from DFU Service.
|
|
||||||
// Send back BLE_DFU_RESP_VAL_NOT_SUPPORTED message to peer.
|
|
||||||
uint32_t err_code = ble_dfu_response_send(p_dfu,
|
|
||||||
BLE_DFU_START_PROCEDURE,
|
|
||||||
BLE_DFU_RESP_VAL_NOT_SUPPORTED);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dfu_app_reset_prepare_set(dfu_app_reset_prepare_t reset_prepare_func)
|
|
||||||
{
|
|
||||||
m_reset_prepare = reset_prepare_func;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dfu_app_dm_appl_instance_set(dm_application_instance_t app_instance)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
err_code = dm_application_instance_set(&app_instance, &m_dm_handle);
|
|
||||||
APP_ERROR_CHECK(err_code);
|
|
||||||
}
|
|
|
@ -1,106 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
*
|
|
||||||
* @defgroup nrf_dfu_app_handler DFU BLE packet handling in application
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @brief Handling of DFU BLE packets in the application.
|
|
||||||
*
|
|
||||||
* @details This module implements the handling of DFU packets for switching
|
|
||||||
* from an application to the bootloader and start DFU mode. The DFU
|
|
||||||
* packets are transmitted over BLE.
|
|
||||||
* This module handles only the StartDFU packet, which allows a BLE
|
|
||||||
* application to expose support for the DFU Service.
|
|
||||||
* The actual DFU Service runs in a dedicated environment after a BLE
|
|
||||||
* disconnect and reset of the \nRFXX device.
|
|
||||||
* The host must reconnect and continue the update procedure with
|
|
||||||
* access to the full DFU Service.
|
|
||||||
*
|
|
||||||
* @note The application must propagate DFU events to this module by calling
|
|
||||||
* @ref dfu_app_on_dfu_evt from the @ref ble_dfu_evt_handler_t callback.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DFU_APP_HANDLER_H__
|
|
||||||
#define DFU_APP_HANDLER_H__
|
|
||||||
|
|
||||||
#include "ble_dfu.h"
|
|
||||||
#include "nrf_svc.h"
|
|
||||||
#include "bootloader_types.h"
|
|
||||||
#include "device_manager.h"
|
|
||||||
|
|
||||||
#define DFU_APP_ATT_TABLE_POS 0 /**< Position for the ATT table changed setting. */
|
|
||||||
#define DFU_APP_ATT_TABLE_CHANGED 1 /**< Value indicating that the ATT table might have changed. This value will be set in the application-specific context in Device Manager when entering DFU mode. */
|
|
||||||
|
|
||||||
/**@brief DFU application reset_prepare function. This function is a callback that allows the
|
|
||||||
* application to prepare for an upcoming application reset.
|
|
||||||
*/
|
|
||||||
typedef void (*dfu_app_reset_prepare_t)(void);
|
|
||||||
|
|
||||||
/**@brief Function for handling events from the DFU Service.
|
|
||||||
*
|
|
||||||
* @details The application must inject this function into the DFU Service or propagate DFU events
|
|
||||||
* to the dfu_app_handler module by calling this function in the application-specific DFU event
|
|
||||||
* handler.
|
|
||||||
*
|
|
||||||
* @param[in] p_dfu Pointer to the DFU Service structure to which the include event relates.
|
|
||||||
* @param[in] p_evt Pointer to the DFU event.
|
|
||||||
*/
|
|
||||||
void dfu_app_on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt);
|
|
||||||
|
|
||||||
/**@brief Function for registering a function to prepare a reset.
|
|
||||||
*
|
|
||||||
* @details The provided function is executed before resetting the system into bootloader/DFU
|
|
||||||
* mode. By registering this function, the caller is notified before the reset and can
|
|
||||||
* thus prepare the application for reset. For example, the application can gracefully
|
|
||||||
* disconnect any peers on BLE, turn of LEDS, ensure that all pending flash operations
|
|
||||||
* have completed, and so on.
|
|
||||||
*
|
|
||||||
* @param[in] reset_prepare_func Function to be executed before a reset.
|
|
||||||
*/
|
|
||||||
void dfu_app_reset_prepare_set(dfu_app_reset_prepare_t reset_prepare_func);
|
|
||||||
|
|
||||||
/**@brief Function for setting the Device Manager application instance.
|
|
||||||
*
|
|
||||||
* @details This function allows to set the @ref dm_application_instance_t value that is returned by the
|
|
||||||
* Device Manager when the application registers using @ref dm_register.
|
|
||||||
* If this function is not called, it is not be possible to share bonding information
|
|
||||||
* from the application to the bootloader/DFU when entering DFU mode.
|
|
||||||
*
|
|
||||||
* @param[in] app_instance Value for the application instance in use.
|
|
||||||
*/
|
|
||||||
void dfu_app_dm_appl_instance_set(dm_application_instance_t app_instance);
|
|
||||||
|
|
||||||
#endif // DFU_APP_HANDLER_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,107 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**@file
|
|
||||||
*
|
|
||||||
* @defgroup dfu_bank_internal Device Firmware Update internal header for bank handling in DFU.
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @brief Device Firmware Update Bank handling module interface.
|
|
||||||
*
|
|
||||||
* @details This header is intended for shared definition and functions between single and dual bank
|
|
||||||
* implementations used for DFU support. It is not supposed to be used for external access
|
|
||||||
* to the DFU module.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifndef DFU_BANK_INTERNAL_H__
|
|
||||||
#define DFU_BANK_INTERNAL_H__
|
|
||||||
|
|
||||||
#include <dfu_types.h>
|
|
||||||
|
|
||||||
/**@brief States of the DFU state machine. */
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
DFU_STATE_INIT_ERROR, /**< State for: dfu_init(...) error. */
|
|
||||||
DFU_STATE_IDLE, /**< State for: idle. */
|
|
||||||
DFU_STATE_PREPARING, /**< State for: preparing, indicates that the flash is being erased and no data packets can be processed. */
|
|
||||||
DFU_STATE_RDY, /**< State for: ready. */
|
|
||||||
DFU_STATE_RX_INIT_PKT, /**< State for: receiving initialization packet. */
|
|
||||||
DFU_STATE_RX_DATA_PKT, /**< State for: receiving data packet. */
|
|
||||||
DFU_STATE_VALIDATE, /**< State for: validate. */
|
|
||||||
DFU_STATE_WAIT_4_ACTIVATE /**< State for: waiting for dfu_image_activate(). */
|
|
||||||
} dfu_state_t;
|
|
||||||
|
|
||||||
#define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */
|
|
||||||
#define DFU_TIMEOUT_INTERVAL APP_TIMER_TICKS(120000, APP_TIMER_PRESCALER) /**< DFU timeout interval in units of timer ticks. */
|
|
||||||
|
|
||||||
#define IS_UPDATING_SD(START_PKT) ((START_PKT).dfu_update_mode & DFU_UPDATE_SD) /**< Macro for determining if a SoftDevice update is ongoing. */
|
|
||||||
#define IS_UPDATING_BL(START_PKT) ((START_PKT).dfu_update_mode & DFU_UPDATE_BL) /**< Macro for determining if a Bootloader update is ongoing. */
|
|
||||||
#define IS_UPDATING_APP(START_PKT) ((START_PKT).dfu_update_mode & DFU_UPDATE_APP) /**< Macro for determining if a Application update is ongoing. */
|
|
||||||
#define IMAGE_WRITE_IN_PROGRESS() (m_data_received > 0) /**< Macro for determining if an image write is in progress. */
|
|
||||||
#define IS_WORD_SIZED(SIZE) ((SIZE & (sizeof(uint32_t) - 1)) == 0) /**< Macro for checking that the provided is word sized. */
|
|
||||||
|
|
||||||
/**@cond NO_DOXYGEN */
|
|
||||||
static uint32_t m_data_received; /**< Amount of received data. */
|
|
||||||
/**@endcond */
|
|
||||||
|
|
||||||
/**@brief Type definition of function used for preparing of the bank before receiving of a
|
|
||||||
* software image.
|
|
||||||
*
|
|
||||||
* @param[in] image_size Size of software image being received.
|
|
||||||
*/
|
|
||||||
typedef void (*dfu_bank_prepare_t)(uint32_t image_size);
|
|
||||||
|
|
||||||
/**@brief Type definition of function used for handling clear complete of the bank before
|
|
||||||
* receiving of a software image.
|
|
||||||
*/
|
|
||||||
typedef void (*dfu_bank_cleared_t)(void);
|
|
||||||
|
|
||||||
/**@brief Type definition of function used for activating of the software image received.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS If the image has been successfully activated any other NRF_ERROR code in
|
|
||||||
* case of a failure.
|
|
||||||
*/
|
|
||||||
typedef uint32_t (*dfu_bank_activate_t)(void);
|
|
||||||
|
|
||||||
/**@brief Structure for holding of function pointers for needed prepare and activate procedure for
|
|
||||||
* the requested update procedure.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
dfu_bank_prepare_t prepare; /**< Function pointer to the prepare function called on start of update procedure. */
|
|
||||||
dfu_bank_cleared_t cleared; /**< Function pointer to the cleared function called after prepare function completes. */
|
|
||||||
dfu_bank_activate_t activate; /**< Function pointer to the activate function called on finalizing the update procedure. */
|
|
||||||
} dfu_bank_func_t;
|
|
||||||
|
|
||||||
#endif // DFU_BANK_INTERNAL_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,100 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
*
|
|
||||||
* @defgroup nrf_dfu_ble_svc DFU BLE SVC
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @brief DFU BLE SVC in bootloader. The DFU BLE SuperVisor Calls allow an application to execute
|
|
||||||
* functions in the installed bootloader.
|
|
||||||
*
|
|
||||||
* @details This module implements handling of SuperVisor Calls in the bootloader.
|
|
||||||
* SuperVisor Calls allow for an application to execute calls into the bootloader.
|
|
||||||
* Currently, it is possible to exchange bonding information (like keys) from the
|
|
||||||
* application to a bootloader supporting DFU OTA using BLE, so the update process can be
|
|
||||||
* done through an already existing bond.
|
|
||||||
*
|
|
||||||
* @note The application must make sure that all SuperVisor Calls (SVC) are forwarded to the
|
|
||||||
* bootloader to ensure correct behavior. Forwarding of SVCs to the bootloader is
|
|
||||||
* done using the SoftDevice SVC @ref sd_softdevice_vector_table_base_set with the value
|
|
||||||
* present in @c NRF_UICR->BOOTLOADERADDR.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DFU_BLE_SVC_H__
|
|
||||||
#define DFU_BLE_SVC_H__
|
|
||||||
|
|
||||||
#include "nrf_svc.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "ble_gap.h"
|
|
||||||
#include "nrf.h"
|
|
||||||
#include "nrf_soc.h"
|
|
||||||
#include "nrf_error_sdm.h"
|
|
||||||
|
|
||||||
#define BOOTLOADER_SVC_BASE 0x0 /**< The number of the lowest SVC number reserved for the bootloader. */
|
|
||||||
#define SYSTEM_SERVICE_ATT_SIZE 8 /**< Size of the system service attribute length including CRC-16 at the end. */
|
|
||||||
|
|
||||||
/**@brief The SVC numbers used by the SVC functions in the SoC library. */
|
|
||||||
enum BOOTLOADER_SVCS
|
|
||||||
{
|
|
||||||
DFU_BLE_SVC_PEER_DATA_SET = BOOTLOADER_SVC_BASE, /**< SVC number for the setting of peer data call. */
|
|
||||||
BOOTLOADER_SVC_LAST
|
|
||||||
};
|
|
||||||
|
|
||||||
/**@brief DFU Peer data structure.
|
|
||||||
*
|
|
||||||
* @details This structure contains peer data needed for connection to a bonded device during DFU.
|
|
||||||
* The peer data must be provided by the application to the bootloader during buttonless
|
|
||||||
* update. See @ref dfu_ble_svc_peer_data_set. It contains bond information about the
|
|
||||||
* desired DFU peer.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
ble_gap_addr_t addr; /**< BLE GAP address of the device that initiated the DFU process. */
|
|
||||||
ble_gap_irk_t irk; /**< IRK of the device that initiated the DFU process if this device uses Private Resolvable Addresses. */
|
|
||||||
ble_gap_enc_key_t enc_key; /**< Encryption key structure containing encrypted diversifier and LTK for re-establishing the bond. */
|
|
||||||
uint8_t sys_serv_attr[SYSTEM_SERVICE_ATT_SIZE]; /**< System service attributes for restoring of Service Changed Indication setting in DFU mode. */
|
|
||||||
} dfu_ble_peer_data_t;
|
|
||||||
|
|
||||||
/**@brief SVC Function for setting peer data containing address, IRK, and LTK to establish bonded
|
|
||||||
* connection in DFU mode.
|
|
||||||
*
|
|
||||||
* @param[in] p_peer_data Pointer to the peer data containing keys for the connection.
|
|
||||||
*
|
|
||||||
* @retval NRF_ERROR_NULL If a NULL pointer was provided as argument.
|
|
||||||
* @retval NRF_SUCCESS If the function completed successfully.
|
|
||||||
*/
|
|
||||||
SVCALL(DFU_BLE_SVC_PEER_DATA_SET, uint32_t, dfu_ble_svc_peer_data_set(dfu_ble_peer_data_t * p_peer_data));
|
|
||||||
|
|
||||||
#endif // DFU_BLE_SVC_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
*
|
|
||||||
* @defgroup nrf_dfu_ble_svc_internal DFU BLE SVC internal
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @brief DFU BLE SVC internal functions in bootloader. The DFU BLE SuperVisor Calls allow an
|
|
||||||
* application to execute functions in the installed bootloader. This interface provides
|
|
||||||
* internal Bootloader DFU functions for retrieving data exchanged through SuperVisor Calls.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DFU_BLE_SVC_INTERNAL_H__
|
|
||||||
#define DFU_BLE_SVC_INTERNAL_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "dfu_ble_svc.h"
|
|
||||||
#include "ble_gap.h"
|
|
||||||
|
|
||||||
/**@brief Internal bootloader/DFU function for retrieving peer data provided from application.
|
|
||||||
*
|
|
||||||
* @param[out] p_peer_data Peer data set by application to be used for DFU connection.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS If peer data is valid and can be used for connection.
|
|
||||||
* @retval NRF_ERROR_NULL If p_peer_data is a NULL pointer.
|
|
||||||
* @retval NRF_ERROR_INVALID_DATA If peer data is not available or invalid.
|
|
||||||
*/
|
|
||||||
uint32_t dfu_ble_peer_data_get(dfu_ble_peer_data_t * p_peer_data);
|
|
||||||
|
|
||||||
#endif // DFU_BLE_SVC_INTERNAL_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,154 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**@file
|
|
||||||
*
|
|
||||||
* @defgroup nrf_dfu_init Init packet handling in DFU
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @brief Device Firmware Update module type and function declaration for init packet handling.
|
|
||||||
*
|
|
||||||
* @details This header contains basic functionality for performing safety checks on software
|
|
||||||
* updates for \nRFXX based devices. It provides a skeleton for pre-checking an init packet
|
|
||||||
* to ensure the following image is compatible with this device. A safety check should
|
|
||||||
* always be performed to prevent accidental flashing of unsupported applications or a
|
|
||||||
* wrong combination of application and SoftDevice.
|
|
||||||
* The device information contains information such as:
|
|
||||||
* - Device type (2 bytes), for example Heart Rate. The device type is a number defined by
|
|
||||||
* the customer. It can be located in UICR or FICR.
|
|
||||||
* - Device revision (2 bytes), for example major revision 1, minor revision 0. The device
|
|
||||||
* revision is a number defined by the customer. It can be located in UICR or FICR.
|
|
||||||
* - List of SoftDevices supported by this application, for example
|
|
||||||
* 0x0049 = S110v6_0_0
|
|
||||||
* 0xFFFE = S110 development (any SoftDevice accepted),
|
|
||||||
* - CRC or hash of firmware image
|
|
||||||
*
|
|
||||||
* @note This module does not support security features such as image signing, but the corresponding
|
|
||||||
* implementation allows for such extensions.
|
|
||||||
* If the init packet is signed by a trusted source, it must be decrypted before it can be
|
|
||||||
* processed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DFU_INIT_H__
|
|
||||||
#define DFU_INIT_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "nrf.h"
|
|
||||||
|
|
||||||
/**@brief Structure contained in an init packet. Contains information on device type, revision, and
|
|
||||||
* supported SoftDevices.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t device_type; /**< Device type (2 bytes), for example Heart Rate. This number must be defined by the customer before production. It can be located in UICR or FICR. */
|
|
||||||
uint16_t device_rev; /**< Device revision (2 bytes), for example major revision 1, minor revision 0. This number must be defined by the customer before production. It can be located in UICR or FICR. */
|
|
||||||
uint32_t app_version; /**< Application version for the image software. This field allows for additional checking, for example ensuring that a downgrade is not allowed. */
|
|
||||||
uint16_t softdevice_len; /**< Number of different SoftDevice revisions compatible with this application. The list of SoftDevice firmware IDs is defined in @ref softdevice. */
|
|
||||||
uint16_t softdevice[1]; /**< Variable length array of SoftDevices compatible with this application. The length of the array is specified in the length field. SoftDevice firmware id 0xFFFE indicates any SoftDevice. */
|
|
||||||
} dfu_init_packet_t;
|
|
||||||
|
|
||||||
/**@brief Structure holding basic device information settings.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t device_type; /**< Device type (2 bytes), for example Heart Rate. This number must be defined by the customer before production. It can be located in UICR or FICR. */
|
|
||||||
uint16_t device_rev; /**< Device revision (2 bytes), for example major revision 1, minor revision 0. This number must be defined by the customer before production. It can be located in UICR or FICR. */
|
|
||||||
} dfu_device_info_t;
|
|
||||||
|
|
||||||
/** The device info offset can be modified to place the device info settings at a different location.
|
|
||||||
* If the customer reserved UICR location is used for other application specific data, the offset
|
|
||||||
* must be updated to avoid collision with that data.
|
|
||||||
*/
|
|
||||||
/** [DFU UICR DEV offset] */
|
|
||||||
#define UICR_CUSTOMER_DEVICE_INFO_OFFSET 0x0 /**< Device info offset inside the customer UICR reserved area. Customers may change this value to place the device information in a user-preferred location. */
|
|
||||||
/** [DFU UICR DEV offset] */
|
|
||||||
|
|
||||||
#define UICR_CUSTOMER_RESERVED_OFFSET 0x80 /**< Customer reserved area in the UICR. The area from UICR + 0x80 is reserved for customer usage. */
|
|
||||||
#define DFU_DEVICE_INFO_BASE (NRF_UICR_BASE + \
|
|
||||||
UICR_CUSTOMER_RESERVED_OFFSET + \
|
|
||||||
UICR_CUSTOMER_DEVICE_INFO_OFFSET) /**< The device information base address inside of UICR. */
|
|
||||||
#define DFU_DEVICE_INFO ((dfu_device_info_t *)DFU_DEVICE_INFO_BASE) /**< The memory mapped structure for device information data. */
|
|
||||||
|
|
||||||
#define DFU_DEVICE_TYPE_EMPTY ((uint16_t)0xFFFF) /**< Mask indicating no device type is present in UICR. 0xFFFF is default flash pattern when not written with data. */
|
|
||||||
#define DFU_DEVICE_REVISION_EMPTY ((uint16_t)0xFFFF) /**< Mask indicating no device revision is present in UICR. 0xFFFF is default flash pattern when not written with data. */
|
|
||||||
#define DFU_SOFTDEVICE_ANY ((uint16_t)0xFFFE) /**< Mask indicating that any SoftDevice is allowed for updating this application. Allows for easy development. Not to be used in production images. */
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief DFU prevalidate call for pre-checking the received init packet.
|
|
||||||
*
|
|
||||||
* @details Pre-validation will safety check the firmware image to be transfered in second stage.
|
|
||||||
* The function currently checks the device type, device revision, application firmware
|
|
||||||
* version, and supported SoftDevices. More checks should be added according to
|
|
||||||
* customer-specific requirements.
|
|
||||||
*
|
|
||||||
* @param[in] p_init_data Pointer to the init packet. If the init packet is encrypted or signed,
|
|
||||||
* it must first be decrypted before being checked.
|
|
||||||
* @param[in] init_data_len Length of the init data.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS If the pre-validation succeeded, that means the image is
|
|
||||||
* supported by the device and it is considered to come from a
|
|
||||||
* trusted source (signing).
|
|
||||||
* @retval NRF_ERROR_INVALID_DATA If the pre-validation failed, that means the image is not
|
|
||||||
* supported by the device or comes from an un-trusted source
|
|
||||||
* (signing).
|
|
||||||
* @retval NRF_ERROR_INVALID_LENGTH If the size of the init packet is not within the limits of
|
|
||||||
* the init packet handler.
|
|
||||||
*/
|
|
||||||
uint32_t dfu_init_prevalidate(uint8_t * p_init_data, uint32_t init_data_len);
|
|
||||||
|
|
||||||
/**@brief DFU postvalidate call for post-checking the received image using the init packet.
|
|
||||||
*
|
|
||||||
* @details Post-validation can verify the integrity check the firmware image received before
|
|
||||||
* activating the image.
|
|
||||||
* Checks performed can be:
|
|
||||||
* - A simple CRC as shown in the corresponding implementation of this API in the file
|
|
||||||
* dfu_init_template.c
|
|
||||||
* - A hash for better verification of the image.
|
|
||||||
* - A signature to ensure the image originates from a trusted source.
|
|
||||||
* Checks are intended to be expanded for customer-specific requirements.
|
|
||||||
*
|
|
||||||
* @param[in] p_image Pointer to the received image. The init data provided in the call
|
|
||||||
* \ref dfu_init_prevalidate will be used for validating the image.
|
|
||||||
* @param[in] image_len Length of the image data.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS If the post-validation succeeded, that meant the integrity of the
|
|
||||||
* image has been verified and the image originates from a trusted
|
|
||||||
* source (signing).
|
|
||||||
* @retval NRF_ERROR_INVALID_DATA If the post-validation failed, that meant the post check of the
|
|
||||||
* image failed such as the CRC is not matching the image transfered
|
|
||||||
* or the verification of the image fails (signing).
|
|
||||||
*/
|
|
||||||
uint32_t dfu_init_postvalidate(uint8_t * p_image, uint32_t image_len);
|
|
||||||
|
|
||||||
#endif // DFU_INIT_H__
|
|
||||||
|
|
||||||
/**@} */
|
|
|
@ -1,177 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**@file
|
|
||||||
*
|
|
||||||
* @defgroup nrf_dfu_init_template Template file with an DFU init packet handling example.
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @ingroup nrf_dfu
|
|
||||||
*
|
|
||||||
* @brief This file contains a template on how to implement DFU init packet handling.
|
|
||||||
*
|
|
||||||
* @details The template shows how device type and revision can be used for a safety check of the
|
|
||||||
* received image. It shows how validation can be performed in two stages:
|
|
||||||
* - Stage 1: Pre-check of firmware image before transfer to ensure the firmware matches:
|
|
||||||
* - Device Type.
|
|
||||||
* - Device Revision.
|
|
||||||
* Installed SoftDevice.
|
|
||||||
* This template can be extended with additional checks according to needs.
|
|
||||||
* For example, such a check could be the origin of the image (trusted source)
|
|
||||||
* based on a signature scheme.
|
|
||||||
* - Stage 2: Post-check of the image after image transfer but before installing firmware.
|
|
||||||
* For example, such a check could be an integrity check in form of hashing or
|
|
||||||
* verification of a signature.
|
|
||||||
* In this template, a simple CRC check is carried out.
|
|
||||||
* The CRC check can be replaced with other mechanisms, like signing.
|
|
||||||
*
|
|
||||||
* @note This module does not support security features such as image signing, but the
|
|
||||||
* implementation allows for such extension.
|
|
||||||
* If the init packet is signed by a trusted source, it must be decrypted before it can be
|
|
||||||
* processed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "dfu_init.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <dfu_types.h>
|
|
||||||
#include "nrf_error.h"
|
|
||||||
#include "crc16.h"
|
|
||||||
|
|
||||||
#define DFU_INIT_PACKET_EXT_LENGTH_MIN 2 //< Minimum length of the extended init packet. The extended init packet may contain a CRC, a HASH, or other data. This value must be changed according to the requirements of the system. The template uses a minimum value of two in order to hold a CRC. */
|
|
||||||
#define DFU_INIT_PACKET_EXT_LENGTH_MAX 10 //< Maximum length of the extended init packet. The extended init packet may contain a CRC, a HASH, or other data. This value must be changed according to the requirements of the system. The template uses a maximum value of 10 in order to hold a CRC and any padded data on transport layer without overflow. */
|
|
||||||
|
|
||||||
static uint8_t m_extended_packet[DFU_INIT_PACKET_EXT_LENGTH_MAX]; //< Data array for storage of the extended data received. The extended data follows the normal init data of type \ref dfu_init_packet_t. Extended data can be used for a CRC, hash, signature, or other data. */
|
|
||||||
static uint8_t m_extended_packet_length; //< Length of the extended data received with init packet. */
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t dfu_init_prevalidate(uint8_t * p_init_data, uint32_t init_data_len)
|
|
||||||
{
|
|
||||||
uint32_t i = 0;
|
|
||||||
|
|
||||||
// In order to support signing or encryption then any init packet decryption function / library
|
|
||||||
// should be called from here or implemented at this location.
|
|
||||||
|
|
||||||
// Length check to ensure valid data are parsed.
|
|
||||||
if (init_data_len < sizeof(dfu_init_packet_t))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_LENGTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Current template uses clear text data so they can be casted for pre-check.
|
|
||||||
dfu_init_packet_t * p_init_packet = (dfu_init_packet_t *)p_init_data;
|
|
||||||
|
|
||||||
m_extended_packet_length = ((uint32_t)p_init_data + init_data_len) -
|
|
||||||
(uint32_t)&p_init_packet->softdevice[p_init_packet->softdevice_len];
|
|
||||||
if (m_extended_packet_length < DFU_INIT_PACKET_EXT_LENGTH_MIN)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_LENGTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((uint32_t)p_init_data + init_data_len) <
|
|
||||||
(uint32_t)&p_init_packet->softdevice[p_init_packet->softdevice_len])
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_LENGTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(m_extended_packet,
|
|
||||||
&p_init_packet->softdevice[p_init_packet->softdevice_len],
|
|
||||||
m_extended_packet_length);
|
|
||||||
|
|
||||||
/** [DFU init application version] */
|
|
||||||
// To support application versioning, this check should be updated.
|
|
||||||
// This template allows for any application to be installed. However,
|
|
||||||
// customers can place a revision number at the bottom of the application
|
|
||||||
// to be verified by the bootloader. This can be done at a location
|
|
||||||
// relative to the application, for example the application start
|
|
||||||
// address + 0x0100.
|
|
||||||
/** [DFU init application version] */
|
|
||||||
|
|
||||||
// First check to verify the image to be transfered matches the device type.
|
|
||||||
// If no Device type is present in DFU_DEVICE_INFO then any image will be accepted.
|
|
||||||
if ((DFU_DEVICE_INFO->device_type != DFU_DEVICE_TYPE_EMPTY) &&
|
|
||||||
(p_init_packet->device_type != DFU_DEVICE_INFO->device_type))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Second check to verify the image to be transfered matches the device revision.
|
|
||||||
// If no Device revision is present in DFU_DEVICE_INFO then any image will be accepted.
|
|
||||||
if ((DFU_DEVICE_INFO->device_rev != DFU_DEVICE_REVISION_EMPTY) &&
|
|
||||||
(p_init_packet->device_rev != DFU_DEVICE_INFO->device_rev))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Third check: Check the array of supported SoftDevices by this application.
|
|
||||||
// If the installed SoftDevice does not match any SoftDevice in the list then an
|
|
||||||
// error is returned.
|
|
||||||
while (i < p_init_packet->softdevice_len)
|
|
||||||
{
|
|
||||||
if (p_init_packet->softdevice[i] == DFU_SOFTDEVICE_ANY ||
|
|
||||||
p_init_packet->softdevice[i++] == SD_FWID_GET(MBR_SIZE))
|
|
||||||
{
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No matching SoftDevice found - Return NRF_ERROR_INVALID_DATA.
|
|
||||||
return NRF_ERROR_INVALID_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t dfu_init_postvalidate(uint8_t * p_image, uint32_t image_len)
|
|
||||||
{
|
|
||||||
#if NEED_CRC_CHECK /* disabled for now */
|
|
||||||
uint16_t image_crc;
|
|
||||||
uint16_t received_crc;
|
|
||||||
|
|
||||||
// In order to support hashing (and signing) then the (decrypted) hash should be fetched and
|
|
||||||
// the corresponding hash should be calculated over the image at this location.
|
|
||||||
// If hashing (or signing) is added to the system then the CRC validation should be removed.
|
|
||||||
|
|
||||||
// calculate CRC from active block.
|
|
||||||
image_crc = crc16_compute(p_image, image_len, NULL);
|
|
||||||
|
|
||||||
// Decode the received CRC from extended data.
|
|
||||||
received_crc = uint16_decode((uint8_t *)&m_extended_packet[0]);
|
|
||||||
|
|
||||||
// Compare the received and calculated CRC.
|
|
||||||
if (image_crc != received_crc)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_DATA;
|
|
||||||
}
|
|
||||||
#endif /* NEED_CRC_CHECK */
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**@file
|
|
||||||
*
|
|
||||||
* @defgroup nrf_dfu_transport DFU transport API.
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @brief DFU transport module interface.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DFU_TRANSPORT_H__
|
|
||||||
#define DFU_TRANSPORT_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/**@brief Function for starting the update of Device Firmware.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
*/
|
|
||||||
uint32_t dfu_transport_update_start(void);
|
|
||||||
|
|
||||||
/**@brief Function for closing the transport layer.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
*/
|
|
||||||
uint32_t dfu_transport_close(void);
|
|
||||||
|
|
||||||
#endif // DFU_TRANSPORT_H__
|
|
||||||
|
|
||||||
/**@} */
|
|
|
@ -1,167 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**@file
|
|
||||||
*
|
|
||||||
* @defgroup nrf_dfu_types Types and definitions.
|
|
||||||
* @{
|
|
||||||
*
|
|
||||||
* @ingroup nrf_dfu
|
|
||||||
*
|
|
||||||
* @brief Device Firmware Update module type and definitions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DFU_TYPES_H__
|
|
||||||
#define DFU_TYPES_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "nrf_sdm.h"
|
|
||||||
#include "nrf.h"
|
|
||||||
#include "app_util.h"
|
|
||||||
|
|
||||||
#define NRF_UICR_BOOT_START_ADDRESS (NRF_UICR_BASE + 0x14) /**< Register where the bootloader start address is stored in the UICR register. */
|
|
||||||
|
|
||||||
#define CODE_REGION_1_START SD_SIZE_GET(MBR_SIZE) /**< This field should correspond to the size of Code Region 0, (which is identical to Start of Code Region 1), found in UICR.CLEN0 register. This value is used for compile safety, as the linker will fail if application expands into bootloader. Runtime, the bootloader will use the value found in UICR.CLEN0. */
|
|
||||||
#define SOFTDEVICE_REGION_START MBR_SIZE /**< This field should correspond to start address of the bootloader, found in UICR.RESERVED, 0x10001014, register. This value is used for sanity check, so the bootloader will fail immediately if this value differs from runtime value. The value is used to determine max application size for updating. */
|
|
||||||
|
|
||||||
#ifdef NRF51
|
|
||||||
#ifdef SIGNING
|
|
||||||
#define BOOTLOADER_REGION_START 0x00039C00 /**< This field should correspond to start address of the bootloader, found in UICR.RESERVED, 0x10001014, register. This value is used for sanity check, so the bootloader will fail immediately if this value differs from runtime value. The value is used to determine max application size for updating. */
|
|
||||||
#define BOOTLOADER_SETTINGS_ADDRESS 0x0003D800 /**< The field specifies the page location of the bootloader settings address. */
|
|
||||||
#else
|
|
||||||
#define BOOTLOADER_REGION_START 0x0003C000 /**< This field should correspond to start address of the bootloader, found in UICR.RESERVED, 0x10001014, register. This value is used for sanity check, so the bootloader will fail immediately if this value differs from runtime value. The value is used to determine max application size for updating. */
|
|
||||||
#define BOOTLOADER_SETTINGS_ADDRESS 0x0003FC00 /**< The field specifies the page location of the bootloader settings address. */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CODE_PAGE_SIZE 0x0400 /**< Size of a flash codepage. Used for size of the reserved flash space in the bootloader region. Will be runtime checked against NRF_UICR->CODEPAGESIZE to ensure the region is correct. */
|
|
||||||
#elif NRF52
|
|
||||||
#define BOOTLOADER_REGION_START 0x0007B000 /**< This field should correspond to start address of the bootloader, found in UICR.RESERVED, 0x10001014, register. This value is used for sanity check, so the bootloader will fail immediately if this value differs from runtime value. The value is used to determine max application size for updating. */
|
|
||||||
#define BOOTLOADER_SETTINGS_ADDRESS 0x0007F000 /**< The field specifies the page location of the bootloader settings address. */
|
|
||||||
#define CODE_PAGE_SIZE 0x1000 /**< Size of a flash codepage. Used for size of the reserved flash space in the bootloader region. Will be runtime checked against NRF_UICR->CODEPAGESIZE to ensure the region is correct. */
|
|
||||||
#else
|
|
||||||
#error No target defined
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DFU_REGION_TOTAL_SIZE (BOOTLOADER_REGION_START - CODE_REGION_1_START) /**< Total size of the region between SD and Bootloader. */
|
|
||||||
|
|
||||||
#define DFU_APP_DATA_RESERVED 0x0000 /**< Size of Application Data that must be preserved between application updates. This value must be a multiple of page size. Page size is 0x400 (1024d) bytes, thus this value must be 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, etc. */
|
|
||||||
#define DFU_BANK_PADDING (DFU_APP_DATA_RESERVED % (2 * CODE_PAGE_SIZE)) /**< Padding to ensure that image size banked is always page sized. */
|
|
||||||
#define DFU_IMAGE_MAX_SIZE_FULL (DFU_REGION_TOTAL_SIZE - DFU_APP_DATA_RESERVED) /**< Maximum size of an application, excluding save data from the application. */
|
|
||||||
#define DFU_IMAGE_MAX_SIZE_BANKED ((DFU_REGION_TOTAL_SIZE - \
|
|
||||||
DFU_APP_DATA_RESERVED - \
|
|
||||||
DFU_BANK_PADDING) / 2) /**< Maximum size of an application, excluding save data from the application. */
|
|
||||||
|
|
||||||
#define DFU_BL_IMAGE_MAX_SIZE (BOOTLOADER_SETTINGS_ADDRESS - BOOTLOADER_REGION_START) /**< Maximum size of a bootloader, excluding save data from the current bootloader. */
|
|
||||||
|
|
||||||
#define DFU_BANK_0_REGION_START CODE_REGION_1_START /**< Bank 0 region start. */
|
|
||||||
#define DFU_BANK_1_REGION_START (DFU_BANK_0_REGION_START + DFU_IMAGE_MAX_SIZE_BANKED) /**< Bank 1 region start. */
|
|
||||||
|
|
||||||
#define EMPTY_FLASH_MASK 0xFFFFFFFF /**< Bit mask that defines an empty address in flash. */
|
|
||||||
|
|
||||||
#define INVALID_PACKET 0x00 /**< Invalid packet identifies. */
|
|
||||||
#define INIT_PACKET 0x01 /**< Packet identifies for initialization packet. */
|
|
||||||
#define STOP_INIT_PACKET 0x02 /**< Packet identifies for stop initialization packet. Used when complete init packet has been received so that the init packet can be used for pre validaiton. */
|
|
||||||
#define START_PACKET 0x03 /**< Packet identifies for the Data Start Packet. */
|
|
||||||
#define DATA_PACKET 0x04 /**< Packet identifies for a Data Packet. */
|
|
||||||
#define STOP_DATA_PACKET 0x05 /**< Packet identifies for the Data Stop Packet. */
|
|
||||||
|
|
||||||
#define DFU_UPDATE_SD 0x01 /**< Bit field indicating update of SoftDevice is ongoing. */
|
|
||||||
#define DFU_UPDATE_BL 0x02 /**< Bit field indicating update of bootloader is ongoing. */
|
|
||||||
#define DFU_UPDATE_APP 0x04 /**< Bit field indicating update of application is ongoing. */
|
|
||||||
|
|
||||||
#define DFU_INIT_RX 0x00 /**< Op Code identifies for receiving init packet. */
|
|
||||||
#define DFU_INIT_COMPLETE 0x01 /**< Op Code identifies for transmission complete of init packet. */
|
|
||||||
|
|
||||||
// Safe guard to ensure during compile time that the DFU_APP_DATA_RESERVED is a multiple of page size.
|
|
||||||
STATIC_ASSERT((((DFU_APP_DATA_RESERVED) & (CODE_PAGE_SIZE - 1)) == 0x00));
|
|
||||||
|
|
||||||
/**@brief Structure holding a start packet containing update mode and image sizes.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t dfu_update_mode; /**< Packet type, used to identify the content of the received packet referenced by data packet. */
|
|
||||||
uint32_t sd_image_size; /**< Size of the SoftDevice image to be transferred. Zero if no SoftDevice image will be transfered. */
|
|
||||||
uint32_t bl_image_size; /**< Size of the Bootloader image to be transferred. Zero if no Bootloader image will be transfered. */
|
|
||||||
uint32_t app_image_size; /**< Size of the application image to be transmitted. Zero if no Bootloader image will be transfered. */
|
|
||||||
} dfu_start_packet_t;
|
|
||||||
|
|
||||||
/**@brief Structure holding a bootloader init/data packet received.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t packet_length; /**< Packet length of the data packet. Each data is word size, meaning length of 4 is 4 words, not bytes. */
|
|
||||||
uint32_t * p_data_packet; /**< Data Packet received. Each data is a word size entry. */
|
|
||||||
} dfu_data_packet_t;
|
|
||||||
|
|
||||||
/**@brief Structure for holding dfu update packet. Packet type indicate the type of packet.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t packet_type; /**< Packet type, used to identify the content of the received packet referenced by data packet. */
|
|
||||||
union
|
|
||||||
{
|
|
||||||
dfu_data_packet_t data_packet; /**< Used when packet type is INIT_PACKET or DATA_PACKET. Packet contains data received for init or data. */
|
|
||||||
dfu_start_packet_t * start_packet; /**< Used when packet type is START_DATA_PACKET. Will contain information on software to be updtaed, i.e. SoftDevice, Bootloader and/or Application along with image sizes. */
|
|
||||||
} params;
|
|
||||||
} dfu_update_packet_t;
|
|
||||||
|
|
||||||
/**@brief DFU status error codes.
|
|
||||||
*/
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
DFU_UPDATE_APP_COMPLETE, /**< Status update of application complete.*/
|
|
||||||
DFU_UPDATE_SD_COMPLETE, /**< Status update of SoftDevice update complete. Note that this solely indicates that a new SoftDevice has been received and stored in bank 0 and 1. */
|
|
||||||
DFU_UPDATE_SD_SWAPPED, /**< Status update of SoftDevice update complete. Note that this solely indicates that a new SoftDevice has been received and stored in bank 0 and 1. */
|
|
||||||
DFU_UPDATE_BOOT_COMPLETE, /**< Status update complete.*/
|
|
||||||
DFU_BANK_0_ERASED, /**< Status bank 0 erased.*/
|
|
||||||
DFU_TIMEOUT, /**< Status timeout.*/
|
|
||||||
DFU_RESET /**< Status Reset to indicate current update procedure has been aborted and system should reset. */
|
|
||||||
} dfu_update_status_code_t;
|
|
||||||
|
|
||||||
/**@brief Structure holding DFU complete event.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
dfu_update_status_code_t status_code; /**< Device Firmware Update status. */
|
|
||||||
uint16_t app_crc; /**< CRC of the recieved application. */
|
|
||||||
uint32_t sd_size; /**< Size of the recieved SoftDevice. */
|
|
||||||
uint32_t bl_size; /**< Size of the recieved BootLoader. */
|
|
||||||
uint32_t app_size; /**< Size of the recieved Application. */
|
|
||||||
uint32_t sd_image_start; /**< Location in flash where the received SoftDevice image is stored. */
|
|
||||||
} dfu_update_status_t;
|
|
||||||
|
|
||||||
/**@brief Update complete handler type. */
|
|
||||||
typedef void (*dfu_complete_handler_t)(dfu_update_status_t dfu_update_status);
|
|
||||||
|
|
||||||
#endif // DFU_TYPES_H__
|
|
||||||
|
|
||||||
/**@} */
|
|
|
@ -1,52 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
*
|
|
||||||
* @defgroup memory_pool_internal Memory Pool Internal
|
|
||||||
* @{
|
|
||||||
* @ingroup memory_pool
|
|
||||||
*
|
|
||||||
* @brief Memory pool internal definitions
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MEM_POOL_INTERNAL_H__
|
|
||||||
#define MEM_POOL_INTERNAL_H__
|
|
||||||
|
|
||||||
#define TX_BUF_SIZE 4u /**< TX buffer size in bytes. */
|
|
||||||
#define RX_BUF_SIZE 32u /**< RX buffer size in bytes. */
|
|
||||||
|
|
||||||
#define RX_BUF_QUEUE_SIZE 8u /**< RX buffer element size. */
|
|
||||||
|
|
||||||
#endif // MEM_POOL_INTERNAL_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,51 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "crc16.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
uint16_t crc16_compute(const uint8_t * p_data, uint32_t size, const uint16_t * p_crc)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
uint16_t crc = (p_crc == NULL) ? 0xffff : *p_crc;
|
|
||||||
|
|
||||||
for (i = 0; i < size; i++)
|
|
||||||
{
|
|
||||||
crc = (unsigned char)(crc >> 8) | (crc << 8);
|
|
||||||
crc ^= p_data[i];
|
|
||||||
crc ^= (unsigned char)(crc & 0xff) >> 4;
|
|
||||||
crc ^= (crc << 8) << 4;
|
|
||||||
crc ^= ((crc & 0xff) << 4) << 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return crc;
|
|
||||||
}
|
|
|
@ -1,63 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
*
|
|
||||||
* @defgroup crc_compute CRC compute
|
|
||||||
* @{
|
|
||||||
* @ingroup hci_transport
|
|
||||||
*
|
|
||||||
* @brief This module implements the CRC-16 calculation in the blocks.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CRC16_H__
|
|
||||||
#define CRC16_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/**@brief Function for calculating CRC-16 in blocks.
|
|
||||||
*
|
|
||||||
* Feed each consecutive data block into this function, along with the current value of p_crc as
|
|
||||||
* returned by the previous call of this function. The first call of this function should pass NULL
|
|
||||||
* as the initial value of the crc in p_crc.
|
|
||||||
*
|
|
||||||
* @param[in] p_data The input data block for computation.
|
|
||||||
* @param[in] size The size of the input data block in bytes.
|
|
||||||
* @param[in] p_crc The previous calculated CRC-16 value or NULL if first call.
|
|
||||||
*
|
|
||||||
* @return The updated CRC-16 value, based on the input supplied.
|
|
||||||
*/
|
|
||||||
uint16_t crc16_compute(const uint8_t * p_data, uint32_t size, const uint16_t * p_crc);
|
|
||||||
|
|
||||||
#endif // CRC16_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,280 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SECTION_VARS_H__
|
|
||||||
#define SECTION_VARS_H__
|
|
||||||
|
|
||||||
#include "app_util.h"
|
|
||||||
|
|
||||||
#if defined __ICC_ARM__
|
|
||||||
|
|
||||||
// turn on language extensions for iar
|
|
||||||
#pragma language=extended
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup section_vars Section variables
|
|
||||||
* @ingroup app_common
|
|
||||||
* @{
|
|
||||||
* @brief Section variables.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**@brief Macro to delay macro expression of pragma
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define NRF_PRAGMA(x) _Pragma(#x)
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro to register section by name in code
|
|
||||||
*
|
|
||||||
* @param[in] section_name Name of the section to register
|
|
||||||
**/
|
|
||||||
#if defined __GNUC__
|
|
||||||
|
|
||||||
// Not required by this compiler
|
|
||||||
#define NRF_SECTION_VARS_REGISTER_SECTION(section_name)
|
|
||||||
|
|
||||||
#elif defined __ICCARM__
|
|
||||||
|
|
||||||
#define NRF_SECTION_VARS_REGISTER_SECTION(section_name) NRF_PRAGMA(section = ## #section_name )
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#error TODO
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*lint -save -e27 */
|
|
||||||
|
|
||||||
/**@brief Macro for accessing start of a named data section by symbol
|
|
||||||
*
|
|
||||||
* @details The symbol that this macro resolves to is used to access the section
|
|
||||||
* by start address.
|
|
||||||
*
|
|
||||||
* @param[in] section_name Name of the section
|
|
||||||
*/
|
|
||||||
#if defined __GNUC__
|
|
||||||
|
|
||||||
#define NRF_SECTION_VARS_START_SYMBOL(section_name) __start_ ## section_name
|
|
||||||
|
|
||||||
#elif defined __ICCARM__
|
|
||||||
|
|
||||||
#define NRF_SECTION_VARS_START_SYMBOL(section_name) __section_begin(#section_name)
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#error TODO
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for accessing end of a named data section by symbol
|
|
||||||
*
|
|
||||||
* @details The symbol that this macro resolves to is used to access the section
|
|
||||||
* by end address.
|
|
||||||
*
|
|
||||||
* @param[in] section_name Name of the section
|
|
||||||
*/
|
|
||||||
#if defined __GNUC__
|
|
||||||
|
|
||||||
#define NRF_SECTION_VARS_END_SYMBOL(section_name) __stop_ ## section_name
|
|
||||||
|
|
||||||
#elif defined __ICCARM__
|
|
||||||
|
|
||||||
#define NRF_SECTION_VARS_END_SYMBOL(section_name) __section_end(#section_name)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*lint -restore */
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for accessing Length of a named section
|
|
||||||
*
|
|
||||||
* @details This macro is used to get the size of a named section.
|
|
||||||
*
|
|
||||||
* @param[in] section_name Name of the section
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined __GNUC__
|
|
||||||
|
|
||||||
#define NRF_SECTION_VARS_LENGTH(section_name) \
|
|
||||||
((uint32_t)&NRF_SECTION_VARS_END_SYMBOL(section_name) - (uint32_t)&NRF_SECTION_VARS_START_SYMBOL(section_name))
|
|
||||||
|
|
||||||
#elif defined __ICCARM__
|
|
||||||
|
|
||||||
#define NRF_SECTION_VARS_LENGTH(section_name) \
|
|
||||||
((uint32_t)NRF_SECTION_VARS_END_SYMBOL(section_name) - (uint32_t)NRF_SECTION_VARS_START_SYMBOL(section_name))
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#error TODO
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for accessing the start address of a named section
|
|
||||||
*
|
|
||||||
* param[in] section_name Name of the section to get the start address from
|
|
||||||
*/
|
|
||||||
#if defined __GNUC__
|
|
||||||
|
|
||||||
#define NRF_SECTION_VARS_START_ADDR(section_name) (uint32_t)&NRF_SECTION_VARS_START_SYMBOL(section_name)
|
|
||||||
|
|
||||||
#elif defined __ICCARM__
|
|
||||||
#define NRF_SECTION_VARS_START_ADDR(section_name) (uint32_t)iar_ ## section_name ## _start
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#error TODO
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*@brief Macro for accessing the end address of a named section
|
|
||||||
*
|
|
||||||
* @param[in] section_name Name of the section to get end address from
|
|
||||||
*/
|
|
||||||
#if defined __GNUC__
|
|
||||||
|
|
||||||
#define NRF_SECTION_VARS_END_ADDR(section_name) (uint32_t)&NRF_SECTION_VARS_END_SYMBOL(section_name)
|
|
||||||
|
|
||||||
#elif defined __ICCARM__
|
|
||||||
|
|
||||||
#define NRF_SECTION_VARS_END_ADDR(section_name) (uint32_t)iar_ ## section_name ## _end
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#error TODO
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for declaring symbols for named sections
|
|
||||||
*
|
|
||||||
* @note These external declarations of section specific symbols are required for the linker in GCC and Keil (not IAR)
|
|
||||||
*
|
|
||||||
* @param[in] type_name Name of the type stored in the section
|
|
||||||
* @param[in] section_name Name of the section
|
|
||||||
*/
|
|
||||||
#if defined __GNUC__
|
|
||||||
|
|
||||||
#define NRF_SECTION_VARS_REGISTER_SYMBOLS(type_name, section_name) \
|
|
||||||
extern type_name* NRF_SECTION_VARS_START_SYMBOL(section_name); \
|
|
||||||
extern void* NRF_SECTION_VARS_END_SYMBOL(section_name)
|
|
||||||
|
|
||||||
#elif defined __ICCARM__
|
|
||||||
|
|
||||||
// No symbol registration required for IAR
|
|
||||||
#define NRF_SECTION_VARS_REGISTER_SYMBOLS(type_name, section_name) \
|
|
||||||
extern void* iar_ ## section_name ## _start = __section_begin(#section_name); \
|
|
||||||
extern void* iar_ ## section_name ## _end = __section_end(#section_name)
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#error TODO
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro to add symbols to a named section
|
|
||||||
*
|
|
||||||
* @details The symbols are placed in a named section. All calls to this macro
|
|
||||||
* will result in symbols being placed in a contiguous manner in the named section.
|
|
||||||
* This macro ensures that the symbol is not removed because of optimization level.
|
|
||||||
*
|
|
||||||
* @warning There is no guarantee for ordering of placement. If ordering is required
|
|
||||||
*
|
|
||||||
* @warning The symbols added in the named section must be word aligned to
|
|
||||||
* ensure that compilers do not pad the section during symbol placement.
|
|
||||||
*
|
|
||||||
* @param[in] section_name Name of the section
|
|
||||||
* @param[in] type_def Datatype of the symbol to place in the given section
|
|
||||||
*/
|
|
||||||
#if defined __GNUC__
|
|
||||||
|
|
||||||
#define NRF_SECTION_VARS_ADD(section_name, type_def) \
|
|
||||||
static type_def __attribute__ ((section( #section_name ))) __attribute__ ((used))
|
|
||||||
|
|
||||||
#elif defined __ICCARM__
|
|
||||||
|
|
||||||
#define NRF_SECTION_VARS_ADD(section_name, type_def) \
|
|
||||||
__root type_def @ #section_name
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#error TODO
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro to get symbol from named section
|
|
||||||
*
|
|
||||||
* @warning The stored symbol can only be resolved using this macro if the
|
|
||||||
* type of the data is word aligned. The operation of acquiring
|
|
||||||
* the stored symbol relies on sizeof of the stored type, no
|
|
||||||
* padding can exist in the named section in between individual
|
|
||||||
* stored items or this macro will fail.
|
|
||||||
*
|
|
||||||
* @param[in] i Index of item in section
|
|
||||||
* @param[in] type_name Type name of item in section
|
|
||||||
* @param[in] section_name Name of the section
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined __GNUC__
|
|
||||||
|
|
||||||
#define NRF_SECTION_VARS_GET(i, type_name, section_name) \
|
|
||||||
(type_name*)(NRF_SECTION_VARS_START_ADDR(section_name) + i * sizeof(type_name))
|
|
||||||
|
|
||||||
#elif defined __ICCARM__
|
|
||||||
|
|
||||||
#define NRF_SECTION_VARS_GET(i, type_name, section_name) \
|
|
||||||
(type_name*)iar_ ## section_name ## _start + (i * sizeof(type_name))
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#error TODO
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro to get number of items in named section
|
|
||||||
*
|
|
||||||
* @param[in] type_name Type name of item in section
|
|
||||||
* @param[in] section_name Name of the section
|
|
||||||
*/
|
|
||||||
#define NRF_SECTION_VARS_COUNT(type_name, section_name) \
|
|
||||||
NRF_SECTION_VARS_LENGTH(section_name) / sizeof(type_name)
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif // SECTION_VARS_H__
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,566 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FDS_H__
|
|
||||||
#define FDS_H__
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup flash_data_storage Flash Data Storage
|
|
||||||
* @ingroup app_common
|
|
||||||
* @{
|
|
||||||
* @brief Flash Data Storage (FDS).
|
|
||||||
*
|
|
||||||
* @details Flash Data Storage (FDS) is a minimalistic filesystem for the on-chip flash.
|
|
||||||
* It can be used to manipulate @e records, which consist of a piece of data, made up
|
|
||||||
* of one or more chunks, and an associated key pair.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "sdk_errors.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief */
|
|
||||||
#define SIZEOF_WORDS(val) (sizeof(val) / 4)
|
|
||||||
|
|
||||||
/**@brief Reserved type key used to flag cleared records.
|
|
||||||
* May not be used as a record key by the application. */
|
|
||||||
#define FDS_TYPE_ID_INVALID (0x0000)
|
|
||||||
/**@brief Reserved instance key used to check for missing or corrupted metadata.
|
|
||||||
* May not be used as a record key by the application. */
|
|
||||||
#define FDS_INSTANCE_ID_INVALID (0xFFFF)
|
|
||||||
|
|
||||||
|
|
||||||
typedef uint32_t fds_record_id_t;
|
|
||||||
typedef uint16_t fds_type_id_t;
|
|
||||||
typedef uint16_t fds_length_t;
|
|
||||||
typedef uint16_t fds_instance_id_t;
|
|
||||||
typedef uint16_t fds_checksum_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief A piece of a record metadata, keeping information about one of its keys (type) and its
|
|
||||||
* lenght, expressed in 4 byte words. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
fds_type_id_t type; /**< The record type ID. */
|
|
||||||
fds_length_t length_words; /**< Length of the record's data, in 4 byte words. */
|
|
||||||
} fds_tl_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief A piece of a record metadata, keeping information about one of its keys (instance) and
|
|
||||||
* its checksum. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
fds_instance_id_t instance; /**< The record instance ID. */
|
|
||||||
fds_checksum_t checksum; /**< Checksum of the entire record, including the metadata. */
|
|
||||||
} fds_ic_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief The record metadata. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
fds_tl_t tl; /**< See @ref fds_tl_t. */
|
|
||||||
fds_ic_t ic; /**< See @ref fds_ic_t. */
|
|
||||||
fds_record_id_t id; /**< The unique record ID (32 bits). */
|
|
||||||
} fds_header_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef fds_header_t fds_record_header_t;
|
|
||||||
|
|
||||||
/**@brief The record descriptor structure, used to manipulate a record.
|
|
||||||
* @note This structure is meant to be opaque to the user, who does not need to access
|
|
||||||
* any of its fields.
|
|
||||||
* @note This structure does not need special initialization.
|
|
||||||
* @warning Do not reuse the same descriptor for different records. If you do, be sure to set
|
|
||||||
* its fields to zero. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t record_id; /**< The unique record ID. */
|
|
||||||
uint32_t const * p_rec; /**< The last known record address in flash. */
|
|
||||||
uint16_t vpage_id; /**< The virtual page ID in which the record is stored. */
|
|
||||||
uint16_t gc_magic; /**< Number of times the GC algorithm has been run. */
|
|
||||||
uint16_t ptr_magic; /**< Used to verify the validity of p_rec. */
|
|
||||||
} fds_record_desc_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief The record key, used to lookup records.
|
|
||||||
* @note The uniqueness of either field is not enforced by the system. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t type;
|
|
||||||
uint16_t instance;
|
|
||||||
} fds_record_key_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Structure used for reading a record back from flash memory. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
// TODO: the header should be a pointer.
|
|
||||||
fds_header_t header; /**< The record header (metadata), as stored in flash. */
|
|
||||||
uint32_t const * p_data; /**< The record data. */
|
|
||||||
} fds_record_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief A record chunk, containing a piece of data to be stored in a record.
|
|
||||||
*
|
|
||||||
* @note p_data must be aligned on a (4 bytes) word boundary.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
void const * p_data; /**< Pointer to the data to store. Must be word aligned. */
|
|
||||||
fds_length_t length_words; /**< Length of data pointed by p_data, in 4 byte words. */
|
|
||||||
} fds_record_chunk_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief A token to a reserved space in flash, created by @ref fds_reserve.
|
|
||||||
* Use @ref fds_write_reserved to write the record in the reserved space,
|
|
||||||
* or @ref fds_reserve_cancel to cancel the reservation.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t vpage_id; /**< The virtual ID of the page where space was reserved. */
|
|
||||||
fds_length_t length_words; /**< The amount of space reserved, in 4 byte words. */
|
|
||||||
} fds_write_token_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief A token to keep information about the progress of @ref fds_find, @ref fds_find_by_type
|
|
||||||
* and @ref fds_find_by_instance operations.
|
|
||||||
* @note This structure is meant to be opaque to the user, who does not need to access any of its
|
|
||||||
* fields.
|
|
||||||
* @note The token does not need special initialization.
|
|
||||||
* @warning Do not reuse the same token to search for different records. If you do, be sure to set
|
|
||||||
* its fields to zero. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t const * p_addr;
|
|
||||||
uint32_t magic;
|
|
||||||
uint16_t vpage_id;
|
|
||||||
} fds_find_token_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
FDS_CMD_NONE, /**< No command. */
|
|
||||||
FDS_CMD_INIT, /**< Module initialization commnad. Used in @ref fds_init */
|
|
||||||
FDS_CMD_WRITE, /**< Write command. Used in @ref fds_write and @ref fds_write_reserved. */
|
|
||||||
FDS_CMD_UPDATE, /**< Update command. Used in @ref fds_update. */
|
|
||||||
FDS_CMD_CLEAR, /**< Clear record command. Used in @ref fds_clear and @ref fds_update. */
|
|
||||||
FDS_CMD_CLEAR_INST, /**< Clear instance command. Used in @ref fds_clear_by_instance. */
|
|
||||||
FDS_CMD_GC /**< Garbage collection. Used in @ref fds_gc. */
|
|
||||||
} fds_cmd_id_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Flash data storage callback function.
|
|
||||||
*
|
|
||||||
* @param result Result of the command.
|
|
||||||
* @param cmd The command associated with the callback.
|
|
||||||
* @param record_id The unique ID of the record associated with the callback.
|
|
||||||
* @param record_key The key pair of the record associated with the callback.
|
|
||||||
*/
|
|
||||||
typedef void (*fds_cb_t)(ret_code_t result,
|
|
||||||
fds_cmd_id_t cmd,
|
|
||||||
fds_record_id_t record_id,
|
|
||||||
fds_record_key_t record_key);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to register a callback for the module events.
|
|
||||||
* @details The maximum amount of callback which can be registered can be configured by
|
|
||||||
* changing the FDS_MAX_USERS macro in fds_config.h.
|
|
||||||
*
|
|
||||||
* @param[in] cb The callback function.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Error. Maximum number of registered callbacks reached.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_register(fds_cb_t cb);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to initialize the module.
|
|
||||||
*
|
|
||||||
* @details This function initializes the module and installs the filesystem, if it is not
|
|
||||||
* installed yet.
|
|
||||||
*
|
|
||||||
* @note This function is asynchronous. Completion is reported with a callback through the
|
|
||||||
* registered event handler. To be able to receive such callback, be sure to call
|
|
||||||
* @ref fds_register before calling @ref fds_init.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. The command was queued.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Error. The module is currently undergoing initialization.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Error. Insufficient space to install the filesystem, or
|
|
||||||
* insufficient resources to perform the installation.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_init(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to write a record to flash.
|
|
||||||
*
|
|
||||||
* @details This function can be used to write a record to flash. A record data consists of
|
|
||||||
* multiple chunks and is supplied to the function as an array of fds_record_chunk_t
|
|
||||||
* structures. The maximum lenght of a record data may not exceed the size of one flash
|
|
||||||
* page minus FDS_HEADER_SIZE words.
|
|
||||||
*
|
|
||||||
* @note This function is asynchronous, therefore, completion is reported with a callback
|
|
||||||
* through the registered event handler.
|
|
||||||
*
|
|
||||||
* @note The record data must be aligned on a 4 byte boundary, and because it is not buffered
|
|
||||||
* internally, it must be kept in memory by the application until the callback for the
|
|
||||||
* command has been received, i.e., the command completed.
|
|
||||||
*
|
|
||||||
* @param[out] p_desc The record descriptor. It may be NULL.
|
|
||||||
* @param[in] key The record key pair.
|
|
||||||
* @param[in] num_chunks The number of elements in the chunks array.
|
|
||||||
* @param[in] chunks An array of chunks making up the record data.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. The command was queued.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
|
|
||||||
* @retval NRF_ERROR_INVALID_DATA Error. The key contains an invalid type or instance.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR Error. The record data is not aligned on a 4 byte boundary.
|
|
||||||
* @retval NRF_ERROR_INVALID_LENGTH Error. The record length exceeds the maximum lenght.
|
|
||||||
* @retval NRF_ERROR_BUSY Error. Insufficient internal resources to queue the operation.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Error. No flash space available to store the record.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_write(fds_record_desc_t * const p_desc,
|
|
||||||
fds_record_key_t key,
|
|
||||||
uint8_t num_chunks,
|
|
||||||
fds_record_chunk_t chunks[]);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to reserve space for a record.
|
|
||||||
*
|
|
||||||
* @details This function can be used to reserve flash space to store a record, which can be
|
|
||||||
* later written down using @ref fds_write_reserved. It is possible to cancel a
|
|
||||||
* reservation by using @ref fds_reserve_cancel.
|
|
||||||
*
|
|
||||||
* @param[out] p_tok A token which can be used to write a record in the reserved space
|
|
||||||
* using @ref fds_write_reserved.
|
|
||||||
* @param[in] length_words The lenght of the record data, in 4 byte words.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. Flash space was successfully reserved.
|
|
||||||
* @retval NRF_ERROR_NULL Error. p_tok is NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Error. Insufficient space.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_reserve(fds_write_token_t * const p_tok, uint16_t length_words);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to cancel a space reservation.
|
|
||||||
*
|
|
||||||
* @param[in] p_tok The token produced by @ref fds_reserve, identifying the reservation to cancel.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. The reservation was canceled.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
|
|
||||||
* @retval NRF_ERROR_NULL Error. p_tok is NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_DATA Error. p_tok contains invalid data.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_reserve_cancel(fds_write_token_t * const p_tok);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to write a record to flash, the space for which has been previously reserved
|
|
||||||
* using @ref fds_reserve.
|
|
||||||
*
|
|
||||||
* @details This function behaves similarly to @ref fds_write, with the exception that it never
|
|
||||||
* fails with NRF_ERROR_NO_MEM.
|
|
||||||
*
|
|
||||||
* @note This function is asynchronous, therefore, completion is reported with a callback
|
|
||||||
* through the registered event handler.
|
|
||||||
*
|
|
||||||
* @note The record data must be aligned on a 4 byte boundary, and because it is not buffered
|
|
||||||
* internally, it must be kept in memory by the application until the callback for the
|
|
||||||
* command has been received, i.e., the command completed.
|
|
||||||
*
|
|
||||||
* @param[in] p_tok The token return by @ref fds_reserve.
|
|
||||||
* @param[out] p_desc The record descriptor. It may be NULL.
|
|
||||||
* @param[in] key The record key pair.
|
|
||||||
* @param[in] num_chunks The number of elements in the chunks array.
|
|
||||||
* @param[in] chunks An array of chunks making up the record data.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. The command was queued.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
|
|
||||||
* @retval NRF_ERROR_INVALID_DATA Error. The key contains an invalid type or instance.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR Error. The record data is not aligned on a 4 byte boundary.
|
|
||||||
* @retval NRF_ERROR_INVALID_LENGTH Error. The record length exceeds the maximum lenght.
|
|
||||||
* @retval NRF_ERROR_BUSY Error. Insufficient internal resources to queue the operation.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_write_reserved(fds_write_token_t const * const p_tok,
|
|
||||||
fds_record_desc_t * const p_desc,
|
|
||||||
fds_record_key_t key,
|
|
||||||
uint8_t num_chunks,
|
|
||||||
fds_record_chunk_t chunks[]);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to clear a record.
|
|
||||||
*
|
|
||||||
* @details Clearing a record has the effect of preventing the system from retrieving the record
|
|
||||||
* descriptor using the @ref fds_find, @ref fds_find_by_type and @ref fds_find_by_instance
|
|
||||||
* functions. Additionally, @ref fds_open calls shall fail when supplied a descritpor for
|
|
||||||
* a record which has been cleared. Clearing a record does not free the space it occupies
|
|
||||||
* in flash. The reclaim flash space used by cleared records, use @ref fds_gc.
|
|
||||||
*
|
|
||||||
* @note This function is asynchronous, therefore, completion is reported with a callback
|
|
||||||
* through the registered event handler.
|
|
||||||
*
|
|
||||||
* @param[in] p_desc The descriptor of the record to clear.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. The command was queued.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
|
|
||||||
* @retval NRF_ERROR_NULL Error. p_desc is NULL.
|
|
||||||
* @retval NRF_ERROR_BUSY Error. Insufficient internal resources to queue the operation.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_clear(fds_record_desc_t * const p_desc);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to clear all records with a given instance.
|
|
||||||
*
|
|
||||||
* @details Clearing a record has the effect of preventing the system from retrieving the record
|
|
||||||
* descriptor using the @ref fds_find, @ref fds_find_by_type and @ref fds_find_by_instance
|
|
||||||
* functions. Additionally, @ref fds_open calls shall fail when supplied a descritpor for
|
|
||||||
* a record which has been cleared. Clearing a record does not free the space it occupies
|
|
||||||
* in flash. The reclaim flash space used by cleared records, use @ref fds_gc.
|
|
||||||
*
|
|
||||||
* @note This function is asynchronous, therefore, completion is reported with a callback
|
|
||||||
* through the registered event handler. Only one callback will be issued. The record
|
|
||||||
* instance ID in the key parameter of the callback will contain the instance ID passed as
|
|
||||||
* parameter to this function. The record ID parameter will be zero, and the type ID equal
|
|
||||||
* to FDS_TYPE_ID_INVALID.
|
|
||||||
*
|
|
||||||
* @param[in] instance The instance ID of the records to clear.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. The command was queued.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
|
|
||||||
* @retval NRF_ERROR_NULL Error. p_desc is NULL.
|
|
||||||
* @retval NRF_ERROR_BUSY Error. Insufficient internal resources to queue the operation.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_clear_by_instance(fds_instance_id_t instance);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to update an existing record.
|
|
||||||
*
|
|
||||||
* @details Updating a record writes a new record with the given key and data in flash, and then
|
|
||||||
* clears the old record.
|
|
||||||
*
|
|
||||||
* @note This function is asynchronous, therefore, completion is reported with a callback
|
|
||||||
* through the registered event handler. Two callbacks will be issued, one to signal that
|
|
||||||
* the updated record has been written down, and another to signal that the old one has been
|
|
||||||
* cleared.
|
|
||||||
*
|
|
||||||
* @note The record data must be aligned on a 4 byte boundary, and because it is not buffered
|
|
||||||
* internally, it must be kept in memory by the application until the callback for the
|
|
||||||
* command has been received, i.e., the command completed.
|
|
||||||
*
|
|
||||||
* @param[in, out] p_desc The descriptor of the record to update. The descriptor of the updated
|
|
||||||
* record, after the function has returned with NRF_SUCCESS.
|
|
||||||
* @param[in] key The record new key pair.
|
|
||||||
* @param[in] num_chunks The number of elements in the chunks array.
|
|
||||||
* @param[in] chunks An array of chunks making up the record new data.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. The command was queued.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
|
|
||||||
* @retval NRF_ERROR_INVALID_DATA Error. The key contains an invalid type or instance.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR Error. The record data is not aligned on a 4 byte boundary.
|
|
||||||
* @retval NRF_ERROR_INVALID_LENGTH Error. The record length exceeds the maximum lenght.
|
|
||||||
* @retval NRF_ERROR_BUSY Error. Insufficient internal resources to queue the operation.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Error. No flash space available to store the record.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_update(fds_record_desc_t * const p_desc,
|
|
||||||
fds_record_key_t key,
|
|
||||||
uint8_t num_chunks,
|
|
||||||
fds_record_chunk_t chunks[]);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to search for records with a given key pair.
|
|
||||||
*
|
|
||||||
* @details Because types are not unique, to search for the next record with the given key call
|
|
||||||
* the function again and supply the same fds_find_token_t structure to resume searching
|
|
||||||
* from the last record found.
|
|
||||||
*
|
|
||||||
* @param[in] type The record type ID.
|
|
||||||
* @param[in] instance The record instance ID.
|
|
||||||
* @param[out] p_desc The descriptor of the record found.
|
|
||||||
* @param[out] p_token A token containing information about the progress of the operation.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. A record was found.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
|
|
||||||
* @retval NRF_ERROR_NULL Error. Either p_desc or p_token are NULL.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND Error. No record with the given key pair was found.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_find(fds_type_id_t type,
|
|
||||||
fds_instance_id_t instance,
|
|
||||||
fds_record_desc_t * const p_desc,
|
|
||||||
fds_find_token_t * const p_token);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to search for records with a given type.
|
|
||||||
*
|
|
||||||
* @details Because types are not unique, to search for the next record with the given key call
|
|
||||||
* the function again and supply the same fds_find_token_t structure to resume searching
|
|
||||||
* from the last record found.
|
|
||||||
*
|
|
||||||
* @param[in] type The type ID in the record key.
|
|
||||||
* @param[out] p_desc The descriptor of the record found.
|
|
||||||
* @param[out] p_token A token containing information about the progress of the operation.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. A record was found.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
|
|
||||||
* @retval NRF_ERROR_NULL Error. Either p_desc or p_token are NULL.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND Error. No record with the given type was found.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_find_by_type(fds_type_id_t type,
|
|
||||||
fds_record_desc_t * const p_desc,
|
|
||||||
fds_find_token_t * const p_token);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to search for records with a given instance.
|
|
||||||
*
|
|
||||||
* @details Because types are not unique, to search for the next record with the given key call
|
|
||||||
* the function again and supply the same fds_find_token_t structure to resume searching
|
|
||||||
* from the last record found.
|
|
||||||
*
|
|
||||||
* @param[in] instance The instance ID in the record key.
|
|
||||||
* @param[out] p_desc The descriptor of the record found.
|
|
||||||
* @param[out] p_token A token containing information about the progress of the operation.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. A record was found.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
|
|
||||||
* @retval NRF_ERROR_NULL Error. Either p_desc or p_token are NULL.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND Error. No record with the given instance was found.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_find_by_instance(fds_instance_id_t instance,
|
|
||||||
fds_record_desc_t * const p_desc,
|
|
||||||
fds_find_token_t * const p_token);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to open a record for reading.
|
|
||||||
*
|
|
||||||
* @details Function to read a record which has been written to flash. This function initializes
|
|
||||||
* a fds_record_t structure which can be used to access the record data as well as
|
|
||||||
* its associated metadata. The pointers provided in the fds_record_t structure are
|
|
||||||
* pointers to flash memory. Opening a record with @ref fds_open prevents the garbage
|
|
||||||
* collection to run on the flash page in which record is stored, therefore the contents
|
|
||||||
* of the memory pointed by the fds_record_t p_data field is guaranteed to remain
|
|
||||||
* unmodified, as long as the record is kept open.
|
|
||||||
*
|
|
||||||
* @note When you are done reading a record, close it using @ref fds_close so that successive
|
|
||||||
* garbage collections can reclaim space on the page where the record is stored, if necessary.
|
|
||||||
*
|
|
||||||
* @param[in] p_desc The descriptor of the record to open.
|
|
||||||
* @param[out] p_record The record data and metadata, as stored in flash.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. The record was opened.
|
|
||||||
* @retval NRF_ERROR_NOT_FOUND Error. The record was not found. It may have been cleared, or it
|
|
||||||
* may have not been written yet.
|
|
||||||
* @retval NRF_ERROR_INVALID_DATA Error. The descriptor contains invalid data.
|
|
||||||
* @retval NRF_ERROR_NULL Error. Either p_desc or p_record are NULL.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_open(fds_record_desc_t * const p_desc,
|
|
||||||
fds_record_t * const p_record);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to close a record, after its contents have been read.
|
|
||||||
*
|
|
||||||
* @details Closing a record allows garbage collection to be run on the page in which the
|
|
||||||
* record being closed is stored (if no other records remain open on that page).
|
|
||||||
*
|
|
||||||
* @note Closing a record, does NOT invalidate its descriptor, which can be safely supplied to
|
|
||||||
* all functions which accept a descriptor as a parameter.
|
|
||||||
*
|
|
||||||
* @param[in] p_desc The descriptor of the record to close.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. The record was closed.
|
|
||||||
* @retval NRF_ERROR_NULL Error. p_desc is NULL.
|
|
||||||
* @retval NRF_ERROR_INVALID_DATA Error. The descriptor contains invalid data.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_close(fds_record_desc_t const * const p_desc);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to perform a garbage collection.
|
|
||||||
*
|
|
||||||
* @details Garbage collection reclaims the flash space occupied by records which have been cleared
|
|
||||||
* using @ref fds_clear.
|
|
||||||
*
|
|
||||||
* @note This function is asynchronous, therefore, completion is reported with a callback
|
|
||||||
* through the registered event handler.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_gc(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to compare two record descriptors.
|
|
||||||
*
|
|
||||||
* @param[in] p_desc_one First descriptor.
|
|
||||||
* @param[in] p_desc_two Second descriptor.
|
|
||||||
*
|
|
||||||
* @retval true If the descriptors identify the same record.
|
|
||||||
* @retval false Otherwise.
|
|
||||||
*/
|
|
||||||
bool fds_descriptor_match(fds_record_desc_t const * const p_desc_one,
|
|
||||||
fds_record_desc_t const * const p_desc_two);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to obtain a descriptor from a record ID.
|
|
||||||
*
|
|
||||||
* @details This function can be used to reconstruct a descriptor from a record ID, such as the
|
|
||||||
* one passed to the callback function.
|
|
||||||
*
|
|
||||||
* @warning This function does not check if a record with the given record ID exists or not. If a
|
|
||||||
* non-existing record ID is supplied, the resulting descriptor will cause other functions
|
|
||||||
* to fail when used as parameter.
|
|
||||||
*
|
|
||||||
* @param[out] p_desc The descriptor of the record with given record ID.
|
|
||||||
* @param[in] record_id The record ID for which to provide a descriptor.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success.
|
|
||||||
* @retval NRF_ERROR_NULL Error. p_desc is NULL.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_descriptor_from_rec_id(fds_record_desc_t * const p_desc,
|
|
||||||
fds_record_id_t record_id);
|
|
||||||
|
|
||||||
/**@brief Function to obtain a record ID from a record descriptor.
|
|
||||||
*
|
|
||||||
* @details This function can be used to extract a record ID from a descriptor. It may be used
|
|
||||||
* in the callback function to determine which record the callback is associated to, if
|
|
||||||
* you have its descriptor.
|
|
||||||
*
|
|
||||||
* @warning This function does not check the record descriptor sanity. If the descriptor is
|
|
||||||
* uninitialized, or has been tampered with, the resulting record ID may be invalid.
|
|
||||||
*
|
|
||||||
* @param[in] p_desc The descriptor from which to extract the record ID.
|
|
||||||
* @param[out] p_record_id The record ID contained in the given descriptor.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success.
|
|
||||||
* @retval NRF_ERROR_NULL Error. Either p_desc is NULL or p_record_id is NULL.
|
|
||||||
*/
|
|
||||||
ret_code_t fds_record_id_from_desc(fds_record_desc_t const * const p_desc,
|
|
||||||
fds_record_id_t * const p_record_id);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif // FDS_H__
|
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FDS_CONFIG_H__
|
|
||||||
#define FDS_CONFIG_H__
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file fds_config.h
|
|
||||||
*
|
|
||||||
* @addtogroup flash_data_storage
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**@brief Configures the size of the internal queue. */
|
|
||||||
#define FDS_CMD_QUEUE_SIZE (8)
|
|
||||||
/**@brief Determines how many @ref fds_record_chunk_t structures can be buffered at any time. */
|
|
||||||
#define FDS_CHUNK_QUEUE_SIZE (8)
|
|
||||||
|
|
||||||
/**@brief Configures the number of physical flash pages to use. Out of the total, one is reserved
|
|
||||||
* for garbage collection, hence, two pages is the minimum: one for the application data
|
|
||||||
* and one for the system. */
|
|
||||||
#define FDS_MAX_PAGES (2)
|
|
||||||
/**@brief Configures the maximum number of callbacks which can be registred. */
|
|
||||||
#define FDS_MAX_USERS (10)
|
|
||||||
|
|
||||||
/** Page tag definitions. */
|
|
||||||
#define FDS_PAGE_TAG_WORD_0_SWAP (0xA5A5A5A5)
|
|
||||||
#define FDS_PAGE_TAG_WORD_0_VALID (0xA4A4A4A4)
|
|
||||||
#define FDS_PAGE_TAG_WORD_1 (0xAABBCCDD)
|
|
||||||
#define FDS_PAGE_TAG_WORD_2 (0xAABB01DD) /**< Includes version. */
|
|
||||||
#define FDS_PAGE_TAG_WORD_3 (0x1CEB00DA)
|
|
||||||
#define FDS_PAGE_TAG_WORD_3_GC (0x1CEB00D8)
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif // FDS_CONFIG_H__
|
|
|
@ -1,178 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FDS_TYPES_INTERNAL__
|
|
||||||
#define FDS_TYPES_INTERNAL__
|
|
||||||
|
|
||||||
#include "fds.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "nrf_soc.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define COMMAND_EXECUTING (NRF_SUCCESS)
|
|
||||||
#define COMMAND_COMPLETED (0x1234)
|
|
||||||
//#define COMMAND_FAILED (0x1236)
|
|
||||||
|
|
||||||
#define FDS_MAGIC_HWORD (0xF11E)
|
|
||||||
#define FDS_MAGIC_WORD (0x15ABE11A)
|
|
||||||
#define FDS_ERASED_WORD (0xFFFFFFFF)
|
|
||||||
|
|
||||||
#define FDS_PAGE_TAG_SIZE (4) /**< Page tag size, in 4 byte words. */
|
|
||||||
|
|
||||||
#define FDS_VPAGE_ID_UNKNOWN (0xFFFF)
|
|
||||||
|
|
||||||
#define FDS_WRITE_OFFSET_TL (0) /**< Offset of TL from the record base address, in 4 byte words. */
|
|
||||||
#define FDS_WRITE_OFFSET_IC (1) /**< Offset of IC from the record base address, in 4 byte words. */
|
|
||||||
#define FDS_WRITE_OFFSET_ID (2) /**< Offset of ID from the record base address, in 4 byte words. */
|
|
||||||
#define FDS_WRITE_OFFSET_DATA (3) /**< Offset of the data (chunks) from the record base address, in 4 byte words. */
|
|
||||||
|
|
||||||
#define FDS_HEADER_SIZE_TL (1) /**< Size of the TL part of the header, in 4 byte words. */
|
|
||||||
#define FDS_HEADER_SIZE_ID (1) /**< Size of the IC part of the header, in 4 byte words. */
|
|
||||||
#define FDS_HEADER_SIZE_IC (1) /**< Size of the IC part of the header, in 4 byte words. */
|
|
||||||
#define FDS_HEADER_SIZE (3) /**< Size of the whole header, in 4 byte words. */
|
|
||||||
|
|
||||||
#define FDS_CMD_QUEUE_SIZE_INIT (1)
|
|
||||||
#define FDS_CMD_QUEUE_SIZE_WRITE (1)
|
|
||||||
#define FDS_CMD_QUEUE_SIZE_CLEAR (1)
|
|
||||||
#define FDS_CMD_QUEUE_SIZE_UPDATE (2)
|
|
||||||
#define FDS_CMD_QUEUE_SIZE_GC (1)
|
|
||||||
|
|
||||||
|
|
||||||
//static uint8_t m_nested_critical;
|
|
||||||
|
|
||||||
/** Macros to enable and disable application interrupts. */
|
|
||||||
#define CRITICAL_SECTION_ENTER() //sd_nvic_critical_region_enter(&m_nested_critical)
|
|
||||||
#define CRITICAL_SECTION_EXIT() //sd_nvic_critical_region_exit ( m_nested_critical)
|
|
||||||
|
|
||||||
/**@brief Page types. */
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
FDS_PAGE_UNDEFINED, /**< Undefined page type. */
|
|
||||||
FDS_PAGE_ERASED, /**< Page is erased. */
|
|
||||||
FDS_PAGE_VALID, /**< Page is ready for storage. */
|
|
||||||
FDS_PAGE_SWAP, /**< Page is reserved for GC. */
|
|
||||||
FDS_PAGE_GC /**< Page is being garbage collected. */
|
|
||||||
} fds_page_type_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
FDS_OP_NONE = 0x00, /**< No operation. */
|
|
||||||
FDS_OP_WRITE_TL, /**< Write the type and length. */
|
|
||||||
FDS_OP_WRITE_ID, /**< Write the record ID. */
|
|
||||||
FDS_OP_WRITE_CHUNK, /**< Write the record value. */
|
|
||||||
FDS_OP_WRITE_IC, /**< Write the instance and checksum. */
|
|
||||||
FDS_OP_CLEAR_TL,
|
|
||||||
FDS_OP_CLEAR_INSTANCE,
|
|
||||||
FDS_OP_DONE,
|
|
||||||
} fds_opcode_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
FDS_FLAG_INITIALIZING = (1 << 0), /**< TODO: Not really needed atm? */
|
|
||||||
FDS_FLAG_INITIALIZED = (1 << 1), /**< Flag indicating that flash data storage has been initialized. */
|
|
||||||
FDS_FLAG_PROCESSING = (1 << 2), /**< Flag indicating that queue is being processed. */
|
|
||||||
FDS_FLAG_CAN_GC = (1 << 3), /**< Flag indicating that fds can regain data by performing garbage collection. */
|
|
||||||
} fds_flags_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t const * start_addr;
|
|
||||||
uint16_t vpage_id; /**< The page logical ID. */
|
|
||||||
uint16_t volatile write_offset; /**< The page write offset, in 4 bytes words. */
|
|
||||||
uint16_t volatile words_reserved; /**< The amount of words reserved by fds_write_reserve() on this page. */
|
|
||||||
uint16_t volatile records_open;
|
|
||||||
fds_page_type_t page_type : 4; /**< The page type. */
|
|
||||||
} fds_page_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
fds_cmd_id_t id : 4; /**< The ID of the command. */
|
|
||||||
fds_opcode_t op_code : 4;
|
|
||||||
uint8_t num_chunks; /**< Number of operations this command has left in the operation queue. */
|
|
||||||
uint16_t chunk_offset; /**< Offset used for writing the record value(s), in 4 byte words. */
|
|
||||||
uint16_t vpage_id; /**< The virtual page ID where we reserved the flash space for this command. */
|
|
||||||
fds_record_header_t record_header;
|
|
||||||
} fds_cmd_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Defines command queue, an element is free if the op_code field is not invalid.
|
|
||||||
*
|
|
||||||
* @details Defines commands enqueued for flash access. At any point in time, this queue has one or
|
|
||||||
* more flash access operations pending if the count field is not zero. When the queue is
|
|
||||||
* not empty, the rp (read pointer) field points to the flash access command in progress
|
|
||||||
* or, if none is in progress, the command to be requested next. The queue implements a
|
|
||||||
* simple first in first out algorithm. Data addresses are assumed to be resident.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
fds_cmd_t cmd[FDS_CMD_QUEUE_SIZE]; /**< Array to maintain flash access operation details. */
|
|
||||||
uint8_t volatile rp; /**< The index of the command being executed. */
|
|
||||||
uint8_t volatile count; /**< Number of elements in the queue. */
|
|
||||||
} fds_cmd_queue_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
fds_record_chunk_t chunk[FDS_CHUNK_QUEUE_SIZE];
|
|
||||||
uint8_t volatile rp;
|
|
||||||
uint8_t volatile count;
|
|
||||||
} fds_chunk_queue_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
NONE,
|
|
||||||
BEGIN,
|
|
||||||
RESUME,
|
|
||||||
GC_PAGE,
|
|
||||||
COPY_RECORD,
|
|
||||||
READY_SWAP,
|
|
||||||
NEW_SWAP,
|
|
||||||
INIT_SWAP
|
|
||||||
} fds_gc_state_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t cur_page;
|
|
||||||
uint16_t swap_page;
|
|
||||||
uint32_t const * p_scan_addr;
|
|
||||||
fds_gc_state_t state;
|
|
||||||
bool do_gc_page[FDS_MAX_PAGES];
|
|
||||||
} fds_gc_data_t;
|
|
||||||
|
|
||||||
#endif // FDS_TYPES_INTERNAL__
|
|
|
@ -1,569 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "fstorage.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "fstorage_config.h"
|
|
||||||
#include "nrf_error.h"
|
|
||||||
#include "nrf_soc.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define FS_FLAG_INIT (1 << 0) /**< fstorage has been initialized. */
|
|
||||||
#define FS_FLAG_PROCESSING (1 << 1) /**< fstorage is executing queued flash operations. */
|
|
||||||
#define FS_FLAG_FLASH_REQ_PENDING (1 << 2) /**< fstorage is waiting for a flash operation initiated by another module to complete. */
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro invocation that registers section fs_data.
|
|
||||||
*
|
|
||||||
* @details Required for compilation.
|
|
||||||
*/
|
|
||||||
NRF_SECTION_VARS_REGISTER_SECTION(fs_data);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro invocation that declares symbols used to find the beginning and end of the section fs_data.
|
|
||||||
*
|
|
||||||
* @details Required for compilation.
|
|
||||||
*/
|
|
||||||
NRF_SECTION_VARS_REGISTER_SYMBOLS(fs_config_t, fs_data);
|
|
||||||
|
|
||||||
|
|
||||||
/**@defgroup Section vars helper macros.
|
|
||||||
*
|
|
||||||
* @details Macros used to manipulate registered section variables.
|
|
||||||
*/
|
|
||||||
/**@brief Get section variable with fstorage configuration by index. */
|
|
||||||
#define FS_SECTION_VARS_GET(i) NRF_SECTION_VARS_GET(i, fs_config_t, fs_data)
|
|
||||||
/**@brief Get the number of registered section variables. */
|
|
||||||
#define FS_SECTION_VARS_COUNT NRF_SECTION_VARS_COUNT(fs_config_t, fs_data)
|
|
||||||
/**@brief Get the start address of the registered section variables. */
|
|
||||||
#define FS_SECTION_VARS_START_ADDR NRF_SECTION_VARS_START_ADDR(fs_data)
|
|
||||||
/**@brief Get the end address of the registered section variables. */
|
|
||||||
#define FS_SECTION_VARS_END_ADDR NRF_SECTION_VARS_END_ADDR(fs_data)
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief The command queue element.
|
|
||||||
*
|
|
||||||
* @details Encapsulate details of a command requested to this module.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
fs_config_t const * p_config; /**< The configuration of the user who requested the operation. */
|
|
||||||
uint8_t op_code; /**< Operation code. */
|
|
||||||
uint32_t const * p_src; /**< Pointer to the data to be written to flash. The data must be kept in memory until the operation has finished. */
|
|
||||||
uint32_t const * p_addr; /**< Destination of the data in flash. */
|
|
||||||
fs_length_t length_words; /**< Length of the operation */
|
|
||||||
fs_length_t offset; /**< Offset of the operation if operation is done in chunks */
|
|
||||||
} fs_cmd_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Structure that defines the command queue
|
|
||||||
*
|
|
||||||
* @details This queue holds flash operations requested to the module.
|
|
||||||
* The data to be written must be kept in memory until the write operation is completed,
|
|
||||||
* i.e., a callback indicating completion is received by the application.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t rp; /**< The current element being processed. */
|
|
||||||
uint8_t count; /**< Number of elements in the queue. */
|
|
||||||
fs_cmd_t cmd[FS_CMD_QUEUE_SIZE]; /**< Array to maintain flash access operation details. */
|
|
||||||
} fs_cmd_queue_t;
|
|
||||||
|
|
||||||
|
|
||||||
static uint8_t m_flags; /**< FStorage status flags. */
|
|
||||||
static fs_cmd_queue_t m_cmd_queue; /**< Flash operation request queue. */
|
|
||||||
static uint16_t m_retry_count = 0; /**< Number of times a single flash operation was retried. */
|
|
||||||
|
|
||||||
|
|
||||||
// Function prototypes
|
|
||||||
static ret_code_t queue_process(void);
|
|
||||||
static ret_code_t queue_process_impl(void);
|
|
||||||
static void app_notify(uint32_t result, fs_cmd_t const * p_cmd);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro to check that the configuration is non-NULL and within
|
|
||||||
* valid section variable memory bounds.
|
|
||||||
*
|
|
||||||
* @param[in] config Configuration to check.
|
|
||||||
*/
|
|
||||||
#define FS_CHECK_CONFIG(config) \
|
|
||||||
((FS_SECTION_VARS_START_ADDR < config) && (config < FS_SECTION_VARS_END_ADDR))
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to check that the configuration is non-NULL and within
|
|
||||||
* valid section variable memory bounds.
|
|
||||||
*
|
|
||||||
* @param[in] config Configuration to check.
|
|
||||||
*/
|
|
||||||
static bool check_config(fs_config_t const * const config)
|
|
||||||
{
|
|
||||||
if (config == NULL)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((FS_SECTION_VARS_START_ADDR <= (uint32_t)config) && ((uint32_t)config < FS_SECTION_VARS_END_ADDR))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to initialize the queue. */
|
|
||||||
static void queue_init(void)
|
|
||||||
{
|
|
||||||
memset(&m_cmd_queue, 0, sizeof(fs_cmd_queue_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to reset a queue item to its default values.
|
|
||||||
*
|
|
||||||
* @param index Index of the queue element.
|
|
||||||
*/
|
|
||||||
static void cmd_reset(uint32_t index)
|
|
||||||
{
|
|
||||||
memset(&m_cmd_queue.cmd[index], 0, sizeof(fs_cmd_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to enqueue flash access command
|
|
||||||
*
|
|
||||||
* @param[in] config Registered configuration.
|
|
||||||
* @param[in] op_code Operation code.
|
|
||||||
* @param[in] address Destination of the data.
|
|
||||||
* @param[in] p_src Source of data or NULL if n/a.
|
|
||||||
* @param[in] length Length of the data, in 4 byte words.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. Command enqueued.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Error. Queue is full.
|
|
||||||
* @retval Any error returned by the SoftDevice flash API.
|
|
||||||
*/
|
|
||||||
static ret_code_t cmd_enqueue(fs_config_t const * p_config,
|
|
||||||
uint8_t op_code,
|
|
||||||
uint32_t const * p_addr,
|
|
||||||
uint32_t const * p_src,
|
|
||||||
fs_length_t length_words)
|
|
||||||
{
|
|
||||||
fs_cmd_t * p_cmd;
|
|
||||||
uint8_t write_pos;
|
|
||||||
|
|
||||||
if (m_cmd_queue.count == FS_CMD_QUEUE_SIZE - 1)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
write_pos = (m_cmd_queue.rp + m_cmd_queue.count) % FS_CMD_QUEUE_SIZE;
|
|
||||||
|
|
||||||
p_cmd = &m_cmd_queue.cmd[write_pos];
|
|
||||||
|
|
||||||
p_cmd->p_config = p_config;
|
|
||||||
p_cmd->op_code = op_code;
|
|
||||||
p_cmd->p_src = p_src;
|
|
||||||
p_cmd->p_addr = p_addr;
|
|
||||||
p_cmd->length_words = length_words;
|
|
||||||
|
|
||||||
m_cmd_queue.count++;
|
|
||||||
|
|
||||||
return queue_process();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to consume queue item and notify the return value of the operation.
|
|
||||||
*
|
|
||||||
* @details This function will report the result and remove the command from the queue after
|
|
||||||
* notification.
|
|
||||||
*/
|
|
||||||
static void cmd_consume(uint32_t result, const fs_cmd_t * p_cmd)
|
|
||||||
{
|
|
||||||
// Consume the current item on the queue.
|
|
||||||
uint8_t rp = m_cmd_queue.rp;
|
|
||||||
|
|
||||||
m_cmd_queue.count--;
|
|
||||||
if (m_cmd_queue.count == 0)
|
|
||||||
{
|
|
||||||
// There are no elements left. Stop processing the queue.
|
|
||||||
m_flags &= ~FS_FLAG_PROCESSING;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (++(m_cmd_queue.rp) == FS_CMD_QUEUE_SIZE)
|
|
||||||
{
|
|
||||||
m_cmd_queue.rp = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify upon successful operation.
|
|
||||||
app_notify(result, p_cmd);
|
|
||||||
|
|
||||||
// Reset the queue element.
|
|
||||||
cmd_reset(rp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to store data to flash.
|
|
||||||
*
|
|
||||||
* @param[in] p_cmd The queue element associated with the operation.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. The request was sent to the SoftDevice.
|
|
||||||
* @retval Any error returned by the SoftDevice flash API.
|
|
||||||
*/
|
|
||||||
static __INLINE uint32_t store_execute(fs_cmd_t const * const p_cmd)
|
|
||||||
{
|
|
||||||
// Write in chunks if write-size is larger than FS_MAX_WRITE_SIZE.
|
|
||||||
fs_length_t const length = ((p_cmd->length_words - p_cmd->offset) < FS_MAX_WRITE_SIZE_WORDS) ?
|
|
||||||
(p_cmd->length_words - p_cmd->offset) : FS_MAX_WRITE_SIZE_WORDS;
|
|
||||||
|
|
||||||
return sd_flash_write((uint32_t*)p_cmd->p_addr + p_cmd->offset /* destination */,
|
|
||||||
(uint32_t*)p_cmd->p_src + p_cmd->offset /* source */,
|
|
||||||
length);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to erase a page.
|
|
||||||
*
|
|
||||||
* @param[in] p_cmd The queue element associated with the operation.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. The request was sent to the SoftDevice.
|
|
||||||
* @retval Any error returned by the SoftDevice flash API.
|
|
||||||
*/
|
|
||||||
static __INLINE uint32_t erase_execute(fs_cmd_t const * const p_cmd)
|
|
||||||
{
|
|
||||||
// Erase the page.
|
|
||||||
return sd_flash_page_erase((uint32_t)(p_cmd->p_addr + p_cmd->offset) / FS_PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to process the current element in the queue and return the result.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success.
|
|
||||||
* @retval NRF_ERROR_FORBIDDEN Error. Undefined command.
|
|
||||||
* @retval Any error returned by the SoftDevice flash API.
|
|
||||||
*/
|
|
||||||
static uint32_t queue_process_impl(void)
|
|
||||||
{
|
|
||||||
uint32_t ret;
|
|
||||||
|
|
||||||
fs_cmd_t const * const p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp];
|
|
||||||
|
|
||||||
switch (p_cmd->op_code)
|
|
||||||
{
|
|
||||||
case FS_OP_STORE:
|
|
||||||
ret = store_execute(p_cmd);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FS_OP_ERASE:
|
|
||||||
ret = erase_execute(p_cmd);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FS_OP_NONE:
|
|
||||||
ret = NRF_SUCCESS;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ret = NRF_ERROR_FORBIDDEN;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Starts processing the queue if there are no pending flash operations
|
|
||||||
* for which we are awaiting a callback.
|
|
||||||
*/
|
|
||||||
static ret_code_t queue_process(void)
|
|
||||||
{
|
|
||||||
ret_code_t ret = NRF_SUCCESS;
|
|
||||||
|
|
||||||
/** If the queue is not being processed, and there are still
|
|
||||||
* some elements in it, then start processing. */
|
|
||||||
if ( !(m_flags & FS_FLAG_PROCESSING) &&
|
|
||||||
(m_cmd_queue.count > 0))
|
|
||||||
{
|
|
||||||
m_flags |= FS_FLAG_PROCESSING;
|
|
||||||
|
|
||||||
ret = queue_process_impl();
|
|
||||||
|
|
||||||
/** There is ongoing flash-operation which was not
|
|
||||||
* initiated by fstorage. */
|
|
||||||
if (ret == NRF_ERROR_BUSY)
|
|
||||||
{
|
|
||||||
// Wait for a system callback.
|
|
||||||
m_flags |= FS_FLAG_FLASH_REQ_PENDING;
|
|
||||||
|
|
||||||
// Stop processing the queue.
|
|
||||||
m_flags &= ~FS_FLAG_PROCESSING;
|
|
||||||
|
|
||||||
ret = NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
else if (ret != NRF_SUCCESS)
|
|
||||||
{
|
|
||||||
// Another error has occurred.
|
|
||||||
app_notify(ret, &m_cmd_queue.cmd[m_cmd_queue.rp]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we are already processing the queue, return immediately.
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Flash operation success callback handler.
|
|
||||||
*
|
|
||||||
* @details This function updates read/write pointers.
|
|
||||||
* This function resets retry count.
|
|
||||||
*/
|
|
||||||
static __INLINE void on_operation_success(void)
|
|
||||||
{
|
|
||||||
fs_cmd_t * const p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp];
|
|
||||||
|
|
||||||
m_retry_count = 0;
|
|
||||||
|
|
||||||
switch (p_cmd->op_code)
|
|
||||||
{
|
|
||||||
case FS_OP_STORE:
|
|
||||||
// Update the offset on successful write.
|
|
||||||
p_cmd->offset += FS_MAX_WRITE_SIZE_WORDS;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FS_OP_ERASE:
|
|
||||||
// Update the offset to correspond to the page that has been erased.
|
|
||||||
p_cmd->offset += FS_PAGE_SIZE_WORDS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If offset is equal to or larger than length, then the operation has finished.
|
|
||||||
if (p_cmd->offset >= p_cmd->length_words)
|
|
||||||
{
|
|
||||||
cmd_consume(NRF_SUCCESS, p_cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
queue_process();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Flash operation failure callback handler.
|
|
||||||
*
|
|
||||||
* @details Function to keep track of retries and notify failures.
|
|
||||||
*/
|
|
||||||
static __INLINE void on_operation_failure(uint32_t sys_evt)
|
|
||||||
{
|
|
||||||
const fs_cmd_t * p_cmd;
|
|
||||||
|
|
||||||
if (++m_retry_count > FS_CMD_MAX_RETRIES)
|
|
||||||
{
|
|
||||||
p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp];
|
|
||||||
cmd_consume(NRF_ERROR_TIMEOUT, p_cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
queue_process();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to notify users.
|
|
||||||
*
|
|
||||||
* @param[in] result Result of the flash operation.
|
|
||||||
* @param[in] p_cmd The command associated with the callback.
|
|
||||||
*/
|
|
||||||
static void app_notify(uint32_t result, fs_cmd_t const * const p_cmd)
|
|
||||||
{
|
|
||||||
p_cmd->p_config->cb(p_cmd->op_code, result, p_cmd->p_addr, p_cmd->length_words);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t fs_init(void)
|
|
||||||
{
|
|
||||||
uint16_t lowest_index = 0;
|
|
||||||
uint16_t lowest_order = 0xFFFF;
|
|
||||||
uint32_t * current_end = (uint32_t*)FS_PAGE_END_ADDR;
|
|
||||||
uint32_t num_left = FS_SECTION_VARS_COUNT;
|
|
||||||
|
|
||||||
queue_init();
|
|
||||||
|
|
||||||
/** Assign pages to registered users, beginning with the ones with the lowest
|
|
||||||
* order, which will be assigned pages with the lowest memory address. */
|
|
||||||
do
|
|
||||||
{
|
|
||||||
fs_config_t * p_config;
|
|
||||||
for (uint16_t i = 0; i < FS_SECTION_VARS_COUNT; i++)
|
|
||||||
{
|
|
||||||
p_config = FS_SECTION_VARS_GET(i);
|
|
||||||
|
|
||||||
// Skip the ones which have the end-address already set.
|
|
||||||
if (p_config->p_end_addr != NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (p_config->page_order < lowest_order)
|
|
||||||
{
|
|
||||||
lowest_order = p_config->page_order;
|
|
||||||
lowest_index = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p_config = FS_SECTION_VARS_GET(lowest_index);
|
|
||||||
|
|
||||||
p_config->p_end_addr = current_end;
|
|
||||||
p_config->p_start_addr = p_config->p_end_addr - (p_config->num_pages * FS_PAGE_SIZE_WORDS);
|
|
||||||
|
|
||||||
current_end = p_config->p_start_addr;
|
|
||||||
lowest_order = 0xFFFF;
|
|
||||||
|
|
||||||
} while ( --num_left > 0 );
|
|
||||||
|
|
||||||
m_flags |= FS_FLAG_INIT;
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t fs_store(fs_config_t const * p_config,
|
|
||||||
uint32_t const * p_addr,
|
|
||||||
uint32_t const * const p_data,
|
|
||||||
fs_length_t length_words)
|
|
||||||
{
|
|
||||||
if ((m_flags & FS_FLAG_INIT) == 0)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!check_config(p_config))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_FORBIDDEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_word_aligned(p_addr))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_ADDR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the erase operation is on pages owned by this user (configuration).
|
|
||||||
if ((p_addr < p_config->p_start_addr) || ((p_addr + length_words) > p_config->p_end_addr))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_ADDR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cmd_enqueue(p_config, FS_OP_STORE, p_addr, p_data, length_words);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ret_code_t fs_erase(fs_config_t const * p_config,
|
|
||||||
uint32_t * const p_addr,
|
|
||||||
fs_length_t const length_words)
|
|
||||||
{
|
|
||||||
if ((m_flags & FS_FLAG_INIT) == 0)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!check_config(p_config))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_FORBIDDEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Check that the address is aligned on a page boundary and the length to erase
|
|
||||||
* is a multiple of the page size. */
|
|
||||||
if (((uint32_t)p_addr & (FS_PAGE_SIZE - 1)) ||
|
|
||||||
(length_words & (FS_PAGE_SIZE_WORDS - 1)))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_ADDR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the erase operation is on pages owned by this user (configuration).
|
|
||||||
if ((p_addr < p_config->p_start_addr) || ((p_addr + length_words) > p_config->p_end_addr))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_ADDR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cmd_enqueue(p_config, FS_OP_ERASE, p_addr, NULL, length_words);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to handle system events from the SoftDevice.
|
|
||||||
*
|
|
||||||
* @details This function should be dispatched system events if any of the modules used by
|
|
||||||
* the application rely on FStorage. Examples include @ref Peer Manager and
|
|
||||||
* @ref Flash Data Storage.
|
|
||||||
*
|
|
||||||
* @param[in] sys_evt System Event received.
|
|
||||||
*/
|
|
||||||
void fs_sys_event_handler(uint32_t sys_evt)
|
|
||||||
{
|
|
||||||
if (m_flags & FS_FLAG_PROCESSING)
|
|
||||||
{
|
|
||||||
/** A flash operation was initiated by this module.
|
|
||||||
* Handle its result. */
|
|
||||||
switch (sys_evt)
|
|
||||||
{
|
|
||||||
case NRF_EVT_FLASH_OPERATION_SUCCESS:
|
|
||||||
on_operation_success();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NRF_EVT_FLASH_OPERATION_ERROR:
|
|
||||||
on_operation_failure(sys_evt);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ((m_flags & FS_FLAG_FLASH_REQ_PENDING))
|
|
||||||
{
|
|
||||||
/** A flash operation was initiated outside this module.
|
|
||||||
* We have now receveid a callback which indicates it has
|
|
||||||
* finished. Clear the FS_FLAG_FLASH_REQ_PENDING flag. */
|
|
||||||
m_flags &= ~FS_FLAG_FLASH_REQ_PENDING;
|
|
||||||
|
|
||||||
// Resume processing the queue, if necessary.
|
|
||||||
queue_process();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Just for testing out section vars (across many compilers).
|
|
||||||
void fs_debug_print()
|
|
||||||
{
|
|
||||||
printf("fs start address: 0x%08lx\r\n", (unsigned long)FS_SECTION_VARS_START_ADDR);
|
|
||||||
printf("fs end address: 0x%08lx\r\n", (unsigned long)FS_SECTION_VARS_END_ADDR);
|
|
||||||
printf("Num items: 0x%08lx\r\n", (unsigned long)FS_SECTION_VARS_COUNT);
|
|
||||||
printf("===== ITEMS %lu =====\r\n", (unsigned long)FS_SECTION_VARS_COUNT);
|
|
||||||
|
|
||||||
for(uint32_t i = 0; i < FS_SECTION_VARS_COUNT; i++)
|
|
||||||
{
|
|
||||||
fs_config_t* config = FS_SECTION_VARS_GET(i);
|
|
||||||
printf( "Address: 0x%08lx, CB: 0x%08lx\r\n",
|
|
||||||
(unsigned long)config, (unsigned long)config->cb );
|
|
||||||
}
|
|
||||||
printf("\r\n");
|
|
||||||
}
|
|
|
@ -1,159 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef FS_H__
|
|
||||||
#define FS_H__
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
*
|
|
||||||
* @defgroup fstorage FStorage
|
|
||||||
* @{
|
|
||||||
* @ingroup app_common
|
|
||||||
* @brief Module which provides low level functionality to store data to flash.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "section_vars.h"
|
|
||||||
#include "fstorage_config.h"
|
|
||||||
#include "sdk_errors.h"
|
|
||||||
|
|
||||||
|
|
||||||
typedef uint16_t fs_length_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
FS_OP_NONE = 0,
|
|
||||||
FS_OP_STORE = 1,
|
|
||||||
FS_OP_ERASE = 2
|
|
||||||
} fs_oper_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Callback for flash operations.
|
|
||||||
*
|
|
||||||
* @param[in] op_code Flash access operation code.
|
|
||||||
* @param[in] result Result of the operation.
|
|
||||||
* @param[in] data Pointer to resulting data (or NULL if not in use).
|
|
||||||
* @param[in] length_words Length of data in words.
|
|
||||||
*/
|
|
||||||
typedef void (*fs_cb_t)(uint8_t op_code,
|
|
||||||
uint32_t result,
|
|
||||||
uint32_t const * p_data,
|
|
||||||
fs_length_t length_words);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Flash storage config variable.
|
|
||||||
*
|
|
||||||
* @details The fstorage module will update the start_addr and end_address according to
|
|
||||||
* ordering rules and the number of pages requested by the fstorage module user.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
const fs_cb_t cb; /**< Callback to run when flash operation has completed. */
|
|
||||||
const uint8_t num_pages; /**< The number of pages to reserve for flash storage. */
|
|
||||||
const uint8_t page_order; /**< The order used to allocate pages. */
|
|
||||||
uint32_t * p_start_addr; /**< Pointer to the start address of the allocated flash storage. Set by running @ref fs_init. */
|
|
||||||
uint32_t * p_end_addr; /**< Pointer to the end address of the allcoated flash storage. Set by running @ref fs_init. */
|
|
||||||
} fs_config_t;
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for registering of flash storage configuration variable.
|
|
||||||
*
|
|
||||||
* @details This macro is expected to be invoked in the code unit that that require
|
|
||||||
* flash storage. Invoking this places the registered configuration variable
|
|
||||||
* in a section named "fs_data" that the fstorage module uses during initialization
|
|
||||||
* and regular operation.
|
|
||||||
*/
|
|
||||||
#define FS_SECTION_VARS_ADD(type_def) NRF_SECTION_VARS_ADD(fs_data, type_def)
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to initialize FStorage.
|
|
||||||
*
|
|
||||||
* @details This function allocates flash data pages according to the
|
|
||||||
* number requested in the config variable. The data used to initialize.
|
|
||||||
* the fstorage is section placed variables in the data section "fs_data".
|
|
||||||
*/
|
|
||||||
ret_code_t fs_init(void);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to store data in flash.
|
|
||||||
*
|
|
||||||
* @warning The data to be written to flash has to be kept in memory until the operation has
|
|
||||||
* terminated, i.e., a callback is received.
|
|
||||||
*
|
|
||||||
* @param[in] p_config Const pointer to configiguration of module user that requests a store operation.
|
|
||||||
* @param[in] p_addr Write address of store operation.
|
|
||||||
* @param[in] p_data Pointer to the data to store.
|
|
||||||
* @param[in] length_words Length of the data to store.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. Command queued.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR Error. Data is unaligned or invalid configuration.
|
|
||||||
* @retval Any error returned by the SoftDevice flash API.
|
|
||||||
*/
|
|
||||||
ret_code_t fs_store(fs_config_t const * p_config,
|
|
||||||
uint32_t const * p_addr,
|
|
||||||
uint32_t const * const p_data,
|
|
||||||
fs_length_t length_words);
|
|
||||||
|
|
||||||
|
|
||||||
/** Function to erase a page in flash.
|
|
||||||
*
|
|
||||||
* @note The erase address must be aligned on a page boundary. The length in words must be
|
|
||||||
* equivalent to the page size.
|
|
||||||
*
|
|
||||||
* @param[in] p_config Pointer to the configuration of the user that requests the operation.
|
|
||||||
* @param[in] p_addr Address of page to erase (the same as first word in the page).
|
|
||||||
* @param[in] length_words Length (in 4 byte words) of the area to erase.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Success. Command queued.
|
|
||||||
* @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR Error. Data is unaligned or invalid configuration.
|
|
||||||
* @retval Any error returned by the SoftDevice flash API.
|
|
||||||
*/
|
|
||||||
ret_code_t fs_erase(fs_config_t const * p_config,
|
|
||||||
uint32_t * const p_addr,
|
|
||||||
fs_length_t length_words);
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function to call to handle events from the SoftDevice
|
|
||||||
*
|
|
||||||
* @param sys_evt System event from the SoftDevice
|
|
||||||
*/
|
|
||||||
void fs_sys_event_handler(uint32_t sys_evt);
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif // FS_H__
|
|
|
@ -1,113 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef FS_CONFIG_H__
|
|
||||||
#define FS_CONFIG_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "nrf.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup fstorage_config FStorage configuration
|
|
||||||
* @ingroup fstorage
|
|
||||||
* @{
|
|
||||||
* @brief FStorage configuration.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for max number of operations in the fs cmd queue.
|
|
||||||
*/
|
|
||||||
#define FS_CMD_QUEUE_SIZE (8)
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for max number of retries for a flash command before it notifies as failed.
|
|
||||||
*/
|
|
||||||
#define FS_CMD_MAX_RETRIES (3)
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for the content of a flash address that has not been written to.
|
|
||||||
*/
|
|
||||||
#define FS_EMPTY_MASK (0xFFFFFFFF)
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for flash page size according to chip family
|
|
||||||
*/
|
|
||||||
#if defined (NRF51)
|
|
||||||
#define FS_PAGE_SIZE (1024)
|
|
||||||
#elif defined (NRF52)
|
|
||||||
#define FS_PAGE_SIZE (4096)
|
|
||||||
#else
|
|
||||||
#error "Device family must be defined. See nrf.h."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*@brief Macro for flash page size according to chip family
|
|
||||||
*/
|
|
||||||
#define FS_PAGE_SIZE_WORDS (FS_PAGE_SIZE/4)
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Static inline function that provides last page address
|
|
||||||
*
|
|
||||||
* @note If there is a bootloader present the bootloader address read from UICR
|
|
||||||
* will act as the page beyond the end of the available flash storage
|
|
||||||
*/
|
|
||||||
static __INLINE uint32_t fs_flash_page_end_addr()
|
|
||||||
{
|
|
||||||
uint32_t const bootloader_addr = NRF_UICR->NRFFW[0];
|
|
||||||
return ((bootloader_addr != FS_EMPTY_MASK) ?
|
|
||||||
bootloader_addr : NRF_FICR->CODESIZE * FS_PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro for last page address
|
|
||||||
*
|
|
||||||
* @note If there is a bootloader present the bootloader address read from UICR
|
|
||||||
* will act as the page beyond the end of the available flash storage
|
|
||||||
*/
|
|
||||||
#define FS_PAGE_END_ADDR fs_flash_page_end_addr()
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Macro to describe the write
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#if defined (NRF51)
|
|
||||||
#define FS_MAX_WRITE_SIZE_WORDS (256)
|
|
||||||
#elif defined (NRF52)
|
|
||||||
#define FS_MAX_WRITE_SIZE_WORDS (1024)
|
|
||||||
#else
|
|
||||||
#error "Device family must be defined. see nrf.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#endif // FS_CONFIG_H__
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
|
@ -1,255 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "hci_mem_pool.h"
|
|
||||||
#include "hci_mem_pool_internal.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
/**@brief RX buffer element instance structure.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint8_t rx_buffer[RX_BUF_SIZE]; /**< RX buffer memory array. */
|
|
||||||
uint32_t length; /**< Length of the RX buffer memory array. */
|
|
||||||
} rx_buffer_elem_t;
|
|
||||||
|
|
||||||
/**@brief RX buffer queue element instance structure.
|
|
||||||
*/
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
rx_buffer_elem_t * p_buffer; /**< Pointer to RX buffer element. */
|
|
||||||
uint32_t free_window_count; /**< Free space element count. */
|
|
||||||
uint32_t free_available_count; /**< Free area element count. */
|
|
||||||
uint32_t read_available_count; /**< Read area element count. */
|
|
||||||
uint32_t write_index; /**< Write position index. */
|
|
||||||
uint32_t read_index; /**< Read position index. */
|
|
||||||
uint32_t free_index; /**< Free position index. */
|
|
||||||
} rx_buffer_queue_t;
|
|
||||||
|
|
||||||
static bool m_is_tx_allocated; /**< Boolean value to determine if the TX buffer is allocated. */
|
|
||||||
static rx_buffer_elem_t m_rx_buffer_elem_queue[RX_BUF_QUEUE_SIZE]; /**< RX buffer element instances. */
|
|
||||||
static rx_buffer_queue_t m_rx_buffer_queue; /**< RX buffer queue element instance. */
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t hci_mem_pool_open(void)
|
|
||||||
{
|
|
||||||
m_is_tx_allocated = false;
|
|
||||||
m_rx_buffer_queue.p_buffer = m_rx_buffer_elem_queue;
|
|
||||||
m_rx_buffer_queue.free_window_count = RX_BUF_QUEUE_SIZE;
|
|
||||||
m_rx_buffer_queue.free_available_count = 0;
|
|
||||||
m_rx_buffer_queue.read_available_count = 0;
|
|
||||||
m_rx_buffer_queue.write_index = 0;
|
|
||||||
m_rx_buffer_queue.read_index = 0;
|
|
||||||
m_rx_buffer_queue.free_index = 0;
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t hci_mem_pool_close(void)
|
|
||||||
{
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer)
|
|
||||||
{
|
|
||||||
static uint8_t tx_buffer[TX_BUF_SIZE];
|
|
||||||
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
if (pp_buffer == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_is_tx_allocated)
|
|
||||||
{
|
|
||||||
m_is_tx_allocated = true;
|
|
||||||
*pp_buffer = tx_buffer;
|
|
||||||
err_code = NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err_code = NRF_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t hci_mem_pool_tx_free(void)
|
|
||||||
{
|
|
||||||
m_is_tx_allocated = false;
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
if (pp_buffer == NULL)
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NULL;
|
|
||||||
}
|
|
||||||
*pp_buffer = NULL;
|
|
||||||
|
|
||||||
if (m_rx_buffer_queue.free_window_count != 0)
|
|
||||||
{
|
|
||||||
if (length <= RX_BUF_SIZE)
|
|
||||||
{
|
|
||||||
--(m_rx_buffer_queue.free_window_count);
|
|
||||||
++(m_rx_buffer_queue.read_available_count);
|
|
||||||
|
|
||||||
*pp_buffer =
|
|
||||||
m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.write_index].rx_buffer;
|
|
||||||
|
|
||||||
m_rx_buffer_queue.free_index |= (1u << m_rx_buffer_queue.write_index);
|
|
||||||
|
|
||||||
// @note: Adjust the write_index making use of the fact that the buffer size is of
|
|
||||||
// power of two and two's complement arithmetic. For details refer example to book
|
|
||||||
// "Making embedded systems: Elicia White".
|
|
||||||
m_rx_buffer_queue.write_index =
|
|
||||||
(m_rx_buffer_queue.write_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
|
|
||||||
|
|
||||||
err_code = NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err_code = NRF_ERROR_DATA_SIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err_code = NRF_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
uint32_t consume_index;
|
|
||||||
uint32_t start_index;
|
|
||||||
|
|
||||||
if (m_rx_buffer_queue.free_available_count != 0)
|
|
||||||
{
|
|
||||||
// Find the buffer that has been freed -
|
|
||||||
// Start at read_index minus free_available_count and then increment until read index.
|
|
||||||
err_code = NRF_ERROR_INVALID_ADDR;
|
|
||||||
consume_index = (m_rx_buffer_queue.read_index - m_rx_buffer_queue.free_available_count) &
|
|
||||||
(RX_BUF_QUEUE_SIZE - 1u);
|
|
||||||
start_index = consume_index;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (m_rx_buffer_queue.p_buffer[consume_index].rx_buffer == p_buffer)
|
|
||||||
{
|
|
||||||
m_rx_buffer_queue.free_index ^= (1u << consume_index);
|
|
||||||
err_code = NRF_SUCCESS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
consume_index = (consume_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (consume_index != m_rx_buffer_queue.read_index);
|
|
||||||
|
|
||||||
while (!(m_rx_buffer_queue.free_index & (1 << start_index)) &&
|
|
||||||
(m_rx_buffer_queue.free_available_count != 0))
|
|
||||||
{
|
|
||||||
--(m_rx_buffer_queue.free_available_count);
|
|
||||||
++(m_rx_buffer_queue.free_window_count);
|
|
||||||
start_index = (consume_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err_code = NRF_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t hci_mem_pool_rx_data_size_set(uint32_t length)
|
|
||||||
{
|
|
||||||
// @note: Adjust the write_index making use of the fact that the buffer size is of power
|
|
||||||
// of two and two's complement arithmetic. For details refer example to book
|
|
||||||
// "Making embedded systems: Elicia White".
|
|
||||||
const uint32_t index = (m_rx_buffer_queue.write_index - 1u) & (RX_BUF_QUEUE_SIZE - 1u);
|
|
||||||
m_rx_buffer_queue.p_buffer[index].length = length;
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t hci_mem_pool_rx_extract(uint8_t ** pp_buffer, uint32_t * p_length)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
if ((pp_buffer == NULL) || (p_length == NULL))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_rx_buffer_queue.read_available_count != 0)
|
|
||||||
{
|
|
||||||
--(m_rx_buffer_queue.read_available_count);
|
|
||||||
++(m_rx_buffer_queue.free_available_count);
|
|
||||||
|
|
||||||
*pp_buffer =
|
|
||||||
m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].rx_buffer;
|
|
||||||
*p_length =
|
|
||||||
m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].length;
|
|
||||||
|
|
||||||
// @note: Adjust the write_index making use of the fact that the buffer size is of power
|
|
||||||
// of two and two's complement arithmetic. For details refer example to book
|
|
||||||
// "Making embedded systems: Elicia White".
|
|
||||||
m_rx_buffer_queue.read_index =
|
|
||||||
(m_rx_buffer_queue.read_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u);
|
|
||||||
|
|
||||||
err_code = NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err_code = NRF_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err_code;
|
|
||||||
}
|
|
|
@ -1,152 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
*
|
|
||||||
* @defgroup memory_pool Memory pool
|
|
||||||
* @{
|
|
||||||
* @ingroup app_common
|
|
||||||
*
|
|
||||||
* @brief Memory pool implementation
|
|
||||||
*
|
|
||||||
* Memory pool implementation, based on circular buffer data structure, which supports asynchronous
|
|
||||||
* processing of RX data. The current default implementation supports 1 TX buffer and 4 RX buffers.
|
|
||||||
* The memory managed by the pool is allocated from static storage instead of heap. The internal
|
|
||||||
* design of the circular buffer implementing the RX memory layout is illustrated in the picture
|
|
||||||
* below.
|
|
||||||
*
|
|
||||||
* @image html memory_pool.png "Circular buffer design"
|
|
||||||
*
|
|
||||||
* The expected call order for the RX APIs is as follows:
|
|
||||||
* - hci_mem_pool_rx_produce
|
|
||||||
* - hci_mem_pool_rx_data_size_set
|
|
||||||
* - hci_mem_pool_rx_extract
|
|
||||||
* - hci_mem_pool_rx_consume
|
|
||||||
*
|
|
||||||
* @warning If the above mentioned expected call order is violated the end result can be undefined.
|
|
||||||
*
|
|
||||||
* \par Component specific configuration options
|
|
||||||
*
|
|
||||||
* The following compile time configuration options are available to suit various implementations:
|
|
||||||
* - TX_BUF_SIZE TX buffer size in bytes.
|
|
||||||
* - RX_BUF_SIZE RX buffer size in bytes.
|
|
||||||
* - RX_BUF_QUEUE_SIZE RX buffer element size.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef HCI_MEM_POOL_H__
|
|
||||||
#define HCI_MEM_POOL_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "nrf_error.h"
|
|
||||||
|
|
||||||
/**@brief Function for opening the module.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
*/
|
|
||||||
uint32_t hci_mem_pool_open(void);
|
|
||||||
|
|
||||||
/**@brief Function for closing the module.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
*/
|
|
||||||
uint32_t hci_mem_pool_close(void);
|
|
||||||
|
|
||||||
/**@brief Function for allocating requested amount of TX memory.
|
|
||||||
*
|
|
||||||
* @param[out] pp_buffer Pointer to the allocated memory.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success. Memory was allocated.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Operation failure. No memory available for allocation.
|
|
||||||
* @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
|
|
||||||
*/
|
|
||||||
uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer);
|
|
||||||
|
|
||||||
/**@brief Function for freeing previously allocated TX memory.
|
|
||||||
*
|
|
||||||
* @note Memory management follows the FIFO principle meaning that free() order must match the
|
|
||||||
* alloc(...) order, which is the reason for omitting exact memory block identifier as an
|
|
||||||
* input parameter.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success. Memory was freed.
|
|
||||||
*/
|
|
||||||
uint32_t hci_mem_pool_tx_free(void);
|
|
||||||
|
|
||||||
/**@brief Function for producing a free RX memory block for usage.
|
|
||||||
*
|
|
||||||
* @note Upon produce request amount being 0, NRF_SUCCESS is returned.
|
|
||||||
*
|
|
||||||
* @param[in] length Amount, in bytes, of free memory to be produced.
|
|
||||||
* @param[out] pp_buffer Pointer to the allocated memory.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success. Free RX memory block produced.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Operation failure. No suitable memory available for allocation.
|
|
||||||
* @retval NRF_ERROR_DATA_SIZE Operation failure. Request size exceeds limit.
|
|
||||||
* @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
|
|
||||||
*/
|
|
||||||
uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer);
|
|
||||||
|
|
||||||
/**@brief Function for setting the length of the last produced RX memory block.
|
|
||||||
*
|
|
||||||
* @warning If call to this API is omitted the end result is that the following call to
|
|
||||||
* mem_pool_rx_extract will return incorrect data in the p_length output parameter.
|
|
||||||
*
|
|
||||||
* @param[in] length Amount, in bytes, of actual memory used.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success. Length was set.
|
|
||||||
*/
|
|
||||||
uint32_t hci_mem_pool_rx_data_size_set(uint32_t length);
|
|
||||||
|
|
||||||
/**@brief Function for extracting a packet, which has been filled with read data, for further
|
|
||||||
* processing.
|
|
||||||
*
|
|
||||||
* @param[out] pp_buffer Pointer to the packet data.
|
|
||||||
* @param[out] p_length Length of packet data in bytes.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Operation failure. No packet available to extract.
|
|
||||||
* @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
|
|
||||||
*/
|
|
||||||
uint32_t hci_mem_pool_rx_extract(uint8_t ** pp_buffer, uint32_t * p_length);
|
|
||||||
|
|
||||||
/**@brief Function for freeing previously extracted packet, which has been filled with read data.
|
|
||||||
*
|
|
||||||
* @param[in] p_buffer Pointer to consumed buffer.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Operation success.
|
|
||||||
* @retval NRF_ERROR_NO_MEM Operation failure. No packet available to free.
|
|
||||||
* @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer.
|
|
||||||
*/
|
|
||||||
uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer);
|
|
||||||
|
|
||||||
#endif // HCI_MEM_POOL_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -1,212 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "app_scheduler.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "nrf_soc.h"
|
|
||||||
#include "nrf_assert.h"
|
|
||||||
#include "app_util.h"
|
|
||||||
#include "app_util_platform.h"
|
|
||||||
|
|
||||||
/**@brief Structure for holding a scheduled event header. */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
app_sched_event_handler_t handler; /**< Pointer to event handler to receive the event. */
|
|
||||||
uint16_t event_data_size; /**< Size of event data. */
|
|
||||||
} event_header_t;
|
|
||||||
|
|
||||||
STATIC_ASSERT(sizeof(event_header_t) <= APP_SCHED_EVENT_HEADER_SIZE);
|
|
||||||
|
|
||||||
static event_header_t * m_queue_event_headers; /**< Array for holding the queue event headers. */
|
|
||||||
static uint8_t * m_queue_event_data; /**< Array for holding the queue event data. */
|
|
||||||
static volatile uint8_t m_queue_start_index; /**< Index of queue entry at the start of the queue. */
|
|
||||||
static volatile uint8_t m_queue_end_index; /**< Index of queue entry at the end of the queue. */
|
|
||||||
static uint16_t m_queue_event_size; /**< Maximum event size in queue. */
|
|
||||||
static uint16_t m_queue_size; /**< Number of queue entries. */
|
|
||||||
|
|
||||||
/**@brief Function for incrementing a queue index, and handle wrap-around.
|
|
||||||
*
|
|
||||||
* @param[in] index Old index.
|
|
||||||
*
|
|
||||||
* @return New (incremented) index.
|
|
||||||
*/
|
|
||||||
static __INLINE uint8_t next_index(uint8_t index)
|
|
||||||
{
|
|
||||||
return (index < m_queue_size) ? (index + 1) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static __INLINE uint8_t app_sched_queue_full()
|
|
||||||
{
|
|
||||||
uint8_t tmp = m_queue_start_index;
|
|
||||||
return next_index(m_queue_end_index) == tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Macro for checking if a queue is full. */
|
|
||||||
#define APP_SCHED_QUEUE_FULL() app_sched_queue_full()
|
|
||||||
|
|
||||||
|
|
||||||
static __INLINE uint8_t app_sched_queue_empty()
|
|
||||||
{
|
|
||||||
uint8_t tmp = m_queue_start_index;
|
|
||||||
return m_queue_end_index == tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**@brief Macro for checking if a queue is empty. */
|
|
||||||
#define APP_SCHED_QUEUE_EMPTY() app_sched_queue_empty()
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t app_sched_init(uint16_t event_size, uint16_t queue_size, void * p_event_buffer)
|
|
||||||
{
|
|
||||||
uint16_t data_start_index = (queue_size + 1) * sizeof(event_header_t);
|
|
||||||
|
|
||||||
// Check that buffer is correctly aligned
|
|
||||||
if (!is_word_aligned(p_event_buffer))
|
|
||||||
{
|
|
||||||
return NRF_ERROR_INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize event scheduler
|
|
||||||
m_queue_event_headers = p_event_buffer;
|
|
||||||
m_queue_event_data = &((uint8_t *)p_event_buffer)[data_start_index];
|
|
||||||
m_queue_end_index = 0;
|
|
||||||
m_queue_start_index = 0;
|
|
||||||
m_queue_event_size = event_size;
|
|
||||||
m_queue_size = queue_size;
|
|
||||||
|
|
||||||
return NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t app_sched_event_put(void * p_event_data,
|
|
||||||
uint16_t event_data_size,
|
|
||||||
app_sched_event_handler_t handler)
|
|
||||||
{
|
|
||||||
uint32_t err_code;
|
|
||||||
|
|
||||||
if (event_data_size <= m_queue_event_size)
|
|
||||||
{
|
|
||||||
uint16_t event_index = 0xFFFF;
|
|
||||||
|
|
||||||
CRITICAL_REGION_ENTER();
|
|
||||||
|
|
||||||
if (!APP_SCHED_QUEUE_FULL())
|
|
||||||
{
|
|
||||||
event_index = m_queue_end_index;
|
|
||||||
m_queue_end_index = next_index(m_queue_end_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
CRITICAL_REGION_EXIT();
|
|
||||||
|
|
||||||
if (event_index != 0xFFFF)
|
|
||||||
{
|
|
||||||
// NOTE: This can be done outside the critical region since the event consumer will
|
|
||||||
// always be called from the main loop, and will thus never interrupt this code.
|
|
||||||
m_queue_event_headers[event_index].handler = handler;
|
|
||||||
if ((p_event_data != NULL) && (event_data_size > 0))
|
|
||||||
{
|
|
||||||
memcpy(&m_queue_event_data[event_index * m_queue_event_size],
|
|
||||||
p_event_data,
|
|
||||||
event_data_size);
|
|
||||||
m_queue_event_headers[event_index].event_data_size = event_data_size;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_queue_event_headers[event_index].event_data_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
err_code = NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err_code = NRF_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
err_code = NRF_ERROR_INVALID_LENGTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**@brief Function for reading the next event from specified event queue.
|
|
||||||
*
|
|
||||||
* @param[out] pp_event_data Pointer to pointer to event data.
|
|
||||||
* @param[out] p_event_data_size Pointer to size of event data.
|
|
||||||
* @param[out] p_event_handler Pointer to event handler function pointer.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS if new event, NRF_ERROR_NOT_FOUND if event queue is empty.
|
|
||||||
*/
|
|
||||||
static uint32_t app_sched_event_get(void ** pp_event_data,
|
|
||||||
uint16_t * p_event_data_size,
|
|
||||||
app_sched_event_handler_t * p_event_handler)
|
|
||||||
{
|
|
||||||
uint32_t err_code = NRF_ERROR_NOT_FOUND;
|
|
||||||
|
|
||||||
if (!APP_SCHED_QUEUE_EMPTY())
|
|
||||||
{
|
|
||||||
uint16_t event_index;
|
|
||||||
|
|
||||||
// NOTE: There is no need for a critical region here, as this function will only be called
|
|
||||||
// from app_sched_execute() from inside the main loop, so it will never interrupt
|
|
||||||
// app_sched_event_put(). Also, updating of (i.e. writing to) the start index will be
|
|
||||||
// an atomic operation.
|
|
||||||
event_index = m_queue_start_index;
|
|
||||||
m_queue_start_index = next_index(m_queue_start_index);
|
|
||||||
|
|
||||||
*pp_event_data = &m_queue_event_data[event_index * m_queue_event_size];
|
|
||||||
*p_event_data_size = m_queue_event_headers[event_index].event_data_size;
|
|
||||||
*p_event_handler = m_queue_event_headers[event_index].handler;
|
|
||||||
|
|
||||||
err_code = NRF_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void app_sched_execute(void)
|
|
||||||
{
|
|
||||||
void * p_event_data;
|
|
||||||
uint16_t event_data_size;
|
|
||||||
app_sched_event_handler_t event_handler;
|
|
||||||
|
|
||||||
// Get next event (if any), and execute handler
|
|
||||||
while ((app_sched_event_get(&p_event_data, &event_data_size, &event_handler) == NRF_SUCCESS))
|
|
||||||
{
|
|
||||||
event_handler(p_event_data, event_data_size);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,173 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) Nordic Semiconductor ASA
|
|
||||||
* 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 Nordic Semiconductor ASA nor the names of other
|
|
||||||
* contributors to this software 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file
|
|
||||||
*
|
|
||||||
* @defgroup app_scheduler Scheduler
|
|
||||||
* @{
|
|
||||||
* @ingroup app_common
|
|
||||||
*
|
|
||||||
* @brief The scheduler is used for transferring execution from the interrupt context to the main
|
|
||||||
* context.
|
|
||||||
*
|
|
||||||
* @details See @ref seq_diagrams_sched for sequence diagrams illustrating the flow of events
|
|
||||||
* when using the Scheduler.
|
|
||||||
*
|
|
||||||
* @section app_scheduler_req Requirements:
|
|
||||||
*
|
|
||||||
* @subsection main_context_logic Logic in main context:
|
|
||||||
*
|
|
||||||
* - Define an event handler for each type of event expected.
|
|
||||||
* - Initialize the scheduler by calling the APP_SCHED_INIT() macro before entering the
|
|
||||||
* application main loop.
|
|
||||||
* - Call app_sched_execute() from the main loop each time the application wakes up because of an
|
|
||||||
* event (typically when sd_app_evt_wait() returns).
|
|
||||||
*
|
|
||||||
* @subsection int_context_logic Logic in interrupt context:
|
|
||||||
*
|
|
||||||
* - In the interrupt handler, call app_sched_event_put()
|
|
||||||
* with the appropriate data and event handler. This will insert an event into the
|
|
||||||
* scheduler's queue. The app_sched_execute() function will pull this event and call its
|
|
||||||
* handler in the main context.
|
|
||||||
*
|
|
||||||
* @if (PERIPHERAL)
|
|
||||||
* For an example usage of the scheduler, see the implementations of
|
|
||||||
* @ref ble_sdk_app_hids_mouse and @ref ble_sdk_app_hids_keyboard.
|
|
||||||
* @endif
|
|
||||||
*
|
|
||||||
* @image html scheduler_working.jpg The high level design of the scheduler
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef APP_SCHEDULER_H__
|
|
||||||
#define APP_SCHEDULER_H__
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "app_error.h"
|
|
||||||
#include "app_util.h"
|
|
||||||
|
|
||||||
#define APP_SCHED_EVENT_HEADER_SIZE 8 /**< Size of app_scheduler.event_header_t (only for use inside APP_SCHED_BUF_SIZE()). */
|
|
||||||
|
|
||||||
/**@brief Compute number of bytes required to hold the scheduler buffer.
|
|
||||||
*
|
|
||||||
* @param[in] EVENT_SIZE Maximum size of events to be passed through the scheduler.
|
|
||||||
* @param[in] QUEUE_SIZE Number of entries in scheduler queue (i.e. the maximum number of events
|
|
||||||
* that can be scheduled for execution).
|
|
||||||
*
|
|
||||||
* @return Required scheduler buffer size (in bytes).
|
|
||||||
*/
|
|
||||||
#define APP_SCHED_BUF_SIZE(EVENT_SIZE, QUEUE_SIZE) \
|
|
||||||
(((EVENT_SIZE) + APP_SCHED_EVENT_HEADER_SIZE) * ((QUEUE_SIZE) + 1))
|
|
||||||
|
|
||||||
/**@brief Scheduler event handler type. */
|
|
||||||
typedef void (*app_sched_event_handler_t)(void * p_event_data, uint16_t event_size);
|
|
||||||
|
|
||||||
/**@brief Macro for initializing the event scheduler.
|
|
||||||
*
|
|
||||||
* @details It will also handle dimensioning and allocation of the memory buffer required by the
|
|
||||||
* scheduler, making sure the buffer is correctly aligned.
|
|
||||||
*
|
|
||||||
* @param[in] EVENT_SIZE Maximum size of events to be passed through the scheduler.
|
|
||||||
* @param[in] QUEUE_SIZE Number of entries in scheduler queue (i.e. the maximum number of events
|
|
||||||
* that can be scheduled for execution).
|
|
||||||
*
|
|
||||||
* @note Since this macro allocates a buffer, it must only be called once (it is OK to call it
|
|
||||||
* several times as long as it is from the same location, e.g. to do a reinitialization).
|
|
||||||
*/
|
|
||||||
#define APP_SCHED_INIT(EVENT_SIZE, QUEUE_SIZE) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
static uint32_t APP_SCHED_BUF[CEIL_DIV(APP_SCHED_BUF_SIZE((EVENT_SIZE), (QUEUE_SIZE)), \
|
|
||||||
sizeof(uint32_t))]; \
|
|
||||||
uint32_t ERR_CODE = app_sched_init((EVENT_SIZE), (QUEUE_SIZE), APP_SCHED_BUF); \
|
|
||||||
APP_ERROR_CHECK(ERR_CODE); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/**@brief Function for initializing the Scheduler.
|
|
||||||
*
|
|
||||||
* @details It must be called before entering the main loop.
|
|
||||||
*
|
|
||||||
* @param[in] max_event_size Maximum size of events to be passed through the scheduler.
|
|
||||||
* @param[in] queue_size Number of entries in scheduler queue (i.e. the maximum number of
|
|
||||||
* events that can be scheduled for execution).
|
|
||||||
* @param[in] p_evt_buffer Pointer to memory buffer for holding the scheduler queue. It must
|
|
||||||
* be dimensioned using the APP_SCHED_BUFFER_SIZE() macro. The buffer
|
|
||||||
* must be aligned to a 4 byte boundary.
|
|
||||||
*
|
|
||||||
* @note Normally initialization should be done using the APP_SCHED_INIT() macro, as that will both
|
|
||||||
* allocate the scheduler buffer, and also align the buffer correctly.
|
|
||||||
*
|
|
||||||
* @retval NRF_SUCCESS Successful initialization.
|
|
||||||
* @retval NRF_ERROR_INVALID_PARAM Invalid parameter (buffer not aligned to a 4 byte
|
|
||||||
* boundary).
|
|
||||||
*/
|
|
||||||
uint32_t app_sched_init(uint16_t max_event_size, uint16_t queue_size, void * p_evt_buffer);
|
|
||||||
|
|
||||||
/**@brief Function for executing all scheduled events.
|
|
||||||
*
|
|
||||||
* @details This function must be called from within the main loop. It will execute all events
|
|
||||||
* scheduled since the last time it was called.
|
|
||||||
*/
|
|
||||||
void app_sched_execute(void);
|
|
||||||
|
|
||||||
/**@brief Function for scheduling an event.
|
|
||||||
*
|
|
||||||
* @details Puts an event into the event queue.
|
|
||||||
*
|
|
||||||
* @param[in] p_event_data Pointer to event data to be scheduled.
|
|
||||||
* @param[in] event_size Size of event data to be scheduled.
|
|
||||||
* @param[in] handler Event handler to receive the event.
|
|
||||||
*
|
|
||||||
* @return NRF_SUCCESS on success, otherwise an error code.
|
|
||||||
*/
|
|
||||||
uint32_t app_sched_event_put(void * p_event_data,
|
|
||||||
uint16_t event_size,
|
|
||||||
app_sched_event_handler_t handler);
|
|
||||||
|
|
||||||
#ifdef APP_SCHEDULER_WITH_PAUSE
|
|
||||||
/**@brief A function to pause the scheduler.
|
|
||||||
*
|
|
||||||
* @details When the scheduler is paused events are not pulled from the scheduler queue for
|
|
||||||
* processing. The function can be called multiple times. To unblock the scheduler the
|
|
||||||
* function @ref app_sched_resume has to be called the same number of times.
|
|
||||||
*/
|
|
||||||
void app_sched_pause(void);
|
|
||||||
|
|
||||||
/**@brief A function to resume a scheduler.
|
|
||||||
*
|
|
||||||
* @details To unblock the scheduler this function has to be called the same number of times as
|
|
||||||
* @ref app_sched_pause function.
|
|
||||||
*/
|
|
||||||
void app_sched_resume(void);
|
|
||||||
#endif
|
|
||||||
#endif // APP_SCHEDULER_H__
|
|
||||||
|
|
||||||
/** @} */
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue