just a fork

Fork of BLE_API by Bluetooth Low Energy

Committer:
vcoubard
Date:
Wed Apr 06 19:15:30 2016 +0100
Revision:
1179:4ab722f8dca0
Parent:
1177:f9060dc8c5ab
Child:
1183:1589830dbdb7
Synchronized with git rev ca632aaf
Author: Andres Amaya Garcia
Update Gap state after advertising times out

The BLE API was not updating the Gap internal state when the advertising stops
because of a user timeout. This commit fixes the issue by updating the internal
state structure in Gap just before the registered callbacks are notified of the
advertising timeout.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vcoubard 1146:3fbf341b09dd 1 /* mbed Microcontroller Library
vcoubard 1146:3fbf341b09dd 2 * Copyright (c) 2006-2013 ARM Limited
vcoubard 1146:3fbf341b09dd 3 *
vcoubard 1146:3fbf341b09dd 4 * Licensed under the Apache License, Version 2.0 (the "License");
vcoubard 1146:3fbf341b09dd 5 * you may not use this file except in compliance with the License.
vcoubard 1146:3fbf341b09dd 6 * You may obtain a copy of the License at
vcoubard 1146:3fbf341b09dd 7 *
vcoubard 1146:3fbf341b09dd 8 * http://www.apache.org/licenses/LICENSE-2.0
vcoubard 1146:3fbf341b09dd 9 *
vcoubard 1146:3fbf341b09dd 10 * Unless required by applicable law or agreed to in writing, software
vcoubard 1146:3fbf341b09dd 11 * distributed under the License is distributed on an "AS IS" BASIS,
vcoubard 1146:3fbf341b09dd 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
vcoubard 1146:3fbf341b09dd 13 * See the License for the specific language governing permissions and
vcoubard 1146:3fbf341b09dd 14 * limitations under the License.
vcoubard 1146:3fbf341b09dd 15 */
vcoubard 1146:3fbf341b09dd 16 #ifndef MBED_CALLCHAIN_OF_FUNCTION_POINTERS_WITH_CONTEXT_H
vcoubard 1146:3fbf341b09dd 17 #define MBED_CALLCHAIN_OF_FUNCTION_POINTERS_WITH_CONTEXT_H
vcoubard 1146:3fbf341b09dd 18
vcoubard 1146:3fbf341b09dd 19 #include <string.h>
vcoubard 1146:3fbf341b09dd 20 #include "FunctionPointerWithContext.h"
vcoubard 1146:3fbf341b09dd 21 #include "SafeBool.h"
vcoubard 1146:3fbf341b09dd 22
vcoubard 1146:3fbf341b09dd 23
vcoubard 1146:3fbf341b09dd 24 /** Group one or more functions in an instance of a CallChainOfFunctionPointersWithContext, then call them in
vcoubard 1146:3fbf341b09dd 25 * sequence using CallChainOfFunctionPointersWithContext::call(). Used mostly by the interrupt chaining code,
vcoubard 1146:3fbf341b09dd 26 * but can be used for other purposes.
vcoubard 1146:3fbf341b09dd 27 *
vcoubard 1146:3fbf341b09dd 28 * Example:
vcoubard 1146:3fbf341b09dd 29 * @code
vcoubard 1146:3fbf341b09dd 30 *
vcoubard 1146:3fbf341b09dd 31 * CallChainOfFunctionPointersWithContext<void *> chain;
vcoubard 1146:3fbf341b09dd 32 *
vcoubard 1146:3fbf341b09dd 33 * void first(void *context) {
vcoubard 1146:3fbf341b09dd 34 * printf("'first' function.\n");
vcoubard 1146:3fbf341b09dd 35 * }
vcoubard 1146:3fbf341b09dd 36 *
vcoubard 1146:3fbf341b09dd 37 * void second(void *context) {
vcoubard 1146:3fbf341b09dd 38 * printf("'second' function.\n");
vcoubard 1146:3fbf341b09dd 39 * }
vcoubard 1146:3fbf341b09dd 40 *
vcoubard 1146:3fbf341b09dd 41 * class Test {
vcoubard 1146:3fbf341b09dd 42 * public:
vcoubard 1146:3fbf341b09dd 43 * void f(void *context) {
vcoubard 1146:3fbf341b09dd 44 * printf("A::f (class member).\n");
vcoubard 1146:3fbf341b09dd 45 * }
vcoubard 1146:3fbf341b09dd 46 * };
vcoubard 1146:3fbf341b09dd 47 *
vcoubard 1146:3fbf341b09dd 48 * int main() {
vcoubard 1146:3fbf341b09dd 49 * Test test;
vcoubard 1146:3fbf341b09dd 50 *
vcoubard 1146:3fbf341b09dd 51 * chain.add(second);
vcoubard 1146:3fbf341b09dd 52 * chain.add_front(first);
vcoubard 1146:3fbf341b09dd 53 * chain.add(&test, &Test::f);
vcoubard 1146:3fbf341b09dd 54 * chain.call();
vcoubard 1146:3fbf341b09dd 55 * }
vcoubard 1146:3fbf341b09dd 56 * @endcode
vcoubard 1146:3fbf341b09dd 57 */
vcoubard 1179:4ab722f8dca0 58
vcoubard 1146:3fbf341b09dd 59 template <typename ContextType>
vcoubard 1146:3fbf341b09dd 60 class CallChainOfFunctionPointersWithContext : public SafeBool<CallChainOfFunctionPointersWithContext<ContextType> > {
vcoubard 1146:3fbf341b09dd 61 public:
vcoubard 1146:3fbf341b09dd 62 typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t;
vcoubard 1146:3fbf341b09dd 63
vcoubard 1146:3fbf341b09dd 64 public:
vcoubard 1179:4ab722f8dca0 65 /** Create an empty chain.
vcoubard 1179:4ab722f8dca0 66 *
vcoubard 1179:4ab722f8dca0 67 * @param size (optional) Initial size of the chain.
vcoubard 1146:3fbf341b09dd 68 */
vcoubard 1146:3fbf341b09dd 69 CallChainOfFunctionPointersWithContext() : chainHead(NULL) {
vcoubard 1146:3fbf341b09dd 70 /* empty */
vcoubard 1146:3fbf341b09dd 71 }
vcoubard 1146:3fbf341b09dd 72
vcoubard 1146:3fbf341b09dd 73 virtual ~CallChainOfFunctionPointersWithContext() {
vcoubard 1146:3fbf341b09dd 74 clear();
vcoubard 1146:3fbf341b09dd 75 }
vcoubard 1146:3fbf341b09dd 76
vcoubard 1179:4ab722f8dca0 77 /** Add a function at the front of the chain.
vcoubard 1146:3fbf341b09dd 78 *
vcoubard 1179:4ab722f8dca0 79 * @param function A pointer to a void function.
vcoubard 1146:3fbf341b09dd 80 *
vcoubard 1179:4ab722f8dca0 81 * @returns
vcoubard 1179:4ab722f8dca0 82 * The function object created for 'function'.
vcoubard 1146:3fbf341b09dd 83 */
vcoubard 1146:3fbf341b09dd 84 pFunctionPointerWithContext_t add(void (*function)(ContextType context)) {
vcoubard 1146:3fbf341b09dd 85 return common_add(new FunctionPointerWithContext<ContextType>(function));
vcoubard 1146:3fbf341b09dd 86 }
vcoubard 1146:3fbf341b09dd 87
vcoubard 1179:4ab722f8dca0 88 /** Add a function at the front of the chain.
vcoubard 1146:3fbf341b09dd 89 *
vcoubard 1179:4ab722f8dca0 90 * @param tptr Pointer to the object to call the member function on.
vcoubard 1179:4ab722f8dca0 91 * @param mptr Pointer to the member function to be called.
vcoubard 1146:3fbf341b09dd 92 *
vcoubard 1179:4ab722f8dca0 93 * @returns
vcoubard 1179:4ab722f8dca0 94 * The function object created for 'tptr' and 'mptr'.
vcoubard 1146:3fbf341b09dd 95 */
vcoubard 1146:3fbf341b09dd 96 template<typename T>
vcoubard 1146:3fbf341b09dd 97 pFunctionPointerWithContext_t add(T *tptr, void (T::*mptr)(ContextType context)) {
vcoubard 1146:3fbf341b09dd 98 return common_add(new FunctionPointerWithContext<ContextType>(tptr, mptr));
vcoubard 1146:3fbf341b09dd 99 }
vcoubard 1146:3fbf341b09dd 100
vcoubard 1179:4ab722f8dca0 101 /** Add a function at the front of the chain.
vcoubard 1146:3fbf341b09dd 102 *
vcoubard 1179:4ab722f8dca0 103 * @param func The FunctionPointerWithContext to add.
vcoubard 1146:3fbf341b09dd 104 */
vcoubard 1146:3fbf341b09dd 105 pFunctionPointerWithContext_t add(const FunctionPointerWithContext<ContextType>& func) {
vcoubard 1146:3fbf341b09dd 106 return common_add(new FunctionPointerWithContext<ContextType>(func));
vcoubard 1146:3fbf341b09dd 107 }
vcoubard 1146:3fbf341b09dd 108
vcoubard 1179:4ab722f8dca0 109 /**
vcoubard 1179:4ab722f8dca0 110 * Detach a function pointer from a callchain
vcoubard 1179:4ab722f8dca0 111 *
vcoubard 1179:4ab722f8dca0 112 * @oaram toDetach FunctionPointerWithContext to detach from this callchain
vcoubard 1179:4ab722f8dca0 113 *
vcoubard 1179:4ab722f8dca0 114 * @return true if a function pointer has been detached and false otherwise
vcoubard 1179:4ab722f8dca0 115 */
vcoubard 1179:4ab722f8dca0 116 bool detach(const FunctionPointerWithContext<ContextType>& toDetach) {
vcoubard 1146:3fbf341b09dd 117 pFunctionPointerWithContext_t current = chainHead;
vcoubard 1146:3fbf341b09dd 118 pFunctionPointerWithContext_t previous = NULL;
vcoubard 1146:3fbf341b09dd 119
vcoubard 1146:3fbf341b09dd 120 while (current) {
vcoubard 1179:4ab722f8dca0 121 if(*current == toDetach) {
vcoubard 1146:3fbf341b09dd 122 if(previous == NULL) {
vcoubard 1179:4ab722f8dca0 123 if(currentCalled == current) {
vcoubard 1146:3fbf341b09dd 124 currentCalled = NULL;
vcoubard 1146:3fbf341b09dd 125 }
vcoubard 1146:3fbf341b09dd 126 chainHead = current->getNext();
vcoubard 1146:3fbf341b09dd 127 } else {
vcoubard 1179:4ab722f8dca0 128 if(currentCalled == current) {
vcoubard 1146:3fbf341b09dd 129 currentCalled = previous;
vcoubard 1146:3fbf341b09dd 130 }
vcoubard 1146:3fbf341b09dd 131 previous->chainAsNext(current->getNext());
vcoubard 1146:3fbf341b09dd 132 }
vcoubard 1146:3fbf341b09dd 133 delete current;
vcoubard 1146:3fbf341b09dd 134 return true;
vcoubard 1146:3fbf341b09dd 135 }
vcoubard 1146:3fbf341b09dd 136
vcoubard 1146:3fbf341b09dd 137 previous = current;
vcoubard 1146:3fbf341b09dd 138 current = current->getNext();
vcoubard 1146:3fbf341b09dd 139 }
vcoubard 1146:3fbf341b09dd 140
vcoubard 1146:3fbf341b09dd 141 return false;
vcoubard 1146:3fbf341b09dd 142 }
vcoubard 1146:3fbf341b09dd 143
vcoubard 1179:4ab722f8dca0 144 /** Clear the call chain (remove all functions in the chain).
vcoubard 1146:3fbf341b09dd 145 */
vcoubard 1146:3fbf341b09dd 146 void clear(void) {
vcoubard 1146:3fbf341b09dd 147 pFunctionPointerWithContext_t fptr = chainHead;
vcoubard 1146:3fbf341b09dd 148 while (fptr) {
vcoubard 1146:3fbf341b09dd 149 pFunctionPointerWithContext_t deadPtr = fptr;
vcoubard 1146:3fbf341b09dd 150 fptr = deadPtr->getNext();
vcoubard 1146:3fbf341b09dd 151 delete deadPtr;
vcoubard 1146:3fbf341b09dd 152 }
vcoubard 1146:3fbf341b09dd 153
vcoubard 1146:3fbf341b09dd 154 chainHead = NULL;
vcoubard 1146:3fbf341b09dd 155 }
vcoubard 1146:3fbf341b09dd 156
vcoubard 1146:3fbf341b09dd 157 bool hasCallbacksAttached(void) const {
vcoubard 1146:3fbf341b09dd 158 return (chainHead != NULL);
vcoubard 1146:3fbf341b09dd 159 }
vcoubard 1146:3fbf341b09dd 160
vcoubard 1179:4ab722f8dca0 161 /** Call all the functions in the chain in sequence
vcoubard 1146:3fbf341b09dd 162 */
vcoubard 1146:3fbf341b09dd 163 void call(ContextType context) {
vcoubard 1146:3fbf341b09dd 164 ((const CallChainOfFunctionPointersWithContext*) this)->call(context);
vcoubard 1146:3fbf341b09dd 165 }
vcoubard 1146:3fbf341b09dd 166
vcoubard 1146:3fbf341b09dd 167 /**
vcoubard 1179:4ab722f8dca0 168 * @brief same as above but const
vcoubard 1146:3fbf341b09dd 169 */
vcoubard 1146:3fbf341b09dd 170 void call(ContextType context) const {
vcoubard 1146:3fbf341b09dd 171 currentCalled = chainHead;
vcoubard 1146:3fbf341b09dd 172
vcoubard 1179:4ab722f8dca0 173 while(currentCalled) {
vcoubard 1146:3fbf341b09dd 174 currentCalled->call(context);
vcoubard 1146:3fbf341b09dd 175 // if this was the head and the call removed the head
vcoubard 1179:4ab722f8dca0 176 if(currentCalled == NULL) {
vcoubard 1146:3fbf341b09dd 177 currentCalled = chainHead;
vcoubard 1146:3fbf341b09dd 178 } else {
vcoubard 1146:3fbf341b09dd 179 currentCalled = currentCalled->getNext();
vcoubard 1146:3fbf341b09dd 180 }
vcoubard 1146:3fbf341b09dd 181 }
vcoubard 1146:3fbf341b09dd 182 }
vcoubard 1146:3fbf341b09dd 183
vcoubard 1146:3fbf341b09dd 184 /**
vcoubard 1179:4ab722f8dca0 185 * @brief same as above but with function call operator
vcoubard 1179:4ab722f8dca0 186 * \code
vcoubard 1179:4ab722f8dca0 187 *
vcoubard 1146:3fbf341b09dd 188 * void first(bool);
vcoubard 1146:3fbf341b09dd 189 * void second(bool);
vcoubard 1179:4ab722f8dca0 190 *
vcoubard 1146:3fbf341b09dd 191 * CallChainOfFunctionPointerWithContext<bool> foo;
vcoubard 1179:4ab722f8dca0 192 *
vcoubard 1146:3fbf341b09dd 193 * foo.attach(first);
vcoubard 1146:3fbf341b09dd 194 * foo.attach(second);
vcoubard 1179:4ab722f8dca0 195 *
vcoubard 1146:3fbf341b09dd 196 * // call the callchain like a function
vcoubard 1146:3fbf341b09dd 197 * foo(true);
vcoubard 1179:4ab722f8dca0 198 *
vcoubard 1179:4ab722f8dca0 199 * \endcode
vcoubard 1146:3fbf341b09dd 200 */
vcoubard 1146:3fbf341b09dd 201 void operator()(ContextType context) const {
vcoubard 1146:3fbf341b09dd 202 call(context);
vcoubard 1146:3fbf341b09dd 203 }
vcoubard 1146:3fbf341b09dd 204
vcoubard 1146:3fbf341b09dd 205 /**
vcoubard 1179:4ab722f8dca0 206 * @brief bool conversion operation
vcoubard 1146:3fbf341b09dd 207 */
vcoubard 1146:3fbf341b09dd 208 bool toBool() const {
vcoubard 1146:3fbf341b09dd 209 return chainHead != NULL;
vcoubard 1146:3fbf341b09dd 210 }
vcoubard 1146:3fbf341b09dd 211
vcoubard 1146:3fbf341b09dd 212 private:
vcoubard 1146:3fbf341b09dd 213 pFunctionPointerWithContext_t common_add(pFunctionPointerWithContext_t pf) {
vcoubard 1146:3fbf341b09dd 214 if (chainHead == NULL) {
vcoubard 1146:3fbf341b09dd 215 chainHead = pf;
vcoubard 1146:3fbf341b09dd 216 } else {
vcoubard 1146:3fbf341b09dd 217 pf->chainAsNext(chainHead);
vcoubard 1146:3fbf341b09dd 218 chainHead = pf;
vcoubard 1146:3fbf341b09dd 219 }
vcoubard 1146:3fbf341b09dd 220
vcoubard 1146:3fbf341b09dd 221 return chainHead;
vcoubard 1146:3fbf341b09dd 222 }
vcoubard 1146:3fbf341b09dd 223
vcoubard 1146:3fbf341b09dd 224 private:
vcoubard 1146:3fbf341b09dd 225 pFunctionPointerWithContext_t chainHead;
vcoubard 1179:4ab722f8dca0 226 // iterator during a function call, this has to be mutable because the call function is const.
vcoubard 1179:4ab722f8dca0 227 // Note: mutable is the correct behaviour here, the iterator never leak outside the object.
vcoubard 1179:4ab722f8dca0 228 // So the object can still be seen as logically const even if it change its internal state
vcoubard 1146:3fbf341b09dd 229 mutable pFunctionPointerWithContext_t currentCalled;
vcoubard 1146:3fbf341b09dd 230
vcoubard 1146:3fbf341b09dd 231
vcoubard 1146:3fbf341b09dd 232 /* Disallow copy constructor and assignment operators. */
vcoubard 1146:3fbf341b09dd 233 private:
vcoubard 1146:3fbf341b09dd 234 CallChainOfFunctionPointersWithContext(const CallChainOfFunctionPointersWithContext &);
vcoubard 1146:3fbf341b09dd 235 CallChainOfFunctionPointersWithContext & operator = (const CallChainOfFunctionPointersWithContext &);
vcoubard 1146:3fbf341b09dd 236 };
vcoubard 1146:3fbf341b09dd 237
rgrover1 710:b2e1a2660ec2 238 #endif