1 /*
2  *  Copyright (c) 2016, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *   This file implements the OpenThread Operational Dataset API (for both FTD and MTD).
32  */
33 
34 #include "openthread-core-config.h"
35 
36 #include <openthread/dataset.h>
37 
38 #include "common/instance.hpp"
39 #include "common/locator_getters.hpp"
40 #include "meshcop/dataset_manager.hpp"
41 #include "meshcop/meshcop.hpp"
42 
43 using namespace ot;
44 
otDatasetIsCommissioned(otInstance * aInstance)45 bool otDatasetIsCommissioned(otInstance *aInstance)
46 {
47     Instance &instance = *static_cast<Instance *>(aInstance);
48 
49     return instance.Get<MeshCoP::ActiveDataset>().IsCommissioned();
50 }
51 
otDatasetGetActive(otInstance * aInstance,otOperationalDataset * aDataset)52 otError otDatasetGetActive(otInstance *aInstance, otOperationalDataset *aDataset)
53 {
54     Instance &instance = *static_cast<Instance *>(aInstance);
55 
56     OT_ASSERT(aDataset != nullptr);
57 
58     return instance.Get<MeshCoP::ActiveDataset>().Read(*static_cast<MeshCoP::Dataset::Info *>(aDataset));
59 }
60 
otDatasetGetActiveTlvs(otInstance * aInstance,otOperationalDatasetTlvs * aDataset)61 otError otDatasetGetActiveTlvs(otInstance *aInstance, otOperationalDatasetTlvs *aDataset)
62 {
63     Instance &instance = *static_cast<Instance *>(aInstance);
64 
65     OT_ASSERT(aDataset != nullptr);
66 
67     return instance.Get<MeshCoP::ActiveDataset>().Read(*aDataset);
68 }
69 
otDatasetSetActive(otInstance * aInstance,const otOperationalDataset * aDataset)70 otError otDatasetSetActive(otInstance *aInstance, const otOperationalDataset *aDataset)
71 {
72     Instance &instance = *static_cast<Instance *>(aInstance);
73 
74     OT_ASSERT(aDataset != nullptr);
75 
76     return instance.Get<MeshCoP::ActiveDataset>().Save(*static_cast<const MeshCoP::Dataset::Info *>(aDataset));
77 }
78 
otDatasetSetActiveTlvs(otInstance * aInstance,const otOperationalDatasetTlvs * aDataset)79 otError otDatasetSetActiveTlvs(otInstance *aInstance, const otOperationalDatasetTlvs *aDataset)
80 {
81     Instance &instance = *static_cast<Instance *>(aInstance);
82 
83     OT_ASSERT(aDataset != nullptr);
84 
85     return instance.Get<MeshCoP::ActiveDataset>().Save(*aDataset);
86 }
87 
otDatasetGetPending(otInstance * aInstance,otOperationalDataset * aDataset)88 otError otDatasetGetPending(otInstance *aInstance, otOperationalDataset *aDataset)
89 {
90     Instance &instance = *static_cast<Instance *>(aInstance);
91 
92     OT_ASSERT(aDataset != nullptr);
93 
94     return instance.Get<MeshCoP::PendingDataset>().Read(*static_cast<MeshCoP::Dataset::Info *>(aDataset));
95 }
96 
otDatasetGetPendingTlvs(otInstance * aInstance,otOperationalDatasetTlvs * aDataset)97 otError otDatasetGetPendingTlvs(otInstance *aInstance, otOperationalDatasetTlvs *aDataset)
98 {
99     Instance &instance = *static_cast<Instance *>(aInstance);
100 
101     OT_ASSERT(aDataset != nullptr);
102 
103     return instance.Get<MeshCoP::PendingDataset>().Read(*aDataset);
104 }
105 
otDatasetSetPending(otInstance * aInstance,const otOperationalDataset * aDataset)106 otError otDatasetSetPending(otInstance *aInstance, const otOperationalDataset *aDataset)
107 {
108     Instance &instance = *static_cast<Instance *>(aInstance);
109 
110     OT_ASSERT(aDataset != nullptr);
111 
112     return instance.Get<MeshCoP::PendingDataset>().Save(*static_cast<const MeshCoP::Dataset::Info *>(aDataset));
113 }
114 
otDatasetSetPendingTlvs(otInstance * aInstance,const otOperationalDatasetTlvs * aDataset)115 otError otDatasetSetPendingTlvs(otInstance *aInstance, const otOperationalDatasetTlvs *aDataset)
116 {
117     Instance &instance = *static_cast<Instance *>(aInstance);
118 
119     OT_ASSERT(aDataset != nullptr);
120 
121     return instance.Get<MeshCoP::PendingDataset>().Save(*aDataset);
122 }
123 
otDatasetSendMgmtActiveGet(otInstance * aInstance,const otOperationalDatasetComponents * aDatasetComponents,const uint8_t * aTlvTypes,uint8_t aLength,const otIp6Address * aAddress)124 otError otDatasetSendMgmtActiveGet(otInstance *                          aInstance,
125                                    const otOperationalDatasetComponents *aDatasetComponents,
126                                    const uint8_t *                       aTlvTypes,
127                                    uint8_t                               aLength,
128                                    const otIp6Address *                  aAddress)
129 {
130     Instance &instance = *static_cast<Instance *>(aInstance);
131 
132     return instance.Get<MeshCoP::ActiveDataset>().SendGetRequest(
133         *static_cast<const MeshCoP::Dataset::Components *>(aDatasetComponents), aTlvTypes, aLength, aAddress);
134 }
135 
otDatasetSendMgmtActiveSet(otInstance * aInstance,const otOperationalDataset * aDataset,const uint8_t * aTlvs,uint8_t aLength,otDatasetMgmtSetCallback aCallback,void * aContext)136 otError otDatasetSendMgmtActiveSet(otInstance *                aInstance,
137                                    const otOperationalDataset *aDataset,
138                                    const uint8_t *             aTlvs,
139                                    uint8_t                     aLength,
140                                    otDatasetMgmtSetCallback    aCallback,
141                                    void *                      aContext)
142 {
143     Instance &instance = *static_cast<Instance *>(aInstance);
144 
145     return instance.Get<MeshCoP::ActiveDataset>().SendSetRequest(*static_cast<const MeshCoP::Dataset::Info *>(aDataset),
146                                                                  aTlvs, aLength, aCallback, aContext);
147 }
148 
otDatasetSendMgmtPendingGet(otInstance * aInstance,const otOperationalDatasetComponents * aDatasetComponents,const uint8_t * aTlvTypes,uint8_t aLength,const otIp6Address * aAddress)149 otError otDatasetSendMgmtPendingGet(otInstance *                          aInstance,
150                                     const otOperationalDatasetComponents *aDatasetComponents,
151                                     const uint8_t *                       aTlvTypes,
152                                     uint8_t                               aLength,
153                                     const otIp6Address *                  aAddress)
154 {
155     Instance &instance = *static_cast<Instance *>(aInstance);
156 
157     return instance.Get<MeshCoP::PendingDataset>().SendGetRequest(
158         *static_cast<const MeshCoP::Dataset::Components *>(aDatasetComponents), aTlvTypes, aLength, aAddress);
159 }
160 
otDatasetSendMgmtPendingSet(otInstance * aInstance,const otOperationalDataset * aDataset,const uint8_t * aTlvs,uint8_t aLength,otDatasetMgmtSetCallback aCallback,void * aContext)161 otError otDatasetSendMgmtPendingSet(otInstance *                aInstance,
162                                     const otOperationalDataset *aDataset,
163                                     const uint8_t *             aTlvs,
164                                     uint8_t                     aLength,
165                                     otDatasetMgmtSetCallback    aCallback,
166                                     void *                      aContext)
167 {
168     Instance &instance = *static_cast<Instance *>(aInstance);
169 
170     return instance.Get<MeshCoP::PendingDataset>().SendSetRequest(
171         *static_cast<const MeshCoP::Dataset::Info *>(aDataset), aTlvs, aLength, aCallback, aContext);
172 }
173 
174 #if OPENTHREAD_FTD
otDatasetGeneratePskc(const char * aPassPhrase,const otNetworkName * aNetworkName,const otExtendedPanId * aExtPanId,otPskc * aPskc)175 otError otDatasetGeneratePskc(const char *           aPassPhrase,
176                               const otNetworkName *  aNetworkName,
177                               const otExtendedPanId *aExtPanId,
178                               otPskc *               aPskc)
179 {
180     return MeshCoP::GeneratePskc(aPassPhrase, *static_cast<const Mac::NetworkName *>(aNetworkName),
181                                  *static_cast<const Mac::ExtendedPanId *>(aExtPanId), *static_cast<Pskc *>(aPskc));
182 }
183 #endif // OPENTHREAD_FTD
184 
otNetworkNameFromString(otNetworkName * aNetworkName,const char * aNameString)185 otError otNetworkNameFromString(otNetworkName *aNetworkName, const char *aNameString)
186 {
187     otError error = static_cast<Mac::NetworkName *>(aNetworkName)->Set(aNameString);
188 
189     return (error == OT_ERROR_ALREADY) ? OT_ERROR_NONE : error;
190 }
191 
otDatasetParseTlvs(const otOperationalDatasetTlvs * aDatasetTlvs,otOperationalDataset * aDataset)192 otError otDatasetParseTlvs(const otOperationalDatasetTlvs *aDatasetTlvs, otOperationalDataset *aDataset)
193 {
194     Error            error = kErrorNone;
195     MeshCoP::Dataset dataset;
196 
197     dataset.SetFrom(*aDatasetTlvs);
198     VerifyOrExit(dataset.IsValid(), error = kErrorInvalidArgs);
199     dataset.ConvertTo(*static_cast<MeshCoP::Dataset::Info *>(aDataset));
200 
201 exit:
202     return error;
203 }
204