add "LE Device Address" 0x1B to advertising data types

Fork of BLE_API by Bluetooth Low Energy

Committer:
vcoubard
Date:
Mon Jan 11 08:51:49 2016 +0000
Revision:
1088:709ebced28ab
Parent:
1052:b55e1ad3e1b3
Synchronized with git rev 0781293b
Author: Andres Amaya Garcia
Add onShutdown to register callbacks

Add an onShutdown() function to Gap, GattClient, GattServer and
SecurityManager. The callbacks are added to a private callback chain in each of
the instances. The callbacks will be executed inside each object's reset()
function BEFORE the state of the instance is cleared. The developers of the
platform-specific implementation must call the parent class' reset() function
for the callbacks to be executed.

Finally, an onShutdown() function that returns the shutdown callchain is added
to allow detaching callbacks.

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>
vcoubard 1052:b55e1ad3e1b3 21 #include "SafeBool.h"
rgrover1 710:b2e1a2660ec2 22
rgrover1 710:b2e1a2660ec2 23 /** A class for storing and calling a pointer to a static or member void function
vcoubard 1048:efb29faf12fc 24 * that takes a context.
rgrover1 710:b2e1a2660ec2 25 */
rgrover1 710:b2e1a2660ec2 26 template <typename ContextType>
vcoubard 1052:b55e1ad3e1b3 27 class FunctionPointerWithContext : public SafeBool<FunctionPointerWithContext<ContextType> > {
rgrover1 710:b2e1a2660ec2 28 public:
rgrover1 710:b2e1a2660ec2 29 typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t;
vcoubard 1045:b9d15970040f 30 typedef const FunctionPointerWithContext<ContextType> *cpFunctionPointerWithContext_t;
rgrover1 710:b2e1a2660ec2 31 typedef void (*pvoidfcontext_t)(ContextType context);
rgrover1 710:b2e1a2660ec2 32
vcoubard 1048:efb29faf12fc 33 /** Create a FunctionPointerWithContext, attaching a static function.
rgrover1 710:b2e1a2660ec2 34 *
vcoubard 1048:efb29faf12fc 35 * @param function The void static function to attach (default is none).
rgrover1 710:b2e1a2660ec2 36 */
rgrover1 710:b2e1a2660ec2 37 FunctionPointerWithContext(void (*function)(ContextType context) = NULL) :
vcoubard 1046:87a2ebe45470 38 _memberFunctionAndPointer(), _caller(NULL), _next(NULL) {
rgrover1 710:b2e1a2660ec2 39 attach(function);
rgrover1 710:b2e1a2660ec2 40 }
rgrover1 710:b2e1a2660ec2 41
vcoubard 1048:efb29faf12fc 42 /** Create a FunctionPointerWithContext, attaching a member function.
rgrover1 710:b2e1a2660ec2 43 *
vcoubard 1048:efb29faf12fc 44 * @param object The object pointer to invoke the member function on (the "this" pointer).
vcoubard 1048:efb29faf12fc 45 * @param function The address of the void member function to attach.
rgrover1 710:b2e1a2660ec2 46 */
rgrover1 710:b2e1a2660ec2 47 template<typename T>
rgrover1 710:b2e1a2660ec2 48 FunctionPointerWithContext(T *object, void (T::*member)(ContextType context)) :
rgrover1 897:838e1375dbaa 49 _memberFunctionAndPointer(), _caller(NULL), _next(NULL) {
rgrover1 710:b2e1a2660ec2 50 attach(object, member);
rgrover1 710:b2e1a2660ec2 51 }
rgrover1 710:b2e1a2660ec2 52
vcoubard 1046:87a2ebe45470 53 FunctionPointerWithContext(const FunctionPointerWithContext& that) :
vcoubard 1046:87a2ebe45470 54 _memberFunctionAndPointer(that._memberFunctionAndPointer), _caller(that._caller), _next(NULL) {
vcoubard 1046:87a2ebe45470 55 }
vcoubard 1046:87a2ebe45470 56
vcoubard 1046:87a2ebe45470 57 FunctionPointerWithContext& operator=(const FunctionPointerWithContext& that) {
vcoubard 1046:87a2ebe45470 58 _memberFunctionAndPointer = that._memberFunctionAndPointer;
vcoubard 1046:87a2ebe45470 59 _caller = that._caller;
vcoubard 1046:87a2ebe45470 60 _next = NULL;
vcoubard 1046:87a2ebe45470 61 return *this;
vcoubard 1046:87a2ebe45470 62 }
vcoubard 1046:87a2ebe45470 63
vcoubard 1048:efb29faf12fc 64 /** Attach a static function.
rgrover1 710:b2e1a2660ec2 65 *
vcoubard 1048:efb29faf12fc 66 * @param function The void static function to attach (default is none).
rgrover1 710:b2e1a2660ec2 67 */
rgrover1 710:b2e1a2660ec2 68 void attach(void (*function)(ContextType context) = NULL) {
rgrover1 710:b2e1a2660ec2 69 _function = function;
rgrover1 897:838e1375dbaa 70 _caller = functioncaller;
rgrover1 710:b2e1a2660ec2 71 }
rgrover1 710:b2e1a2660ec2 72
vcoubard 1048:efb29faf12fc 73 /** Attach a member function.
rgrover1 710:b2e1a2660ec2 74 *
vcoubard 1048:efb29faf12fc 75 * @param object The object pointer to invoke the member function on (the "this" pointer).
vcoubard 1048:efb29faf12fc 76 * @param function The address of the void member function to attach.
rgrover1 710:b2e1a2660ec2 77 */
rgrover1 710:b2e1a2660ec2 78 template<typename T>
rgrover1 710:b2e1a2660ec2 79 void attach(T *object, void (T::*member)(ContextType context)) {
rgrover1 897:838e1375dbaa 80 _memberFunctionAndPointer._object = static_cast<void *>(object);
rgrover1 897:838e1375dbaa 81 memcpy(_memberFunctionAndPointer._memberFunction, (char*) &member, sizeof(member));
rgrover1 897:838e1375dbaa 82 _caller = &FunctionPointerWithContext::membercaller<T>;
rgrover1 710:b2e1a2660ec2 83 }
rgrover1 710:b2e1a2660ec2 84
vcoubard 1048:efb29faf12fc 85 /** Call the attached static or member function; if there are chained
rgrover1 710:b2e1a2660ec2 86 * FunctionPointers their callbacks are invoked as well.
vcoubard 1048:efb29faf12fc 87 * @Note: All chained callbacks stack up, so hopefully there won't be too
rgrover1 710:b2e1a2660ec2 88 * many FunctionPointers in a chain. */
vcoubard 1045:b9d15970040f 89 void call(ContextType context) const {
rgrover1 952:8a6c287de1be 90 _caller(this, context);
vcoubard 1052:b55e1ad3e1b3 91 }
vcoubard 1042:21a86ac7f5b1 92
vcoubard 1052:b55e1ad3e1b3 93 /**
vcoubard 1052:b55e1ad3e1b3 94 * @brief Same as above
vcoubard 1052:b55e1ad3e1b3 95 */
vcoubard 1052:b55e1ad3e1b3 96 void operator()(ContextType context) const {
vcoubard 1052:b55e1ad3e1b3 97 call(context);
rgrover1 990:53ac0ac3aa39 98 }
rgrover1 990:53ac0ac3aa39 99
vcoubard 1049:d99774db03b4 100 /** Same as above, workaround for mbed os FunctionPointer implementation. */
vcoubard 1049:d99774db03b4 101 void call(ContextType context) {
vcoubard 1052:b55e1ad3e1b3 102 ((const FunctionPointerWithContext*) this)->call(context);
vcoubard 1052:b55e1ad3e1b3 103 }
vcoubard 1052:b55e1ad3e1b3 104
vcoubard 1052:b55e1ad3e1b3 105 typedef void (FunctionPointerWithContext::*bool_type)() const;
vcoubard 1049:d99774db03b4 106
vcoubard 1052:b55e1ad3e1b3 107 /**
vcoubard 1052:b55e1ad3e1b3 108 * implementation of safe bool operator
vcoubard 1052:b55e1ad3e1b3 109 */
vcoubard 1052:b55e1ad3e1b3 110 bool toBool() const {
vcoubard 1052:b55e1ad3e1b3 111 return (_function || _memberFunctionAndPointer._object);
vcoubard 1049:d99774db03b4 112 }
vcoubard 1049:d99774db03b4 113
rgrover1 990:53ac0ac3aa39 114 /**
vcoubard 1048:efb29faf12fc 115 * Set up an external FunctionPointer as a next in the chain of related
rgrover1 710:b2e1a2660ec2 116 * callbacks. Invoking call() on the head FunctionPointer will invoke all
rgrover1 710:b2e1a2660ec2 117 * chained callbacks.
rgrover1 710:b2e1a2660ec2 118 *
rgrover1 710:b2e1a2660ec2 119 * Refer to 'CallChain' as an alternative.
rgrover1 710:b2e1a2660ec2 120 */
rgrover1 710:b2e1a2660ec2 121 void chainAsNext(pFunctionPointerWithContext_t next) {
rgrover1 710:b2e1a2660ec2 122 _next = next;
rgrover1 710:b2e1a2660ec2 123 }
rgrover1 710:b2e1a2660ec2 124
rgrover1 710:b2e1a2660ec2 125 pFunctionPointerWithContext_t getNext(void) const {
rgrover1 710:b2e1a2660ec2 126 return _next;
rgrover1 710:b2e1a2660ec2 127 }
rgrover1 710:b2e1a2660ec2 128
rgrover1 710:b2e1a2660ec2 129 pvoidfcontext_t get_function() const {
rgrover1 710:b2e1a2660ec2 130 return (pvoidfcontext_t)_function;
rgrover1 710:b2e1a2660ec2 131 }
rgrover1 710:b2e1a2660ec2 132
vcoubard 1045:b9d15970040f 133 friend bool operator==(const FunctionPointerWithContext& lhs, const FunctionPointerWithContext& rhs) {
vcoubard 1045:b9d15970040f 134 return rhs._caller == lhs._caller &&
vcoubard 1045:b9d15970040f 135 memcmp(
vcoubard 1045:b9d15970040f 136 &rhs._memberFunctionAndPointer,
vcoubard 1045:b9d15970040f 137 &lhs._memberFunctionAndPointer,
vcoubard 1045:b9d15970040f 138 sizeof(rhs._memberFunctionAndPointer)
vcoubard 1045:b9d15970040f 139 ) == 0;
vcoubard 1045:b9d15970040f 140 }
vcoubard 1045:b9d15970040f 141
rgrover1 710:b2e1a2660ec2 142 private:
rgrover1 710:b2e1a2660ec2 143 template<typename T>
vcoubard 1045:b9d15970040f 144 static void membercaller(cpFunctionPointerWithContext_t self, ContextType context) {
rgrover1 897:838e1375dbaa 145 if (self->_memberFunctionAndPointer._object) {
rgrover1 897:838e1375dbaa 146 T *o = static_cast<T *>(self->_memberFunctionAndPointer._object);
rgrover1 897:838e1375dbaa 147 void (T::*m)(ContextType);
rgrover1 897:838e1375dbaa 148 memcpy((char*) &m, self->_memberFunctionAndPointer._memberFunction, sizeof(m));
rgrover1 897:838e1375dbaa 149 (o->*m)(context);
rgrover1 897:838e1375dbaa 150 }
rgrover1 897:838e1375dbaa 151 }
rgrover1 897:838e1375dbaa 152
vcoubard 1045:b9d15970040f 153 static void functioncaller(cpFunctionPointerWithContext_t self, ContextType context) {
rgrover1 897:838e1375dbaa 154 if (self->_function) {
rgrover1 897:838e1375dbaa 155 self->_function(context);
rgrover1 897:838e1375dbaa 156 }
rgrover1 710:b2e1a2660ec2 157 }
rgrover1 710:b2e1a2660ec2 158
rgrover1 897:838e1375dbaa 159 struct MemberFunctionAndPtr {
rgrover1 897:838e1375dbaa 160 /*
vcoubard 1048:efb29faf12fc 161 * Forward declaration of a class and a member function to this class.
rgrover1 897:838e1375dbaa 162 * Because the compiler doesn't know anything about the forwarded member
rgrover1 897:838e1375dbaa 163 * function, it will always use the biggest size and the biggest alignment
rgrover1 897:838e1375dbaa 164 * that a member function can take for objects of type UndefinedMemberFunction.
rgrover1 897:838e1375dbaa 165 */
rgrover1 897:838e1375dbaa 166 class UndefinedClass;
rgrover1 897:838e1375dbaa 167 typedef void (UndefinedClass::*UndefinedMemberFunction)(ContextType);
rgrover1 897:838e1375dbaa 168
rgrover1 897:838e1375dbaa 169 void* _object;
rgrover1 897:838e1375dbaa 170 union {
rgrover1 897:838e1375dbaa 171 char _memberFunction[sizeof(UndefinedMemberFunction)];
rgrover1 897:838e1375dbaa 172 UndefinedMemberFunction _alignment;
rgrover1 897:838e1375dbaa 173 };
rgrover1 897:838e1375dbaa 174 };
rgrover1 897:838e1375dbaa 175
rgrover1 897:838e1375dbaa 176 union {
vcoubard 1048:efb29faf12fc 177 pvoidfcontext_t _function; /**< Static function pointer - NULL if none attached */
rgrover1 897:838e1375dbaa 178 /**
rgrover1 897:838e1375dbaa 179 * object this pointer and pointer to member -
rgrover1 897:838e1375dbaa 180 * _memberFunctionAndPointer._object will be NULL if none attached
rgrover1 897:838e1375dbaa 181 */
vcoubard 1045:b9d15970040f 182 mutable MemberFunctionAndPtr _memberFunctionAndPointer;
rgrover1 897:838e1375dbaa 183 };
rgrover1 897:838e1375dbaa 184
vcoubard 1045:b9d15970040f 185 void (*_caller)(const FunctionPointerWithContext*, ContextType);
rgrover1 897:838e1375dbaa 186
vcoubard 1048:efb29faf12fc 187 pFunctionPointerWithContext_t _next; /**< Optional link to make a chain out of functionPointers. This
rgrover1 710:b2e1a2660ec2 188 * allows chaining function pointers without requiring
vcoubard 1048:efb29faf12fc 189 * external memory to manage the chain. Refer to
rgrover1 710:b2e1a2660ec2 190 * 'CallChain' as an alternative. */
rgrover1 710:b2e1a2660ec2 191 };
rgrover1 710:b2e1a2660ec2 192
rgrover1 993:4d62b7967c11 193 /**
rgrover1 993:4d62b7967c11 194 * @brief Create a new FunctionPointerWithContext which bind an instance and a
rgrover1 993:4d62b7967c11 195 * a member function together.
rgrover1 993:4d62b7967c11 196 * @details This little helper is a just here to eliminate the need to write the
rgrover1 993:4d62b7967c11 197 * FunctionPointerWithContext type each time you want to create one by kicking
rgrover1 993:4d62b7967c11 198 * automatic type deduction of function templates. With this function, it is easy
rgrover1 993:4d62b7967c11 199 * to write only one entry point for functions which expect a FunctionPointer
rgrover1 993:4d62b7967c11 200 * in parameters.
rgrover1 993:4d62b7967c11 201 *
rgrover1 993:4d62b7967c11 202 * @param object to bound with member function
rgrover1 993:4d62b7967c11 203 * @param member The member function called
rgrover1 993:4d62b7967c11 204 * @return a new FunctionPointerWithContext
rgrover1 993:4d62b7967c11 205 */
rgrover1 993:4d62b7967c11 206 template<typename T, typename ContextType>
rgrover1 993:4d62b7967c11 207 FunctionPointerWithContext<ContextType> makeFunctionPointer(T *object, void (T::*member)(ContextType context))
rgrover1 993:4d62b7967c11 208 {
rgrover1 993:4d62b7967c11 209 return FunctionPointerWithContext<ContextType>(object, member);
rgrover1 993:4d62b7967c11 210 }
rgrover1 993:4d62b7967c11 211
rgrover1 710:b2e1a2660ec2 212 #endif // ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H