Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BLE::init() should also be able to take an <object, member> tuple for its callback #97

Merged
merged 5 commits into from
Nov 3, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 51 additions & 9 deletions ble/BLE.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "GattServer.h"
#include "GattClient.h"

#include "ble/FunctionPointerWithContext.h"

#ifdef YOTTA_CFG_MBED_OS
#include "mbed-drivers/mbed_error.h"
#else
Expand All @@ -41,16 +43,28 @@ class BLE
typedef unsigned InstanceID_t; /** The type returned by BLE::getInstanceID(). */

/**
* The function signature for callbacks for initialization completion.
* The context provided to init-completion-callbacks (see init() below).
*
* @param ble
* A reference to the BLE instance being initialized.
* @param error
* This captures the result of initialization. It is set to
* BLE_ERROR_NONE if initialization completed successfully. Else
* the error value is implementation specific.
*/
struct InitializationCompleteCallbackContext {
BLE& ble; /* Reference to the BLE object which has been initialized */
ble_error_t error; /* Error status of the initialization. It is set to BLE_ERROR_NONE initialization completed successfully. */
};

/**
* The signature for function-pointer like callbacks for initialization-completion.
*
* @note There are two versions of init(). In addition to the simple
* function-pointer, init() can also take a <Object, member> tuple as its
* callback target. In case of the latter, the following declaration doesn't apply.
*/
typedef void (*InitializationCompleteCallback_t)(BLE &ble, ble_error_t error);
typedef void (*InitializationCompleteCallback_t)(InitializationCompleteCallbackContext *context);

/**
* Initialize the BLE controller. This should be called before using
Expand All @@ -63,7 +77,7 @@ class BLE
* context where ordering is compiler specific and can't be guaranteed--it
* is safe to call BLE::init() from within main().
*
* @param callback
* @param initCompleteCallback
* A callback for when initialization completes for a BLE
* instance. This is an optional parameter, if no callback is
* setup the application can still determine the status of
Expand All @@ -72,17 +86,36 @@ class BLE
* @return BLE_ERROR_NONE if the initialization procedure was started
* successfully.
*
* @note The underlying stack must invoke the initialization completion
* callback in response to init(). In some cases, initialization is
* instantaneous (or blocking); if so, it is acceptable for the stack-
* specific implementation of init() to invoke the completion callback
* directly--i.e. within its own context.
* @note If init() returns BLE_ERROR_NONE, the underlying stack must invoke
* the initialization completion callback at some point.
*
* @note In some cases, initialization is instantaneous (or blocking); if
* so, it is acceptable for the stack-specific implementation of init()
* to invoke the completion callback directly--i.e. within its own
* context.
*
* @note Nearly all BLE APIs would return
* BLE_ERROR_INITIALIZATION_INCOMPLETE if used on an instance before the
* corresponding transport is initialized.
*
* @note There are two versions of init(). In addition to the simple
* function-pointer, init() can also take an <Object, member> tuple as its
* callback target.
*/
ble_error_t init(InitializationCompleteCallback_t initCompleteCallback = NULL) {
FunctionPointerWithContext<InitializationCompleteCallbackContext *> callback(initCompleteCallback);
initImplementation(callback);
}

/**
* An alternate declaration for init(). This one takes an <Object, member> tuple as its
* callback target.
*/
ble_error_t init(InitializationCompleteCallback_t callback = NULL);
template<typename T>
ble_error_t init(T *object, void (T::*initCompleteCallback)(InitializationCompleteCallbackContext *context)) {
FunctionPointerWithContext<InitializationCompleteCallbackContext *> callback(object, initCompleteCallback);
initImplementation(callback);
}

/**
* @return true if initialization has completed for the underlying BLE
Expand Down Expand Up @@ -1387,6 +1420,15 @@ class BLE
return securityManager().onPasskeyDisplay(callback);
}

private:
/**
* Implementation of init() [internal to BLE_API].
*
* The implementation is separated into a private method because it isn't
* suitable to be included in the header.
*/
ble_error_t initImplementation(FunctionPointerWithContext<InitializationCompleteCallbackContext *> callback);

private:
BLE(const BLE&);
BLE &operator=(const BLE &);
Expand Down
3 changes: 2 additions & 1 deletion ble/BLEInstanceBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ class GattClient;
class BLEInstanceBase
{
public:
virtual ble_error_t init(BLE::InstanceID_t instanceID, BLE::InitializationCompleteCallback_t) = 0;
virtual ble_error_t init(BLE::InstanceID_t instanceID,
FunctionPointerWithContext<BLE::InitializationCompleteCallbackContext *> initCallback) = 0;
virtual bool hasInitialized(void) const = 0;
virtual ble_error_t shutdown(void) = 0;
virtual const char * getVersion(void) = 0;
Expand Down
24 changes: 11 additions & 13 deletions ble/FunctionPointerWithContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@

#include <string.h>



/** A class for storing and calling a pointer to a static or member void function
* which takes a context.
*/
Expand Down Expand Up @@ -107,10 +105,10 @@ class FunctionPointerWithContext {
template<typename T>
static void membercaller(pFunctionPointerWithContext_t self, ContextType context) {
if (self->_memberFunctionAndPointer._object) {
T *o = static_cast<T *>(self->_memberFunctionAndPointer._object);
T *o = static_cast<T *>(self->_memberFunctionAndPointer._object);
void (T::*m)(ContextType);
memcpy((char*) &m, self->_memberFunctionAndPointer._memberFunction, sizeof(m));
(o->*m)(context);
(o->*m)(context);
}
}

Expand All @@ -122,9 +120,9 @@ class FunctionPointerWithContext {

struct MemberFunctionAndPtr {
/*
* forward declaration of a class and a member function to this class.
* Because the compiler doesn't know anything about the forwarded member
* function, it will always use the biggest size and the biggest alignment
* forward declaration of a class and a member function to this class.
* Because the compiler doesn't know anything about the forwarded member
* function, it will always use the biggest size and the biggest alignment
* that a member function can take for objects of type UndefinedMemberFunction.
*/
class UndefinedClass;
Expand All @@ -133,17 +131,17 @@ class FunctionPointerWithContext {
void* _object;
union {
char _memberFunction[sizeof(UndefinedMemberFunction)];
UndefinedMemberFunction _alignment;
UndefinedMemberFunction _alignment;
};
};

union {
pvoidfcontext_t _function; /**< static function pointer - NULL if none attached */
/**
* object this pointer and pointer to member -
* _memberFunctionAndPointer._object will be NULL if none attached
*/
MemberFunctionAndPtr _memberFunctionAndPointer;
/**
* object this pointer and pointer to member -
* _memberFunctionAndPointer._object will be NULL if none attached
*/
MemberFunctionAndPtr _memberFunctionAndPointer;
};

void (*_caller)(FunctionPointerWithContext*, ContextType);
Expand Down
2 changes: 1 addition & 1 deletion source/BLE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
#endif

ble_error_t
BLE::init(BLE::InitializationCompleteCallback_t callback)
BLE::initImplementation(FunctionPointerWithContext<InitializationCompleteCallbackContext *> callback)
{
ble_error_t err = transport->init(instanceID, callback);
if (err != BLE_ERROR_NONE) {
Expand Down