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: generic event filter #5299

Merged
merged 4 commits into from
Nov 22, 2017
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
1 change: 1 addition & 0 deletions features/FEATURE_BLE/ble/BLE.h
Original file line number Diff line number Diff line change
Expand Up @@ -1560,6 +1560,7 @@ class BLE
InstanceID_t instanceID;
BLEInstanceBase *transport; /* The device-specific backend */
OnEventsToProcessCallback_t whenEventsToProcess;
bool event_signaled;
};

typedef BLE BLEDevice; /**< @deprecated This type alias is retained for the
Expand Down
155 changes: 155 additions & 0 deletions features/FEATURE_BLE/ble/SafeEnum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/* mbed Microcontroller Library
* Copyright (c) 2017-2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#ifndef BLE_SAFE_ENUM_H_
#define BLE_SAFE_ENUM_H_

#include <stddef.h>
#include <stdint.h>

namespace ble {

/**
* Helper class used to define safe enumerations.
*
* C++ 98 enums expose different security holes:
* - Scope The scope of the enum is the scope defining it. In other words,
* enumerator defined at namespace scope are in the same scope that other
* enumerator defined in that namespace even if they belong to a different
* enumeration.
* As a result it is really easy to collide names between two different
* enumerators. At the end, the programmer has to protect its declaration
* with long prefixing.
* - Unsafe comparison: enumerators really just are named integer and can be
* implicitly converted to integer. As a result it is possible to compare
* value of different enum type.
* - Layout: The layout type of enumerations is implementation defined.
*
* This template class expose a framework to overcome those issues:
*
* First enum has to be defined in a structure which inherit from this class.
* The target type is the name of the structure containing the enumeration
* while LayoutType is the inner type used to stored the enum.
*
* Comparison operator are provided so it is not possible to compare a SafeEnum
* of a type to another SafeEnum of a different type.
*
* Implicit conversion to integer is not defined, users have to either use the
* value function which return the integer value stored in an EnumType. Client
* class can also define their own conversion operation.
*
* @tparam Target structure containing the enumeration definition.
* @tparam LayoutType Inner type used to store enumeration value.
*
* @code

struct color_t : SafeEnum<color_t> {
enum type {
RED,
GREEN,
BLACK
};

color_t(type) : SafeEnum<color_t>(type) { }
};

// use an uint8_t to store the enumeration value
struct shape_t : SafeEnum<shape_t, uint8_t> {
enum type {
RECTANGLE,
CIRCLE,
TRIANGLE
};

shape_t(type) : SafeEnum<shape_t>(type) { }
};

// shape enumerator is in the shape_t scope.
shape_t shape = shape_t::RECTANGLE;

shape_t shape = color_t::RED; // Compilation error

if (shape == shape_t::CIRCLE) {
}

// compilation error
if (shape == color_t::RED) {

}

void sink(shape_t); (1)
void sink(color_t); (2)

sink(shape); // use overload (1)
sink(color); // use overload (2)

// explicit access to the value is mandatory when a SafeEnum value is used
// as the condition in a switch statement
switch(shape.value()) {
case shape_t::RECTANGLE:
break;
}

* @endcode
*/
template<typename Target, typename LayoutType = unsigned int>
struct SafeEnum {

/**
* Construction of an enumeration value.
*/
SafeEnum(LayoutType value) : _value(value) { }

/**
* Equal to operator for SafeEnum instances.
*
* @param lhs left hand side of the comparison
* @param rhs right hand side of the comparison
*
* @return true if the inner value of lhs and rhs are equal and false
* otherwise.
*/
friend bool operator==(SafeEnum lhs, SafeEnum rhs) {
return lhs._value == rhs._value;
}

/**
* Not equal to operator for SafeEnum instances.
*
* @param lhs left hand side of the comparison
* @param rhs right hand side of the comparison
*
* @return true if the inner value of lhs and rhs are not equal and false
* otherwise.
*/
friend bool operator!=(SafeEnum lhs, SafeEnum rhs) {
return !(lhs == rhs);
}

/**
* Explicit access to the inner value of the SafeEnum instance.
*/
LayoutType value() const {
return _value;
}

private:
LayoutType _value;
};

} // namespace ble

#endif /* BLE_SAFE_ENUM_H_ */
Loading