File: nRF5xCharacteristicDescriptorDiscoverer.h

package info (click to toggle)
firmware-microbit-micropython 1.0.1-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid
  • size: 25,448 kB
  • sloc: ansic: 83,496; cpp: 27,664; python: 2,475; asm: 274; makefile: 245; javascript: 41; sh: 25
file content (214 lines) | stat: -rw-r--r-- 8,485 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/* mbed Microcontroller Library
 * Copyright (c) 2006-2015 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 __NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__
#define __NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__

#include "ble/Gap.h"
#include "ble/DiscoveredCharacteristic.h"
#include "ble/CharacteristicDescriptorDiscovery.h"
#include "ble/GattClient.h"
#include "ble_gattc.h"

/**
 * @brief Manage the discovery of Characteristic descriptors
 * @details is a bridge between BLE API and Nordic stack regarding Characteristic
 * Descriptor discovery. The BLE API can launch, monitor and ask for termination
 * of a discovery. The Nordic stack will provide new descriptors and indicate when
 * the discovery is done.
 */
class nRF5xCharacteristicDescriptorDiscoverer
{
    typedef CharacteristicDescriptorDiscovery::DiscoveryCallback_t DiscoveryCallback_t;
    typedef CharacteristicDescriptorDiscovery::TerminationCallback_t TerminationCallback_t;

public:
    /**
     * @brief Construct a new characteristic descriptor discoverer.
     */
    nRF5xCharacteristicDescriptorDiscoverer();

    /**
     * @brief Destroy a characteristic descriptor discoverer.
     */
    ~nRF5xCharacteristicDescriptorDiscoverer();

    /**
     * Launch a new characteristic descriptor discovery for a given DiscoveredCharacteristic.
     * @param characteristic The characteristic owning the descriptors to discover.
     * @param discoveryCallback The callback called when a descriptor is discovered.
     * @param terminationCallback The callback called when the discovery process end.
     * @return BLE_ERROR_NONE if characteristic descriptor discovery is launched successfully;
     *         else an appropriate error.
     * @note: this will be called by BLE API side.
     */
    ble_error_t launch(
        const DiscoveredCharacteristic& characteristic,
        const DiscoveryCallback_t& discoveryCallback,
        const TerminationCallback_t& terminationCallback
    );

    /**
     * @brief indicate if a characteristic descriptor discovery is active for a
     * given DiscoveredCharacteristic.
     * @param characteristic The characteristic for whom the descriptor might be
     * currently discovered.
     * @return true if descriptors of characteristic are discovered, false otherwise.
     * @note: this will be called by BLE API side.
     */
    bool isActive(const DiscoveredCharacteristic& characteristic) const;

    /**
     * @brief request the termination of characteristic descriptor discovery
     * for a give DiscoveredCharacteristic
     * @param characteristic The characteristic for whom the descriptor discovery
     * should be stopped.
     * @note: this will be called by BLE API side.
     */
    void requestTerminate(const DiscoveredCharacteristic& characteristic);

    /**
     * @brief process descriptors discovered from the Nordic stack.
     * @param connectionHandle The connection handle upon which descriptors has been
     * discovered.
     * @param descriptors Discovered descriptors.
     * @note This will be called by the Nordic stack.
     */
    void process(uint16_t connectionHandle, const ble_gattc_evt_desc_disc_rsp_t& descriptors);

    /**
     * @brief Called by the Nordic stack when the discovery is over.
     * @param The connection handle upon which the discovery process is done.
     * @param err An error if the termination is due to an error.
     */
    void terminate(uint16_t connectionHandle, ble_error_t err);

private:
    // protection against copy construction and assignment
    nRF5xCharacteristicDescriptorDiscoverer(const nRF5xCharacteristicDescriptorDiscoverer&);
    nRF5xCharacteristicDescriptorDiscoverer& operator=(const nRF5xCharacteristicDescriptorDiscoverer&);

    /**
     * @brief Discovery process, it store the DiscoveredCharacteristic, the
     * discovery callback and the termination callback.
     */
    class Discovery {
    public:
        /**
         * @brief Construct an empty discovery, such can be considerate as a not running discovery.
         * @note #isEmpty function will return true
         */
        Discovery();

        /**
         * @brief Construct a valid discovery process.
         *
         * @param c the characteristic from whom descriptors will be discovered.
         * @param dCb The discovery callback called each time a descriptor is discovered.
         * @param tCb The termination callback called when the discovery terminate.
         *
         * @note #isEmpty function will return false
         */
        Discovery(const DiscoveredCharacteristic& c, const DiscoveryCallback_t& dCb, const TerminationCallback_t& tCb);

        /**
         * @brief Process the discovery of a descriptor.
         *
         * @param handle The attribute handle of the descriptor found
         * @param uuid The UUID of the descriptor found.
         */
        void process(GattAttribute::Handle_t handle, const UUID& uuid);

        /**
         * @brief Terminate the discovery process.
         *
         * @param err Error associate with the termination
         * @note after this call #isEmpty function will return true.
         */
        void terminate(ble_error_t err);

        /**
         * @brief check if the discovery process is empty or not. Empty discovery are
         * not running.
         *
         * @detail Discovery are empty after:
         *     - a default construction
         *     - a copy construction form a default constructed
         *     - an assignment from a default constructed Discovery
         * @return true if the Discovery is empty and false otherwise.
         */
        bool isEmpty() const;

        /**
         * @brief return the characteristic from whom descriptors are discovered.
         * @return the characteristic from whom descriptors are discovered.
         */
        const DiscoveredCharacteristic& getCharacteristic() const;

        /**
         * @brief equal to operator, test if two discovery process are equal
         *
         * @param lhs left hand side of the expression
         * @param rhs right hand side of the expression
         * @return true if lhs == rhs
         */
        friend bool operator==(const Discovery& lhs, const Discovery& rhs) {
            return lhs.characteristic == rhs.characteristic &&
                   lhs.onDiscovery == rhs.onDiscovery &&
                   lhs.onTerminate == rhs.onTerminate;
        }

        /**
         * @brief not equal to operator, test if two discovery process are not equal
         *
         * @param lhs left hand side of the expression
         * @param rhs right hand side of the expression
         * @return true if lhs != rhs
         */
        friend bool operator!=(const Discovery& lhs, const Discovery& rhs) {
            return !(lhs == rhs);
        }

    private:
        DiscoveredCharacteristic characteristic;
        DiscoveryCallback_t onDiscovery;
        TerminationCallback_t onTerminate;
    };

    // find a running discovery process
    Discovery* findRunningDiscovery(const DiscoveredCharacteristic& characteristic);
    Discovery* findRunningDiscovery(uint16_t handle);

    // Called to terminate a discovery is over.
    void terminate(Discovery* discovery, ble_error_t err);

    // get one slot for a discovery process
    Discovery* getAvailableDiscoverySlot();

    // indicate if a connection is already running a discovery
    bool isConnectionInUse(uint16_t connHandle);

    // low level start of a discovery
    static ble_error_t gattc_descriptors_discover(uint16_t connection_handle, uint16_t start_handle, uint16_t end_handle);

    // count of concurrent connections which can run a descriptor discovery process
    static const size_t MAXIMUM_CONCURRENT_CONNECTIONS_COUNT = 3;

    // array of running discoveries
    Discovery discoveryRunning[MAXIMUM_CONCURRENT_CONNECTIONS_COUNT];
};

#endif /*__NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__*/