├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── DOXYGEN_FRONTPAGE.md ├── LICENSE ├── README.md ├── apache-2.0.txt ├── ble.doxyfile ├── ble ├── BLE.h ├── BLEInstanceBase.h ├── BLEProtocol.h ├── CallChainOfFunctionPointersWithContext.h ├── CharacteristicDescriptorDiscovery.h ├── DiscoveredCharacteristic.h ├── DiscoveredCharacteristicDescriptor.h ├── DiscoveredService.h ├── FunctionPointerWithContext.h ├── Gap.h ├── GapAdvertisingData.h ├── GapAdvertisingParams.h ├── GapEvents.h ├── GapScanningParams.h ├── GattAttribute.h ├── GattCallbackParamTypes.h ├── GattCharacteristic.h ├── GattClient.h ├── GattServer.h ├── GattServerEvents.h ├── GattService.h ├── SafeBool.h ├── SecurityManager.h ├── ServiceDiscovery.h ├── UUID.h ├── blecommon.h ├── deprecate.h └── services │ ├── BatteryService.h │ ├── DFUService.h │ ├── DeviceInformationService.h │ ├── EddystoneConfigService.h │ ├── EddystoneService.h │ ├── EnvironmentalService.h │ ├── HealthThermometerService.h │ ├── HeartRateService.h │ ├── LinkLossService.h │ ├── UARTService.h │ ├── URIBeaconConfigService.h │ └── iBeacon.h ├── module.json └── source ├── BLE.cpp ├── BLEInstanceBase.cpp ├── DiscoveredCharacteristic.cpp ├── GapScanningParams.cpp └── services ├── DFUService.cpp ├── UARTService.cpp └── URIBeaconConfigService.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore the generated Doxygen output 2 | apidoc/ 3 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Hello! 2 | We are an open source project of [ARM mbed](https://www.mbed.com). Contributions via [pull request](https://github.com/ARMmbed/ble/pulls), and [bug reports](https://github.com/ARMmbed/ble/issues) are welcome! 3 | 4 | Please submit your pull request to the `develop` branch of [this module](https://github.com/ARMmbed/ble/tree/develop). Commits to develop will be merge into the master branch at the time of the next release. 5 | 6 | # Contributor agreement 7 | For your pull request to be accepted, we will need you to agree to our [contributor agreement](https://developer.mbed.org/contributor_agreement/) to give us the necessary rights to use and distribute your contributions. (To click through the agreement create an account on mbed.com and log in.) 8 | -------------------------------------------------------------------------------- /DOXYGEN_FRONTPAGE.md: -------------------------------------------------------------------------------- 1 | # BLE API {#mainpage} 2 | 3 | The BLE module within mbed OS offers a high abstraction level for using 4 | Bluetooth Low Energy on multiple platforms. 5 | 6 | This documentation describes the internal structure of the mbed 7 | [BLE API](https://github.com/armmbed/ble). 8 | 9 | For getting started with BLE on mbed, check our [introduction 10 | page](https://docs.mbed.com/docs/ble-intros/en/latest/). 11 | 12 | For mbed OS examples using BLE, check [this 13 | repository](https://github.com/armmbed/ble-examples). For mbed-classic 14 | examples, please refer to [code under mbed.org](https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/). 15 | 16 | ## Supported Services 17 | 18 | Currently supported reference services include: 19 | 20 | * [Battery](@ref BatteryService) 21 | * [Device Firmware Update (DFU)](@ref DFUService) 22 | * [Device Information](@ref DeviceInformationService) 23 | * [Health Thermometer](@ref HealthThermometerService) 24 | * [Heart Rate](@ref HeartRateService) 25 | * [UART](@ref UARTService) 26 | * [UriBeacon](@ref URIBeaconConfigService) 27 | * [iBeacon](@ref iBeacon) 28 | 29 | The [documentation](https://docs.mbed.com/docs/ble-intros/en/latest/AdvSamples/Overview/) 30 | contains an overview on how to create new, application-specific services. 31 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Unless specifically indicated otherwise in a file, files are licensed 2 | under the Apache 2.0 license, as can be found in: apache-2.0.txt 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mbed Bluetooth Low Energy Stack 2 | This is the Github repo for the `BLE_API` used by developer.mbed.org. Please see the [mbed BLE Homepage](https://developer.mbed.org/teams/Bluetooth-Low-Energy/) for all documentation, code examples and general help. 3 | 4 | # Supported Services 5 | Supported GATT services and constantly being added and can be found in the [ble/services/](https://github.com/ARMmbed/ble/tree/master/ble/services) folder. 6 | 7 | Currently supported services include: 8 | * Battery 9 | * Device Firmware Update (DFU) 10 | * Device Information 11 | * Eddystone Configuration Service 12 | * Health Thermometer 13 | * Heart Rate 14 | * Link Loss 15 | * UART 16 | * UriBeacon 17 | * iBeacon 18 | 19 | The [documentation](https://docs.mbed.com/docs/ble-intros/en/latest/AdvSamples/Overview/) 20 | contains an overview on how to create new, application-specific services. 21 | 22 | # Getting Started 23 | The mbed BLE API is meant to be used in projects on developer.mbed.org. Please see examples and sample project files there. 24 | A good starting point are these pages: 25 | * [mbed BLE Homepage](https://developer.mbed.org/teams/Bluetooth-Low-Energy/) for all things BLE 26 | * [mbed BLE Getting Started Guide](https://developer.mbed.org/forum/team-63-Bluetooth-Low-Energy-community/topic/5262/) a wonderful primer on using BLE with mbed 27 | * [mbed BLE doc](https://docs.mbed.com/docs/ble-intros/en/latest/) for an introduction to mbed BLE 28 | * [mbed BLE API page](https://docs.mbed.com/docs/ble-api/en/latest/api/index.html) for the Doxygen API documentation 29 | -------------------------------------------------------------------------------- /apache-2.0.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 ARM Limited 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /ble/BLEInstanceBase.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __BLE_DEVICE_INSTANCE_BASE__ 18 | #define __BLE_DEVICE_INSTANCE_BASE__ 19 | 20 | #include "Gap.h" 21 | #include "ble/SecurityManager.h" 22 | #include "ble/BLE.h" 23 | 24 | /* Forward declarations. */ 25 | class GattServer; 26 | class GattClient; 27 | 28 | /** 29 | * The interface for the transport object to be created by the target library's 30 | * createBLEInstance(). 31 | * 32 | * @note This class is part of the interface of BLE API with the implementation; 33 | * therefore, it is meant to be used only by porters rather than normal 34 | * BLE API users. 35 | */ 36 | class BLEInstanceBase 37 | { 38 | public: 39 | BLEInstanceBase() {} 40 | 41 | /** 42 | * Virtual destructor of the interface. 43 | */ 44 | virtual ~BLEInstanceBase(); 45 | 46 | /** 47 | * Initialize the underlying BLE stack. This should be called before 48 | * anything else in the BLE API. 49 | * 50 | * @param[in] instanceID 51 | * The ID of the instance to initialize. 52 | * @param[in] initCallback 53 | * A callback for when initialization completes for a BLE 54 | * instance. This is an optional parameter set to NULL when not 55 | * supplied. 56 | * 57 | * @return BLE_ERROR_NONE if the initialization procedure was started 58 | * successfully. 59 | */ 60 | virtual ble_error_t init(BLE::InstanceID_t instanceID, 61 | FunctionPointerWithContext initCallback) = 0; 62 | 63 | /** 64 | * Check whether the underlying stack has already been initialized, 65 | * possible with a call to init(). 66 | * 67 | * @return true if the initialization has completed for the underlying BLE 68 | * stack. 69 | */ 70 | virtual bool hasInitialized(void) const = 0; 71 | 72 | /** 73 | * Shutdown the underlying BLE stack. This includes purging the stack of 74 | * GATT and GAP state and clearing all state from other BLE components 75 | * such as the SecurityManager. init() must be called afterwards to 76 | * re-instantiate services and GAP state. 77 | * 78 | * @return BLE_ERROR_NONE if the underlying stack and all other services of 79 | * the BLE API were shutdown correctly. 80 | */ 81 | virtual ble_error_t shutdown(void) = 0; 82 | 83 | /** 84 | * Fetches a string representation of the underlying BLE stack's version. 85 | * 86 | * @return A pointer to the string representation of the underlying 87 | * BLE stack's version. 88 | */ 89 | virtual const char * getVersion(void) = 0; 90 | 91 | /** 92 | * Accessor to Gap. This function is used by BLE::gap(). 93 | * 94 | * @return A reference to a Gap object associated to this BLE instance. 95 | */ 96 | virtual Gap& getGap() = 0; 97 | 98 | /** 99 | * A const alternative to getGap(). 100 | * 101 | * @return A const reference to a Gap object associated to this BLE instance. 102 | */ 103 | virtual const Gap& getGap() const = 0; 104 | 105 | /** 106 | * Accessor to GattServer. This function is used by BLE::gattServer(). 107 | * 108 | * @return A reference to a GattServer object associated to this BLE instance. 109 | */ 110 | virtual GattServer& getGattServer() = 0; 111 | 112 | /** 113 | * A const alternative to getGattServer(). 114 | * 115 | * @return A const reference to a GattServer object associated to this BLE instance. 116 | */ 117 | virtual const GattServer& getGattServer() const = 0; 118 | 119 | /** 120 | * Accessors to GattClient. This function is used by BLE::gattClient(). 121 | * 122 | * @return A reference to a GattClient object associated to this BLE instance. 123 | */ 124 | virtual GattClient& getGattClient() = 0; 125 | 126 | /** 127 | * Accessors to SecurityManager. This function is used by BLE::securityManager(). 128 | * 129 | * @return A reference to a SecurityManager object associated to this BLE instance. 130 | */ 131 | virtual SecurityManager& getSecurityManager() = 0; 132 | 133 | /** 134 | * A const alternative to getSecurityManager(). 135 | * 136 | * @return A const reference to a SecurityManager object associated to this BLE instance. 137 | */ 138 | virtual const SecurityManager& getSecurityManager() const = 0; 139 | 140 | /** 141 | * Yield control to the BLE stack or to other tasks waiting for events. 142 | * refer to BLE::waitForEvent(). 143 | */ 144 | virtual void waitForEvent(void) = 0; 145 | 146 | /** 147 | * Process ALL pending events living in the BLE stack . 148 | * Return once all events have been consumed. 149 | */ 150 | virtual void processEvents() = 0; 151 | 152 | /** 153 | * This function allow the BLE stack to signal that their is work to do and 154 | * event processing should be done (BLE::processEvent()). 155 | * @param id: The ID of the BLE instance which does have events to process. 156 | */ 157 | void signalEventsToProcess(BLE::InstanceID_t id); 158 | 159 | private: 160 | // this class is not a value type. 161 | // prohibit copy construction and copy assignement 162 | BLEInstanceBase(const BLEInstanceBase&); 163 | BLEInstanceBase& operator=(const BLEInstanceBase&); 164 | }; 165 | 166 | /** 167 | * BLE uses composition to hide an interface object encapsulating the 168 | * backend transport. 169 | * 170 | * The following API is used to create the singleton interface object. An 171 | * implementation for this function must be provided by the device-specific 172 | * library, otherwise there will be a linker error. 173 | */ 174 | extern BLEInstanceBase *createBLEInstance(void); 175 | 176 | #endif // ifndef __BLE_DEVICE_INSTANCE_BASE__ 177 | -------------------------------------------------------------------------------- /ble/BLEProtocol.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __BLE_PROTOCOL_H__ 18 | #define __BLE_PROTOCOL_H__ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | /** 25 | * A common namespace for types and constants used everywhere in BLE API. 26 | */ 27 | namespace BLEProtocol { 28 | /**< 29 | * A simple container for the enumeration of address-types for Protocol addresses. 30 | * 31 | * Adding a struct to encapsulate the contained enumeration prevents 32 | * polluting the BLEProtocol namespace with the enumerated values. It also 33 | * allows type-aliases for the enumeration while retaining the enumerated 34 | * values. i.e. doing: 35 | * typedef AddressType AliasedType; 36 | * 37 | * would allow the use of AliasedType::PUBLIC in code. 38 | */ 39 | struct AddressType { 40 | /**< Address-types for Protocol addresses. */ 41 | enum Type { 42 | PUBLIC = 0, 43 | RANDOM_STATIC, 44 | RANDOM_PRIVATE_RESOLVABLE, 45 | RANDOM_PRIVATE_NON_RESOLVABLE 46 | }; 47 | }; 48 | typedef AddressType::Type AddressType_t; /**< Alias for AddressType::Type */ 49 | 50 | static const size_t ADDR_LEN = 6; /**< Length (in octets) of the BLE MAC address. */ 51 | typedef uint8_t AddressBytes_t[ADDR_LEN]; /**< 48-bit address, in LSB format. */ 52 | 53 | /** 54 | * BLE address. It contains an address-type (AddressType_t) and bytes (AddressBytes_t). 55 | */ 56 | struct Address_t { 57 | AddressType_t type; /**< The type of the BLE address. */ 58 | AddressBytes_t address; /**< The BLE address. */ 59 | 60 | /** 61 | * Construct an Address_t object with the supplied type and address. 62 | * 63 | * @param[in] typeIn 64 | * The BLE address type. 65 | * @param[in] addressIn 66 | * The BLE address. 67 | */ 68 | Address_t(AddressType_t typeIn, const AddressBytes_t& addressIn) : type(typeIn) { 69 | std::copy(addressIn, addressIn + ADDR_LEN, address); 70 | } 71 | 72 | /** 73 | * Empty constructor. 74 | */ 75 | Address_t() : type(), address() { 76 | } 77 | }; 78 | }; 79 | 80 | #endif /* __BLE_PROTOCOL_H__ */ 81 | -------------------------------------------------------------------------------- /ble/CallChainOfFunctionPointersWithContext.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef MBED_CALLCHAIN_OF_FUNCTION_POINTERS_WITH_CONTEXT_H 17 | #define MBED_CALLCHAIN_OF_FUNCTION_POINTERS_WITH_CONTEXT_H 18 | 19 | #include 20 | #include "FunctionPointerWithContext.h" 21 | #include "SafeBool.h" 22 | 23 | 24 | /** Group one or more functions in an instance of a CallChainOfFunctionPointersWithContext, then call them in 25 | * sequence using CallChainOfFunctionPointersWithContext::call(). Used mostly by the interrupt chaining code, 26 | * but can be used for other purposes. 27 | * 28 | * Example: 29 | * @code 30 | * 31 | * CallChainOfFunctionPointersWithContext chain; 32 | * 33 | * void first(void *context) { 34 | * printf("'first' function.\n"); 35 | * } 36 | * 37 | * void second(void *context) { 38 | * printf("'second' function.\n"); 39 | * } 40 | * 41 | * class Test { 42 | * public: 43 | * void f(void *context) { 44 | * printf("A::f (class member).\n"); 45 | * } 46 | * }; 47 | * 48 | * int main() { 49 | * Test test; 50 | * 51 | * chain.add(second); 52 | * chain.add_front(first); 53 | * chain.add(&test, &Test::f); 54 | * chain.call(); 55 | * } 56 | * @endcode 57 | */ 58 | template 59 | class CallChainOfFunctionPointersWithContext : public SafeBool > { 60 | public: 61 | /** 62 | * The type of each callback in the callchain. 63 | */ 64 | typedef FunctionPointerWithContext *pFunctionPointerWithContext_t; 65 | 66 | public: 67 | /** 68 | * Create an empty chain. 69 | */ 70 | CallChainOfFunctionPointersWithContext() : chainHead(NULL) { 71 | /* empty */ 72 | } 73 | 74 | virtual ~CallChainOfFunctionPointersWithContext() { 75 | clear(); 76 | } 77 | 78 | /** 79 | * Add a function at the front of the chain. 80 | * 81 | * @param[in] function 82 | * A pointer to a void function. 83 | * 84 | * @return The function object created for @p function. 85 | */ 86 | pFunctionPointerWithContext_t add(void (*function)(ContextType context)) { 87 | return common_add(new FunctionPointerWithContext(function)); 88 | } 89 | 90 | /** 91 | * Add a function at the front of the chain. 92 | * 93 | * @param[in] tptr 94 | * Pointer to the object to call the member function on. 95 | * @param[in] mptr 96 | * Pointer to the member function to be called. 97 | * 98 | * @return The function object created for @p tptr and @p mptr. 99 | */ 100 | template 101 | pFunctionPointerWithContext_t add(T *tptr, void (T::*mptr)(ContextType context)) { 102 | return common_add(new FunctionPointerWithContext(tptr, mptr)); 103 | } 104 | 105 | /** 106 | * Add a function at the front of the chain. 107 | * 108 | * @param[in] func 109 | * The FunctionPointerWithContext to add. 110 | * 111 | * @return The function object created for @p func. 112 | */ 113 | pFunctionPointerWithContext_t add(const FunctionPointerWithContext& func) { 114 | return common_add(new FunctionPointerWithContext(func)); 115 | } 116 | 117 | /** 118 | * Detach a function pointer from a callchain. 119 | * 120 | * @param[in] toDetach 121 | * FunctionPointerWithContext to detach from this callchain. 122 | * 123 | * @return true if a function pointer has been detached and false otherwise. 124 | * 125 | * @note It is safe to remove a function pointer while the chain is 126 | * traversed by call(ContextType). 127 | */ 128 | bool detach(const FunctionPointerWithContext& toDetach) { 129 | pFunctionPointerWithContext_t current = chainHead; 130 | pFunctionPointerWithContext_t previous = NULL; 131 | 132 | while (current) { 133 | if(*current == toDetach) { 134 | if(previous == NULL) { 135 | if(currentCalled == current) { 136 | currentCalled = NULL; 137 | } 138 | chainHead = current->getNext(); 139 | } else { 140 | if(currentCalled == current) { 141 | currentCalled = previous; 142 | } 143 | previous->chainAsNext(current->getNext()); 144 | } 145 | delete current; 146 | return true; 147 | } 148 | 149 | previous = current; 150 | current = current->getNext(); 151 | } 152 | 153 | return false; 154 | } 155 | 156 | /** 157 | * Clear the call chain (remove all functions in the chain). 158 | */ 159 | void clear(void) { 160 | pFunctionPointerWithContext_t fptr = chainHead; 161 | while (fptr) { 162 | pFunctionPointerWithContext_t deadPtr = fptr; 163 | fptr = deadPtr->getNext(); 164 | delete deadPtr; 165 | } 166 | 167 | chainHead = NULL; 168 | } 169 | 170 | /** 171 | * Check whether the callchain contains any callbacks. 172 | * 173 | * @return true if the callchain is not empty and false otherwise. 174 | */ 175 | bool hasCallbacksAttached(void) const { 176 | return (chainHead != NULL); 177 | } 178 | 179 | /** 180 | * Call all the functions in the chain in sequence. 181 | */ 182 | void call(ContextType context) { 183 | ((const CallChainOfFunctionPointersWithContext*) this)->call(context); 184 | } 185 | 186 | /** 187 | * Same as call() above, but const. 188 | */ 189 | void call(ContextType context) const { 190 | currentCalled = chainHead; 191 | 192 | while(currentCalled) { 193 | currentCalled->call(context); 194 | // if this was the head and the call removed the head 195 | if(currentCalled == NULL) { 196 | currentCalled = chainHead; 197 | } else { 198 | currentCalled = currentCalled->getNext(); 199 | } 200 | } 201 | } 202 | 203 | /** 204 | * Same as call(), but with function call operator. 205 | * @code 206 | * 207 | * void first(bool); 208 | * void second(bool); 209 | * 210 | * CallChainOfFunctionPointerWithContext foo; 211 | * 212 | * foo.attach(first); 213 | * foo.attach(second); 214 | * 215 | * // call the callchain like a function 216 | * foo(true); 217 | * 218 | * @endcode 219 | */ 220 | void operator()(ContextType context) const { 221 | call(context); 222 | } 223 | 224 | /** 225 | * Bool conversion operation. 226 | * 227 | * @return true if the callchain is not empty and false otherwise. 228 | */ 229 | bool toBool() const { 230 | return chainHead != NULL; 231 | } 232 | 233 | private: 234 | /** 235 | * Add a callback to the head of the callchain. 236 | * 237 | * @return A pointer to the head of the callchain. 238 | */ 239 | pFunctionPointerWithContext_t common_add(pFunctionPointerWithContext_t pf) { 240 | if (chainHead == NULL) { 241 | chainHead = pf; 242 | } else { 243 | pf->chainAsNext(chainHead); 244 | chainHead = pf; 245 | } 246 | 247 | return chainHead; 248 | } 249 | 250 | private: 251 | /** 252 | * A pointer to the first callback in the callchain or NULL if the callchain is empty. 253 | */ 254 | pFunctionPointerWithContext_t chainHead; 255 | 256 | /** 257 | * Iterator during a function call, this has to be mutable because the call function is const. 258 | * 259 | * @note Mutable is the correct behaviour here, the iterator never leaks outside the object. 260 | * so the object can still be seen as logically const even if it is modified. 261 | */ 262 | mutable pFunctionPointerWithContext_t currentCalled; 263 | 264 | 265 | /* Disallow copy constructor and assignment operators. */ 266 | private: 267 | CallChainOfFunctionPointersWithContext(const CallChainOfFunctionPointersWithContext &); 268 | CallChainOfFunctionPointersWithContext & operator = (const CallChainOfFunctionPointersWithContext &); 269 | }; 270 | 271 | #endif 272 | -------------------------------------------------------------------------------- /ble/CharacteristicDescriptorDiscovery.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2015 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__ 18 | #define __CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__ 19 | 20 | #include "FunctionPointerWithContext.h" 21 | 22 | class DiscoveredCharacteristic; // forward declaration 23 | class DiscoveredCharacteristicDescriptor; // forward declaration 24 | 25 | /** 26 | * @brief Contain all definitions of callbacks and callbacks parameters types 27 | * related to characteristic descriptor discovery. 28 | * 29 | * @details This class act like a namespace for characteristic descriptor discovery 30 | * types. It act like ServiceDiscovery by providing callbacks and callbacks 31 | * parameters types related to the characteristic descriptor discovery process but 32 | * contrary to ServiceDiscovery class, it does not force the porter to use a 33 | * specific interface for the characteristic descriptor discovery process. 34 | */ 35 | class CharacteristicDescriptorDiscovery { 36 | public: 37 | /** 38 | * @brief Parameter type of CharacteristicDescriptorDiscovery::DiscoveryCallback_t. 39 | * @details Every time a characteristic descriptor has been discovered, the callback 40 | * registered for the discovery operation through GattClient::discoverCharacteristicDescriptors 41 | * or DiscoveredCharacteristic::discoverDescriptors will be called with this parameter. 42 | * 43 | */ 44 | struct DiscoveryCallbackParams_t { 45 | /** 46 | * The characteristic owning the DiscoveredCharacteristicDescriptor 47 | */ 48 | const DiscoveredCharacteristic& characteristic; 49 | 50 | /** 51 | * The characteristic descriptor discovered 52 | */ 53 | const DiscoveredCharacteristicDescriptor& descriptor; 54 | }; 55 | 56 | /** 57 | * @brief Parameter type of CharacteristicDescriptorDiscovery::TerminationCallback_t. 58 | * @details Once a characteristic descriptor discovery process terminate, the termination 59 | * callback registered for the discovery operation through 60 | * GattClient::discoverCharacteristicDescriptors or DiscoveredCharacteristic::discoverDescriptors 61 | * will be called with this parameter. 62 | */ 63 | struct TerminationCallbackParams_t { 64 | /** 65 | * The characteristic for which the descriptors has been discovered 66 | */ 67 | const DiscoveredCharacteristic& characteristic; 68 | 69 | /** 70 | * status of the discovery operation 71 | */ 72 | ble_error_t status; 73 | }; 74 | 75 | /** 76 | * @brief Callback type for when a matching characteristic descriptor is found during 77 | * characteristic descriptor discovery. 78 | * 79 | * @param param A pointer to a DiscoveryCallbackParams_t object which will remain 80 | * valid for the lifetime of the callback. Memory for this object is owned by 81 | * the BLE_API eventing framework. The application can safely make a persistent 82 | * shallow-copy of this object in order to work with the service beyond the 83 | * callback. 84 | */ 85 | typedef FunctionPointerWithContext DiscoveryCallback_t; 86 | 87 | /** 88 | * @brief Callback type for when characteristic descriptor discovery terminates. 89 | * 90 | * @param param A pointer to a TerminationCallbackParams_t object which will remain 91 | * valid for the lifetime of the callback. Memory for this object is owned by 92 | * the BLE_API eventing framework. The application can safely make a persistent 93 | * shallow-copy of this object in order to work with the service beyond the 94 | * callback. 95 | */ 96 | typedef FunctionPointerWithContext TerminationCallback_t; 97 | }; 98 | 99 | #endif // ifndef __CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__ 100 | -------------------------------------------------------------------------------- /ble/DiscoveredCharacteristic.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __DISCOVERED_CHARACTERISTIC_H__ 18 | #define __DISCOVERED_CHARACTERISTIC_H__ 19 | 20 | #include "UUID.h" 21 | #include "Gap.h" 22 | #include "GattAttribute.h" 23 | #include "GattClient.h" 24 | #include "CharacteristicDescriptorDiscovery.h" 25 | #include "ble/DiscoveredCharacteristicDescriptor.h" 26 | 27 | /** 28 | * @brief Representation of a characteristic discovered during a GattClient 29 | * discovery procedure (see GattClient::launchServiceDiscovery ). 30 | * 31 | * @details Provide detailed informations about a discovered characteristic like: 32 | * - Its UUID (see getUUID()). 33 | * - The most important handles of the characteristic definition 34 | * (see getDeclHandle(), getValueHandle(), getLastHandle()) 35 | * - Its properties (see getProperties()). 36 | * This class also provide functions to operate on the characteristic: 37 | * - Read the characteristic value (see read()) 38 | * - Writing a characteristic value (see write() or writeWoResponse()) 39 | * - Discover descriptors inside the characteristic definition. These descriptors 40 | * extends the characteristic. More information about descriptor usage is 41 | * available in DiscoveredCharacteristicDescriptor class. 42 | */ 43 | class DiscoveredCharacteristic { 44 | public: 45 | /** 46 | * Structure that encapsulates the properties of a discovered 47 | * characteristic. 48 | */ 49 | struct Properties_t { 50 | uint8_t _broadcast :1; /**< Broadcasting the value permitted. */ 51 | uint8_t _read :1; /**< Reading the value permitted. */ 52 | uint8_t _writeWoResp :1; /**< Writing the value with Write Command permitted. */ 53 | uint8_t _write :1; /**< Writing the value with Write Request permitted. */ 54 | uint8_t _notify :1; /**< Notifications of the value permitted. */ 55 | uint8_t _indicate :1; /**< Indications of the value permitted. */ 56 | uint8_t _authSignedWrite :1; /**< Writing the value with Signed Write Command permitted. */ 57 | 58 | public: 59 | /** 60 | * @brief Check if broadcasting is permitted. 61 | * 62 | * @return true if broadcasting the value is permitted, and false 63 | * otherwise. 64 | */ 65 | bool broadcast(void) const { 66 | return _broadcast; 67 | } 68 | 69 | /** 70 | * @brief Check reading is permitted. 71 | * 72 | * @return true if reading the value is permitted, and false 73 | * otherwise. 74 | */ 75 | bool read(void) const { 76 | return _read; 77 | } 78 | 79 | /** 80 | * @brief Check if writing with Write Command is permitted. 81 | * 82 | * @return true if writing the value with Write Command is permitted, 83 | * false otherwise. 84 | */ 85 | bool writeWoResp(void) const { 86 | return _writeWoResp; 87 | } 88 | 89 | /** 90 | * @brief Check if writing with Write Request is permitted. 91 | * 92 | * @return true if writing the value with Write Request is permitted, 93 | * false otherwise. 94 | */ 95 | bool write(void) const { 96 | return _write; 97 | } 98 | 99 | /** 100 | * @brief Check notifications are permitted. 101 | * 102 | * @return true if notifications of the value are permitted, false 103 | * otherwise. 104 | */ 105 | bool notify(void) const { 106 | return _notify; 107 | } 108 | 109 | /** 110 | * @brief Check if indications are permitted. 111 | * 112 | * @return true if indications of the value are permitted, false 113 | * otherwise. 114 | */ 115 | bool indicate(void) const { 116 | return _indicate; 117 | } 118 | 119 | /** 120 | * @brief Check if writing with Signed Write Command is permitted. 121 | * 122 | * @return true if writing the value with Signed Write Command is 123 | * permitted, false otherwise. 124 | */ 125 | bool authSignedWrite(void) const { 126 | return _authSignedWrite; 127 | } 128 | 129 | /** 130 | * @brief "Equal to" operator for DiscoveredCharacteristic::Properties_t 131 | * 132 | * @param[in] lhs The left hand side of the equality expression 133 | * @param[in] rhs The right hand side of the equality expression 134 | * 135 | * @return true if operands are equals, false otherwise. 136 | */ 137 | friend bool operator==(Properties_t lhs, Properties_t rhs) { 138 | return lhs._broadcast == rhs._broadcast && 139 | lhs._read == rhs._read && 140 | lhs._writeWoResp == rhs._writeWoResp && 141 | lhs._write == rhs._write && 142 | lhs._notify == rhs._notify && 143 | lhs._indicate == rhs._indicate && 144 | lhs._authSignedWrite == rhs._authSignedWrite; 145 | } 146 | 147 | /** 148 | * @brief "Not equal to" operator for DiscoveredCharacteristic::Properties_t 149 | * 150 | * @param lhs The right hand side of the expression 151 | * @param rhs The left hand side of the expression 152 | * 153 | * @return true if operands are not equals, false otherwise. 154 | */ 155 | friend bool operator!=(Properties_t lhs, Properties_t rhs) { 156 | return !(lhs == rhs); 157 | } 158 | 159 | private: 160 | operator uint8_t() const; /* Disallow implicit conversion into an integer. */ 161 | operator unsigned() const; /* Disallow implicit conversion into an integer. */ 162 | }; 163 | 164 | /** 165 | * Initiate (or continue) a read for the value attribute, optionally at a 166 | * given offset. If the characteristic or descriptor to be read is longer 167 | * than ATT_MTU - 1, this function must be called multiple times with 168 | * appropriate offset to read the complete value. 169 | * 170 | * @param[in] offset 171 | * The position - in the characteristic value bytes stream - where 172 | * the read operation begin. 173 | * 174 | * @return BLE_ERROR_NONE if a read has been initiated, or 175 | * BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or 176 | * BLE_STACK_BUSY if some client procedure is already in progress, or 177 | * BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties. 178 | */ 179 | ble_error_t read(uint16_t offset = 0) const; 180 | 181 | /** 182 | * @brief Same as #read(uint16_t) const but allow the user to register a callback 183 | * which will be fired once the read is done. 184 | * 185 | * @param[in] offset 186 | * The position - in the characteristic value bytes stream - where 187 | * the read operation begin. 188 | * @param[in] onRead 189 | * Continuation of the read operation 190 | */ 191 | ble_error_t read(uint16_t offset, const GattClient::ReadCallback_t& onRead) const; 192 | 193 | /** 194 | * Perform a write without response procedure. 195 | * 196 | * @param[in] length 197 | * The amount of data being written. 198 | * @param[in] value 199 | * The bytes being written. 200 | * 201 | * @note It is important to note that a write without response will generate 202 | * an onDataSent() callback when the packet has been transmitted. There 203 | * will be a BLE-stack specific limit to the number of pending 204 | * writeWoResponse operations; the user may want to use the onDataSent() 205 | * callback for flow-control. 206 | * 207 | * @retval BLE_ERROR_NONE Successfully started the Write procedure, or 208 | * BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or 209 | * BLE_STACK_BUSY if some client procedure is already in progress, or 210 | * BLE_ERROR_NO_MEM if there are no available buffers left to process the request, or 211 | * BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties. 212 | */ 213 | ble_error_t writeWoResponse(uint16_t length, const uint8_t *value) const; 214 | 215 | /** 216 | * Initiate a GATT Characteristic Descriptor Discovery procedure for descriptors within this characteristic. 217 | * 218 | * @param[in] onDescriptorDiscovered This callback will be called every time a descriptor is discovered 219 | * @param[in] onTermination This callback will be called when the discovery process is over. 220 | * 221 | * @return BLE_ERROR_NONE if descriptor discovery is launched successfully; else an appropriate error. 222 | */ 223 | ble_error_t discoverDescriptors(const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& onDescriptorDiscovered, 224 | const CharacteristicDescriptorDiscovery::TerminationCallback_t& onTermination) const; 225 | 226 | /** 227 | * Perform a write procedure. 228 | * 229 | * @param[in] length 230 | * The amount of data being written. 231 | * @param[in] value 232 | * The bytes being written. 233 | * 234 | * @note It is important to note that a write will generate 235 | * an onDataWritten() callback when the peer acknowledges the request. 236 | * 237 | * @retval BLE_ERROR_NONE Successfully started the Write procedure, or 238 | * BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or 239 | * BLE_STACK_BUSY if some client procedure is already in progress, or 240 | * BLE_ERROR_NO_MEM if there are no available buffers left to process the request, or 241 | * BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties. 242 | */ 243 | ble_error_t write(uint16_t length, const uint8_t *value) const; 244 | 245 | /** 246 | * Same as write(uint16_t, const uint8_t *) const but register a callback 247 | * which will be called once the data has been written. 248 | * 249 | * @param[in] length 250 | * The amount of bytes to write. 251 | * @param[in] value 252 | * The bytes to write. 253 | * @param[in] onWrite 254 | * Continuation callback for the write operation 255 | * 256 | * @retval BLE_ERROR_NONE Successfully started the Write procedure, or 257 | * BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or 258 | * BLE_STACK_BUSY if some client procedure is already in progress, or 259 | * BLE_ERROR_NO_MEM if there are no available buffers left to process the request, or 260 | * BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties. 261 | */ 262 | ble_error_t write(uint16_t length, const uint8_t *value, const GattClient::WriteCallback_t& onWrite) const; 263 | 264 | void setupLongUUID(UUID::LongUUIDBytes_t longUUID, UUID::ByteOrder_t order = UUID::MSB) { 265 | uuid.setupLong(longUUID, order); 266 | } 267 | 268 | public: 269 | /** 270 | * @brief Get the UUID of the discovered characteristic 271 | * @return the UUID of this characteristic 272 | */ 273 | const UUID& getUUID(void) const { 274 | return uuid; 275 | } 276 | 277 | /** 278 | * @brief Get the properties of this characteristic 279 | * @return the set of properties of this characteristic 280 | */ 281 | const Properties_t& getProperties(void) const { 282 | return props; 283 | } 284 | 285 | /** 286 | * @brief Get the declaration handle of this characteristic. 287 | * @details The declaration handle is the first handle of a characteristic 288 | * definition. The value accessible at this handle contains the following 289 | * informations: 290 | * - The characteristics properties (see Properties_t). This value can 291 | * be accessed by using #getProperties . 292 | * - The characteristic value attribute handle. This field can be accessed 293 | * by using #getValueHandle . 294 | * - The characteristic UUID, this value can be accessed by using the 295 | * function #getUUID . 296 | * @return the declaration handle of this characteristic. 297 | */ 298 | GattAttribute::Handle_t getDeclHandle(void) const { 299 | return declHandle; 300 | } 301 | 302 | /** 303 | * @brief Return the handle used to access the value of this characteristic. 304 | * @details This handle is the one provided in the characteristic declaration 305 | * value. Usually, it is equal to #getDeclHandle() + 1. But it is not always 306 | * the case. Anyway, users are allowed to use #getDeclHandle() + 1 to access 307 | * the value of a characteristic. 308 | * @return The handle to access the value of this characteristic. 309 | */ 310 | GattAttribute::Handle_t getValueHandle(void) const { 311 | return valueHandle; 312 | } 313 | 314 | /** 315 | * @brief Return the last handle of the characteristic definition. 316 | * @details A Characteristic definition can contain a lot of handles: 317 | * - one for the declaration (see #getDeclHandle) 318 | * - one for the value (see #getValueHandle) 319 | * - zero of more for the characteristic descriptors. 320 | * This handle is the last handle of the characteristic definition. 321 | * @return The last handle of this characteristic definition. 322 | */ 323 | GattAttribute::Handle_t getLastHandle(void) const { 324 | return lastHandle; 325 | } 326 | 327 | /** 328 | * @brief Return the GattClient which can operate on this characteristic. 329 | * @return The GattClient which can operate on this characteristic. 330 | */ 331 | GattClient* getGattClient() { 332 | return gattc; 333 | } 334 | 335 | /** 336 | * @brief Return the GattClient which can operate on this characteristic. 337 | * @return The GattClient which can operate on this characteristic. 338 | */ 339 | const GattClient* getGattClient() const { 340 | return gattc; 341 | } 342 | 343 | /** 344 | * @brief Return the connection handle to the GattServer which contain 345 | * this characteristic. 346 | * @return the connection handle to the GattServer which contain 347 | * this characteristic. 348 | */ 349 | Gap::Handle_t getConnectionHandle() const { 350 | return connHandle; 351 | } 352 | 353 | /** 354 | * @brief "Equal to" operator for DiscoveredCharacteristic 355 | * 356 | * @param[in] lhs 357 | * The left hand side of the equality expression 358 | * @param[in] rhs 359 | * The right hand side of the equality expression 360 | * 361 | * @return true if operands are equals, false otherwise. 362 | */ 363 | friend bool operator==(const DiscoveredCharacteristic& lhs, const DiscoveredCharacteristic& rhs) { 364 | return lhs.gattc == rhs.gattc && 365 | lhs.uuid == rhs.uuid && 366 | lhs.props == rhs.props && 367 | lhs.declHandle == rhs.declHandle && 368 | lhs.valueHandle == rhs.valueHandle && 369 | lhs.lastHandle == rhs.lastHandle && 370 | lhs.connHandle == rhs.connHandle; 371 | } 372 | 373 | /** 374 | * @brief "Not equal to" operator for DiscoveredCharacteristic 375 | * 376 | * @param[in] lhs 377 | * The right hand side of the expression 378 | * @param[in] rhs 379 | * The left hand side of the expression 380 | * 381 | * @return true if operands are not equal, false otherwise. 382 | */ 383 | friend bool operator !=(const DiscoveredCharacteristic& lhs, const DiscoveredCharacteristic& rhs) { 384 | return !(lhs == rhs); 385 | } 386 | 387 | public: 388 | DiscoveredCharacteristic() : gattc(NULL), 389 | uuid(UUID::ShortUUIDBytes_t(0)), 390 | props(), 391 | declHandle(GattAttribute::INVALID_HANDLE), 392 | valueHandle(GattAttribute::INVALID_HANDLE), 393 | lastHandle(GattAttribute::INVALID_HANDLE), 394 | connHandle() { 395 | /* empty */ 396 | } 397 | 398 | protected: 399 | /** 400 | * Pointer to the underlying GattClient for this DiscoveredCharacteristic object. 401 | */ 402 | GattClient *gattc; 403 | 404 | protected: 405 | /** 406 | * Discovered characteristic's UUID. 407 | */ 408 | UUID uuid; 409 | /** 410 | * Hold the configured properties of the discovered characteristic. 411 | * For more information refer to Properties_t. 412 | */ 413 | Properties_t props; 414 | /** 415 | * Value handle of the discovered characteristic's declaration attribute. 416 | */ 417 | GattAttribute::Handle_t declHandle; 418 | /** 419 | * Value handle of the discovered characteristic's value attribute. 420 | */ 421 | GattAttribute::Handle_t valueHandle; 422 | /** 423 | * Value handle of the discovered characteristic's last attribute. 424 | */ 425 | GattAttribute::Handle_t lastHandle; 426 | 427 | /** 428 | * Handle for the connection where the characteristic was discovered. 429 | */ 430 | Gap::Handle_t connHandle; 431 | }; 432 | 433 | #endif /*__DISCOVERED_CHARACTERISTIC_H__*/ 434 | -------------------------------------------------------------------------------- /ble/DiscoveredCharacteristicDescriptor.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __DISCOVERED_CHARACTERISTIC_DESCRIPTOR_H__ 18 | #define __DISCOVERED_CHARACTERISTIC_DESCRIPTOR_H__ 19 | 20 | #include "UUID.h" 21 | #include "Gap.h" 22 | #include "GattAttribute.h" 23 | #include "GattClient.h" 24 | #include "CharacteristicDescriptorDiscovery.h" 25 | 26 | /** 27 | * @brief Representation of a descriptor discovered during a GattClient 28 | * discovery procedure (see GattClient::discoverCharacteristicDescriptors or 29 | * DiscoveredCharacteristic::discoverDescriptors ). 30 | * 31 | * @details Provide detailed informations about a discovered characteristic descriptor 32 | * like: 33 | * - Its UUID (see #getUUID). 34 | * - Its handle (see #getAttributeHandle) 35 | * Basic read (see GattClient::read) and write (see GattClient::write) procedure from 36 | * GattClient can be used access the value of the descriptor. 37 | * 38 | * @todo read member function 39 | * @todo write member function 40 | * @todo enumeration of standard descriptors 41 | */ 42 | class DiscoveredCharacteristicDescriptor { 43 | 44 | public: 45 | 46 | /** 47 | * @brief construct a new instance of a DiscoveredCharacteristicDescriptor 48 | * 49 | * @param client The client from where the descriptor has been discovered 50 | * @param connectionHandle The connection handle on which the descriptor has 51 | * been discovered 52 | * @param attributeHandle The handle of the attribute containing this descriptor 53 | * @param uuid The UUID of the descriptor 54 | */ 55 | DiscoveredCharacteristicDescriptor( 56 | GattClient* client, Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const UUID& uuid) : 57 | _client(client), _connectionHandle(connectionHandle), _uuid(uuid), _gattHandle(attributeHandle) { 58 | 59 | } 60 | 61 | /** 62 | * @brief Return the GattClient which can operate on this descriptor. 63 | * @return The GattClient which can operate on this descriptor. 64 | */ 65 | GattClient* getGattClient() { 66 | return _client; 67 | } 68 | 69 | /** 70 | * @brief Return the GattClient which can operate on this descriptor. 71 | * @return The GattClient which can operate on this descriptor. 72 | */ 73 | const GattClient* getGattClient() const { 74 | return _client; 75 | } 76 | 77 | /** 78 | * @brief Return the connection handle to the GattServer which contain 79 | * this descriptor. 80 | * @return the connection handle to the GattServer which contain 81 | * this descriptor. 82 | */ 83 | Gap::Handle_t getConnectionHandle() const { 84 | return _connectionHandle; 85 | } 86 | 87 | /** 88 | * @brief Return the UUID of this descriptor 89 | * @return the UUID of this descriptor 90 | */ 91 | const UUID& getUUID(void) const { 92 | return _uuid; 93 | } 94 | 95 | /** 96 | * @brief Return the attribute handle to use to access to this descriptor 97 | * on the gatt server. 98 | * @return The attribute handle of the descriptor 99 | */ 100 | GattAttribute::Handle_t getAttributeHandle() const { 101 | return _gattHandle; 102 | } 103 | 104 | private: 105 | GattClient *_client; 106 | Gap::Handle_t _connectionHandle; 107 | UUID _uuid; 108 | GattAttribute::Handle_t _gattHandle; 109 | }; 110 | 111 | #endif /*__DISCOVERED_CHARACTERISTIC_DESCRIPTOR_H__*/ 112 | -------------------------------------------------------------------------------- /ble/DiscoveredService.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __DISCOVERED_SERVICE_H__ 18 | #define __DISCOVERED_SERVICE_H__ 19 | 20 | #include "UUID.h" 21 | #include "GattAttribute.h" 22 | 23 | /**@brief Type for holding information about the service and the characteristics found during 24 | * the discovery process. 25 | */ 26 | class DiscoveredService { 27 | public: 28 | /** 29 | * Set information about the discovered service. 30 | * 31 | * @param[in] uuidIn 32 | * The UUID of the discovered service. 33 | * @param[in] startHandleIn 34 | * The start handle of the discovered service in the peer's 35 | * ATT table. 36 | * @param[in] endHandleIn 37 | * The end handle of the discovered service in the peer's 38 | * ATT table. 39 | */ 40 | void setup(UUID uuidIn, GattAttribute::Handle_t startHandleIn, GattAttribute::Handle_t endHandleIn) { 41 | uuid = uuidIn; 42 | startHandle = startHandleIn; 43 | endHandle = endHandleIn; 44 | } 45 | 46 | /** 47 | * Set the start and end handle of the discovered service. 48 | * @param[in] startHandleIn 49 | * The start handle of the discovered service in the peer's 50 | * ATT table. 51 | * @param[in] endHandleIn 52 | * The end handle of the discovered service in the peer's 53 | * ATT table. 54 | */ 55 | void setup(GattAttribute::Handle_t startHandleIn, GattAttribute::Handle_t endHandleIn) { 56 | startHandle = startHandleIn; 57 | endHandle = endHandleIn; 58 | } 59 | 60 | /** 61 | * Set the long UUID of the discovered service. 62 | * 63 | * @param[in] longUUID 64 | * The long UUID of the discovered service. 65 | * @param[in] order 66 | * The byte ordering of @p longUUID. 67 | */ 68 | void setupLongUUID(UUID::LongUUIDBytes_t longUUID, UUID::ByteOrder_t order = UUID::MSB) { 69 | uuid.setupLong(longUUID, order); 70 | } 71 | 72 | public: 73 | /** 74 | * Get the UUID of the discovered service. 75 | * 76 | * @return A reference to the UUID of the discovered service. 77 | */ 78 | const UUID &getUUID(void) const { 79 | return uuid; 80 | } 81 | 82 | /** 83 | * Get the start handle of the discovered service in the peer's ATT table. 84 | * 85 | * @return A reference to the start handle. 86 | */ 87 | const GattAttribute::Handle_t& getStartHandle(void) const { 88 | return startHandle; 89 | } 90 | 91 | /** 92 | * Get the end handle of the discovered service in the peer's ATT table. 93 | * 94 | * @return A reference to the end handle. 95 | */ 96 | const GattAttribute::Handle_t& getEndHandle(void) const { 97 | return endHandle; 98 | } 99 | 100 | public: 101 | /** 102 | * Construct a DiscoveredService instance. 103 | */ 104 | DiscoveredService() : uuid(UUID::ShortUUIDBytes_t(0)), 105 | startHandle(GattAttribute::INVALID_HANDLE), 106 | endHandle(GattAttribute::INVALID_HANDLE) { 107 | /* empty */ 108 | } 109 | 110 | private: 111 | DiscoveredService(const DiscoveredService &); 112 | 113 | private: 114 | UUID uuid; /**< UUID of the service. */ 115 | GattAttribute::Handle_t startHandle; /**< Service Handle Range. */ 116 | GattAttribute::Handle_t endHandle; /**< Service Handle Range. */ 117 | }; 118 | 119 | #endif /*__DISCOVERED_SERVICE_H__*/ 120 | -------------------------------------------------------------------------------- /ble/FunctionPointerWithContext.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H 18 | #define MBED_FUNCTIONPOINTER_WITH_CONTEXT_H 19 | 20 | #include 21 | #include "SafeBool.h" 22 | 23 | /** A class for storing and calling a pointer to a static or member void function 24 | * that takes a context. 25 | */ 26 | template 27 | class FunctionPointerWithContext : public SafeBool > { 28 | public: 29 | typedef FunctionPointerWithContext *pFunctionPointerWithContext_t; 30 | typedef const FunctionPointerWithContext *cpFunctionPointerWithContext_t; 31 | typedef void (*pvoidfcontext_t)(ContextType context); 32 | 33 | /** Create a FunctionPointerWithContext, attaching a static function. 34 | * 35 | * @param function The void static function to attach (default is none). 36 | */ 37 | FunctionPointerWithContext(void (*function)(ContextType context) = NULL) : 38 | _memberFunctionAndPointer(), _caller(NULL), _next(NULL) { 39 | attach(function); 40 | } 41 | 42 | /** Create a FunctionPointerWithContext, attaching a member function. 43 | * 44 | * @param object The object pointer to invoke the member function on (the "this" pointer). 45 | * @param function The address of the void member function to attach. 46 | */ 47 | template 48 | FunctionPointerWithContext(T *object, void (T::*member)(ContextType context)) : 49 | _memberFunctionAndPointer(), _caller(NULL), _next(NULL) { 50 | attach(object, member); 51 | } 52 | 53 | FunctionPointerWithContext(const FunctionPointerWithContext& that) : 54 | _memberFunctionAndPointer(that._memberFunctionAndPointer), _caller(that._caller), _next(NULL) { 55 | } 56 | 57 | FunctionPointerWithContext& operator=(const FunctionPointerWithContext& that) { 58 | _memberFunctionAndPointer = that._memberFunctionAndPointer; 59 | _caller = that._caller; 60 | _next = NULL; 61 | return *this; 62 | } 63 | 64 | /** Attach a static function. 65 | * 66 | * @param function The void static function to attach (default is none). 67 | */ 68 | void attach(void (*function)(ContextType context) = NULL) { 69 | _function = function; 70 | _caller = functioncaller; 71 | } 72 | 73 | /** Attach a member function. 74 | * 75 | * @param object The object pointer to invoke the member function on (the "this" pointer). 76 | * @param function The address of the void member function to attach. 77 | */ 78 | template 79 | void attach(T *object, void (T::*member)(ContextType context)) { 80 | _memberFunctionAndPointer._object = static_cast(object); 81 | memcpy(_memberFunctionAndPointer._memberFunction, (char*) &member, sizeof(member)); 82 | _caller = &FunctionPointerWithContext::membercaller; 83 | } 84 | 85 | /** Call the attached static or member function; if there are chained 86 | * FunctionPointers their callbacks are invoked as well. 87 | * @Note: All chained callbacks stack up, so hopefully there won't be too 88 | * many FunctionPointers in a chain. */ 89 | void call(ContextType context) const { 90 | _caller(this, context); 91 | } 92 | 93 | /** 94 | * @brief Same as above 95 | */ 96 | void operator()(ContextType context) const { 97 | call(context); 98 | } 99 | 100 | /** Same as above, workaround for mbed os FunctionPointer implementation. */ 101 | void call(ContextType context) { 102 | ((const FunctionPointerWithContext*) this)->call(context); 103 | } 104 | 105 | typedef void (FunctionPointerWithContext::*bool_type)() const; 106 | 107 | /** 108 | * implementation of safe bool operator 109 | */ 110 | bool toBool() const { 111 | return (_function || _memberFunctionAndPointer._object); 112 | } 113 | 114 | /** 115 | * Set up an external FunctionPointer as a next in the chain of related 116 | * callbacks. Invoking call() on the head FunctionPointer will invoke all 117 | * chained callbacks. 118 | * 119 | * Refer to 'CallChain' as an alternative. 120 | */ 121 | void chainAsNext(pFunctionPointerWithContext_t next) { 122 | _next = next; 123 | } 124 | 125 | pFunctionPointerWithContext_t getNext(void) const { 126 | return _next; 127 | } 128 | 129 | pvoidfcontext_t get_function() const { 130 | return (pvoidfcontext_t)_function; 131 | } 132 | 133 | friend bool operator==(const FunctionPointerWithContext& lhs, const FunctionPointerWithContext& rhs) { 134 | return rhs._caller == lhs._caller && 135 | memcmp( 136 | &rhs._memberFunctionAndPointer, 137 | &lhs._memberFunctionAndPointer, 138 | sizeof(rhs._memberFunctionAndPointer) 139 | ) == 0; 140 | } 141 | 142 | private: 143 | template 144 | static void membercaller(cpFunctionPointerWithContext_t self, ContextType context) { 145 | if (self->_memberFunctionAndPointer._object) { 146 | T *o = static_cast(self->_memberFunctionAndPointer._object); 147 | void (T::*m)(ContextType); 148 | memcpy((char*) &m, self->_memberFunctionAndPointer._memberFunction, sizeof(m)); 149 | (o->*m)(context); 150 | } 151 | } 152 | 153 | static void functioncaller(cpFunctionPointerWithContext_t self, ContextType context) { 154 | if (self->_function) { 155 | self->_function(context); 156 | } 157 | } 158 | 159 | struct MemberFunctionAndPtr { 160 | /* 161 | * Forward declaration of a class and a member function to this class. 162 | * Because the compiler doesn't know anything about the forwarded member 163 | * function, it will always use the biggest size and the biggest alignment 164 | * that a member function can take for objects of type UndefinedMemberFunction. 165 | */ 166 | class UndefinedClass; 167 | typedef void (UndefinedClass::*UndefinedMemberFunction)(ContextType); 168 | 169 | void* _object; 170 | union { 171 | char _memberFunction[sizeof(UndefinedMemberFunction)]; 172 | UndefinedMemberFunction _alignment; 173 | }; 174 | }; 175 | 176 | union { 177 | pvoidfcontext_t _function; /**< Static function pointer - NULL if none attached */ 178 | /** 179 | * object this pointer and pointer to member - 180 | * _memberFunctionAndPointer._object will be NULL if none attached 181 | */ 182 | mutable MemberFunctionAndPtr _memberFunctionAndPointer; 183 | }; 184 | 185 | void (*_caller)(const FunctionPointerWithContext*, ContextType); 186 | 187 | pFunctionPointerWithContext_t _next; /**< Optional link to make a chain out of functionPointers. This 188 | * allows chaining function pointers without requiring 189 | * external memory to manage the chain. Refer to 190 | * 'CallChain' as an alternative. */ 191 | }; 192 | 193 | /** 194 | * @brief Create a new FunctionPointerWithContext which bind an instance and a 195 | * a member function together. 196 | * @details This little helper is a just here to eliminate the need to write the 197 | * FunctionPointerWithContext type each time you want to create one by kicking 198 | * automatic type deduction of function templates. With this function, it is easy 199 | * to write only one entry point for functions which expect a FunctionPointer 200 | * in parameters. 201 | * 202 | * @param object to bound with member function 203 | * @param member The member function called 204 | * @return a new FunctionPointerWithContext 205 | */ 206 | template 207 | FunctionPointerWithContext makeFunctionPointer(T *object, void (T::*member)(ContextType context)) 208 | { 209 | return FunctionPointerWithContext(object, member); 210 | } 211 | 212 | #endif // ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H 213 | -------------------------------------------------------------------------------- /ble/GapAdvertisingParams.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __GAP_ADVERTISING_PARAMS_H__ 18 | #define __GAP_ADVERTISING_PARAMS_H__ 19 | 20 | /** 21 | * This class provides a wrapper for the core advertising parameters, 22 | * including the advertising type (Connectable Undirected, 23 | * Non Connectable Undirected and so on), as well as the advertising and 24 | * timeout intervals. 25 | */ 26 | class GapAdvertisingParams { 27 | public: 28 | /** 29 | * Minimum Advertising interval for connectable undirected and connectable 30 | * directed events in 625us units - 20ms. 31 | */ 32 | static const unsigned GAP_ADV_PARAMS_INTERVAL_MIN = 0x0020; 33 | /** 34 | * Minimum Advertising interval for scannable and non-connectable 35 | * undirected events in 625us units - 100ms. 36 | */ 37 | static const unsigned GAP_ADV_PARAMS_INTERVAL_MIN_NONCON = 0x00A0; 38 | /** 39 | * Maximum Advertising interval in 625us units - 10.24s. 40 | */ 41 | static const unsigned GAP_ADV_PARAMS_INTERVAL_MAX = 0x4000; 42 | /** 43 | * Maximum advertising timeout seconds. 44 | */ 45 | static const unsigned GAP_ADV_PARAMS_TIMEOUT_MAX = 0x3FFF; 46 | 47 | /** 48 | * Encapsulates the peripheral advertising modes, which determine how 49 | * the device appears to other central devices in hearing range. 50 | */ 51 | enum AdvertisingType_t { 52 | ADV_CONNECTABLE_UNDIRECTED, /**< Vol 3, Part C, Section 9.3.4 and Vol 6, Part B, Section 2.3.1.1. */ 53 | ADV_CONNECTABLE_DIRECTED, /**< Vol 3, Part C, Section 9.3.3 and Vol 6, Part B, Section 2.3.1.2. */ 54 | ADV_SCANNABLE_UNDIRECTED, /**< Include support for Scan Response payloads, see Vol 6, Part B, Section 2.3.1.4. */ 55 | ADV_NON_CONNECTABLE_UNDIRECTED /**< Vol 3, Part C, Section 9.3.2 and Vol 6, Part B, Section 2.3.1.3. */ 56 | }; 57 | /** 58 | * Type alias for GapAdvertisingParams::AdvertisingType_t. 59 | * 60 | * @deprecated This type alias will be dropped in future releases. 61 | */ 62 | typedef enum AdvertisingType_t AdvertisingType; 63 | 64 | public: 65 | /** 66 | * Construct an instance of GapAdvertisingParams. 67 | * 68 | * @param[in] advType 69 | * Type of advertising. Default is 70 | * GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED. 71 | * @param[in] interval 72 | * Advertising interval in units of 0.625ms. Default is 73 | * GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON. 74 | * @param[in] timeout 75 | * Advertising timeout. Default is 0. 76 | */ 77 | GapAdvertisingParams(AdvertisingType_t advType = ADV_CONNECTABLE_UNDIRECTED, 78 | uint16_t interval = GAP_ADV_PARAMS_INTERVAL_MIN_NONCON, 79 | uint16_t timeout = 0) : _advType(advType), _interval(interval), _timeout(timeout) { 80 | /* Interval checks. */ 81 | if (_advType == ADV_CONNECTABLE_DIRECTED) { 82 | /* Interval must be 0 in directed connectable mode. */ 83 | _interval = 0; 84 | } else if (_advType == ADV_NON_CONNECTABLE_UNDIRECTED) { 85 | /* Min interval is slightly larger than in other modes. */ 86 | if (_interval < GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) { 87 | _interval = GAP_ADV_PARAMS_INTERVAL_MIN_NONCON; 88 | } 89 | if (_interval > GAP_ADV_PARAMS_INTERVAL_MAX) { 90 | _interval = GAP_ADV_PARAMS_INTERVAL_MAX; 91 | } 92 | } else { 93 | /* Stay within interval limits. */ 94 | if (_interval < GAP_ADV_PARAMS_INTERVAL_MIN) { 95 | _interval = GAP_ADV_PARAMS_INTERVAL_MIN; 96 | } 97 | if (_interval > GAP_ADV_PARAMS_INTERVAL_MAX) { 98 | _interval = GAP_ADV_PARAMS_INTERVAL_MAX; 99 | } 100 | } 101 | 102 | /* Timeout checks. */ 103 | if (timeout) { 104 | /* Stay within timeout limits. */ 105 | if (_timeout > GAP_ADV_PARAMS_TIMEOUT_MAX) { 106 | _timeout = GAP_ADV_PARAMS_TIMEOUT_MAX; 107 | } 108 | } 109 | } 110 | 111 | static const uint16_t UNIT_0_625_MS = 625; /**< Number of microseconds in 0.625 milliseconds. */ 112 | /** 113 | * Convert milliseconds to units of 0.625ms. 114 | * 115 | * @param[in] durationInMillis 116 | * The number of milliseconds to convert. 117 | * 118 | * @return The value of @p durationInMillis in units of 0.625ms. 119 | */ 120 | static uint16_t MSEC_TO_ADVERTISEMENT_DURATION_UNITS(uint32_t durationInMillis) { 121 | return (durationInMillis * 1000) / UNIT_0_625_MS; 122 | } 123 | /** 124 | * Convert units of 0.625ms to milliseconds. 125 | * 126 | * @param[in] gapUnits 127 | * The number of units of 0.625ms to convert. 128 | * 129 | * @return The value of @p gapUnits in milliseconds. 130 | */ 131 | static uint16_t ADVERTISEMENT_DURATION_UNITS_TO_MS(uint16_t gapUnits) { 132 | return (gapUnits * UNIT_0_625_MS) / 1000; 133 | } 134 | 135 | /** 136 | * Get the advertising type. 137 | * 138 | * @return The advertising type. 139 | */ 140 | AdvertisingType_t getAdvertisingType(void) const { 141 | return _advType; 142 | } 143 | 144 | /** 145 | * Get the advertising interval in milliseconds. 146 | * 147 | * @return The advertisement interval (in milliseconds). 148 | */ 149 | uint16_t getInterval(void) const { 150 | return ADVERTISEMENT_DURATION_UNITS_TO_MS(_interval); 151 | } 152 | 153 | /** 154 | * Get the advertisement interval in units of 0.625ms. 155 | * 156 | * @return The advertisement interval in advertisement duration units (0.625ms units). 157 | */ 158 | uint16_t getIntervalInADVUnits(void) const { 159 | return _interval; 160 | } 161 | 162 | /** 163 | * Get The advertising timeout. 164 | * 165 | * @return The advertising timeout (in seconds). 166 | */ 167 | uint16_t getTimeout(void) const { 168 | return _timeout; 169 | } 170 | 171 | /** 172 | * Set the advertising type. 173 | * 174 | * @param[in] newAdvType 175 | * The new advertising type. 176 | */ 177 | void setAdvertisingType(AdvertisingType_t newAdvType) { 178 | _advType = newAdvType; 179 | } 180 | 181 | /** 182 | * Set the advertising interval in milliseconds. 183 | * 184 | * @param[in] newInterval 185 | * The new advertising interval in milliseconds. 186 | */ 187 | void setInterval(uint16_t newInterval) { 188 | _interval = MSEC_TO_ADVERTISEMENT_DURATION_UNITS(newInterval); 189 | } 190 | 191 | /** 192 | * Set the advertising timeout. 193 | * 194 | * @param[in] newTimeout 195 | * The new advertising timeout (in seconds). 196 | */ 197 | void setTimeout(uint16_t newTimeout) { 198 | _timeout = newTimeout; 199 | } 200 | 201 | private: 202 | AdvertisingType_t _advType; /**< The advertising type. */ 203 | uint16_t _interval; /**< The advertising interval in ADV duration units (i.e. 0.625ms). */ 204 | uint16_t _timeout; /**< The advertising timeout in seconds. */ 205 | }; 206 | 207 | #endif /* ifndef __GAP_ADVERTISING_PARAMS_H__ */ 208 | -------------------------------------------------------------------------------- /ble/GapEvents.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __GAP_EVENTS_H__ 18 | #define __GAP_EVENTS_H__ 19 | 20 | #include "blecommon.h" 21 | 22 | /**************************************************************************/ 23 | /*! 24 | \brief 25 | The base class used to abstract away the callback events that can be 26 | triggered with the GAP. 27 | */ 28 | /**************************************************************************/ 29 | class GapEvents 30 | { 31 | public: 32 | /******************************************************************/ 33 | /*! 34 | \brief 35 | Identifies GAP events generated by the radio HW when an event 36 | callback occurs. 37 | */ 38 | /******************************************************************/ 39 | typedef enum gapEvent_e { 40 | GAP_EVENT_TIMEOUT = 1, /**< Advertising timed out before a connection could be established. */ 41 | GAP_EVENT_CONNECTED = 2, /**< A connection was established with a central device. */ 42 | GAP_EVENT_DISCONNECTED = 3 /**< A connection was closed or lost with a central device. */ 43 | } gapEvent_t; 44 | }; 45 | 46 | #endif // ifndef __GAP_EVENTS_H__ 47 | -------------------------------------------------------------------------------- /ble/GapScanningParams.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __GAP_SCANNING_PARAMS_H__ 18 | #define __GAP_SCANNING_PARAMS_H__ 19 | 20 | class GapScanningParams { 21 | public: 22 | static const unsigned SCAN_INTERVAL_MIN = 0x0004; /**< Minimum Scan interval in 625us units - 2.5ms. */ 23 | static const unsigned SCAN_INTERVAL_MAX = 0x4000; /**< Maximum Scan interval in 625us units - 10.24s. */ 24 | static const unsigned SCAN_WINDOW_MIN = 0x0004; /**< Minimum Scan window in 625us units - 2.5ms. */ 25 | static const unsigned SCAN_WINDOW_MAX = 0x4000; /**< Maximum Scan window in 625us units - 10.24s. */ 26 | static const unsigned SCAN_TIMEOUT_MIN = 0x0001; /**< Minimum Scan timeout in seconds. */ 27 | static const unsigned SCAN_TIMEOUT_MAX = 0xFFFF; /**< Maximum Scan timeout in seconds. */ 28 | 29 | public: 30 | /** 31 | * Construct an instance of GapScanningParams. 32 | * 33 | * @param[in] interval 34 | * The scan interval in milliseconds. Default is 35 | * GapScanningParams::SCAN_INTERVAL_MIN. 36 | * @param[in] window 37 | * The scan window in milliseconds. Default is 38 | * GapScanningParams::SCAN_WINDOW_MAX. 39 | * @param[in] timeout 40 | * The scan timeout in seconds. Default is 0. 41 | * @param[in] activeScanning 42 | * Set to True if active-scanning is required. This is used to 43 | * fetch the scan response from a peer if possible. Default is 44 | * false. 45 | */ 46 | GapScanningParams(uint16_t interval = SCAN_INTERVAL_MAX, 47 | uint16_t window = SCAN_WINDOW_MAX, 48 | uint16_t timeout = 0, 49 | bool activeScanning = false); 50 | 51 | static const uint16_t UNIT_0_625_MS = 625; /**< Number of microseconds in 0.625 milliseconds. */ 52 | /** 53 | * Convert milliseconds to units of 0.625ms. 54 | * 55 | * @param[in] durationInMillis 56 | * The number of milliseconds to convert. 57 | * 58 | * @return The value of @p durationInMillis in units of 0.625ms. 59 | */ 60 | static uint16_t MSEC_TO_SCAN_DURATION_UNITS(uint32_t durationInMillis) { 61 | return (durationInMillis * 1000) / UNIT_0_625_MS; 62 | } 63 | 64 | /** 65 | * Set the scan interval. 66 | * 67 | * @param[in] newIntervalInMS 68 | * New scan interval in milliseconds. 69 | * 70 | * @return BLE_ERROR_NONE if the new scan interval was set successfully. 71 | */ 72 | ble_error_t setInterval(uint16_t newIntervalInMS); 73 | 74 | /** 75 | * Set the scan window. 76 | * 77 | * @param[in] newWindowInMS 78 | * New scan window in milliseconds. 79 | * 80 | * @return BLE_ERROR_NONE if the new scan window was set successfully. 81 | */ 82 | ble_error_t setWindow(uint16_t newWindowInMS); 83 | 84 | /** 85 | * Set the scan timeout. 86 | * 87 | * @param[in] newTimeout 88 | * New scan timeout in seconds. 89 | * 90 | * @return BLE_ERROR_NONE if the new scan window was set successfully. 91 | */ 92 | ble_error_t setTimeout(uint16_t newTimeout); 93 | 94 | /** 95 | * Set active scanning. This is used to fetch the scan response from a peer 96 | * if possible. 97 | * 98 | * @param[in] activeScanning 99 | * The new boolean value of active scanning. 100 | */ 101 | void setActiveScanning(bool activeScanning); 102 | 103 | public: 104 | /** 105 | * Get the scan interval. 106 | * 107 | * @return the scan interval in units of 0.625ms. 108 | */ 109 | uint16_t getInterval(void) const { 110 | return _interval; 111 | } 112 | 113 | /** 114 | * Get the scan window. 115 | * 116 | * @return the scan window in units of 0.625ms. 117 | */ 118 | uint16_t getWindow(void) const { 119 | return _window; 120 | } 121 | 122 | /** 123 | * Get the scan timeout. 124 | * 125 | * @return The scan timeout in seconds. 126 | */ 127 | uint16_t getTimeout(void) const { 128 | return _timeout; 129 | } 130 | 131 | /** 132 | * Check whether active scanning is set. 133 | * 134 | * @return True if active scanning is set, false otherwise. 135 | */ 136 | bool getActiveScanning(void) const { 137 | return _activeScanning; 138 | } 139 | 140 | private: 141 | uint16_t _interval; /**< Scan interval in units of 625us (between 2.5ms and 10.24s). */ 142 | uint16_t _window; /**< Scan window in units of 625us (between 2.5ms and 10.24s). */ 143 | uint16_t _timeout; /**< Scan timeout between 0x0001 and 0xFFFF in seconds; 0x0000 disables timeout. */ 144 | bool _activeScanning; /**< Obtain the peer device's advertising data and (if possible) scanResponse. */ 145 | 146 | private: 147 | /* Disallow copy constructor. */ 148 | GapScanningParams(const GapScanningParams &); 149 | GapScanningParams& operator =(const GapScanningParams &in); 150 | }; 151 | 152 | #endif /* ifndef __GAP_SCANNING_PARAMS_H__ */ 153 | -------------------------------------------------------------------------------- /ble/GattAttribute.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __GATT_ATTRIBUTE_H__ 18 | #define __GATT_ATTRIBUTE_H__ 19 | 20 | #include "UUID.h" 21 | 22 | /** 23 | * Instances of this class encapsulate the data that belongs to a Bluetooth Low 24 | * Energy attribute. 25 | */ 26 | class GattAttribute { 27 | public: 28 | /** 29 | * Type for the handle or ID of the attribute in the ATT table. These are 30 | * unique and are usually generated by the underlying BLE stack. 31 | */ 32 | typedef uint16_t Handle_t; 33 | /** 34 | * Define the value of an invalid attribute handle. 35 | */ 36 | static const Handle_t INVALID_HANDLE = 0x0000; 37 | 38 | public: 39 | /** 40 | * @brief Creates a new GattAttribute using the specified 41 | * UUID, value length, and inital value. 42 | * 43 | * @param[in] uuid 44 | * The UUID to use for this attribute. 45 | * @param[in] valuePtr 46 | * The memory holding the initial value. 47 | * @param[in] len 48 | * The length in bytes of this attribute's value. 49 | * @param[in] maxLen 50 | * The max length in bytes of this attribute's value. 51 | * @param[in] hasVariableLen 52 | * Whether the attribute's value length changes overtime. 53 | * 54 | * @section EXAMPLE 55 | * 56 | * @code 57 | * 58 | * // UUID = 0x2A19, Min length 2, Max len = 2 59 | * GattAttribute attr = GattAttribute(0x2A19, &someValue, 2, 2); 60 | * 61 | * @endcode 62 | */ 63 | GattAttribute(const UUID &uuid, uint8_t *valuePtr = NULL, uint16_t len = 0, uint16_t maxLen = 0, bool hasVariableLen = true) : 64 | _uuid(uuid), _valuePtr(valuePtr), _lenMax(maxLen), _len(len), _hasVariableLen(hasVariableLen), _handle() { 65 | /* Empty */ 66 | } 67 | 68 | public: 69 | /** 70 | * Get the attribute's handle in the ATT table. 71 | * 72 | * @return The attribute's handle. 73 | */ 74 | Handle_t getHandle(void) const { 75 | return _handle; 76 | } 77 | 78 | /** 79 | * The UUID of the characteristic that this attribute belongs to. 80 | * 81 | * @return The characteristic's UUID. 82 | */ 83 | const UUID &getUUID(void) const { 84 | return _uuid; 85 | } 86 | 87 | /** 88 | * Get the current length of the attribute value. 89 | * 90 | * @return The current length of the attribute value. 91 | */ 92 | uint16_t getLength(void) const { 93 | return _len; 94 | } 95 | 96 | /** 97 | * Get the maximum length of the attribute value. 98 | * 99 | * The maximum length of the attribute value. 100 | */ 101 | uint16_t getMaxLength(void) const { 102 | return _lenMax; 103 | } 104 | 105 | /** 106 | * Get a pointer to the current length of the attribute value. 107 | * 108 | * @return A pointer to the current length of the attribute value. 109 | */ 110 | uint16_t *getLengthPtr(void) { 111 | return &_len; 112 | } 113 | 114 | /** 115 | * Set the attribute handle. 116 | * 117 | * @param[in] id 118 | * The new attribute handle. 119 | */ 120 | void setHandle(Handle_t id) { 121 | _handle = id; 122 | } 123 | 124 | /** 125 | * Get a pointer to the attribute value. 126 | * 127 | * @return A pointer to the attribute value. 128 | */ 129 | uint8_t *getValuePtr(void) { 130 | return _valuePtr; 131 | } 132 | 133 | /** 134 | * Check whether the length of the attribute's value can change over time. 135 | * 136 | * @return true if the attribute has variable length, false otherwise. 137 | */ 138 | bool hasVariableLength(void) const { 139 | return _hasVariableLen; 140 | } 141 | 142 | private: 143 | /** 144 | * Characteristic's UUID. 145 | */ 146 | UUID _uuid; 147 | /** 148 | * Pointer to the attribute's value. 149 | */ 150 | uint8_t *_valuePtr; 151 | /** 152 | * Maximum length of the value pointed to by GattAttribute::_valuePtr. 153 | */ 154 | uint16_t _lenMax; 155 | /** 156 | * Current length of the value pointed to by GattAttribute::_valuePtr. 157 | */ 158 | uint16_t _len; 159 | /** 160 | * Whether the length of the value can change over time. 161 | */ 162 | bool _hasVariableLen; 163 | /** 164 | * The attribute's handle in the ATT table. 165 | */ 166 | Handle_t _handle; 167 | 168 | private: 169 | /* Disallow copy and assignment. */ 170 | GattAttribute(const GattAttribute &); 171 | GattAttribute& operator=(const GattAttribute &); 172 | }; 173 | 174 | #endif /* ifndef __GATT_ATTRIBUTE_H__ */ 175 | -------------------------------------------------------------------------------- /ble/GattCallbackParamTypes.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __GATT_CALLBACK_PARAM_TYPES_H__ 18 | #define __GATT_CALLBACK_PARAM_TYPES_H__ 19 | 20 | struct GattWriteCallbackParams { 21 | /** 22 | * Enumeration for write operations. 23 | */ 24 | enum WriteOp_t { 25 | OP_INVALID = 0x00, /**< Invalid operation. */ 26 | OP_WRITE_REQ = 0x01, /**< Write request. */ 27 | OP_WRITE_CMD = 0x02, /**< Write command. */ 28 | OP_SIGN_WRITE_CMD = 0x03, /**< Signed write command. */ 29 | OP_PREP_WRITE_REQ = 0x04, /**< Prepare write request. */ 30 | OP_EXEC_WRITE_REQ_CANCEL = 0x05, /**< Execute write request: cancel all prepared writes. */ 31 | OP_EXEC_WRITE_REQ_NOW = 0x06, /**< Execute write request: immediately execute all prepared writes. */ 32 | }; 33 | 34 | Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event */ 35 | GattAttribute::Handle_t handle; /**< Attribute Handle to which the write operation applies. */ 36 | WriteOp_t writeOp; /**< Type of write operation. */ 37 | uint16_t offset; /**< Offset for the write operation. */ 38 | uint16_t len; /**< Length (in bytes) of the data to write. */ 39 | /** 40 | * Pointer to the data to write. 41 | * 42 | * @note Data might not persist beyond the callback; make a local copy if 43 | * needed. 44 | */ 45 | const uint8_t *data; 46 | }; 47 | 48 | struct GattReadCallbackParams { 49 | Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event */ 50 | GattAttribute::Handle_t handle; /**< Attribute Handle to which the read operation applies. */ 51 | uint16_t offset; /**< Offset for the read operation. */ 52 | uint16_t len; /**< Length (in bytes) of the data to read. */ 53 | /** 54 | * Pointer to the data read. 55 | * 56 | * @note Data might not persist beyond the callback; make a local copy if 57 | * needed. 58 | */ 59 | const uint8_t *data; 60 | }; 61 | 62 | enum GattAuthCallbackReply_t { 63 | AUTH_CALLBACK_REPLY_SUCCESS = 0x00, /**< Success. */ 64 | AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE = 0x0101, /**< ATT Error: Invalid attribute handle. */ 65 | AUTH_CALLBACK_REPLY_ATTERR_READ_NOT_PERMITTED = 0x0102, /**< ATT Error: Read not permitted. */ 66 | AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED = 0x0103, /**< ATT Error: Write not permitted. */ 67 | AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHENTICATION = 0x0105, /**< ATT Error: Authenticated link required. */ 68 | AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET = 0x0107, /**< ATT Error: The specified offset was past the end of the attribute. */ 69 | AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION = 0x0108, /**< ATT Error: Used in ATT as "insufficient authorization". */ 70 | AUTH_CALLBACK_REPLY_ATTERR_PREPARE_QUEUE_FULL = 0x0109, /**< ATT Error: Used in ATT as "prepare queue full". */ 71 | AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_FOUND = 0x010A, /**< ATT Error: Used in ATT as "attribute not found". */ 72 | AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_LONG = 0x010B, /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */ 73 | AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH = 0x010D, /**< ATT Error: Invalid value size. */ 74 | AUTH_CALLBACK_REPLY_ATTERR_INSUF_RESOURCES = 0x0111, /**< ATT Error: Encrypted link required. */ 75 | }; 76 | 77 | struct GattWriteAuthCallbackParams { 78 | Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event */ 79 | GattAttribute::Handle_t handle; /**< Attribute Handle to which the write operation applies. */ 80 | uint16_t offset; /**< Offset for the write operation. */ 81 | uint16_t len; /**< Length of the incoming data. */ 82 | const uint8_t *data; /**< Incoming data, variable length. */ 83 | /** 84 | * This is the out parameter that the callback needs to set to 85 | * AUTH_CALLBACK_REPLY_SUCCESS for the request to proceed. 86 | */ 87 | GattAuthCallbackReply_t authorizationReply; 88 | }; 89 | 90 | struct GattReadAuthCallbackParams { 91 | Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event */ 92 | GattAttribute::Handle_t handle; /**< Attribute Handle to which the read operation applies. */ 93 | uint16_t offset; /**< Offset for the read operation. */ 94 | uint16_t len; /**< Optional: new length of the outgoing data. */ 95 | uint8_t *data; /**< Optional: new outgoing data. Leave at NULL if data is unchanged. */ 96 | /** 97 | * This is the out parameter that the callback needs to set to 98 | * AUTH_CALLBACK_REPLY_SUCCESS for the request to proceed. 99 | */ 100 | GattAuthCallbackReply_t authorizationReply; 101 | }; 102 | 103 | /** 104 | * For encapsulating handle-value update events (notifications or indications) 105 | * generated at the remote server. 106 | */ 107 | struct GattHVXCallbackParams { 108 | Gap::Handle_t connHandle; /**< The handle of the connection that triggered the event */ 109 | GattAttribute::Handle_t handle; /**< Attribute Handle to which the HVx operation applies. */ 110 | HVXType_t type; /**< Indication or Notification, see HVXType_t. */ 111 | uint16_t len; /**< Attribute data length. */ 112 | const uint8_t *data; /**< Attribute data, variable length. */ 113 | }; 114 | 115 | #endif /*__GATT_CALLBACK_PARAM_TYPES_H__*/ 116 | -------------------------------------------------------------------------------- /ble/GattServerEvents.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __GATT_SERVER_EVENTS_H__ 18 | #define __GATT_SERVER_EVENTS_H__ 19 | 20 | /** 21 | * @brief The base class used to abstract away the callback events that can be 22 | * triggered with the GATT Server. 23 | */ 24 | class GattServerEvents 25 | { 26 | public: 27 | /** 28 | * Enumeration for GattServer events. 29 | */ 30 | typedef enum gattEvent_e { 31 | GATT_EVENT_DATA_SENT = 1, /**< Fired when a message was successfully sent out (notify only?) */ 32 | GATT_EVENT_DATA_WRITTEN = 2, /**< Client wrote data to the server (separate into char and descriptor writes?) */ 33 | GATT_EVENT_UPDATES_ENABLED = 3, /**< Notify/Indicate enabled in CCCD. */ 34 | GATT_EVENT_UPDATES_DISABLED = 4, /**< Notify/Indicate disabled in CCCD. */ 35 | GATT_EVENT_CONFIRMATION_RECEIVED = 5, /**< Response received from Indicate message. */ 36 | GATT_EVENT_READ_AUTHORIZATION_REQ = 6, /**< Request application to authorize read. */ 37 | GATT_EVENT_WRITE_AUTHORIZATION_REQ = 7, /**< Request application to authorize write. */ 38 | } gattEvent_t; 39 | }; 40 | 41 | #endif /* ifndef __GATT_SERVER_EVENTS_H__ */ 42 | -------------------------------------------------------------------------------- /ble/GattService.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __GATT_SERVICE_H__ 18 | #define __GATT_SERVICE_H__ 19 | 20 | #include "UUID.h" 21 | #include "GattCharacteristic.h" 22 | 23 | class GattService { 24 | public: 25 | enum { 26 | UUID_ALERT_NOTIFICATION_SERVICE = 0x1811, 27 | UUID_BATTERY_SERVICE = 0x180F, 28 | UUID_BLOOD_PRESSURE_SERVICE = 0x1810, 29 | UUID_CURRENT_TIME_SERVICE = 0x1805, 30 | UUID_CYCLING_SPEED_AND_CADENCE = 0x1816, 31 | UUID_DEVICE_INFORMATION_SERVICE = 0x180A, 32 | UUID_ENVIRONMENTAL_SERVICE = 0x181A, 33 | UUID_GLUCOSE_SERVICE = 0x1808, 34 | UUID_HEALTH_THERMOMETER_SERVICE = 0x1809, 35 | UUID_HEART_RATE_SERVICE = 0x180D, 36 | UUID_HUMAN_INTERFACE_DEVICE_SERVICE = 0x1812, 37 | UUID_IMMEDIATE_ALERT_SERVICE = 0x1802, 38 | UUID_LINK_LOSS_SERVICE = 0x1803, 39 | UUID_NEXT_DST_CHANGE_SERVICE = 0x1807, 40 | UUID_PHONE_ALERT_STATUS_SERVICE = 0x180E, 41 | UUID_REFERENCE_TIME_UPDATE_SERVICE = 0x1806, 42 | UUID_RUNNING_SPEED_AND_CADENCE = 0x1814, 43 | UUID_SCAN_PARAMETERS_SERVICE = 0x1813, 44 | UUID_TX_POWER_SERVICE = 0x1804 45 | }; 46 | 47 | public: 48 | /** 49 | * @brief Creates a new GattService using the specified 16-bit 50 | * UUID, value length, and properties. 51 | * 52 | * @note The UUID value must be unique and is normally >1. 53 | * 54 | * @param[in] uuid 55 | * The UUID to use for this service. 56 | * @param[in] characteristics 57 | * A pointer to an array of characteristics to be included within this service. 58 | * @param[in] numCharacteristics 59 | * The number of characteristics. 60 | */ 61 | GattService(const UUID &uuid, GattCharacteristic *characteristics[], unsigned numCharacteristics) : 62 | _primaryServiceID(uuid), 63 | _characteristicCount(numCharacteristics), 64 | _characteristics(characteristics), 65 | _handle(0) { 66 | /* empty */ 67 | } 68 | 69 | /** 70 | * Get this service's UUID. 71 | * 72 | * @return A reference to the service's UUID. 73 | */ 74 | const UUID &getUUID(void) const { 75 | return _primaryServiceID; 76 | } 77 | 78 | /** 79 | * Get handle of the service declaration attribute in the ATT table. 80 | * 81 | * @return The service's handle. 82 | */ 83 | uint16_t getHandle(void) const { 84 | return _handle; 85 | } 86 | 87 | /** 88 | * Get the total number of characteristics within this service. 89 | * 90 | * @return The total number of characteristics within this service. 91 | */ 92 | uint8_t getCharacteristicCount(void) const { 93 | return _characteristicCount; 94 | } 95 | 96 | /** 97 | * Set the handle of the service declaration attribute in the ATT table. 98 | * 99 | * @param[in] handle 100 | * The service's handle. 101 | */ 102 | void setHandle(uint16_t handle) { 103 | _handle = handle; 104 | } 105 | 106 | /** 107 | * Get this service's characteristic at a specific index. 108 | * 109 | * @param[in] index 110 | * The index of the characteristic. 111 | * 112 | * @return A pointer to the characterisitic at index @p index. 113 | */ 114 | GattCharacteristic *getCharacteristic(uint8_t index) { 115 | if (index >= _characteristicCount) { 116 | return NULL; 117 | } 118 | 119 | return _characteristics[index]; 120 | } 121 | 122 | private: 123 | /** 124 | * This service's UUID. 125 | */ 126 | UUID _primaryServiceID; 127 | /** 128 | * Total number of characteristics within this service. 129 | */ 130 | uint8_t _characteristicCount; 131 | /** 132 | * An array with pointers to the characteristics added to this service. 133 | */ 134 | GattCharacteristic **_characteristics; 135 | /** 136 | * Handle of the service declaration attribute in the ATT table. 137 | * 138 | * @note This handle is generally assigned by the underlying BLE stack when the 139 | * service is added to the ATT table. 140 | */ 141 | uint16_t _handle; 142 | }; 143 | 144 | #endif /* ifndef __GATT_SERVICE_H__ */ 145 | -------------------------------------------------------------------------------- /ble/SafeBool.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef BLE_API_SAFE_BOOL_H_ 18 | #define BLE_API_SAFE_BOOL_H_ 19 | 20 | /* Safe bool idiom, see : http://www.artima.com/cppsource/safebool.html */ 21 | 22 | namespace SafeBool_ { 23 | /** 24 | * @brief Base class for all intances of SafeBool. 25 | * This base class reduces instantiation of trueTag function. 26 | */ 27 | class base { 28 | template 29 | friend class SafeBool; 30 | 31 | protected: 32 | /** 33 | * The bool type is a pointer to method which can be used in boolean context. 34 | */ 35 | typedef void (base::*BoolType_t)() const; 36 | 37 | /** 38 | * Non implemented call, use to disallow conversion between unrelated types. 39 | */ 40 | void invalidTag() const; 41 | 42 | /** 43 | * Member function which indicate true value. 44 | */ 45 | void trueTag() const {} 46 | }; 47 | 48 | 49 | } 50 | 51 | /** 52 | * @brief template class SafeBool use CRTP to made boolean conversion easy and correct. 53 | * Derived class should implement the function bool toBool() const to make this work. Inheritance 54 | * should be public. 55 | * 56 | * @tparam T Type of the derived class 57 | * 58 | * @code 59 | * 60 | * class A : public SafeBool { 61 | * public: 62 | * 63 | * // boolean conversion 64 | * bool toBool() { 65 | * 66 | * } 67 | * }; 68 | * 69 | * class B : public SafeBool { 70 | * public: 71 | * 72 | * // boolean conversion 73 | * bool toBool() const { 74 | * 75 | * } 76 | * }; 77 | * 78 | * A a; 79 | * B b; 80 | * 81 | * // will compile 82 | * if(a) { 83 | * 84 | * } 85 | * 86 | * // compilation error 87 | * if(a == b) { 88 | * 89 | * } 90 | * 91 | * 92 | * @endcode 93 | */ 94 | template 95 | class SafeBool : public SafeBool_::base { 96 | public: 97 | /** 98 | * Bool operator implementation, derived class has to provide bool toBool() const function. 99 | */ 100 | operator BoolType_t() const { 101 | return (static_cast(this))->toBool() 102 | ? &SafeBool::trueTag : 0; 103 | } 104 | }; 105 | 106 | /** 107 | * Avoid conversion to bool between different classes. 108 | */ 109 | template 110 | void operator==(const SafeBool& lhs,const SafeBool& rhs) { 111 | lhs.invalidTag(); 112 | // return false; 113 | } 114 | 115 | /** 116 | * Avoid conversion to bool between different classes. 117 | */ 118 | template 119 | void operator!=(const SafeBool& lhs,const SafeBool& rhs) { 120 | lhs.invalidTag(); 121 | // return false; 122 | } 123 | 124 | #endif /* BLE_API_SAFE_BOOL_H_ */ 125 | -------------------------------------------------------------------------------- /ble/SecurityManager.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2015 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __SECURITY_MANAGER_H__ 18 | #define __SECURITY_MANAGER_H__ 19 | 20 | #include 21 | 22 | #include "Gap.h" 23 | #include "CallChainOfFunctionPointersWithContext.h" 24 | 25 | class SecurityManager { 26 | public: 27 | enum SecurityMode_t { 28 | SECURITY_MODE_NO_ACCESS, 29 | SECURITY_MODE_ENCRYPTION_OPEN_LINK, /**< Require no protection, open link. */ 30 | SECURITY_MODE_ENCRYPTION_NO_MITM, /**< Require encryption, but no MITM protection. */ 31 | SECURITY_MODE_ENCRYPTION_WITH_MITM, /**< Require encryption and MITM protection. */ 32 | SECURITY_MODE_SIGNED_NO_MITM, /**< Require signing or encryption, but no MITM protection. */ 33 | SECURITY_MODE_SIGNED_WITH_MITM, /**< Require signing or encryption, and MITM protection. */ 34 | }; 35 | 36 | /** 37 | * @brief Defines possible security status or states. 38 | * 39 | * @details Defines possible security status or states of a link when requested by getLinkSecurity(). 40 | */ 41 | enum LinkSecurityStatus_t { 42 | NOT_ENCRYPTED, /**< The link is not secured. */ 43 | ENCRYPTION_IN_PROGRESS, /**< Link security is being established.*/ 44 | ENCRYPTED /**< The link is secure.*/ 45 | }; 46 | 47 | enum SecurityIOCapabilities_t { 48 | IO_CAPS_DISPLAY_ONLY = 0x00, /**< Display only. */ 49 | IO_CAPS_DISPLAY_YESNO = 0x01, /**< Display and yes/no entry. */ 50 | IO_CAPS_KEYBOARD_ONLY = 0x02, /**< Keyboard only. */ 51 | IO_CAPS_NONE = 0x03, /**< No I/O capabilities. */ 52 | IO_CAPS_KEYBOARD_DISPLAY = 0x04, /**< Keyboard and display. */ 53 | }; 54 | 55 | enum SecurityCompletionStatus_t { 56 | SEC_STATUS_SUCCESS = 0x00, /**< Procedure completed with success. */ 57 | SEC_STATUS_TIMEOUT = 0x01, /**< Procedure timed out. */ 58 | SEC_STATUS_PDU_INVALID = 0x02, /**< Invalid PDU received. */ 59 | SEC_STATUS_PASSKEY_ENTRY_FAILED = 0x81, /**< Passkey entry failed (user canceled or other). */ 60 | SEC_STATUS_OOB_NOT_AVAILABLE = 0x82, /**< Out of Band Key not available. */ 61 | SEC_STATUS_AUTH_REQ = 0x83, /**< Authentication requirements not met. */ 62 | SEC_STATUS_CONFIRM_VALUE = 0x84, /**< Confirm value failed. */ 63 | SEC_STATUS_PAIRING_NOT_SUPP = 0x85, /**< Pairing not supported. */ 64 | SEC_STATUS_ENC_KEY_SIZE = 0x86, /**< Encryption key size. */ 65 | SEC_STATUS_SMP_CMD_UNSUPPORTED = 0x87, /**< Unsupported SMP command. */ 66 | SEC_STATUS_UNSPECIFIED = 0x88, /**< Unspecified reason. */ 67 | SEC_STATUS_REPEATED_ATTEMPTS = 0x89, /**< Too little time elapsed since last attempt. */ 68 | SEC_STATUS_INVALID_PARAMS = 0x8A, /**< Invalid parameters. */ 69 | }; 70 | 71 | /** 72 | * Declaration of type containing a passkey to be used during pairing. This 73 | * is passed into initializeSecurity() to specify a pre-programmed passkey 74 | * for authentication instead of generating a random one. 75 | */ 76 | static const unsigned PASSKEY_LEN = 6; 77 | typedef uint8_t Passkey_t[PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ 78 | 79 | public: 80 | typedef void (*HandleSpecificEvent_t)(Gap::Handle_t handle); 81 | typedef void (*SecuritySetupInitiatedCallback_t)(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps); 82 | typedef void (*SecuritySetupCompletedCallback_t)(Gap::Handle_t, SecurityCompletionStatus_t status); 83 | typedef void (*LinkSecuredCallback_t)(Gap::Handle_t handle, SecurityMode_t securityMode); 84 | typedef void (*PasskeyDisplayCallback_t)(Gap::Handle_t handle, const Passkey_t passkey); 85 | 86 | typedef FunctionPointerWithContext SecurityManagerShutdownCallback_t; 87 | typedef CallChainOfFunctionPointersWithContext SecurityManagerShutdownCallbackChain_t; 88 | 89 | /* 90 | * The following functions are meant to be overridden in the platform-specific sub-class. 91 | */ 92 | public: 93 | /** 94 | * Enable the BLE stack's Security Manager. The Security Manager implements 95 | * the actual cryptographic algorithms and protocol exchanges that allow two 96 | * devices to securely exchange data and privately detect each other. 97 | * Calling this API is a prerequisite for encryption and pairing (bonding). 98 | * 99 | * @param[in] enableBonding Allow for bonding. 100 | * @param[in] requireMITM Require protection for man-in-the-middle attacks. 101 | * @param[in] iocaps To specify the I/O capabilities of this peripheral, 102 | * such as availability of a display or keyboard, to 103 | * support out-of-band exchanges of security data. 104 | * @param[in] passkey To specify a static passkey. 105 | * 106 | * @return BLE_ERROR_NONE on success. 107 | */ 108 | virtual ble_error_t init(bool enableBonding = true, 109 | bool requireMITM = true, 110 | SecurityIOCapabilities_t iocaps = IO_CAPS_NONE, 111 | const Passkey_t passkey = NULL) { 112 | /* Avoid compiler warnings about unused variables. */ 113 | (void)enableBonding; 114 | (void)requireMITM; 115 | (void)iocaps; 116 | (void)passkey; 117 | 118 | return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 119 | } 120 | 121 | /** 122 | * Get the security status of a connection. 123 | * 124 | * @param[in] connectionHandle Handle to identify the connection. 125 | * @param[out] securityStatusP Security status. 126 | * 127 | * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 128 | */ 129 | virtual ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) { 130 | /* Avoid compiler warnings about unused variables. */ 131 | (void)connectionHandle; 132 | (void)securityStatusP; 133 | 134 | return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 135 | } 136 | 137 | /** 138 | * Set the security mode on a connection. Useful for elevating the security mode 139 | * once certain conditions are met, e.g., a particular service is found. 140 | * 141 | * @param[in] connectionHandle Handle to identify the connection. 142 | * @param[in] securityMode Requested security mode. 143 | * 144 | * @return BLE_ERROR_NONE or appropriate error code indicating the failure reason. 145 | */ 146 | virtual ble_error_t setLinkSecurity(Gap::Handle_t connectionHandle, SecurityMode_t securityMode) { 147 | /* Avoid compiler warnings about unused variables. */ 148 | (void)connectionHandle; 149 | (void)securityMode; 150 | 151 | return BLE_ERROR_NOT_IMPLEMENTED; 152 | } 153 | 154 | /** 155 | * Delete all peer device context and all related bonding information from 156 | * the database within the security manager. 157 | * 158 | * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure. 159 | * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization or 160 | * application registration. 161 | */ 162 | virtual ble_error_t purgeAllBondingState(void) { 163 | return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 164 | } 165 | 166 | /** 167 | * Get a list of addresses from all peers in the bond table. 168 | * 169 | * @param[in,out] addresses 170 | * (on input) addresses.capacity contains the maximum 171 | * number of addresses to be returned. 172 | * (on output) The populated table with copies of the 173 | * addresses in the implementation's whitelist. 174 | * 175 | * @retval BLE_ERROR_NONE On success, else an error code indicating reason for failure. 176 | * @retval BLE_ERROR_INVALID_STATE If the API is called without module initialization or 177 | * application registration. 178 | * 179 | * @experimental 180 | */ 181 | virtual ble_error_t getAddressesFromBondTable(Gap::Whitelist_t &addresses) const { 182 | /* Avoid compiler warnings about unused variables */ 183 | (void) addresses; 184 | 185 | return BLE_ERROR_NOT_IMPLEMENTED; /* Requesting action from porters: override this API if security is supported. */ 186 | } 187 | 188 | /* Event callback handlers. */ 189 | public: 190 | /** 191 | * Setup a callback to be invoked to notify the user application that the 192 | * SecurityManager instance is about to shutdown (possibly as a result of a call 193 | * to BLE::shutdown()). 194 | * 195 | * @note It is possible to chain together multiple onShutdown callbacks 196 | * (potentially from different modules of an application) to be notified 197 | * before the SecurityManager is shutdown. 198 | * 199 | * @note It is also possible to set up a callback into a member function of 200 | * some object. 201 | * 202 | * @note It is possible to unregister a callback using onShutdown().detach(callback) 203 | */ 204 | void onShutdown(const SecurityManagerShutdownCallback_t& callback) { 205 | shutdownCallChain.add(callback); 206 | } 207 | template 208 | void onShutdown(T *objPtr, void (T::*memberPtr)(const SecurityManager *)) { 209 | shutdownCallChain.add(objPtr, memberPtr); 210 | } 211 | 212 | /** 213 | * @brief provide access to the callchain of shutdown event callbacks 214 | * It is possible to register callbacks using onShutdown().add(callback); 215 | * It is possible to unregister callbacks using onShutdown().detach(callback) 216 | * @return The shutdown event callbacks chain 217 | */ 218 | SecurityManagerShutdownCallbackChain_t& onShutdown() { 219 | return shutdownCallChain; 220 | } 221 | 222 | /** 223 | * To indicate that a security procedure for the link has started. 224 | */ 225 | virtual void onSecuritySetupInitiated(SecuritySetupInitiatedCallback_t callback) {securitySetupInitiatedCallback = callback;} 226 | 227 | /** 228 | * To indicate that the security procedure for the link has completed. 229 | */ 230 | virtual void onSecuritySetupCompleted(SecuritySetupCompletedCallback_t callback) {securitySetupCompletedCallback = callback;} 231 | 232 | /** 233 | * To indicate that the link with the peer is secured. For bonded devices, 234 | * subsequent reconnections with a bonded peer will result only in this callback 235 | * when the link is secured; setup procedures will not occur (unless the 236 | * bonding information is either lost or deleted on either or both sides). 237 | */ 238 | virtual void onLinkSecured(LinkSecuredCallback_t callback) {linkSecuredCallback = callback;} 239 | 240 | /** 241 | * To indicate that device context is stored persistently. 242 | */ 243 | virtual void onSecurityContextStored(HandleSpecificEvent_t callback) {securityContextStoredCallback = callback;} 244 | 245 | /** 246 | * To set the callback for when the passkey needs to be displayed on a peripheral with DISPLAY capability. 247 | */ 248 | virtual void onPasskeyDisplay(PasskeyDisplayCallback_t callback) {passkeyDisplayCallback = callback;} 249 | 250 | /* Entry points for the underlying stack to report events back to the user. */ 251 | public: 252 | void processSecuritySetupInitiatedEvent(Gap::Handle_t handle, bool allowBonding, bool requireMITM, SecurityIOCapabilities_t iocaps) { 253 | if (securitySetupInitiatedCallback) { 254 | securitySetupInitiatedCallback(handle, allowBonding, requireMITM, iocaps); 255 | } 256 | } 257 | 258 | void processSecuritySetupCompletedEvent(Gap::Handle_t handle, SecurityCompletionStatus_t status) { 259 | if (securitySetupCompletedCallback) { 260 | securitySetupCompletedCallback(handle, status); 261 | } 262 | } 263 | 264 | void processLinkSecuredEvent(Gap::Handle_t handle, SecurityMode_t securityMode) { 265 | if (linkSecuredCallback) { 266 | linkSecuredCallback(handle, securityMode); 267 | } 268 | } 269 | 270 | void processSecurityContextStoredEvent(Gap::Handle_t handle) { 271 | if (securityContextStoredCallback) { 272 | securityContextStoredCallback(handle); 273 | } 274 | } 275 | 276 | void processPasskeyDisplayEvent(Gap::Handle_t handle, const Passkey_t passkey) { 277 | if (passkeyDisplayCallback) { 278 | passkeyDisplayCallback(handle, passkey); 279 | } 280 | } 281 | 282 | protected: 283 | SecurityManager() : 284 | securitySetupInitiatedCallback(), 285 | securitySetupCompletedCallback(), 286 | linkSecuredCallback(), 287 | securityContextStoredCallback(), 288 | passkeyDisplayCallback() { 289 | /* empty */ 290 | } 291 | 292 | public: 293 | /** 294 | * Notify all registered onShutdown callbacks that the SecurityManager is 295 | * about to be shutdown and clear all SecurityManager state of the 296 | * associated object. 297 | * 298 | * This function is meant to be overridden in the platform-specific 299 | * sub-class. Nevertheless, the sub-class is only expected to reset its 300 | * state and not the data held in SecurityManager members. This shall be 301 | * achieved by a call to SecurityManager::reset() from the sub-class' 302 | * reset() implementation. 303 | * 304 | * @return BLE_ERROR_NONE on success. 305 | */ 306 | virtual ble_error_t reset(void) { 307 | /* Notify that the instance is about to shutdown */ 308 | shutdownCallChain.call(this); 309 | shutdownCallChain.clear(); 310 | 311 | securitySetupInitiatedCallback = NULL; 312 | securitySetupCompletedCallback = NULL; 313 | linkSecuredCallback = NULL; 314 | securityContextStoredCallback = NULL; 315 | passkeyDisplayCallback = NULL; 316 | 317 | return BLE_ERROR_NONE; 318 | } 319 | 320 | protected: 321 | SecuritySetupInitiatedCallback_t securitySetupInitiatedCallback; 322 | SecuritySetupCompletedCallback_t securitySetupCompletedCallback; 323 | LinkSecuredCallback_t linkSecuredCallback; 324 | HandleSpecificEvent_t securityContextStoredCallback; 325 | PasskeyDisplayCallback_t passkeyDisplayCallback; 326 | 327 | private: 328 | SecurityManagerShutdownCallbackChain_t shutdownCallChain; 329 | }; 330 | 331 | #endif /*__SECURITY_MANAGER_H__*/ 332 | -------------------------------------------------------------------------------- /ble/ServiceDiscovery.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __SERVICE_DISOVERY_H__ 18 | #define __SERVICE_DISOVERY_H__ 19 | 20 | #include "UUID.h" 21 | #include "Gap.h" 22 | #include "GattAttribute.h" 23 | 24 | class DiscoveredService; 25 | class DiscoveredCharacteristic; 26 | 27 | class ServiceDiscovery { 28 | public: 29 | /* 30 | * Exposed application callback types. 31 | */ 32 | 33 | /** 34 | * Callback type for when a matching service is found during service- 35 | * discovery. The receiving function is passed in a pointer to a 36 | * DiscoveredService object, which will remain valid for the lifetime of the 37 | * callback. Memory for this object is owned by the BLE_API eventing 38 | * framework. The application can safely make a persistent shallow-copy of 39 | * this object to work with the service beyond the callback. 40 | */ 41 | typedef FunctionPointerWithContext ServiceCallback_t; 42 | 43 | /** 44 | * Callback type for when a matching characteristic is found during service- 45 | * discovery. The receiving function is passed in a pointer to a 46 | * DiscoveredCharacteristic object, which will remain valid for the lifetime 47 | * of the callback. Memory for this object is owned by the BLE_API eventing 48 | * framework. The application can safely make a persistent shallow-copy of 49 | * this object to work with the characteristic beyond the callback. 50 | */ 51 | typedef FunctionPointerWithContext CharacteristicCallback_t; 52 | 53 | /** 54 | * Callback type for when serviceDiscovery terminates. 55 | */ 56 | typedef FunctionPointerWithContext TerminationCallback_t; 57 | 58 | public: 59 | /** 60 | * Launch service discovery. Once launched, service discovery will remain 61 | * active with callbacks being issued back into the application for matching 62 | * services or characteristics. isActive() can be used to determine status, and 63 | * a termination callback (if set up) will be invoked at the end. Service 64 | * discovery can be terminated prematurely, if needed, using terminate(). 65 | * 66 | * @param connectionHandle 67 | * Handle for the connection with the peer. 68 | * @param sc 69 | * This is the application callback for a matching service. Taken as 70 | * NULL by default. Note: service discovery may still be active 71 | * when this callback is issued; calling asynchronous BLE-stack 72 | * APIs from within this application callback might cause the 73 | * stack to abort service discovery. If this becomes an issue, it 74 | * may be better to make a local copy of the discoveredService and 75 | * wait for service discovery to terminate before operating on the 76 | * service. 77 | * @param cc 78 | * This is the application callback for a matching characteristic. 79 | * Taken as NULL by default. Note: service discovery may still be 80 | * active when this callback is issued; calling asynchronous 81 | * BLE-stack APIs from within this application callback might cause 82 | * the stack to abort service discovery. If this becomes an issue, 83 | * it may be better to make a local copy of the discoveredCharacteristic 84 | * and wait for service discovery to terminate before operating on the 85 | * characteristic. 86 | * @param matchingServiceUUID 87 | * UUID-based filter for specifying a service in which the application is 88 | * interested. By default it is set as the wildcard UUID_UNKNOWN, 89 | * in which case it matches all services. If characteristic-UUID 90 | * filter (below) is set to the wildcard value, then a service 91 | * callback will be invoked for the matching service (or for every 92 | * service if the service filter is a wildcard). 93 | * @param matchingCharacteristicUUIDIn 94 | * UUID-based filter for specifying a characteristic in which the application 95 | * is interested. By default it is set as the wildcard UUID_UKNOWN 96 | * to match against any characteristic. If both service-UUID 97 | * filter and characteristic-UUID filter are used with non-wildcard 98 | * values, then only a single characteristic callback is 99 | * invoked for the matching characteristic. 100 | * 101 | * @note Using wildcard values for both service-UUID and characteristic- 102 | * UUID will result in complete service discovery: callbacks being 103 | * called for every service and characteristic. 104 | * 105 | * @note Providing NULL for the characteristic callback will result in 106 | * characteristic discovery being skipped for each matching 107 | * service. This allows for an inexpensive method to discover only 108 | * services. 109 | * 110 | * @return 111 | * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. 112 | */ 113 | virtual ble_error_t launch(Gap::Handle_t connectionHandle, 114 | ServiceCallback_t sc = NULL, 115 | CharacteristicCallback_t cc = NULL, 116 | const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), 117 | const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) = 0; 118 | 119 | /** 120 | * Check whether service-discovery is currently active. 121 | */ 122 | virtual bool isActive(void) const = 0; 123 | 124 | /** 125 | * Terminate an ongoing service discovery. This should result in an 126 | * invocation of the TerminationCallback if service discovery is active. 127 | */ 128 | virtual void terminate(void) = 0; 129 | 130 | /** 131 | * Set up a callback to be invoked when service discovery is terminated. 132 | */ 133 | virtual void onTermination(TerminationCallback_t callback) = 0; 134 | 135 | /** 136 | * Clear all ServiceDiscovery state of the associated object. 137 | * 138 | * This function is meant to be overridden in the platform-specific 139 | * sub-class. Nevertheless, the sub-class is only expected to reset its 140 | * state and not the data held in ServiceDiscovery members. This shall be 141 | * achieved by a call to ServiceDiscovery::reset() from the sub-class' 142 | * reset() implementation. 143 | * 144 | * @return BLE_ERROR_NONE on success. 145 | */ 146 | virtual ble_error_t reset(void) { 147 | connHandle = 0; 148 | matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN); 149 | serviceCallback = NULL; 150 | matchingCharacteristicUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN); 151 | characteristicCallback = NULL; 152 | 153 | return BLE_ERROR_NONE; 154 | } 155 | 156 | protected: 157 | /** 158 | * Connection handle as provided by the SoftDevice. 159 | */ 160 | Gap::Handle_t connHandle; 161 | /** 162 | * UUID-based filter that specifies the service that the application is 163 | * interested in. 164 | */ 165 | UUID matchingServiceUUID; 166 | /** 167 | * The registered callback handle for when a matching service is found 168 | * during service-discovery. 169 | */ 170 | ServiceCallback_t serviceCallback; 171 | /** 172 | * UUID-based filter that specifies the characteristic that the 173 | * application is interested in. 174 | */ 175 | UUID matchingCharacteristicUUID; 176 | /** 177 | * The registered callback handler for when a matching characteristic is 178 | * found during service-discovery. 179 | */ 180 | CharacteristicCallback_t characteristicCallback; 181 | }; 182 | 183 | #endif /* ifndef __SERVICE_DISOVERY_H__ */ 184 | -------------------------------------------------------------------------------- /ble/UUID.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __UUID_H__ 18 | #define __UUID_H__ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "blecommon.h" 25 | 26 | /** 27 | * A trivial converter for single hexadecimal character to an unsigned integer. 28 | * 29 | * @param c 30 | * Hexadecimal character. 31 | * 32 | * @return The corresponding value as unsigned integer. 33 | */ 34 | static uint8_t char2int(char c) { 35 | if ((c >= '0') && (c <= '9')) { 36 | return c - '0'; 37 | } else if ((c >= 'a') && (c <= 'f')) { 38 | return c - 'a' + 10; 39 | } else if ((c >= 'A') && (c <= 'F')) { 40 | return c - 'A' + 10; 41 | } else { 42 | return 0; 43 | } 44 | } 45 | 46 | /** 47 | * An instance of this class represents a Universally Unique Identifier (UUID) 48 | * in the BLE API. 49 | */ 50 | class UUID { 51 | public: 52 | /** 53 | * Enumeration of the possible types of UUIDs in BLE with regards to length. 54 | */ 55 | enum UUID_Type_t { 56 | UUID_TYPE_SHORT = 0, /**< Short 16-bit UUID. */ 57 | UUID_TYPE_LONG = 1 /**< Full 128-bit UUID. */ 58 | }; 59 | 60 | /** 61 | * Enumeration to specify byte ordering of the long version of the UUID. 62 | */ 63 | typedef enum { 64 | MSB, /**< Most-significant byte first (at the smallest address) */ 65 | LSB /**< least-significant byte first (at the smallest address) */ 66 | } ByteOrder_t; 67 | 68 | /** 69 | * Type for a 16-bit UUID. 70 | */ 71 | typedef uint16_t ShortUUIDBytes_t; 72 | 73 | /** 74 | * Length of a long UUID in bytes. 75 | */ 76 | static const unsigned LENGTH_OF_LONG_UUID = 16; 77 | /** 78 | * Type for a 128-bit UUID. 79 | */ 80 | typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID]; 81 | 82 | /** 83 | * Maximum length of a string representation of a UUID not including the 84 | * null termination ('\0'): two characters per 85 | * byte plus four '-' characters. 86 | */ 87 | static const unsigned MAX_UUID_STRING_LENGTH = LENGTH_OF_LONG_UUID * 2 + 4; 88 | 89 | public: 90 | 91 | /** 92 | * Creates a new 128-bit UUID. 93 | * 94 | * @note The UUID is a unique 128-bit (16 byte) ID used to identify 95 | * different service or characteristics on the BLE device. 96 | * 97 | * @param stringUUID 98 | * The 128-bit (16-byte) UUID as a human readable const-string. 99 | * Format: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX 100 | * Upper and lower case supported. Hyphens are optional, but only 101 | * upto four of them. The UUID is stored internally as a 16 byte 102 | * array, LSB (little endian), which is opposite from the string. 103 | */ 104 | UUID(const char* stringUUID) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) { 105 | bool nibble = false; 106 | uint8_t byte = 0; 107 | size_t baseIndex = 0; 108 | uint8_t tempUUID[LENGTH_OF_LONG_UUID]; 109 | 110 | /* 111 | * Iterate through string, abort if NULL is encountered prematurely. 112 | * Ignore upto four hyphens. 113 | */ 114 | for (size_t index = 0; (index < MAX_UUID_STRING_LENGTH) && (baseIndex < LENGTH_OF_LONG_UUID); index++) { 115 | if (stringUUID[index] == '\0') { 116 | /* Error abort */ 117 | break; 118 | } else if (stringUUID[index] == '-') { 119 | /* Ignore hyphen */ 120 | continue; 121 | } else if (nibble) { 122 | /* Got second nibble */ 123 | byte |= char2int(stringUUID[index]); 124 | nibble = false; 125 | 126 | /* Store copy */ 127 | tempUUID[baseIndex++] = byte; 128 | } else { 129 | /* Got first nibble */ 130 | byte = char2int(stringUUID[index]) << 4; 131 | nibble = true; 132 | } 133 | } 134 | 135 | /* Populate internal variables if string was successfully parsed */ 136 | if (baseIndex == LENGTH_OF_LONG_UUID) { 137 | setupLong(tempUUID, UUID::MSB); 138 | } else { 139 | const uint8_t sig[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 140 | 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB }; 141 | setupLong(sig, UUID::MSB); 142 | } 143 | } 144 | 145 | /** 146 | * Creates a new 128-bit UUID. 147 | * 148 | * @param[in] longUUID 149 | * The 128-bit (16-byte) UUID value. 150 | * @param[in] order 151 | * The bit order of the UUID, MSB by default. 152 | * 153 | * @note The UUID is a unique 128-bit (16 byte) ID used to identify 154 | * different service or characteristics on the BLE device. 155 | */ 156 | UUID(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB) : type(UUID_TYPE_LONG), baseUUID(), shortUUID(0) { 157 | setupLong(longUUID, order); 158 | } 159 | 160 | /** 161 | * Creates a new 16-bit UUID. 162 | * 163 | * For efficiency, and because 16 bytes would take a large chunk of the 164 | * 27-byte data payload length of the Link Layer, the BLE specification adds 165 | * two additional UUID formats: 16-bit and 32-bit UUIDs. These shortened 166 | * formats can be used only with UUIDs that are defined in the Bluetooth 167 | * specification (listed by the Bluetooth SIG as standard 168 | * Bluetooth UUIDs). 169 | * 170 | * To reconstruct the full 128-bit UUID from the shortened version, insert 171 | * the 16-bit short value (indicated by xxxx, including leading zeros) into 172 | * the Bluetooth Base UUID: 173 | * 174 | * 0000xxxx-0000-1000-8000-00805F9B34FB 175 | * 176 | * @param[in] _shortUUID 177 | * The short UUID value. 178 | * 179 | * @note Shortening is not available for UUIDs that are not derived from the 180 | * Bluetooth Base UUID. Such non-standard UUIDs are commonly called 181 | * vendor-specific UUIDs. In these cases, you’ll need to use the full 182 | * 128-bit UUID value at all times. 183 | * 184 | * @note The UUID is a unique 16-bit (2 byte) ID used to identify 185 | * different service or characteristics on the BLE device. 186 | * 187 | * @note We do not yet support 32-bit shortened UUIDs. 188 | */ 189 | UUID(ShortUUIDBytes_t _shortUUID) : type(UUID_TYPE_SHORT), baseUUID(), shortUUID(_shortUUID) { 190 | /* Empty */ 191 | } 192 | 193 | /** 194 | * Copy constructor. 195 | * 196 | * @param[in] source 197 | * The UUID to copy. 198 | */ 199 | UUID(const UUID &source) { 200 | type = source.type; 201 | shortUUID = source.shortUUID; 202 | memcpy(baseUUID, source.baseUUID, LENGTH_OF_LONG_UUID); 203 | } 204 | 205 | /** 206 | * The empty constructor. 207 | * 208 | * @note The type of the resulting UUID instance is UUID_TYPE_SHORT and the 209 | * value BLE_UUID_UNKNOWN. 210 | */ 211 | UUID(void) : type(UUID_TYPE_SHORT), shortUUID(BLE_UUID_UNKNOWN) { 212 | /* empty */ 213 | } 214 | 215 | /** 216 | * Fill in a 128-bit UUID; this is useful when the UUID is not known at the 217 | * time of the object construction. 218 | * 219 | * @param[in] longUUID 220 | * The UUID value to copy. 221 | * @param[in] order 222 | * The byte ordering of the UUID at @p longUUID. 223 | */ 224 | void setupLong(const LongUUIDBytes_t longUUID, ByteOrder_t order = UUID::MSB) { 225 | type = UUID_TYPE_LONG; 226 | if (order == UUID::MSB) { 227 | /* 228 | * Switch endian. Input is big-endian, internal representation 229 | * is little endian. 230 | */ 231 | std::reverse_copy(longUUID, longUUID + LENGTH_OF_LONG_UUID, baseUUID); 232 | } else { 233 | std::copy(longUUID, longUUID + LENGTH_OF_LONG_UUID, baseUUID); 234 | } 235 | shortUUID = (uint16_t)((baseUUID[13] << 8) | (baseUUID[12])); 236 | } 237 | 238 | public: 239 | /** 240 | * Check whether this UUID is short or long. 241 | * 242 | * @return UUID_TYPE_SHORT if the UUID is short, UUID_TYPE_LONG otherwise. 243 | */ 244 | UUID_Type_t shortOrLong(void) const { 245 | return type; 246 | } 247 | 248 | /** 249 | * Get a pointer to the UUID value based on the current UUID type. 250 | * 251 | * @return A pointer to the short UUID if the type is set to 252 | * UUID_TYPE_SHORT. Otherwise, a pointer to the long UUID if the 253 | * type is set to UUID_TYPE_LONG. 254 | */ 255 | const uint8_t *getBaseUUID(void) const { 256 | if (type == UUID_TYPE_SHORT) { 257 | return (const uint8_t*)&shortUUID; 258 | } else { 259 | return baseUUID; 260 | } 261 | } 262 | 263 | /** 264 | * Get the short UUID. 265 | * 266 | * @return The short UUID. 267 | */ 268 | ShortUUIDBytes_t getShortUUID(void) const { 269 | return shortUUID; 270 | } 271 | 272 | /** 273 | * Get the length (in bytes) of the UUID based on its type. 274 | * 275 | * @retval sizeof(ShortUUIDBytes_t) if the UUID type is UUID_TYPE_SHORT. 276 | * @retval LENGTH_OF_LONG_UUID if the UUID type is UUID_TYPE_LONG. 277 | */ 278 | uint8_t getLen(void) const { 279 | return ((type == UUID_TYPE_SHORT) ? sizeof(ShortUUIDBytes_t) : LENGTH_OF_LONG_UUID); 280 | } 281 | 282 | /** 283 | * Overload == operator to enable UUID comparisons. 284 | * 285 | * @param[in] other 286 | * The other UUID in the comparison. 287 | * 288 | * @return true if this == @p other, false otherwise. 289 | */ 290 | bool operator== (const UUID &other) const { 291 | if ((this->type == UUID_TYPE_SHORT) && (other.type == UUID_TYPE_SHORT) && 292 | (this->shortUUID == other.shortUUID)) { 293 | return true; 294 | } 295 | 296 | if ((this->type == UUID_TYPE_LONG) && (other.type == UUID_TYPE_LONG) && 297 | (memcmp(this->baseUUID, other.baseUUID, LENGTH_OF_LONG_UUID) == 0)) { 298 | return true; 299 | } 300 | 301 | return false; 302 | } 303 | 304 | /** 305 | * Overload != operator to enable UUID comparisons. 306 | * 307 | * @param[in] other 308 | * The other UUID in the comparison. 309 | * 310 | * @return true if this != @p other, false otherwise. 311 | */ 312 | bool operator!= (const UUID &other) const { 313 | return !(*this == other); 314 | } 315 | 316 | private: 317 | /** 318 | * The UUID type. Refer to UUID_Type_t. 319 | */ 320 | UUID_Type_t type; 321 | /** 322 | * The long UUID value. 323 | */ 324 | LongUUIDBytes_t baseUUID; 325 | /** 326 | * The short UUID value. 327 | */ 328 | ShortUUIDBytes_t shortUUID; 329 | }; 330 | 331 | #endif // ifndef __UUID_H__ 332 | -------------------------------------------------------------------------------- /ble/blecommon.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __BLE_COMMON_H__ 18 | #define __BLE_COMMON_H__ 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | 25 | /*! @brief Assigned values for BLE UUIDs. */ 26 | enum { 27 | BLE_UUID_UNKNOWN = 0x0000, /**< Reserved UUID. */ 28 | BLE_UUID_SERVICE_PRIMARY = 0x2800, /**< Primary Service. */ 29 | BLE_UUID_SERVICE_SECONDARY = 0x2801, /**< Secondary Service. */ 30 | BLE_UUID_SERVICE_INCLUDE = 0x2802, /**< Include. */ 31 | BLE_UUID_CHARACTERISTIC = 0x2803, /**< Characteristic. */ 32 | BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP = 0x2900, /**< Characteristic Extended Properties Descriptor. */ 33 | BLE_UUID_DESCRIPTOR_CHAR_USER_DESC = 0x2901, /**< Characteristic User Description Descriptor. */ 34 | BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG = 0x2902, /**< Client Characteristic Configuration Descriptor. */ 35 | BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG = 0x2903, /**< Server Characteristic Configuration Descriptor. */ 36 | BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT = 0x2904, /**< Characteristic Presentation Format Descriptor. */ 37 | BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT = 0x2905, /**< Characteristic Aggregate Format Descriptor. */ 38 | 39 | /* GATT specific UUIDs */ 40 | BLE_UUID_GATT = 0x1801, /**< Generic Attribute Profile. */ 41 | BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED = 0x2A05, /**< Service Changed Characteristic. */ 42 | 43 | /* GAP specific UUIDs */ 44 | BLE_UUID_GAP = 0x1800, /**< Generic Access Profile. */ 45 | BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME = 0x2A00, /**< Device Name Characteristic. */ 46 | BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE = 0x2A01, /**< Appearance Characteristic. */ 47 | BLE_UUID_GAP_CHARACTERISTIC_PPF = 0x2A02, /**< Peripheral Privacy Flag Characteristic. */ 48 | BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR = 0x2A03, /**< Reconnection Address Characteristic. */ 49 | BLE_UUID_GAP_CHARACTERISTIC_PPCP = 0x2A04, /**< Peripheral Preferred Connection Parameters Characteristic. */ 50 | }; 51 | 52 | /*! @brief Error codes for the BLE API. */ 53 | enum ble_error_t { 54 | BLE_ERROR_NONE = 0, /**< No error. */ 55 | BLE_ERROR_BUFFER_OVERFLOW = 1, /**< The requested action would cause a buffer overflow and has been aborted. */ 56 | BLE_ERROR_NOT_IMPLEMENTED = 2, /**< Requested a feature that isn't yet implemented or isn't supported by the target HW. */ 57 | BLE_ERROR_PARAM_OUT_OF_RANGE = 3, /**< One of the supplied parameters is outside the valid range. */ 58 | BLE_ERROR_INVALID_PARAM = 4, /**< One of the supplied parameters is invalid. */ 59 | BLE_STACK_BUSY = 5, /**< The stack is busy. */ 60 | BLE_ERROR_INVALID_STATE = 6, /**< Invalid state. */ 61 | BLE_ERROR_NO_MEM = 7, /**< Out of memory */ 62 | BLE_ERROR_OPERATION_NOT_PERMITTED = 8, 63 | BLE_ERROR_INITIALIZATION_INCOMPLETE = 9, 64 | BLE_ERROR_ALREADY_INITIALIZED = 10, 65 | BLE_ERROR_UNSPECIFIED = 11, /**< Unknown error. */ 66 | BLE_ERROR_INTERNAL_STACK_FAILURE = 12, /**< The platform-specific stack failed */ 67 | }; 68 | 69 | /** @brief Default MTU size. */ 70 | static const unsigned BLE_GATT_MTU_SIZE_DEFAULT = 23; 71 | 72 | enum HVXType_t { 73 | BLE_HVX_NOTIFICATION = 0x01, /**< Handle Value Notification. */ 74 | BLE_HVX_INDICATION = 0x02, /**< Handle Value Indication. */ 75 | }; 76 | 77 | #ifdef __cplusplus 78 | } 79 | #endif 80 | 81 | #endif // ifndef __BLE_COMMON_H__ 82 | -------------------------------------------------------------------------------- /ble/deprecate.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __DEPRECATE_H__ 18 | #define __DEPRECATE_H__ 19 | 20 | #ifdef YOTTA_CFG_MBED_OS 21 | #include "compiler-polyfill/attributes.h" 22 | #else 23 | #define __deprecated_message(msg) 24 | #endif 25 | 26 | #endif -------------------------------------------------------------------------------- /ble/services/BatteryService.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __BLE_BATTERY_SERVICE_H__ 18 | #define __BLE_BATTERY_SERVICE_H__ 19 | 20 | #include "ble/BLE.h" 21 | 22 | /** 23 | * @class BatteryService 24 | * @brief BLE Battery Service. This service displays the battery level from 0% to 100%, represented as an 8bit number. 25 | * Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml 26 | * Battery Level Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.battery_level.xml 27 | */ 28 | class BatteryService { 29 | public: 30 | /** 31 | * @param[in] _ble 32 | * BLE object for the underlying controller. 33 | * @param[in] level 34 | * 8bit batterly level. Usually used to represent percentage of batterly charge remaining. 35 | */ 36 | BatteryService(BLE &_ble, uint8_t level = 100) : 37 | ble(_ble), 38 | batteryLevel(level), 39 | batteryLevelCharacteristic(GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, &batteryLevel, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) { 40 | 41 | GattCharacteristic *charTable[] = {&batteryLevelCharacteristic}; 42 | GattService batteryService(GattService::UUID_BATTERY_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); 43 | 44 | ble.addService(batteryService); 45 | } 46 | 47 | /** 48 | * @brief Update the battery level with a new value. Valid values lie between 0 and 100, 49 | * anything outside this range will be ignored. 50 | * 51 | * @param newLevel 52 | * Update to battery level. 53 | */ 54 | void updateBatteryLevel(uint8_t newLevel) { 55 | batteryLevel = newLevel; 56 | ble.gattServer().write(batteryLevelCharacteristic.getValueHandle(), &batteryLevel, 1); 57 | } 58 | 59 | protected: 60 | /** 61 | * A reference to the underlying BLE instance that this object is attached to. 62 | * The services and characteristics will be registered in this BLE instance. 63 | */ 64 | BLE &ble; 65 | 66 | /** 67 | * The current battery level represented as an integer from 0% to 100%. 68 | */ 69 | uint8_t batteryLevel; 70 | /** 71 | * A ReadOnlyGattCharacteristic that allows access to the peer device to the 72 | * batteryLevel value through BLE. 73 | */ 74 | ReadOnlyGattCharacteristic batteryLevelCharacteristic; 75 | }; 76 | 77 | #endif /* #ifndef __BLE_BATTERY_SERVICE_H__*/ 78 | -------------------------------------------------------------------------------- /ble/services/DFUService.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifdef TARGET_NRF51822 /* DFU only supported on nrf51 platforms */ 18 | 19 | #ifndef __BLE_DFU_SERVICE_H__ 20 | #define __BLE_DFU_SERVICE_H__ 21 | 22 | #include "ble/BLE.h" 23 | #include "ble/UUID.h" 24 | 25 | extern "C" { 26 | #include "dfu_app_handler.h" 27 | } 28 | 29 | extern const uint8_t DFUServiceBaseUUID[]; 30 | extern const uint16_t DFUServiceShortUUID; 31 | extern const uint16_t DFUServiceControlCharacteristicShortUUID; 32 | 33 | extern const uint8_t DFUServiceUUID[]; 34 | extern const uint8_t DFUServiceControlCharacteristicUUID[]; 35 | extern const uint8_t DFUServicePacketCharacteristicUUID[]; 36 | 37 | /** 38 | * @class DFUService 39 | * @brief Device Firmware Update Service. 40 | */ 41 | class DFUService { 42 | public: 43 | /** 44 | * @brief Signature for the handover callback. The application may provide this 45 | * callback when setting up the DFU service. The callback is then 46 | * invoked before handing control over to the bootloader. 47 | */ 48 | typedef void (*ResetPrepare_t)(void); 49 | 50 | public: 51 | /** 52 | * @brief Adds Device Firmware Update Service to an existing BLE object. 53 | * 54 | * @param[ref] _ble 55 | * BLE object for the underlying controller. 56 | * @param[in] _handoverCallback 57 | * Application-specific handover callback. 58 | */ 59 | DFUService(BLE &_ble, ResetPrepare_t _handoverCallback = NULL) : 60 | ble(_ble), 61 | controlPoint(DFUServiceControlCharacteristicUUID, controlBytes, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 62 | packet(DFUServicePacketCharacteristicUUID, packetBytes, SIZEOF_PACKET_BYTES, SIZEOF_PACKET_BYTES, 63 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE), 64 | controlBytes(), 65 | packetBytes() { 66 | static bool serviceAdded = false; /* We only add the DFU service once. */ 67 | if (serviceAdded) { 68 | return; 69 | } 70 | 71 | /* Set an initial value for control bytes, so that the application's DFU service can 72 | * be distinguished from the real DFU service provided by the bootloader. */ 73 | controlBytes[0] = 0xFF; 74 | controlBytes[1] = 0xFF; 75 | 76 | GattCharacteristic *dfuChars[] = {&controlPoint, &packet}; 77 | GattService dfuService(DFUServiceUUID, dfuChars, sizeof(dfuChars) / sizeof(GattCharacteristic *)); 78 | 79 | ble.addService(dfuService); 80 | handoverCallback = _handoverCallback; 81 | serviceAdded = true; 82 | 83 | ble.onDataWritten(this, &DFUService::onDataWritten); 84 | } 85 | 86 | /** 87 | * @brief Get the handle for the value attribute of the control characteristic. 88 | */ 89 | uint16_t getControlHandle(void) const { 90 | return controlPoint.getValueHandle(); 91 | } 92 | 93 | /** 94 | * @brief This callback allows the DFU service to receive the initial trigger to 95 | * hand control over to the bootloader. First, the application is given a 96 | * chance to clean up. 97 | * 98 | * @param[in] params 99 | * Information about the characterisitc being updated. 100 | */ 101 | virtual void onDataWritten(const GattWriteCallbackParams *params) { 102 | if (params->handle == controlPoint.getValueHandle()) { 103 | /* At present, writing anything will do the trick - this needs to be improved. */ 104 | if (handoverCallback) { 105 | handoverCallback(); 106 | } 107 | 108 | // Call bootloader_start implicitly trough a event handler call 109 | // it is a work around for bootloader_start not being public in sdk 8.1 110 | ble_dfu_t p_dfu; 111 | ble_dfu_evt_t p_evt; 112 | 113 | p_dfu.conn_handle = params->connHandle; 114 | p_evt.ble_dfu_evt_type = BLE_DFU_START; 115 | 116 | dfu_app_on_dfu_evt(&p_dfu, &p_evt); 117 | } 118 | } 119 | 120 | protected: 121 | static const unsigned SIZEOF_CONTROL_BYTES = 2; 122 | static const unsigned SIZEOF_PACKET_BYTES = 20; 123 | 124 | protected: 125 | BLE &ble; 126 | 127 | /**< Writing to the control characteristic triggers the handover to DFU 128 | * bootloader. At present, writing anything will do the trick - this needs 129 | * to be improved. */ 130 | WriteOnlyArrayGattCharacteristic controlPoint; 131 | 132 | /**< The packet characteristic in this service doesn't do anything meaningful; 133 | * it is only a placeholder to mimic the corresponding characteristic in the 134 | * actual DFU service implemented by the bootloader. Without this, some 135 | * FOTA clients might get confused, because service definitions change after 136 | * handing control over to the bootloader. */ 137 | GattCharacteristic packet; 138 | 139 | uint8_t controlBytes[SIZEOF_CONTROL_BYTES]; 140 | uint8_t packetBytes[SIZEOF_PACKET_BYTES]; 141 | 142 | static ResetPrepare_t handoverCallback; /**< Application-specific handover callback. */ 143 | }; 144 | 145 | #endif /* #ifndef __BLE_DFU_SERVICE_H__*/ 146 | #endif /* #ifdef TARGET_NRF51822 */ 147 | -------------------------------------------------------------------------------- /ble/services/DeviceInformationService.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __BLE_DEVICE_INFORMATION_SERVICE_H__ 18 | #define __BLE_DEVICE_INFORMATION_SERVICE_H__ 19 | 20 | #include "ble/BLE.h" 21 | 22 | /** 23 | * @class DeviceInformationService 24 | * @brief BLE Device Information Service 25 | * Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.device_information.xml 26 | * Manufacturer Name String Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.manufacturer_name_string.xml 27 | */ 28 | class DeviceInformationService { 29 | public: 30 | /** 31 | * @brief Device Information Service Constructor: copies device-specific information 32 | * into the BLE stack. 33 | * 34 | * @param[in] _ble 35 | * A reference to a BLE object for the underlying controller. 36 | * @param[in] manufacturersName 37 | * The name of the manufacturer of the device. 38 | * @param[in] modelNumber 39 | * The model number that is assigned by the device vendor. 40 | * @param[in] serialNumber 41 | * The serial number for a particular instance of the device. 42 | * @param[in] hardwareRevision 43 | * The hardware revision for the hardware within the device. 44 | * @param[in] firmwareRevision 45 | * The device's firmware version. 46 | * @param[in] softwareRevision 47 | * The device's software version. 48 | */ 49 | DeviceInformationService(BLE &_ble, 50 | const char *manufacturersName = NULL, 51 | const char *modelNumber = NULL, 52 | const char *serialNumber = NULL, 53 | const char *hardwareRevision = NULL, 54 | const char *firmwareRevision = NULL, 55 | const char *softwareRevision = NULL) : 56 | ble(_ble), 57 | manufacturersNameStringCharacteristic(GattCharacteristic::UUID_MANUFACTURER_NAME_STRING_CHAR, 58 | (uint8_t *)manufacturersName, 59 | (manufacturersName != NULL) ? strlen(manufacturersName) : 0, /* Min length */ 60 | (manufacturersName != NULL) ? strlen(manufacturersName) : 0, /* Max length */ 61 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), 62 | modelNumberStringCharacteristic(GattCharacteristic::UUID_MODEL_NUMBER_STRING_CHAR, 63 | (uint8_t *)modelNumber, 64 | (modelNumber != NULL) ? strlen(modelNumber) : 0, /* Min length */ 65 | (modelNumber != NULL) ? strlen(modelNumber) : 0, /* Max length */ 66 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), 67 | serialNumberStringCharacteristic(GattCharacteristic::UUID_SERIAL_NUMBER_STRING_CHAR, 68 | (uint8_t *)serialNumber, 69 | (serialNumber != NULL) ? strlen(serialNumber) : 0, /* Min length */ 70 | (serialNumber != NULL) ? strlen(serialNumber) : 0, /* Max length */ 71 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), 72 | hardwareRevisionStringCharacteristic(GattCharacteristic::UUID_HARDWARE_REVISION_STRING_CHAR, 73 | (uint8_t *)hardwareRevision, 74 | (hardwareRevision != NULL) ? strlen(hardwareRevision) : 0, /* Min length */ 75 | (hardwareRevision != NULL) ? strlen(hardwareRevision) : 0, /* Max length */ 76 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), 77 | firmwareRevisionStringCharacteristic(GattCharacteristic::UUID_FIRMWARE_REVISION_STRING_CHAR, 78 | (uint8_t *)firmwareRevision, 79 | (firmwareRevision != NULL) ? strlen(firmwareRevision) : 0, /* Min length */ 80 | (firmwareRevision != NULL) ? strlen(firmwareRevision) : 0, /* Max length */ 81 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), 82 | softwareRevisionStringCharacteristic(GattCharacteristic::UUID_SOFTWARE_REVISION_STRING_CHAR, 83 | (uint8_t *)softwareRevision, 84 | (softwareRevision != NULL) ? strlen(softwareRevision) : 0, /* Min length */ 85 | (softwareRevision != NULL) ? strlen(softwareRevision) : 0, /* Max length */ 86 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ) 87 | { 88 | static bool serviceAdded = false; /* We only add the information service once. */ 89 | if (serviceAdded) { 90 | return; 91 | } 92 | 93 | GattCharacteristic *charTable[] = {&manufacturersNameStringCharacteristic, 94 | &modelNumberStringCharacteristic, 95 | &serialNumberStringCharacteristic, 96 | &hardwareRevisionStringCharacteristic, 97 | &firmwareRevisionStringCharacteristic, 98 | &softwareRevisionStringCharacteristic}; 99 | GattService deviceInformationService(GattService::UUID_DEVICE_INFORMATION_SERVICE, charTable, 100 | sizeof(charTable) / sizeof(GattCharacteristic *)); 101 | 102 | ble.addService(deviceInformationService); 103 | serviceAdded = true; 104 | } 105 | 106 | protected: 107 | /** 108 | * A reference to the BLE instance object to which the services and 109 | * characteristics will be added. 110 | */ 111 | BLE &ble; 112 | /** 113 | * BLE characterising to allow BLE peers access to the manufacturer's name. 114 | */ 115 | GattCharacteristic manufacturersNameStringCharacteristic; 116 | /** 117 | * BLE characterising to allow BLE peers access to the model number. 118 | */ 119 | GattCharacteristic modelNumberStringCharacteristic; 120 | /** 121 | * BLE characterising to allow BLE peers access to the serial number. 122 | */ 123 | GattCharacteristic serialNumberStringCharacteristic; 124 | /** 125 | * BLE characterising to allow BLE peers access to the hardware revision string. 126 | */ 127 | GattCharacteristic hardwareRevisionStringCharacteristic; 128 | /** 129 | * BLE characterising to allow BLE peers access to the firmware revision string. 130 | */ 131 | GattCharacteristic firmwareRevisionStringCharacteristic; 132 | /** 133 | * BLE characterising to allow BLE peers access to the software revision string. 134 | */ 135 | GattCharacteristic softwareRevisionStringCharacteristic; 136 | }; 137 | 138 | #endif /* #ifndef __BLE_DEVICE_INFORMATION_SERVICE_H__*/ 139 | -------------------------------------------------------------------------------- /ble/services/EnvironmentalService.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __BLE_ENVIRONMENTAL_SERVICE_H__ 18 | #define __BLE_ENVIRONMENTAL_SERVICE_H__ 19 | 20 | #include "ble/BLE.h" 21 | 22 | /** 23 | * @class EnvironmentalService 24 | * @brief BLE Environmental Service. This service provides temperature, humidity and pressure measurement. 25 | * Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.environmental_sensing.xml 26 | * Temperature: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature.xml 27 | * Humidity: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.humidity.xml 28 | * Pressure: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.pressure.xml 29 | */ 30 | class EnvironmentalService { 31 | public: 32 | typedef int16_t TemperatureType_t; 33 | typedef uint16_t HumidityType_t; 34 | typedef uint32_t PressureType_t; 35 | 36 | /** 37 | * @brief EnvironmentalService constructor. 38 | * @param ble Reference to BLE device. 39 | * @param temperature_en Enable this characteristic. 40 | * @param humidity_en Enable this characteristic. 41 | * @param pressure_en Enable this characteristic. 42 | */ 43 | EnvironmentalService(BLE& _ble) : 44 | ble(_ble), 45 | temperatureCharacteristic(GattCharacteristic::UUID_TEMPERATURE_CHAR, &temperature), 46 | humidityCharacteristic(GattCharacteristic::UUID_HUMIDITY_CHAR, &humidity), 47 | pressureCharacteristic(GattCharacteristic::UUID_PRESSURE_CHAR, &pressure) 48 | { 49 | static bool serviceAdded = false; /* We should only ever need to add the information service once. */ 50 | if (serviceAdded) { 51 | return; 52 | } 53 | 54 | GattCharacteristic *charTable[] = { &humidityCharacteristic, 55 | &pressureCharacteristic, 56 | &temperatureCharacteristic }; 57 | 58 | GattService environmentalService(GattService::UUID_ENVIRONMENTAL_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); 59 | 60 | ble.gattServer().addService(environmentalService); 61 | serviceAdded = true; 62 | } 63 | 64 | /** 65 | * @brief Update humidity characteristic. 66 | * @param newHumidityVal New humidity measurement. 67 | */ 68 | void updateHumidity(HumidityType_t newHumidityVal) 69 | { 70 | humidity = (HumidityType_t) (newHumidityVal * 100); 71 | ble.gattServer().write(humidityCharacteristic.getValueHandle(), (uint8_t *) &humidity, sizeof(HumidityType_t)); 72 | } 73 | 74 | /** 75 | * @brief Update pressure characteristic. 76 | * @param newPressureVal New pressure measurement. 77 | */ 78 | void updatePressure(PressureType_t newPressureVal) 79 | { 80 | pressure = (PressureType_t) (newPressureVal * 10); 81 | ble.gattServer().write(pressureCharacteristic.getValueHandle(), (uint8_t *) &pressure, sizeof(PressureType_t)); 82 | } 83 | 84 | /** 85 | * @brief Update temperature characteristic. 86 | * @param newTemperatureVal New temperature measurement. 87 | */ 88 | void updateTemperature(float newTemperatureVal) 89 | { 90 | temperature = (TemperatureType_t) (newTemperatureVal * 100); 91 | ble.gattServer().write(temperatureCharacteristic.getValueHandle(), (uint8_t *) &temperature, sizeof(TemperatureType_t)); 92 | } 93 | 94 | private: 95 | BLE& ble; 96 | 97 | TemperatureType_t temperature; 98 | HumidityType_t humidity; 99 | PressureType_t pressure; 100 | 101 | ReadOnlyGattCharacteristic temperatureCharacteristic; 102 | ReadOnlyGattCharacteristic humidityCharacteristic; 103 | ReadOnlyGattCharacteristic pressureCharacteristic; 104 | }; 105 | 106 | #endif /* #ifndef __BLE_ENVIRONMENTAL_SERVICE_H__*/ 107 | -------------------------------------------------------------------------------- /ble/services/HealthThermometerService.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __BLE_HEALTH_THERMOMETER_SERVICE_H__ 18 | #define __BLE_HEALTH_THERMOMETER_SERVICE_H__ 19 | 20 | #include "ble/BLE.h" 21 | 22 | /** 23 | * @class HealthThermometerService 24 | * @brief BLE Health Thermometer Service. This service provides the location of the thermometer and the temperature. 25 | * Service: https://developer.bluetooth.org/gatt/profiles/Pages/ProfileViewer.aspx?u=org.bluetooth.profile.health_thermometer.xml 26 | * Temperature Measurement: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_measurement.xml 27 | * Temperature Type: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_type.xml 28 | */ 29 | class HealthThermometerService { 30 | public: 31 | /** 32 | * @enum Sensor Location. 33 | * @brief Location of sensor on the body. 34 | */ 35 | enum SensorLocation_t { 36 | LOCATION_ARMPIT = 1, /*!< Armpit. */ 37 | LOCATION_BODY, /*!< Body. */ 38 | LOCATION_EAR, /*!< Ear. */ 39 | LOCATION_FINGER, /*!< Finger. */ 40 | LOCATION_GI_TRACT, /*!< GI tract */ 41 | LOCATION_MOUTH, /*!< Mouth. */ 42 | LOCATION_RECTUM, /*!< Rectum. */ 43 | LOCATION_TOE, /*!< Toe. */ 44 | LOCATION_EAR_DRUM, /*!< Eardrum. */ 45 | }; 46 | 47 | public: 48 | /** 49 | * @brief Add the Health Thermometer Service to an existing BLE object, initialize with temperature and location. 50 | * @param[ref] _ble Reference to the BLE device. 51 | * @param[in] initialTemp Initial value in celsius. 52 | * @param[in] _location 53 | */ 54 | HealthThermometerService(BLE &_ble, float initialTemp, uint8_t _location) : 55 | ble(_ble), 56 | valueBytes(initialTemp), 57 | tempMeasurement(GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR, (TemperatureValueBytes *)valueBytes.getPointer(), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 58 | tempLocation(GattCharacteristic::UUID_TEMPERATURE_TYPE_CHAR, &_location) { 59 | 60 | GattCharacteristic *hrmChars[] = {&tempMeasurement, &tempLocation, }; 61 | GattService hrmService(GattService::UUID_HEALTH_THERMOMETER_SERVICE, hrmChars, sizeof(hrmChars) / sizeof(GattCharacteristic *)); 62 | 63 | ble.addService(hrmService); 64 | } 65 | 66 | /** 67 | * @brief Update the temperature being broadcast. 68 | * 69 | * @param[in] temperature 70 | * Floating point value of the temperature. 71 | * 72 | */ 73 | void updateTemperature(float temperature) { 74 | if (ble.getGapState().connected) { 75 | valueBytes.updateTemperature(temperature); 76 | ble.gattServer().write(tempMeasurement.getValueHandle(), valueBytes.getPointer(), sizeof(TemperatureValueBytes)); 77 | } 78 | } 79 | 80 | /** 81 | * @brief Update the location. 82 | * @param loc 83 | * New location value. 84 | */ 85 | void updateLocation(SensorLocation_t loc) { 86 | ble.gattServer().write(tempLocation.getValueHandle(), reinterpret_cast(&loc), sizeof(uint8_t)); 87 | } 88 | 89 | private: 90 | /* Private internal representation for the bytes used to work with the vaulue of the temperature characteristic. */ 91 | struct TemperatureValueBytes { 92 | static const unsigned OFFSET_OF_FLAGS = 0; 93 | static const unsigned OFFSET_OF_VALUE = OFFSET_OF_FLAGS + sizeof(uint8_t); 94 | static const unsigned SIZEOF_VALUE_BYTES = sizeof(uint8_t) + sizeof(float); 95 | 96 | static const unsigned TEMPERATURE_UNITS_FLAG_POS = 0; 97 | static const unsigned TIMESTAMP_FLAG_POS = 1; 98 | static const unsigned TEMPERATURE_TYPE_FLAG_POS = 2; 99 | 100 | static const uint8_t TEMPERATURE_UNITS_CELSIUS = 0; 101 | static const uint8_t TEMPERATURE_UNITS_FAHRENHEIT = 1; 102 | 103 | TemperatureValueBytes(float initialTemperature) : bytes() { 104 | /* Assumption: temperature values are expressed in celsius */ 105 | bytes[OFFSET_OF_FLAGS] = (TEMPERATURE_UNITS_CELSIUS << TEMPERATURE_UNITS_FLAG_POS) | 106 | (false << TIMESTAMP_FLAG_POS) | 107 | (false << TEMPERATURE_TYPE_FLAG_POS); 108 | updateTemperature(initialTemperature); 109 | } 110 | 111 | void updateTemperature(float temp) { 112 | uint32_t temp_ieee11073 = quick_ieee11073_from_float(temp); 113 | memcpy(&bytes[OFFSET_OF_VALUE], &temp_ieee11073, sizeof(float)); 114 | } 115 | 116 | uint8_t *getPointer(void) { 117 | return bytes; 118 | } 119 | 120 | const uint8_t *getPointer(void) const { 121 | return bytes; 122 | } 123 | 124 | private: 125 | /** 126 | * @brief A very quick conversion between a float temperature and 11073-20601 FLOAT-Type. 127 | * @param temperature The temperature as a float. 128 | * @return The temperature in 11073-20601 FLOAT-Type format. 129 | */ 130 | uint32_t quick_ieee11073_from_float(float temperature) { 131 | uint8_t exponent = 0xFE; //Exponent is -2 132 | uint32_t mantissa = (uint32_t)(temperature * 100); 133 | 134 | return (((uint32_t)exponent) << 24) | mantissa; 135 | } 136 | 137 | private: 138 | /* First byte: 8-bit flags. Second field is a float holding the temperature value. */ 139 | /* See https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.temperature_measurement.xml */ 140 | uint8_t bytes[SIZEOF_VALUE_BYTES]; 141 | }; 142 | 143 | protected: 144 | BLE &ble; 145 | TemperatureValueBytes valueBytes; 146 | ReadOnlyGattCharacteristic tempMeasurement; 147 | ReadOnlyGattCharacteristic tempLocation; 148 | }; 149 | 150 | #endif /* #ifndef __BLE_HEALTH_THERMOMETER_SERVICE_H__*/ 151 | -------------------------------------------------------------------------------- /ble/services/HeartRateService.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __BLE_HEART_RATE_SERVICE_H__ 18 | #define __BLE_HEART_RATE_SERVICE_H__ 19 | 20 | #include "ble/BLE.h" 21 | 22 | /** 23 | * @class HeartRateService 24 | * @brief BLE Service for HeartRate. This BLE Service contains the location of the sensor and the heart rate in beats per minute. 25 | * Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.heart_rate.xml 26 | * HRM Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml 27 | * Location: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.body_sensor_location.xml 28 | */ 29 | class HeartRateService { 30 | public: 31 | /** 32 | * @enum SensorLocation 33 | * @brief Location of the heart rate sensor on body. 34 | */ 35 | enum { 36 | LOCATION_OTHER = 0, /*!< Other location. */ 37 | LOCATION_CHEST, /*!< Chest. */ 38 | LOCATION_WRIST, /*!< Wrist. */ 39 | LOCATION_FINGER, /*!< Finger. */ 40 | LOCATION_HAND, /*!< Hand. */ 41 | LOCATION_EAR_LOBE, /*!< Earlobe. */ 42 | LOCATION_FOOT, /*!< Foot. */ 43 | }; 44 | 45 | public: 46 | /** 47 | * @brief Constructor with 8-bit HRM Counter value. 48 | * 49 | * @param[ref] _ble 50 | * Reference to the underlying BLE. 51 | * @param[in] hrmCounter (8-bit) 52 | * Initial value for the HRM counter. 53 | * @param[in] location 54 | * Sensor's location. 55 | */ 56 | HeartRateService(BLE &_ble, uint8_t hrmCounter, uint8_t location) : 57 | ble(_ble), 58 | valueBytes(hrmCounter), 59 | hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(), 60 | valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES, 61 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 62 | hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, &location), 63 | controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, &controlPointValue) { 64 | setupService(); 65 | } 66 | 67 | /** 68 | * @brief Constructor with a 16-bit HRM Counter value. 69 | * 70 | * @param[in] _ble 71 | * Reference to the underlying BLE. 72 | * @param[in] hrmCounter (8-bit) 73 | * Initial value for the HRM counter. 74 | * @param[in] location 75 | * Sensor's location. 76 | */ 77 | HeartRateService(BLE &_ble, uint16_t hrmCounter, uint8_t location) : 78 | ble(_ble), 79 | valueBytes(hrmCounter), 80 | hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, valueBytes.getPointer(), 81 | valueBytes.getNumValueBytes(), HeartRateValueBytes::MAX_VALUE_BYTES, 82 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), 83 | hrmLocation(GattCharacteristic::UUID_BODY_SENSOR_LOCATION_CHAR, &location), 84 | controlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, &controlPointValue) { 85 | setupService(); 86 | } 87 | 88 | /** 89 | * @brief Set a new 8-bit value for the heart rate. 90 | * 91 | * @param[in] hrmCounter 92 | * Heart rate in BPM. 93 | */ 94 | void updateHeartRate(uint8_t hrmCounter) { 95 | valueBytes.updateHeartRate(hrmCounter); 96 | ble.gattServer().write(hrmRate.getValueHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes()); 97 | } 98 | 99 | /** 100 | * Set a new 16-bit value for the heart rate. 101 | * 102 | * @param[in] hrmCounter 103 | * Heart rate in BPM. 104 | */ 105 | void updateHeartRate(uint16_t hrmCounter) { 106 | valueBytes.updateHeartRate(hrmCounter); 107 | ble.gattServer().write(hrmRate.getValueHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes()); 108 | } 109 | 110 | /** 111 | * This callback allows the heart rate service to receive updates to the 112 | * controlPoint characteristic. 113 | * 114 | * @param[in] params 115 | * Information about the characterisitc being updated. 116 | */ 117 | virtual void onDataWritten(const GattWriteCallbackParams *params) { 118 | if (params->handle == controlPoint.getValueAttribute().getHandle()) { 119 | /* Do something here if the new value is 1; else you can override this method by 120 | * extending this class. 121 | * @NOTE: If you are extending this class, be sure to also call 122 | * ble.onDataWritten(this, &ExtendedHRService::onDataWritten); in 123 | * your constructor. 124 | */ 125 | } 126 | } 127 | 128 | protected: 129 | void setupService(void) { 130 | GattCharacteristic *charTable[] = {&hrmRate, &hrmLocation, &controlPoint}; 131 | GattService hrmService(GattService::UUID_HEART_RATE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); 132 | 133 | ble.addService(hrmService); 134 | ble.onDataWritten(this, &HeartRateService::onDataWritten); 135 | } 136 | 137 | protected: 138 | /* Private internal representation for the bytes used to work with the value of the heart rate characteristic. */ 139 | struct HeartRateValueBytes { 140 | static const unsigned MAX_VALUE_BYTES = 3; /* Flags, and up to two bytes for heart rate. */ 141 | static const unsigned FLAGS_BYTE_INDEX = 0; 142 | 143 | static const unsigned VALUE_FORMAT_BITNUM = 0; 144 | static const uint8_t VALUE_FORMAT_FLAG = (1 << VALUE_FORMAT_BITNUM); 145 | 146 | HeartRateValueBytes(uint8_t hrmCounter) : valueBytes() { 147 | updateHeartRate(hrmCounter); 148 | } 149 | 150 | HeartRateValueBytes(uint16_t hrmCounter) : valueBytes() { 151 | updateHeartRate(hrmCounter); 152 | } 153 | 154 | void updateHeartRate(uint8_t hrmCounter) { 155 | valueBytes[FLAGS_BYTE_INDEX] &= ~VALUE_FORMAT_FLAG; 156 | valueBytes[FLAGS_BYTE_INDEX + 1] = hrmCounter; 157 | } 158 | 159 | void updateHeartRate(uint16_t hrmCounter) { 160 | valueBytes[FLAGS_BYTE_INDEX] |= VALUE_FORMAT_FLAG; 161 | valueBytes[FLAGS_BYTE_INDEX + 1] = (uint8_t)(hrmCounter & 0xFF); 162 | valueBytes[FLAGS_BYTE_INDEX + 2] = (uint8_t)(hrmCounter >> 8); 163 | } 164 | 165 | uint8_t *getPointer(void) { 166 | return valueBytes; 167 | } 168 | 169 | const uint8_t *getPointer(void) const { 170 | return valueBytes; 171 | } 172 | 173 | unsigned getNumValueBytes(void) const { 174 | return 1 + ((valueBytes[FLAGS_BYTE_INDEX] & VALUE_FORMAT_FLAG) ? sizeof(uint16_t) : sizeof(uint8_t)); 175 | } 176 | 177 | private: 178 | /* First byte: 8-bit values, no extra info. Second byte: uint8_t HRM value */ 179 | /* See https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */ 180 | uint8_t valueBytes[MAX_VALUE_BYTES]; 181 | }; 182 | 183 | protected: 184 | BLE &ble; 185 | 186 | HeartRateValueBytes valueBytes; 187 | uint8_t controlPointValue; 188 | 189 | GattCharacteristic hrmRate; 190 | ReadOnlyGattCharacteristic hrmLocation; 191 | WriteOnlyGattCharacteristic controlPoint; 192 | }; 193 | 194 | #endif /* #ifndef __BLE_HEART_RATE_SERVICE_H__*/ 195 | -------------------------------------------------------------------------------- /ble/services/LinkLossService.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __BLE_LINK_LOSS_SERVICE_H__ 18 | #define __BLE_LINK_LOSS_SERVICE_H__ 19 | 20 | #include "ble/Gap.h" 21 | 22 | /** 23 | * @class LinkLossService 24 | * @brief This service defines behavior when a link is lost between two devices. 25 | * Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.link_loss.xml 26 | * Alertness Level Char: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.alert_level.xml 27 | */ 28 | class LinkLossService { 29 | public: 30 | enum AlertLevel_t { 31 | NO_ALERT = 0, 32 | MILD_ALERT = 1, 33 | HIGH_ALERT = 2 34 | }; 35 | 36 | typedef void (* callback_t)(AlertLevel_t level); 37 | 38 | /** 39 | * @param[ref] ble 40 | * BLE object for the underlying controller. 41 | */ 42 | LinkLossService(BLE &bleIn, callback_t callbackIn, AlertLevel_t levelIn = NO_ALERT) : 43 | ble(bleIn), 44 | alertLevel(levelIn), 45 | callback(callbackIn), 46 | alertLevelChar(GattCharacteristic::UUID_ALERT_LEVEL_CHAR, reinterpret_cast(&alertLevel)) { 47 | static bool serviceAdded = false; /* We should only ever add one LinkLoss service. */ 48 | if (serviceAdded) { 49 | return; 50 | } 51 | 52 | GattCharacteristic *charTable[] = {&alertLevelChar}; 53 | GattService linkLossService(GattService::UUID_LINK_LOSS_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); 54 | 55 | ble.gattServer().addService(linkLossService); 56 | serviceAdded = true; 57 | 58 | ble.gap().onDisconnection(this, &LinkLossService::onDisconnectionFilter); 59 | ble.gattServer().onDataWritten(this, &LinkLossService::onDataWritten); 60 | } 61 | 62 | /** 63 | * Update the callback. 64 | */ 65 | void setCallback(callback_t newCallback) { 66 | callback = newCallback; 67 | } 68 | 69 | /** 70 | * Update alertness level. 71 | */ 72 | void setAlertLevel(AlertLevel_t newLevel) { 73 | alertLevel = newLevel; 74 | } 75 | 76 | protected: 77 | /** 78 | * This callback allows receiving updates to the AlertLevel characteristic. 79 | * 80 | * @param[in] params 81 | * Information about the characterisitc being updated. 82 | */ 83 | virtual void onDataWritten(const GattWriteCallbackParams *params) { 84 | if (params->handle == alertLevelChar.getValueHandle()) { 85 | alertLevel = *reinterpret_cast(params->data); 86 | } 87 | } 88 | 89 | void onDisconnectionFilter(const Gap::DisconnectionCallbackParams_t *params) { 90 | if (alertLevel != NO_ALERT) { 91 | callback(alertLevel); 92 | } 93 | } 94 | 95 | protected: 96 | BLE &ble; 97 | AlertLevel_t alertLevel; 98 | callback_t callback; 99 | 100 | ReadWriteGattCharacteristic alertLevelChar; 101 | }; 102 | 103 | #endif /* __BLE_LINK_LOSS_SERVICE_H__ */ 104 | -------------------------------------------------------------------------------- /ble/services/UARTService.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef __BLE_UART_SERVICE_H__ 18 | #define __BLE_UART_SERVICE_H__ 19 | 20 | #ifdef YOTTA_CFG_MBED_OS 21 | #include "mbed-drivers/mbed.h" 22 | #include "mbed-drivers/Stream.h" 23 | #else 24 | #include "mbed.h" 25 | #include "Stream.h" 26 | #endif 27 | 28 | #include "ble/UUID.h" 29 | #include "ble/BLE.h" 30 | 31 | extern const uint8_t UARTServiceBaseUUID[UUID::LENGTH_OF_LONG_UUID]; 32 | extern const uint16_t UARTServiceShortUUID; 33 | extern const uint16_t UARTServiceTXCharacteristicShortUUID; 34 | extern const uint16_t UARTServiceRXCharacteristicShortUUID; 35 | 36 | extern const uint8_t UARTServiceUUID[UUID::LENGTH_OF_LONG_UUID]; 37 | extern const uint8_t UARTServiceUUID_reversed[UUID::LENGTH_OF_LONG_UUID]; 38 | 39 | extern const uint8_t UARTServiceTXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID]; 40 | extern const uint8_t UARTServiceRXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID]; 41 | 42 | /** 43 | * @class UARTService. 44 | * @brief BLE Service to enable UART over BLE. 45 | */ 46 | class UARTService { 47 | public: 48 | /**< Maximum length of data (in bytes) that the UART service module can transmit to the peer. */ 49 | static const unsigned BLE_UART_SERVICE_MAX_DATA_LEN = (BLE_GATT_MTU_SIZE_DEFAULT - 3); 50 | 51 | public: 52 | 53 | /** 54 | * @param[ref] ble 55 | * BLE object for the underlying controller. 56 | */ 57 | UARTService(BLE &_ble) : 58 | ble(_ble), 59 | receiveBuffer(), 60 | sendBuffer(), 61 | sendBufferIndex(0), 62 | numBytesReceived(0), 63 | receiveBufferIndex(0), 64 | txCharacteristic(UARTServiceTXCharacteristicUUID, receiveBuffer, 1, BLE_UART_SERVICE_MAX_DATA_LEN, 65 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE), 66 | rxCharacteristic(UARTServiceRXCharacteristicUUID, sendBuffer, 1, BLE_UART_SERVICE_MAX_DATA_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) { 67 | GattCharacteristic *charTable[] = {&txCharacteristic, &rxCharacteristic}; 68 | GattService uartService(UARTServiceUUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); 69 | 70 | ble.addService(uartService); 71 | ble.onDataWritten(this, &UARTService::onDataWritten); 72 | } 73 | 74 | /** 75 | * Note: TX and RX characteristics are to be interpreted from the viewpoint of the GATT client using this service. 76 | */ 77 | uint16_t getTXCharacteristicHandle() { 78 | return txCharacteristic.getValueAttribute().getHandle(); 79 | } 80 | 81 | /** 82 | * Note: TX and RX characteristics are to be interpreted from the viewpoint of the GATT client using this service. 83 | */ 84 | uint16_t getRXCharacteristicHandle() { 85 | return rxCharacteristic.getValueAttribute().getHandle(); 86 | } 87 | 88 | /** 89 | * We attempt to collect bytes before pushing them to the UART RX 90 | * characteristic; writing to the RX characteristic then generates 91 | * notifications for the client. Updates made in quick succession to a 92 | * notification-generating characteristic result in data being buffered 93 | * in the Bluetooth stack as notifications are sent out. The stack has 94 | * its limits for this buffering - typically a small number under 10. 95 | * Collecting data into the sendBuffer buffer helps mitigate the rate of 96 | * updates. But we shouldn't buffer a large amount of data before updating 97 | * the characteristic, otherwise the client needs to turn around and make 98 | * a long read request; this is because notifications include only the first 99 | * 20 bytes of the updated data. 100 | * 101 | * @param buffer The received update. 102 | * @param length Number of characters to be appended. 103 | * @return Number of characters appended to the rxCharacteristic. 104 | */ 105 | size_t write(const void *_buffer, size_t length) { 106 | size_t origLength = length; 107 | const uint8_t *buffer = static_cast(_buffer); 108 | 109 | if (ble.getGapState().connected) { 110 | unsigned bufferIndex = 0; 111 | while (length) { 112 | unsigned bytesRemainingInSendBuffer = BLE_UART_SERVICE_MAX_DATA_LEN - sendBufferIndex; 113 | unsigned bytesToCopy = (length < bytesRemainingInSendBuffer) ? length : bytesRemainingInSendBuffer; 114 | 115 | /* Copy bytes into sendBuffer. */ 116 | memcpy(&sendBuffer[sendBufferIndex], &buffer[bufferIndex], bytesToCopy); 117 | length -= bytesToCopy; 118 | sendBufferIndex += bytesToCopy; 119 | bufferIndex += bytesToCopy; 120 | 121 | /* Have we collected enough? */ 122 | if ((sendBufferIndex == BLE_UART_SERVICE_MAX_DATA_LEN) || 123 | // (sendBuffer[sendBufferIndex - 1] == '\r') || 124 | (sendBuffer[sendBufferIndex - 1] == '\n')) { 125 | ble.gattServer().write(getRXCharacteristicHandle(), static_cast(sendBuffer), sendBufferIndex); 126 | sendBufferIndex = 0; 127 | } 128 | } 129 | } 130 | 131 | return origLength; 132 | } 133 | 134 | /** 135 | * Helper function to write out strings. 136 | * @param str The received string. 137 | * @return Number of characters appended to the rxCharacteristic. 138 | */ 139 | size_t writeString(const char *str) { 140 | return write(str, strlen(str)); 141 | } 142 | 143 | /** 144 | * Override for Stream::_putc(). 145 | * @param c 146 | * This function writes the character c, cast to an unsigned char, to stream. 147 | * @return 148 | * The character written as an unsigned char cast to an int or EOF on error. 149 | */ 150 | int _putc(int c) { 151 | return (write(&c, 1) == 1) ? 1 : EOF; 152 | } 153 | 154 | /** 155 | * Override for Stream::_getc(). 156 | * @return 157 | * The character read. 158 | */ 159 | int _getc() { 160 | if (receiveBufferIndex == numBytesReceived) { 161 | return EOF; 162 | } 163 | 164 | return receiveBuffer[receiveBufferIndex++]; 165 | } 166 | 167 | protected: 168 | /** 169 | * This callback allows the UART service to receive updates to the 170 | * txCharacteristic. The application should forward the call to this 171 | * function from the global onDataWritten() callback handler; if that's 172 | * not used, this method can be used as a callback directly. 173 | */ 174 | void onDataWritten(const GattWriteCallbackParams *params) { 175 | if (params->handle == getTXCharacteristicHandle()) { 176 | uint16_t bytesRead = params->len; 177 | if (bytesRead <= BLE_UART_SERVICE_MAX_DATA_LEN) { 178 | numBytesReceived = bytesRead; 179 | receiveBufferIndex = 0; 180 | memcpy(receiveBuffer, params->data, numBytesReceived); 181 | } 182 | } 183 | } 184 | 185 | protected: 186 | BLE &ble; 187 | 188 | uint8_t receiveBuffer[BLE_UART_SERVICE_MAX_DATA_LEN]; /**< The local buffer into which we receive 189 | * inbound data before forwarding it to the 190 | * application. */ 191 | 192 | uint8_t sendBuffer[BLE_UART_SERVICE_MAX_DATA_LEN]; /**< The local buffer into which outbound data is 193 | * accumulated before being pushed to the 194 | * rxCharacteristic. */ 195 | uint8_t sendBufferIndex; 196 | uint8_t numBytesReceived; 197 | uint8_t receiveBufferIndex; 198 | 199 | GattCharacteristic txCharacteristic; /**< From the point of view of the external client, this is the characteristic 200 | * they'd write into in order to communicate with this application. */ 201 | GattCharacteristic rxCharacteristic; /**< From the point of view of the external client, this is the characteristic 202 | * they'd read from in order to receive the bytes transmitted by this 203 | * application. */ 204 | }; 205 | 206 | #endif /* #ifndef __BLE_UART_SERVICE_H__*/ 207 | -------------------------------------------------------------------------------- /ble/services/iBeacon.h: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2015 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef __BLE_IBEACON_H__ 17 | #define __BLE_IBEACON_H__ 18 | 19 | #include "core_cmInstr.h" 20 | #include "ble/BLE.h" 21 | 22 | /** 23 | * @class iBeacon 24 | * @brief iBeacon Service. This sets up a device to broadcast advertising packets to mimic an iBeacon. 25 | */ 26 | class iBeacon 27 | { 28 | public: 29 | typedef const uint8_t LocationUUID_t[16]; 30 | 31 | union Payload { 32 | uint8_t raw[25]; 33 | struct { 34 | uint16_t companyID; 35 | uint8_t ID; 36 | uint8_t len; 37 | uint8_t proximityUUID[16]; 38 | uint16_t majorNumber; 39 | uint16_t minorNumber; 40 | uint8_t txPower; 41 | }; 42 | 43 | Payload(LocationUUID_t uuid, uint16_t majNum, uint16_t minNum, uint8_t transmitPower, uint16_t companyIDIn) : 44 | companyID(companyIDIn), ID(0x02), len(0x15), majorNumber(__REV16(majNum)), minorNumber(__REV16(minNum)), txPower(transmitPower) 45 | { 46 | memcpy(proximityUUID, uuid, sizeof(LocationUUID_t)); 47 | } 48 | }; 49 | 50 | public: 51 | iBeacon(BLE &_ble, 52 | LocationUUID_t uuid, 53 | uint16_t majNum, 54 | uint16_t minNum, 55 | uint8_t txP = 0xC8, 56 | uint16_t compID = 0x004C) : 57 | ble(_ble), data(uuid, majNum, minNum, txP, compID) 58 | { 59 | // Generate the 0x020106 part of the iBeacon Prefix. 60 | ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE ); 61 | // Generate the 0x1AFF part of the iBeacon Prefix. 62 | ble.accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, data.raw, sizeof(data.raw)); 63 | 64 | // Set advertising type. 65 | ble.setAdvertisingType(GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED); 66 | } 67 | 68 | protected: 69 | BLE &ble; 70 | Payload data; 71 | }; 72 | 73 | typedef iBeacon iBeaconService; /* This type-alias is deprecated. Please use iBeacon directly. This alias may be dropped from a future release. */ 74 | 75 | #endif //__BLE_IBEACON_H__ 76 | -------------------------------------------------------------------------------- /module.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ble", 3 | "version": "2.7.0", 4 | "description": "The BLE module offers a high level abstraction for using Bluetooth Low Energy on multiple platforms.", 5 | "keywords": [ 6 | "Bluetooth", 7 | "BLE", 8 | "mbed", 9 | "mbed-official" 10 | ], 11 | "author": "Rohit Grover", 12 | "repository": { 13 | "url": "https://github.com/ARMmbed/ble.git", 14 | "type": "git" 15 | }, 16 | "homepage": "https://developer.mbed.org/teams/Bluetooth-Low-Energy/", 17 | "licenses": [ 18 | { 19 | "url": "https://spdx.org/licenses/Apache-2.0", 20 | "type": "Apache-2.0" 21 | } 22 | ], 23 | "dependencies": {}, 24 | "targetDependencies": { 25 | "st-ble-shield": { 26 | "x-nucleo-idb0xa1": "^2.1.0" 27 | }, 28 | "nrf51822": { 29 | "ble-nrf51822": "^2.8.0" 30 | }, 31 | "nrf52832": { 32 | "ble-nrf52832": "ARMmbed/ble-nrf52832" 33 | }, 34 | "cordio": { 35 | "ble-wicentric": "~0.0.4" 36 | }, 37 | "mbed-classic": { 38 | "mbed-classic": "~0.0.1" 39 | }, 40 | "mbed-os": { 41 | "mbed-drivers": "*", 42 | "compiler-polyfill": "^1.2.1" 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /source/BLE.cpp: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "ble/BLE.h" 18 | #include "ble/BLEInstanceBase.h" 19 | 20 | #if defined(TARGET_OTA_ENABLED) 21 | #include "ble/services/DFUService.h" 22 | #endif 23 | 24 | #ifdef YOTTA_CFG_MBED_OS 25 | #include 26 | #endif 27 | 28 | #if !defined(YOTTA_CFG_MBED_OS) 29 | #include 30 | #include 31 | #endif 32 | 33 | ble_error_t 34 | BLE::initImplementation(FunctionPointerWithContext callback) 35 | { 36 | ble_error_t err = transport->init(instanceID, callback); 37 | if (err != BLE_ERROR_NONE) { 38 | return err; 39 | } 40 | 41 | /* Platforms enabled for DFU should introduce the DFU Service into 42 | * applications automatically. */ 43 | #if defined(TARGET_OTA_ENABLED) 44 | static DFUService dfu(*this); // defined static so that the object remains alive 45 | #endif // TARGET_OTA_ENABLED 46 | 47 | return BLE_ERROR_NONE; 48 | } 49 | 50 | /** 51 | * BLE::Instance() and BLE constructor rely upon a static array of initializers 52 | * to create actual BLE transport instances. A description of these instances 53 | * and initializers is supposed to be put in some .json file contributing to 54 | * yotta's configuration (typically in the target definition described by 55 | * target.json). Here's a sample: 56 | * 57 | * "config": { 58 | * ... 59 | * "ble_instances": { 60 | * "count": 1, 61 | * "0" : { 62 | * "initializer" : "createBLEInstance" 63 | * } 64 | * } 65 | * ... 66 | * } 67 | * 68 | * The following macros result in translating the above config into a static 69 | * array: instanceConstructors. 70 | */ 71 | #ifdef YOTTA_CFG_BLE_INSTANCES_COUNT 72 | #define CONCATENATE(A, B) A ## B 73 | #define EXPAND(X) X /* this adds a level of indirection needed to allow macro-expansion following a token-paste operation (see use of CONCATENATE() below). */ 74 | 75 | #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1 YOTTA_CFG_BLE_INSTANCES_0_INITIALIZER 76 | #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_1, YOTTA_CFG_BLE_INSTANCES_1_INITIALIZER 77 | #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_2, YOTTA_CFG_BLE_INSTANCES_2_INITIALIZER 78 | #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_3, YOTTA_CFG_BLE_INSTANCES_3_INITIALIZER 79 | #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_5 INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_4, YOTTA_CFG_BLE_INSTANCES_4_INITIALIZER 80 | /* ... add more of the above if ever needed */ 81 | 82 | #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(N) EXPAND(CONCATENATE(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS_, N)) 83 | #elif !defined(INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS) 84 | /* 85 | * The following applies when building without yotta. By default BLE_API provides 86 | * a trivial initializer list containing a single constructor: createBLEInstance. 87 | * This may be overridden. 88 | */ 89 | #define INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS createBLEInstance 90 | 91 | // yotta unlike mbed-cli has proper dependency mechanisms 92 | // It is not required to defined a stub for createBLEInstance 93 | #if !defined(YOTTA_CFG_MBED_OS) 94 | 95 | // this stub is required by ARMCC otherwise link will systematically fail 96 | MBED_WEAK BLEInstanceBase* createBLEInstance() { 97 | error("Please provide an implementation for mbed BLE"); 98 | return NULL; 99 | } 100 | 101 | #endif 102 | 103 | 104 | #endif /* YOTTA_CFG_BLE_INSTANCES_COUNT */ 105 | 106 | typedef BLEInstanceBase *(*InstanceConstructor_t)(void); 107 | static const InstanceConstructor_t instanceConstructors[BLE::NUM_INSTANCES] = { 108 | #ifndef YOTTA_CFG_BLE_INSTANCES_COUNT 109 | INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS 110 | #else 111 | INITIALIZER_LIST_FOR_INSTANCE_CONSTRUCTORS(YOTTA_CFG_BLE_INSTANCES_COUNT) 112 | #endif 113 | }; 114 | 115 | BLE & 116 | BLE::Instance(InstanceID_t id) 117 | { 118 | static BLE *singletons[NUM_INSTANCES]; 119 | if (id < NUM_INSTANCES) { 120 | if (singletons[id] == NULL) { 121 | singletons[id] = new BLE(id); /* This object will never be freed. */ 122 | } 123 | 124 | return *singletons[id]; 125 | } 126 | 127 | /* we come here only in the case of a bad interfaceID. */ 128 | static BLE badSingleton(NUM_INSTANCES /* this is a bad index; and will result in a NULL transport. */); 129 | return badSingleton; 130 | } 131 | 132 | #ifdef YOTTA_CFG_MBED_OS 133 | void defaultSchedulingCallback(BLE::OnEventsToProcessCallbackContext* params) { 134 | minar::Scheduler::postCallback(¶ms->ble, &BLE::processEvents); 135 | } 136 | #else 137 | #define defaultSchedulingCallback NULL 138 | #endif 139 | 140 | 141 | BLE::BLE(InstanceID_t instanceIDIn) : instanceID(instanceIDIn), transport(), 142 | whenEventsToProcess(defaultSchedulingCallback) 143 | { 144 | static BLEInstanceBase *transportInstances[NUM_INSTANCES]; 145 | 146 | if (instanceID < NUM_INSTANCES) { 147 | if (!transportInstances[instanceID]) { 148 | transportInstances[instanceID] = instanceConstructors[instanceID](); /* Call the stack's initializer for the transport object. */ 149 | } 150 | transport = transportInstances[instanceID]; 151 | } else { 152 | transport = NULL; 153 | } 154 | } 155 | 156 | bool BLE::hasInitialized(void) const 157 | { 158 | if (!transport) { 159 | error("bad handle to underlying transport"); 160 | } 161 | 162 | return transport->hasInitialized(); 163 | } 164 | 165 | ble_error_t BLE::shutdown(void) 166 | { 167 | if (!transport) { 168 | error("bad handle to underlying transport"); 169 | } 170 | 171 | return transport->shutdown(); 172 | } 173 | 174 | const char *BLE::getVersion(void) 175 | { 176 | if (!transport) { 177 | error("bad handle to underlying transport"); 178 | } 179 | 180 | return transport->getVersion(); 181 | } 182 | 183 | const Gap &BLE::gap() const 184 | { 185 | if (!transport) { 186 | error("bad handle to underlying transport"); 187 | } 188 | 189 | return transport->getGap(); 190 | } 191 | 192 | Gap &BLE::gap() 193 | { 194 | if (!transport) { 195 | error("bad handle to underlying transport"); 196 | } 197 | 198 | return transport->getGap(); 199 | } 200 | 201 | const GattServer& BLE::gattServer() const 202 | { 203 | if (!transport) { 204 | error("bad handle to underlying transport"); 205 | } 206 | 207 | return transport->getGattServer(); 208 | } 209 | 210 | GattServer& BLE::gattServer() 211 | { 212 | if (!transport) { 213 | error("bad handle to underlying transport"); 214 | } 215 | 216 | return transport->getGattServer(); 217 | } 218 | 219 | const GattClient& BLE::gattClient() const 220 | { 221 | if (!transport) { 222 | error("bad handle to underlying transport"); 223 | } 224 | 225 | return transport->getGattClient(); 226 | } 227 | 228 | GattClient& BLE::gattClient() 229 | { 230 | if (!transport) { 231 | error("bad handle to underlying transport"); 232 | } 233 | 234 | return transport->getGattClient(); 235 | } 236 | 237 | const SecurityManager& BLE::securityManager() const 238 | { 239 | if (!transport) { 240 | error("bad handle to underlying transport"); 241 | } 242 | 243 | return transport->getSecurityManager(); 244 | } 245 | 246 | SecurityManager& BLE::securityManager() 247 | { 248 | if (!transport) { 249 | error("bad handle to underlying transport"); 250 | } 251 | 252 | return transport->getSecurityManager(); 253 | } 254 | 255 | void BLE::waitForEvent(void) 256 | { 257 | if (!transport) { 258 | error("bad handle to underlying transport"); 259 | } 260 | 261 | transport->waitForEvent(); 262 | } 263 | 264 | void BLE::processEvents() 265 | { 266 | if (!transport) { 267 | error("bad handle to underlying transport"); 268 | } 269 | 270 | transport->processEvents(); 271 | } 272 | 273 | void BLE::onEventsToProcess(const BLE::OnEventsToProcessCallback_t& callback) 274 | { 275 | whenEventsToProcess = callback; 276 | } 277 | 278 | void BLE::signalEventsToProcess() 279 | { 280 | if (whenEventsToProcess) { 281 | OnEventsToProcessCallbackContext params = { 282 | *this 283 | }; 284 | whenEventsToProcess(¶ms); 285 | } 286 | } 287 | -------------------------------------------------------------------------------- /source/BLEInstanceBase.cpp: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "ble/BLE.h" 18 | #include "ble/BLEInstanceBase.h" 19 | 20 | BLEInstanceBase::~BLEInstanceBase() 21 | { 22 | // empty destructor 23 | } 24 | 25 | void BLEInstanceBase::signalEventsToProcess(BLE::InstanceID_t id) 26 | { 27 | BLE::Instance(id).signalEventsToProcess(); 28 | } 29 | -------------------------------------------------------------------------------- /source/DiscoveredCharacteristic.cpp: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "ble/DiscoveredCharacteristic.h" 18 | #include "ble/GattClient.h" 19 | 20 | ble_error_t 21 | DiscoveredCharacteristic::read(uint16_t offset) const 22 | { 23 | if (!props.read()) { 24 | return BLE_ERROR_OPERATION_NOT_PERMITTED; 25 | } 26 | 27 | if (!gattc) { 28 | return BLE_ERROR_INVALID_STATE; 29 | } 30 | 31 | return gattc->read(connHandle, valueHandle, offset); 32 | } 33 | 34 | struct OneShotReadCallback { 35 | static void launch(GattClient* client, Gap::Handle_t connHandle, 36 | GattAttribute::Handle_t handle, const GattClient::ReadCallback_t& cb) { 37 | OneShotReadCallback* oneShot = new OneShotReadCallback(client, connHandle, handle, cb); 38 | oneShot->attach(); 39 | // delete will be made when this callback is called 40 | } 41 | 42 | private: 43 | OneShotReadCallback(GattClient* client, Gap::Handle_t connHandle, 44 | GattAttribute::Handle_t handle, const GattClient::ReadCallback_t& cb) : 45 | _client(client), 46 | _connHandle(connHandle), 47 | _handle(handle), 48 | _callback(cb) { } 49 | 50 | void attach() { 51 | _client->onDataRead(makeFunctionPointer(this, &OneShotReadCallback::call)); 52 | } 53 | 54 | void call(const GattReadCallbackParams* params) { 55 | // verifiy that it is the right characteristic on the right connection 56 | if (params->connHandle == _connHandle && params->handle == _handle) { 57 | _callback(params); 58 | _client->onDataRead().detach(makeFunctionPointer(this, &OneShotReadCallback::call)); 59 | delete this; 60 | } 61 | } 62 | 63 | GattClient* _client; 64 | Gap::Handle_t _connHandle; 65 | GattAttribute::Handle_t _handle; 66 | GattClient::ReadCallback_t _callback; 67 | }; 68 | 69 | ble_error_t DiscoveredCharacteristic::read(uint16_t offset, const GattClient::ReadCallback_t& onRead) const { 70 | ble_error_t error = read(offset); 71 | if (error) { 72 | return error; 73 | } 74 | 75 | OneShotReadCallback::launch(gattc, connHandle, valueHandle, onRead); 76 | 77 | return error; 78 | } 79 | 80 | ble_error_t 81 | DiscoveredCharacteristic::write(uint16_t length, const uint8_t *value) const 82 | { 83 | if (!props.write()) { 84 | return BLE_ERROR_OPERATION_NOT_PERMITTED; 85 | } 86 | 87 | if (!gattc) { 88 | return BLE_ERROR_INVALID_STATE; 89 | } 90 | 91 | return gattc->write(GattClient::GATT_OP_WRITE_REQ, connHandle, valueHandle, length, value); 92 | } 93 | 94 | ble_error_t 95 | DiscoveredCharacteristic::writeWoResponse(uint16_t length, const uint8_t *value) const 96 | { 97 | if (!props.writeWoResp()) { 98 | return BLE_ERROR_OPERATION_NOT_PERMITTED; 99 | } 100 | 101 | if (!gattc) { 102 | return BLE_ERROR_INVALID_STATE; 103 | } 104 | 105 | return gattc->write(GattClient::GATT_OP_WRITE_CMD, connHandle, valueHandle, length, value); 106 | } 107 | 108 | struct OneShotWriteCallback { 109 | static void launch(GattClient* client, Gap::Handle_t connHandle, 110 | GattAttribute::Handle_t handle, const GattClient::WriteCallback_t& cb) { 111 | OneShotWriteCallback* oneShot = new OneShotWriteCallback(client, connHandle, handle, cb); 112 | oneShot->attach(); 113 | // delete will be made when this callback is called 114 | } 115 | 116 | private: 117 | OneShotWriteCallback(GattClient* client, Gap::Handle_t connHandle, 118 | GattAttribute::Handle_t handle, const GattClient::WriteCallback_t& cb) : 119 | _client(client), 120 | _connHandle(connHandle), 121 | _handle(handle), 122 | _callback(cb) { } 123 | 124 | void attach() { 125 | _client->onDataWritten(makeFunctionPointer(this, &OneShotWriteCallback::call)); 126 | } 127 | 128 | void call(const GattWriteCallbackParams* params) { 129 | // verifiy that it is the right characteristic on the right connection 130 | if (params->connHandle == _connHandle && params->handle == _handle) { 131 | _callback(params); 132 | _client->onDataWritten().detach(makeFunctionPointer(this, &OneShotWriteCallback::call)); 133 | delete this; 134 | } 135 | } 136 | 137 | GattClient* _client; 138 | Gap::Handle_t _connHandle; 139 | GattAttribute::Handle_t _handle; 140 | GattClient::WriteCallback_t _callback; 141 | }; 142 | 143 | ble_error_t DiscoveredCharacteristic::write(uint16_t length, const uint8_t *value, const GattClient::WriteCallback_t& onRead) const { 144 | ble_error_t error = write(length, value); 145 | if (error) { 146 | return error; 147 | } 148 | 149 | OneShotWriteCallback::launch(gattc, connHandle, valueHandle, onRead); 150 | 151 | return error; 152 | } 153 | 154 | ble_error_t DiscoveredCharacteristic::discoverDescriptors( 155 | const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& onCharacteristicDiscovered, 156 | const CharacteristicDescriptorDiscovery::TerminationCallback_t& onTermination) const { 157 | 158 | if(!gattc) { 159 | return BLE_ERROR_INVALID_STATE; 160 | } 161 | 162 | ble_error_t err = gattc->discoverCharacteristicDescriptors( 163 | *this, onCharacteristicDiscovered, onTermination 164 | ); 165 | 166 | return err; 167 | } 168 | -------------------------------------------------------------------------------- /source/GapScanningParams.cpp: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "ble/Gap.h" 18 | #include "ble/GapScanningParams.h" 19 | 20 | GapScanningParams::GapScanningParams(uint16_t interval, uint16_t window, uint16_t timeout, bool activeScanning) : 21 | _interval(MSEC_TO_SCAN_DURATION_UNITS(interval)), 22 | _window(MSEC_TO_SCAN_DURATION_UNITS(window)), 23 | _timeout(timeout), 24 | _activeScanning(activeScanning) { 25 | /* stay within limits */ 26 | if (_interval < SCAN_INTERVAL_MIN) { 27 | _interval = SCAN_INTERVAL_MIN; 28 | } 29 | if (_interval > SCAN_INTERVAL_MAX) { 30 | _interval = SCAN_INTERVAL_MAX; 31 | } 32 | if (_window < SCAN_WINDOW_MIN) { 33 | _window = SCAN_WINDOW_MIN; 34 | } 35 | if (_window > SCAN_WINDOW_MAX) { 36 | _window = SCAN_WINDOW_MAX; 37 | } 38 | } 39 | 40 | ble_error_t 41 | GapScanningParams::setInterval(uint16_t newIntervalInMS) 42 | { 43 | uint16_t newInterval = MSEC_TO_SCAN_DURATION_UNITS(newIntervalInMS); 44 | if ((newInterval >= SCAN_INTERVAL_MIN) && (newInterval < SCAN_INTERVAL_MAX)) { 45 | _interval = newInterval; 46 | return BLE_ERROR_NONE; 47 | } 48 | 49 | return BLE_ERROR_PARAM_OUT_OF_RANGE; 50 | } 51 | 52 | ble_error_t 53 | GapScanningParams::setWindow(uint16_t newWindowInMS) 54 | { 55 | uint16_t newWindow = MSEC_TO_SCAN_DURATION_UNITS(newWindowInMS); 56 | if ((newWindow >= SCAN_WINDOW_MIN) && (newWindow < SCAN_WINDOW_MAX)) { 57 | _window = newWindow; 58 | return BLE_ERROR_NONE; 59 | } 60 | 61 | return BLE_ERROR_PARAM_OUT_OF_RANGE; 62 | } 63 | 64 | ble_error_t 65 | GapScanningParams::setTimeout(uint16_t newTimeout) 66 | { 67 | _timeout = newTimeout; 68 | return BLE_ERROR_NONE; 69 | } 70 | 71 | void 72 | GapScanningParams::setActiveScanning(bool activeScanning) 73 | { 74 | _activeScanning = activeScanning; 75 | } 76 | -------------------------------------------------------------------------------- /source/services/DFUService.cpp: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifdef TARGET_NRF51822 /* DFU only supported on nrf51 platforms */ 18 | 19 | #include "ble/services/DFUService.h" 20 | 21 | const uint8_t DFUServiceBaseUUID[] = { 22 | 0x00, 0x00, 0x00, 0x00, 0x12, 0x12, 0xEF, 0xDE, 23 | 0x15, 0x23, 0x78, 0x5F, 0xEA, 0xBC, 0xD1, 0x23, 24 | }; 25 | const uint16_t DFUServiceShortUUID = 0x1530; 26 | const uint16_t DFUServiceControlCharacteristicShortUUID = 0x1531; 27 | const uint16_t DFUServicePacketCharacteristicShortUUID = 0x1532; 28 | 29 | const uint8_t DFUServiceUUID[] = { 30 | 0x00, 0x00, (uint8_t)(DFUServiceShortUUID >> 8), (uint8_t)(DFUServiceShortUUID & 0xFF), 0x12, 0x12, 0xEF, 0xDE, 31 | 0x15, 0x23, 0x78, 0x5F, 0xEA, 0xBC, 0xD1, 0x23, 32 | }; 33 | const uint8_t DFUServiceControlCharacteristicUUID[] = { 34 | 0x00, 0x00, (uint8_t)(DFUServiceControlCharacteristicShortUUID >> 8), (uint8_t)(DFUServiceControlCharacteristicShortUUID & 0xFF), 0x12, 0x12, 0xEF, 0xDE, 35 | 0x15, 0x23, 0x78, 0x5F, 0xEA, 0xBC, 0xD1, 0x23, 36 | }; 37 | const uint8_t DFUServicePacketCharacteristicUUID[] = { 38 | 0x00, 0x00, (uint8_t)(DFUServicePacketCharacteristicShortUUID >> 8), (uint8_t)(DFUServicePacketCharacteristicShortUUID & 0xFF), 0x12, 0x12, 0xEF, 0xDE, 39 | 0x15, 0x23, 0x78, 0x5F, 0xEA, 0xBC, 0xD1, 0x23, 40 | }; 41 | 42 | DFUService::ResetPrepare_t DFUService::handoverCallback = NULL; 43 | 44 | #endif /* #ifdef TARGET_NRF51822 */ 45 | -------------------------------------------------------------------------------- /source/services/UARTService.cpp: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "ble/services/UARTService.h" 18 | 19 | const uint8_t UARTServiceBaseUUID[UUID::LENGTH_OF_LONG_UUID] = { 20 | 0x6E, 0x40, 0x00, 0x00, 0xB5, 0xA3, 0xF3, 0x93, 21 | 0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E, 22 | }; 23 | const uint16_t UARTServiceShortUUID = 0x0001; 24 | const uint16_t UARTServiceTXCharacteristicShortUUID = 0x0002; 25 | const uint16_t UARTServiceRXCharacteristicShortUUID = 0x0003; 26 | const uint8_t UARTServiceUUID[UUID::LENGTH_OF_LONG_UUID] = { 27 | 0x6E, 0x40, (uint8_t)(UARTServiceShortUUID >> 8), (uint8_t)(UARTServiceShortUUID & 0xFF), 0xB5, 0xA3, 0xF3, 0x93, 28 | 0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E, 29 | }; 30 | const uint8_t UARTServiceUUID_reversed[UUID::LENGTH_OF_LONG_UUID] = { 31 | 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 32 | 0x93, 0xF3, 0xA3, 0xB5, (uint8_t)(UARTServiceShortUUID & 0xFF), (uint8_t)(UARTServiceShortUUID >> 8), 0x40, 0x6E 33 | }; 34 | const uint8_t UARTServiceTXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID] = { 35 | 0x6E, 0x40, (uint8_t)(UARTServiceTXCharacteristicShortUUID >> 8), (uint8_t)(UARTServiceTXCharacteristicShortUUID & 0xFF), 0xB5, 0xA3, 0xF3, 0x93, 36 | 0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E, 37 | }; 38 | const uint8_t UARTServiceRXCharacteristicUUID[UUID::LENGTH_OF_LONG_UUID] = { 39 | 0x6E, 0x40, (uint8_t)(UARTServiceRXCharacteristicShortUUID >> 8), (uint8_t)(UARTServiceRXCharacteristicShortUUID & 0xFF), 0xB5, 0xA3, 0xF3, 0x93, 40 | 0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC, 0xCA, 0x9E, 41 | }; 42 | -------------------------------------------------------------------------------- /source/services/URIBeaconConfigService.cpp: -------------------------------------------------------------------------------- 1 | /* mbed Microcontroller Library 2 | * Copyright (c) 2006-2013 ARM Limited 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "ble/services/URIBeaconConfigService.h" 18 | 19 | #define UUID_URI_BEACON(FIRST, SECOND) { \ 20 | 0xee, 0x0c, FIRST, SECOND, 0x87, 0x86, 0x40, 0xba, \ 21 | 0xab, 0x96, 0x99, 0xb9, 0x1a, 0xc9, 0x81, 0xd8, \ 22 | } 23 | 24 | const uint8_t UUID_URI_BEACON_SERVICE[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x80); 25 | const uint8_t UUID_LOCK_STATE_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x81); 26 | const uint8_t UUID_LOCK_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x82); 27 | const uint8_t UUID_UNLOCK_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x83); 28 | const uint8_t UUID_URI_DATA_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x84); 29 | const uint8_t UUID_FLAGS_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x85); 30 | const uint8_t UUID_ADV_POWER_LEVELS_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x86); 31 | const uint8_t UUID_TX_POWER_MODE_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x87); 32 | const uint8_t UUID_BEACON_PERIOD_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x88); 33 | const uint8_t UUID_RESET_CHAR[UUID::LENGTH_OF_LONG_UUID] = UUID_URI_BEACON(0x20, 0x89); 34 | 35 | const uint8_t BEACON_UUID[sizeof(UUID::ShortUUIDBytes_t)] = {0xD8, 0xFE}; 36 | --------------------------------------------------------------------------------