extend

Fork of BLE_API by Bluetooth Low Energy

Committer:
rgrover1
Date:
Thu Jul 02 09:06:11 2015 +0100
Revision:
716:11b41f651697
Parent:
public/CallChainOfFunctionPointersWithContext.h@714:a6130aaa0fd9
Child:
893:e83bb5ea8a8a
Synchronized with git rev d80fec88
Author: Rohit Grover
Release 0.4.0
=============

This is a major release which introduces the GATT Client functionality. It
also aligns BLE_API with builds using our new package manager: yotta
(https://github.com/armmbed/yotta).

Many APIs have seen some redesign. We encourage our users to pay attention to
the changes and migrate appropriately over time. We've also taken care to
ensure that existing code continues to work the same way. There's more
documentation in the form of comment headers for APIs to explain proper usage;
in many cases comment headers suggest alternative use of APIs.

Enhancements
~~~~~~~~~~~~

* Introduce GattClient. This includes functionality for service-discovery,
connections, and attribute-reads and writes. You'll find a demo program for
LEDBlinker on the mbed.org Bluetooth team page to use the new APIs. Some of
the GATT client functionality hasn't been implemented yet, but the APIs have
been added.

* Most APIs in the abstract base classes like Gap and GattServer return
BLE_ERROR_NOT_IMPLEMENTED. Previously many APIs were pure-virtual, which did
not permit partial ports to compile.

* We've added a new abstract base class for SecurityManager. All security
related APIs have been moved into that.

* BLEDevice has been renamed as BLE. A deprecated alias for BLEDevice is
available to support existing code.

* There has been a major cleanup of APIs under BLE. APIs have now been
categorized as belonging to Gap, GattServer, GattClient, or SecurityManager.
There are accessors to get references for Gap, GattServer, GattClient, and
SecurityManager. A former call to ble.setAddress(...) is now expected to be
achieved with ble.gap().setAddress(...).

* We've cleaned up our APIs, and this has resulted in dropping some APIs like
BLE::reset().

* We've also dropped GattServer::initializeGattDatabase(). THis was added at
some point to support controllers where a commit point was needed to
indicate when the application had finished constructing the GATT database.
This API would get called internally before Gap::startAdvertising(). We now
expect the underlying port to do the equivalent of initializeGattDatabase()
implicitly upon Gap::startAdvertising().

* The callback for BLE.onTimeout() now receives a TimeoutSource_t to indicate
the cause of the timeout. This is perhaps the only breaking API change. We
expect it to have very little disruptive effect.

* We've added a version of Gap::disconnect() which takes a connection handle.
The previous API (which did not take a connection handle) has been
deprecated; it will still work for situations where there's only a single
active connection. We hold on to that API to allow existing code to migrate
to the new API.

Bugfixes
~~~~~~~~

* None.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 710:b2e1a2660ec2 1 /* mbed Microcontroller Library
rgrover1 710:b2e1a2660ec2 2 * Copyright (c) 2006-2013 ARM Limited
rgrover1 710:b2e1a2660ec2 3 *
rgrover1 710:b2e1a2660ec2 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 710:b2e1a2660ec2 5 * you may not use this file except in compliance with the License.
rgrover1 710:b2e1a2660ec2 6 * You may obtain a copy of the License at
rgrover1 710:b2e1a2660ec2 7 *
rgrover1 710:b2e1a2660ec2 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 710:b2e1a2660ec2 9 *
rgrover1 710:b2e1a2660ec2 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 710:b2e1a2660ec2 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 710:b2e1a2660ec2 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 710:b2e1a2660ec2 13 * See the License for the specific language governing permissions and
rgrover1 710:b2e1a2660ec2 14 * limitations under the License.
rgrover1 710:b2e1a2660ec2 15 */
rgrover1 710:b2e1a2660ec2 16 #ifndef MBED_CALLCHAIN_OF_FUNCTION_POINTERS_WITH_CONTEXT_H
rgrover1 710:b2e1a2660ec2 17 #define MBED_CALLCHAIN_OF_FUNCTION_POINTERS_WITH_CONTEXT_H
rgrover1 710:b2e1a2660ec2 18
rgrover1 710:b2e1a2660ec2 19 #include <string.h>
rgrover1 710:b2e1a2660ec2 20 #include "FunctionPointerWithContext.h"
rgrover1 710:b2e1a2660ec2 21
rgrover1 710:b2e1a2660ec2 22
rgrover1 710:b2e1a2660ec2 23 /** Group one or more functions in an instance of a CallChainOfFunctionPointersWithContext, then call them in
rgrover1 710:b2e1a2660ec2 24 * sequence using CallChainOfFunctionPointersWithContext::call(). Used mostly by the interrupt chaining code,
rgrover1 710:b2e1a2660ec2 25 * but can be used for other purposes.
rgrover1 710:b2e1a2660ec2 26 *
rgrover1 710:b2e1a2660ec2 27 * Example:
rgrover1 710:b2e1a2660ec2 28 * @code
rgrover1 710:b2e1a2660ec2 29 *
rgrover1 710:b2e1a2660ec2 30 * CallChainOfFunctionPointersWithContext<void *> chain;
rgrover1 710:b2e1a2660ec2 31 *
rgrover1 710:b2e1a2660ec2 32 * void first(void *context) {
rgrover1 710:b2e1a2660ec2 33 * printf("'first' function.\n");
rgrover1 710:b2e1a2660ec2 34 * }
rgrover1 710:b2e1a2660ec2 35 *
rgrover1 710:b2e1a2660ec2 36 * void second(void *context) {
rgrover1 710:b2e1a2660ec2 37 * printf("'second' function.\n");
rgrover1 710:b2e1a2660ec2 38 * }
rgrover1 710:b2e1a2660ec2 39 *
rgrover1 710:b2e1a2660ec2 40 * class Test {
rgrover1 710:b2e1a2660ec2 41 * public:
rgrover1 710:b2e1a2660ec2 42 * void f(void *context) {
rgrover1 710:b2e1a2660ec2 43 * printf("A::f (class member).\n");
rgrover1 710:b2e1a2660ec2 44 * }
rgrover1 710:b2e1a2660ec2 45 * };
rgrover1 710:b2e1a2660ec2 46 *
rgrover1 710:b2e1a2660ec2 47 * int main() {
rgrover1 710:b2e1a2660ec2 48 * Test test;
rgrover1 710:b2e1a2660ec2 49 *
rgrover1 710:b2e1a2660ec2 50 * chain.add(second);
rgrover1 710:b2e1a2660ec2 51 * chain.add_front(first);
rgrover1 710:b2e1a2660ec2 52 * chain.add(&test, &Test::f);
rgrover1 710:b2e1a2660ec2 53 * chain.call();
rgrover1 710:b2e1a2660ec2 54 * }
rgrover1 710:b2e1a2660ec2 55 * @endcode
rgrover1 710:b2e1a2660ec2 56 */
rgrover1 710:b2e1a2660ec2 57
rgrover1 710:b2e1a2660ec2 58 template <typename ContextType>
rgrover1 710:b2e1a2660ec2 59 class CallChainOfFunctionPointersWithContext {
rgrover1 710:b2e1a2660ec2 60 public:
rgrover1 710:b2e1a2660ec2 61 typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t;
rgrover1 710:b2e1a2660ec2 62
rgrover1 710:b2e1a2660ec2 63 public:
rgrover1 710:b2e1a2660ec2 64 /** Create an empty chain
rgrover1 710:b2e1a2660ec2 65 *
rgrover1 710:b2e1a2660ec2 66 * @param size (optional) Initial size of the chain
rgrover1 710:b2e1a2660ec2 67 */
rgrover1 710:b2e1a2660ec2 68 CallChainOfFunctionPointersWithContext() : chainHead(NULL) {
rgrover1 710:b2e1a2660ec2 69 /* empty */
rgrover1 710:b2e1a2660ec2 70 }
rgrover1 710:b2e1a2660ec2 71
rgrover1 710:b2e1a2660ec2 72 virtual ~CallChainOfFunctionPointersWithContext() {
rgrover1 710:b2e1a2660ec2 73 clear();
rgrover1 710:b2e1a2660ec2 74 }
rgrover1 710:b2e1a2660ec2 75
rgrover1 710:b2e1a2660ec2 76 /** Add a function at the front of the chain
rgrover1 710:b2e1a2660ec2 77 *
rgrover1 710:b2e1a2660ec2 78 * @param function A pointer to a void function
rgrover1 710:b2e1a2660ec2 79 *
rgrover1 710:b2e1a2660ec2 80 * @returns
rgrover1 710:b2e1a2660ec2 81 * The function object created for 'function'
rgrover1 710:b2e1a2660ec2 82 */
rgrover1 710:b2e1a2660ec2 83 pFunctionPointerWithContext_t add(void (*function)(ContextType context)) {
rgrover1 710:b2e1a2660ec2 84 return common_add(new FunctionPointerWithContext<ContextType>(function));
rgrover1 710:b2e1a2660ec2 85 }
rgrover1 710:b2e1a2660ec2 86
rgrover1 710:b2e1a2660ec2 87 /** Add a function at the front of the chain
rgrover1 710:b2e1a2660ec2 88 *
rgrover1 710:b2e1a2660ec2 89 * @param tptr pointer to the object to call the member function on
rgrover1 710:b2e1a2660ec2 90 * @param mptr pointer to the member function to be called
rgrover1 710:b2e1a2660ec2 91 *
rgrover1 710:b2e1a2660ec2 92 * @returns
rgrover1 710:b2e1a2660ec2 93 * The function object created for 'tptr' and 'mptr'
rgrover1 710:b2e1a2660ec2 94 */
rgrover1 710:b2e1a2660ec2 95 template<typename T>
rgrover1 710:b2e1a2660ec2 96 pFunctionPointerWithContext_t add(T *tptr, void (T::*mptr)(ContextType context)) {
rgrover1 710:b2e1a2660ec2 97 return common_add(new FunctionPointerWithContext<ContextType>(tptr, mptr));
rgrover1 710:b2e1a2660ec2 98 }
rgrover1 710:b2e1a2660ec2 99
rgrover1 710:b2e1a2660ec2 100 /** Clear the call chain (remove all functions in the chain).
rgrover1 710:b2e1a2660ec2 101 */
rgrover1 710:b2e1a2660ec2 102 void clear(void) {
rgrover1 710:b2e1a2660ec2 103 pFunctionPointerWithContext_t fptr = chainHead;
rgrover1 710:b2e1a2660ec2 104 while (fptr) {
rgrover1 710:b2e1a2660ec2 105 pFunctionPointerWithContext_t deadPtr = fptr;
rgrover1 710:b2e1a2660ec2 106 fptr = deadPtr->getNext();
rgrover1 710:b2e1a2660ec2 107 delete deadPtr;
rgrover1 710:b2e1a2660ec2 108 }
rgrover1 710:b2e1a2660ec2 109
rgrover1 710:b2e1a2660ec2 110 chainHead = NULL;
rgrover1 710:b2e1a2660ec2 111 }
rgrover1 710:b2e1a2660ec2 112
rgrover1 710:b2e1a2660ec2 113 bool hasCallbacksAttached(void) const {
rgrover1 710:b2e1a2660ec2 114 return (chainHead != NULL);
rgrover1 710:b2e1a2660ec2 115 }
rgrover1 710:b2e1a2660ec2 116
rgrover1 710:b2e1a2660ec2 117 /** Call all the functions in the chain in sequence
rgrover1 710:b2e1a2660ec2 118 * @Note: the stack frames of all the callbacks within the chained
rgrover1 710:b2e1a2660ec2 119 * FunctionPointers will stack up. Hopefully there won't be too many
rgrover1 710:b2e1a2660ec2 120 * chained FunctionPointers.
rgrover1 710:b2e1a2660ec2 121 */
rgrover1 710:b2e1a2660ec2 122 void call(ContextType context) {
rgrover1 710:b2e1a2660ec2 123 if (chainHead) {
rgrover1 710:b2e1a2660ec2 124 chainHead->call(context);
rgrover1 710:b2e1a2660ec2 125 }
rgrover1 710:b2e1a2660ec2 126 }
rgrover1 710:b2e1a2660ec2 127
rgrover1 710:b2e1a2660ec2 128 private:
rgrover1 710:b2e1a2660ec2 129 pFunctionPointerWithContext_t common_add(pFunctionPointerWithContext_t pf) {
rgrover1 710:b2e1a2660ec2 130 if (chainHead == NULL) {
rgrover1 710:b2e1a2660ec2 131 chainHead = pf;
rgrover1 710:b2e1a2660ec2 132 } else {
rgrover1 710:b2e1a2660ec2 133 pf->chainAsNext(chainHead);
rgrover1 710:b2e1a2660ec2 134 chainHead = pf;
rgrover1 710:b2e1a2660ec2 135 }
rgrover1 710:b2e1a2660ec2 136
rgrover1 710:b2e1a2660ec2 137 return chainHead;
rgrover1 710:b2e1a2660ec2 138 }
rgrover1 710:b2e1a2660ec2 139
rgrover1 710:b2e1a2660ec2 140 private:
rgrover1 710:b2e1a2660ec2 141 pFunctionPointerWithContext_t chainHead;
rgrover1 710:b2e1a2660ec2 142
rgrover1 710:b2e1a2660ec2 143 /* disallow copy constructor and assignment operators */
rgrover1 710:b2e1a2660ec2 144 private:
rgrover1 710:b2e1a2660ec2 145 CallChainOfFunctionPointersWithContext(const CallChainOfFunctionPointersWithContext &);
rgrover1 710:b2e1a2660ec2 146 CallChainOfFunctionPointersWithContext & operator = (const CallChainOfFunctionPointersWithContext &);
rgrover1 710:b2e1a2660ec2 147 };
rgrover1 710:b2e1a2660ec2 148
rgrover1 710:b2e1a2660ec2 149 #endif