aboutsummaryrefslogtreecommitdiff
path: root/src/utils/thread_helper.hpp
blob: aefa19610b63a4703cf53110b348c9a0ed9ad14b (plain)
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
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/*
 *    Copyright (c) 2020, The OpenThread Authors.
 *    All rights reserved.
 *
 *    Redistribution and use in source and binary forms, with or without
 *    modification, are permitted provided that the following conditions are met:
 *    1. Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *    3. Neither the name of the copyright holder nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *    POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @file
 *   This file includes definitions for Thread helper.
 */

#ifndef OTBR_THREAD_HELPER_HPP_
#define OTBR_THREAD_HELPER_HPP_

#include <chrono>
#include <functional>
#include <map>
#include <random>
#include <string>
#include <vector>

#include <openthread/instance.h>
#include <openthread/ip6.h>
#include <openthread/jam_detection.h>
#include <openthread/joiner.h>
#include <openthread/netdata.h>
#include <openthread/thread.h>

namespace otbr {
namespace Ncp {
class ControllerOpenThread;
}
} // namespace otbr

namespace otbr {
namespace agent {

/**
 * This class implements Thread helper.
 */
class ThreadHelper
{
public:
    using DeviceRoleHandler = std::function<void(otDeviceRole)>;
    using ScanHandler       = std::function<void(otError, const std::vector<otActiveScanResult> &)>;
    using ResultHandler     = std::function<void(otError)>;

    /**
     * The constructor of a Thread helper.
     *
     * @param[in]   aInstance  The Thread instance.
     * @param[in]   aNcp       The ncp controller.
     *
     */
    ThreadHelper(otInstance *aInstance, otbr::Ncp::ControllerOpenThread *aNcp);

    /**
     * This method adds a callback for device role change.
     *
     * @param[in]   aHandler  The device role handler.
     *
     */
    void AddDeviceRoleHandler(DeviceRoleHandler aHandler);

    /**
     * This method permits unsecure join on port.
     *
     * @param[in]   aPort     The port number.
     * @param[in]   aSeconds  The timeout to close the port, 0 for never close.
     *
     * @returns The error value of underlying OpenThread api calls.
     *
     */
    otError PermitUnsecureJoin(uint16_t aPort, uint32_t aSeconds);

    /**
     * This method performs a Thread network scan.
     *
     * @param[in]   aHandler  The scan result handler.
     *
     */
    void Scan(ScanHandler aHandler);

    /**
     * This method attaches the device to the Thread network.
     *
     * @note The joiner start and the attach proccesses are exclusive
     *
     * @param[in]   aNetworkName    The network name.
     * @param[in]   aPanId          The pan id, UINT16_MAX for random.
     * @param[in]   aExtPanId       The extended pan id, UINT64_MAX for random.
     * @param[in]   aNetworkKey     The network key, empty for random.
     * @param[in]   aPSKc           The pre-shared commissioner key, empty for random.
     * @param[in]   aChannelMask    A bitmask for valid channels, will random select one.
     * @param[in]   aHandler        The attach result handler.
     *
     */
    void Attach(const std::string &         aNetworkName,
                uint16_t                    aPanId,
                uint64_t                    aExtPanId,
                const std::vector<uint8_t> &aNetworkKey,
                const std::vector<uint8_t> &aPSKc,
                uint32_t                    aChannelMask,
                ResultHandler               aHandler);

    /**
     * This method detaches the device from the Thread network.
     *
     * @returns The error value of underlying OpenThread API calls.
     *
     */
    otError Detach(void);

    /**
     * This method attaches the device to the Thread network.
     *
     * @note The joiner start and the attach proccesses are exclusive, and the
     *       network parameter will be set through the active dataset.
     *
     * @param[in]   aHandler        The attach result handler.
     *
     */
    void Attach(ResultHandler aHandler);

    /**
     * This method makes all nodes in the current network attach to the network specified by the dataset TLVs.
     *
     * @param[in] aDatasetTlvs  The dataset TLVs.
     * @param[in] aHandler      The result handler.
     *
     */
    void AttachAllNodesTo(const std::vector<uint8_t> &aDatasetTlvs, ResultHandler aHandler);

    /**
     * This method resets the OpenThread stack.
     *
     * @returns The error value of underlying OpenThread api calls.
     *
     */
    otError Reset(void);

    /**
     * This method triggers a thread join process.
     *
     * @note The joiner start and the attach proccesses are exclusive
     *
     * @param[in]   aPskd             The pre-shared key for device.
     * @param[in]   aProvisioningUrl  The provision url.
     * @param[in]   aVendorName       The vendor name.
     * @param[in]   aVendorModel      The vendor model.
     * @param[in]   aVendorSwVersion  The vendor software version.
     * @param[in]   aVendorData       The vendor custom data.
     * @param[in]   aHandler          The join result handler.
     *
     */
    void JoinerStart(const std::string &aPskd,
                     const std::string &aProvisioningUrl,
                     const std::string &aVendorName,
                     const std::string &aVendorModel,
                     const std::string &aVendorSwVersion,
                     const std::string &aVendorData,
                     ResultHandler      aHandler);

    /**
     * This method tries to restore the network after reboot
     *
     * @returns The error value of underlying OpenThread api calls.
     *
     */
    otError TryResumeNetwork(void);

    /**
     * This method returns the underlying OpenThread instance.
     *
     * @returns The underlying instance.
     *
     */
    otInstance *GetInstance(void) { return mInstance; }

    /**
     * This method handles OpenThread state changed notification.
     *
     * @param[in]  aFlags    A bit-field indicating specific state that has changed.  See `OT_CHANGED_*` definitions.
     *
     */
    void StateChangedCallback(otChangedFlags aFlags);

    /**
     * This method logs OpenThread action result.
     *
     * @param[in] aAction   The action OpenThread performs.
     * @param[in] aError    The action result.
     *
     */
    static void LogOpenThreadResult(const char *aAction, otError aError);

private:
    static void ActiveScanHandler(otActiveScanResult *aResult, void *aThreadHelper);
    void        ActiveScanHandler(otActiveScanResult *aResult);

    static void JoinerCallback(otError aError, void *aThreadHelper);
    void        JoinerCallback(otError aResult);

    static void MgmtSetResponseHandler(otError aResult, void *aContext);
    void        MgmtSetResponseHandler(otError aResult);

    void    RandomFill(void *aBuf, size_t size);
    uint8_t RandomChannelFromChannelMask(uint32_t aChannelMask);

    otInstance *mInstance;

    otbr::Ncp::ControllerOpenThread *mNcp;

    ScanHandler                     mScanHandler;
    std::vector<otActiveScanResult> mScanResults;

    std::vector<DeviceRoleHandler> mDeviceRoleHandlers;

    std::map<uint16_t, size_t> mUnsecurePortRefCounter;

    ResultHandler mAttachHandler;
    ResultHandler mJoinerHandler;

    std::random_device mRandomDevice;
};

} // namespace agent
} // namespace otbr

#endif // OTBR_THREAD_HELPER_HPP_