Skip to content

Commit 4466c25

Browse files
committed
Introduce ChainableEventHandler base class and ChainableGattServerEventHandler subclass.
The ChainableGattServerEventHandler enables chaining together GattServer::EventHandlers. An application can register separate event handlers (eg: for different services that need to handle GattServer events) and then set the global GattServer::setEventHandler to the instance of ChainableGattServerEventHandler with all registered GattServer::EventHandlers. Common functionality has been split off into ChainableEventHandler.
1 parent 0548981 commit 4466c25

File tree

2 files changed

+248
-0
lines changed

2 files changed

+248
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2020 ARM Limited
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#ifndef MBED_CHAINABLEEVENTHANDLER_H_
19+
#define MBED_CHAINABLEEVENTHANDLER_H_
20+
21+
#include <new>
22+
23+
/**
24+
* Base class for chainable EventHandlers. Acts as a collection
25+
* of discrete EventHandlers that can be linked together and
26+
* notified when relevant events happen
27+
*/
28+
template<typename T>
29+
class ChainableEventHandler
30+
{
31+
32+
public:
33+
34+
ChainableEventHandler() { }
35+
36+
virtual ~ChainableEventHandler() {
37+
// Clean up all nodes
38+
auto it = head;
39+
while(it) {
40+
node_t* temp = it;
41+
it = it->next;
42+
delete temp;
43+
}
44+
}
45+
46+
/**
47+
* Add an EventHandler to be notified of events sent to
48+
* this ChainableGattServerEventHandler
49+
*
50+
* @param[in] event_handler Handler to add to chain
51+
*/
52+
void addEventHandler(T* event_handler) {
53+
auto eh = new (std::nothrow) node_t { event_handler, nullptr };
54+
if(!eh) { return; }
55+
if(!head) {
56+
head = eh;
57+
} else {
58+
auto *it = head;
59+
while(it->next) {
60+
it = it->next;
61+
}
62+
it->next = eh;
63+
}
64+
}
65+
66+
/**
67+
* Remove an EventHandler previously added with addEventHandler.
68+
*
69+
* @param[in] event_handler Pointer to event handler to remove
70+
*/
71+
void removeEventHandler(T* target) {
72+
node_t* to_remove = head;
73+
if(head->eh == target) {
74+
head = head->next;
75+
} else {
76+
auto* it = head;
77+
while(it->next) {
78+
if(it->next->eh == target) {
79+
to_remove = it->next;
80+
break;
81+
}
82+
it = it->next;
83+
}
84+
if(it->next) {
85+
it->next = to_remove->next;
86+
} else {
87+
to_remove = nullptr;
88+
}
89+
}
90+
91+
delete to_remove;
92+
}
93+
94+
protected:
95+
96+
template<typename... Args>
97+
void execute_on_all(void (T::*fn)(Args...), Args&... args) {
98+
auto it = head;
99+
while(it) {
100+
(it->eh->*fn)(args...);
101+
it = it->next;
102+
}
103+
}
104+
105+
private:
106+
107+
struct node_t {
108+
T* eh;
109+
node_t* next = nullptr;
110+
};
111+
112+
node_t *head = nullptr;
113+
114+
};
115+
116+
#endif /* MBED_CHAINABLEEVENTHANDLER_H_ */
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2006-2020 ARM Limited
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#ifndef MBED_CHAINABLEGATTSERVEREVENTHANDLER_H_
20+
#define MBED_CHAINABLEGATTSERVEREVENTHANDLER_H_
21+
22+
#include "ble/GattServer.h"
23+
#include "ble/common/ChainableEventHandler.h"
24+
25+
/**
26+
* GattServer::EventHandler implementation that allows the application
27+
* to register multiple separate EventHandlers to be called when
28+
* GattServer events happen.
29+
*/
30+
class ChainableGattServerEventHandler : public ble::GattServer::EventHandler,
31+
public ChainableEventHandler<ble::GattServer::EventHandler>
32+
{
33+
34+
public:
35+
36+
ChainableGattServerEventHandler() { }
37+
38+
virtual ~ChainableGattServerEventHandler() { }
39+
40+
/**
41+
* Function invoked when the connections changes the ATT_MTU which controls
42+
* the maximum size of an attribute that can be read in a single L2CAP packet
43+
* which might be fragmented across multiple packets.
44+
*
45+
* @param connectionHandle The handle of the connection that changed the size.
46+
* @param attMtuSize
47+
*/
48+
void onAttMtuChange(ble::connection_handle_t connectionHandle, uint16_t attMtuSize) override {
49+
execute_on_all(&ble::GattServer::EventHandler::onAttMtuChange,
50+
connectionHandle, attMtuSize);
51+
}
52+
53+
/**
54+
* Function invoked when the server has sent data to a client as
55+
* part of a notification/indication.
56+
*
57+
* @note params has a temporary scope and should be copied by the
58+
* application if needed later
59+
*/
60+
void onDataSent(const GattDataSentCallbackParams* params) override {
61+
execute_on_all(&ble::GattServer::EventHandler::onDataSent, params);
62+
}
63+
64+
/**
65+
* Function invoked when a client writes an attribute
66+
*
67+
* @note params has a temporary scope and should be copied by the
68+
* application if needed later
69+
*/
70+
void onDataWritten(const GattWriteCallbackParams *params) override {
71+
execute_on_all(&ble::GattServer::EventHandler::onDataWritten, params);
72+
}
73+
74+
/**
75+
* Function invoked when a client reads an attribute
76+
*
77+
* @note This functionality may not be available on all underlying stacks.
78+
* Application code may work around that limitation by monitoring read
79+
* requests instead of read events.
80+
*
81+
* @note params has a temporary scope and should be copied by the
82+
* application if needed later
83+
*
84+
* @see GattCharacteristic::setReadAuthorizationCallback()
85+
* @see isOnDataReadAvailable().
86+
*/
87+
void onDataRead(const GattReadCallbackParams *params) override {
88+
execute_on_all(&ble::GattServer::EventHandler::onDataRead, params);
89+
}
90+
91+
/**
92+
* Function invoked when the GattServer instance is about
93+
* to be shut down. This can result in a call to reset() or BLE::reset().
94+
*/
95+
void onShutdown(const GattServer *server) override {
96+
execute_on_all(&ble::GattServer::EventHandler::onShutdown, server);
97+
}
98+
99+
/**
100+
* Function invoked when the client has subscribed to characteristic updates
101+
*
102+
* @note params has a temporary scope and should be copied by the
103+
* application if needed later
104+
*/
105+
void onUpdatesEnabled(const GattUpdatesEnabledCallbackParams* params) override {
106+
execute_on_all(&ble::GattServer::EventHandler::onUpdatesEnabled, params);
107+
}
108+
109+
/**
110+
* Function invoked when the client has unsubscribed to characteristic updates
111+
*
112+
* @note params has a temporary scope and should be copied by the
113+
* application if needed later
114+
*/
115+
void onUpdatesDisabled(const GattUpdatesDisabledCallbackParams* params) override {
116+
execute_on_all(&ble::GattServer::EventHandler::onUpdatesDisabled, params);
117+
}
118+
119+
/**
120+
* Function invoked when an ACK has been received for an
121+
* indication sent to the client.
122+
*
123+
* @note params has a temporary scope and should be copied by the
124+
* application if needed later
125+
*/
126+
void onConfirmationReceived(const GattConfirmationReceivedCallbackParams* params) override {
127+
execute_on_all(&ble::GattServer::EventHandler::onConfirmationReceived, params);
128+
}
129+
130+
};
131+
132+
#endif /* MBED_CHAINABLEGATTSERVEREVENTHANDLER_H_ */

0 commit comments

Comments
 (0)