Updated

Fork of BLE_API by Bluetooth Low Energy

Committer:
rgrover1
Date:
Thu Jul 02 09:06:11 2015 +0100
Revision:
716:11b41f651697
Parent:
public/FunctionPointerWithContext.h@714:a6130aaa0fd9
Child:
848:47c11ba90ff4
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
rgrover1 710:b2e1a2660ec2 17 #ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H
rgrover1 710:b2e1a2660ec2 18 #define MBED_FUNCTIONPOINTER_WITH_CONTEXT_H
rgrover1 710:b2e1a2660ec2 19
rgrover1 710:b2e1a2660ec2 20 #include <string.h>
rgrover1 710:b2e1a2660ec2 21
rgrover1 710:b2e1a2660ec2 22
rgrover1 710:b2e1a2660ec2 23 /** A class for storing and calling a pointer to a static or member void function
rgrover1 710:b2e1a2660ec2 24 * which takes a context.
rgrover1 710:b2e1a2660ec2 25 */
rgrover1 710:b2e1a2660ec2 26 template <typename ContextType>
rgrover1 710:b2e1a2660ec2 27 class FunctionPointerWithContext {
rgrover1 710:b2e1a2660ec2 28 public:
rgrover1 710:b2e1a2660ec2 29 typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t;
rgrover1 710:b2e1a2660ec2 30 typedef void (*pvoidfcontext_t)(ContextType context);
rgrover1 710:b2e1a2660ec2 31
rgrover1 710:b2e1a2660ec2 32 /** Create a FunctionPointerWithContext, attaching a static function
rgrover1 710:b2e1a2660ec2 33 *
rgrover1 710:b2e1a2660ec2 34 * @param function The void static function to attach (default is none)
rgrover1 710:b2e1a2660ec2 35 */
rgrover1 710:b2e1a2660ec2 36 FunctionPointerWithContext(void (*function)(ContextType context) = NULL) :
rgrover1 710:b2e1a2660ec2 37 _function(NULL), _object(NULL), _member(), _membercaller(NULL), _next(NULL) {
rgrover1 710:b2e1a2660ec2 38 attach(function);
rgrover1 710:b2e1a2660ec2 39 }
rgrover1 710:b2e1a2660ec2 40
rgrover1 710:b2e1a2660ec2 41 /** Create a FunctionPointerWithContext, attaching a member function
rgrover1 710:b2e1a2660ec2 42 *
rgrover1 710:b2e1a2660ec2 43 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
rgrover1 710:b2e1a2660ec2 44 * @param function The address of the void member function to attach
rgrover1 710:b2e1a2660ec2 45 */
rgrover1 710:b2e1a2660ec2 46 template<typename T>
rgrover1 710:b2e1a2660ec2 47 FunctionPointerWithContext(T *object, void (T::*member)(ContextType context)) :
rgrover1 710:b2e1a2660ec2 48 _function(NULL), _object(NULL), _member(), _membercaller(NULL), _next(NULL) {
rgrover1 710:b2e1a2660ec2 49 attach(object, member);
rgrover1 710:b2e1a2660ec2 50 }
rgrover1 710:b2e1a2660ec2 51
rgrover1 710:b2e1a2660ec2 52 /** Attach a static function
rgrover1 710:b2e1a2660ec2 53 *
rgrover1 710:b2e1a2660ec2 54 * @param function The void static function to attach (default is none)
rgrover1 710:b2e1a2660ec2 55 */
rgrover1 710:b2e1a2660ec2 56 void attach(void (*function)(ContextType context) = NULL) {
rgrover1 710:b2e1a2660ec2 57 _function = function;
rgrover1 710:b2e1a2660ec2 58 }
rgrover1 710:b2e1a2660ec2 59
rgrover1 710:b2e1a2660ec2 60 /** Attach a member function
rgrover1 710:b2e1a2660ec2 61 *
rgrover1 710:b2e1a2660ec2 62 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
rgrover1 710:b2e1a2660ec2 63 * @param function The address of the void member function to attach
rgrover1 710:b2e1a2660ec2 64 */
rgrover1 710:b2e1a2660ec2 65 template<typename T>
rgrover1 710:b2e1a2660ec2 66 void attach(T *object, void (T::*member)(ContextType context)) {
rgrover1 710:b2e1a2660ec2 67 _object = static_cast<void *>(object);
rgrover1 710:b2e1a2660ec2 68 memcpy(_member, (char *)&member, sizeof(member));
rgrover1 710:b2e1a2660ec2 69 _membercaller = &FunctionPointerWithContext::membercaller<T>;
rgrover1 710:b2e1a2660ec2 70 }
rgrover1 710:b2e1a2660ec2 71
rgrover1 710:b2e1a2660ec2 72 /** Call the attached static or member function; and if there are chained
rgrover1 710:b2e1a2660ec2 73 * FunctionPointers their callbacks are invoked as well.
rgrover1 710:b2e1a2660ec2 74 * @Note: all chained callbacks stack up; so hopefully there won't be too
rgrover1 710:b2e1a2660ec2 75 * many FunctionPointers in a chain. */
rgrover1 710:b2e1a2660ec2 76 void call(ContextType context) {
rgrover1 710:b2e1a2660ec2 77 if (_function) {
rgrover1 710:b2e1a2660ec2 78 _function(context);
rgrover1 710:b2e1a2660ec2 79 } else if (_object && _membercaller) {
rgrover1 710:b2e1a2660ec2 80 _membercaller(_object, _member, context);
rgrover1 710:b2e1a2660ec2 81 }
rgrover1 710:b2e1a2660ec2 82
rgrover1 710:b2e1a2660ec2 83 /* Propagate the call to next in the chain. */
rgrover1 710:b2e1a2660ec2 84 if (_next) {
rgrover1 710:b2e1a2660ec2 85 _next->call(context);
rgrover1 710:b2e1a2660ec2 86 }
rgrover1 710:b2e1a2660ec2 87 }
rgrover1 710:b2e1a2660ec2 88
rgrover1 710:b2e1a2660ec2 89 /**
rgrover1 710:b2e1a2660ec2 90 * Setup an external FunctionPointer as a next in the chain of related
rgrover1 710:b2e1a2660ec2 91 * callbacks. Invoking call() on the head FunctionPointer will invoke all
rgrover1 710:b2e1a2660ec2 92 * chained callbacks.
rgrover1 710:b2e1a2660ec2 93 *
rgrover1 710:b2e1a2660ec2 94 * Refer to 'CallChain' as an alternative.
rgrover1 710:b2e1a2660ec2 95 */
rgrover1 710:b2e1a2660ec2 96 void chainAsNext(pFunctionPointerWithContext_t next) {
rgrover1 710:b2e1a2660ec2 97 _next = next;
rgrover1 710:b2e1a2660ec2 98 }
rgrover1 710:b2e1a2660ec2 99
rgrover1 710:b2e1a2660ec2 100 pFunctionPointerWithContext_t getNext(void) const {
rgrover1 710:b2e1a2660ec2 101 return _next;
rgrover1 710:b2e1a2660ec2 102 }
rgrover1 710:b2e1a2660ec2 103
rgrover1 710:b2e1a2660ec2 104 pvoidfcontext_t get_function() const {
rgrover1 710:b2e1a2660ec2 105 return (pvoidfcontext_t)_function;
rgrover1 710:b2e1a2660ec2 106 }
rgrover1 710:b2e1a2660ec2 107
rgrover1 710:b2e1a2660ec2 108 private:
rgrover1 710:b2e1a2660ec2 109 template<typename T>
rgrover1 710:b2e1a2660ec2 110 static void membercaller(void *object, char *member, ContextType context) {
rgrover1 710:b2e1a2660ec2 111 T *o = static_cast<T *>(object);
rgrover1 710:b2e1a2660ec2 112 void (T::*m)(ContextType);
rgrover1 710:b2e1a2660ec2 113 memcpy((char *)&m, member, sizeof(m));
rgrover1 710:b2e1a2660ec2 114 (o->*m)(context);
rgrover1 710:b2e1a2660ec2 115 }
rgrover1 710:b2e1a2660ec2 116
rgrover1 710:b2e1a2660ec2 117 void (*_function)(ContextType context); /**< static function pointer - NULL if none attached */
rgrover1 710:b2e1a2660ec2 118 void *_object; /**< object this pointer - NULL if none attached */
rgrover1 710:b2e1a2660ec2 119 char _member[16]; /**< raw member function pointer storage - converted back by
rgrover1 710:b2e1a2660ec2 120 * registered _membercaller */
rgrover1 710:b2e1a2660ec2 121 void (*_membercaller)(void *, char *, ContextType); /**< registered membercaller function to convert back and call
rgrover1 710:b2e1a2660ec2 122 * _member on _object passing the context. */
rgrover1 710:b2e1a2660ec2 123 pFunctionPointerWithContext_t _next; /**< Optional link to make a chain out of functionPointers; this
rgrover1 710:b2e1a2660ec2 124 * allows chaining function pointers without requiring
rgrover1 710:b2e1a2660ec2 125 * external memory to manage the chain. Also refer to
rgrover1 710:b2e1a2660ec2 126 * 'CallChain' as an alternative. */
rgrover1 710:b2e1a2660ec2 127 };
rgrover1 710:b2e1a2660ec2 128
rgrover1 710:b2e1a2660ec2 129 #endif // ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H