1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker * Copyright (c) 2022, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker * All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker *
5*cfb92d14SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker * 1. Redistributions of source code must strain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker * 3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker * names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker *
16*cfb92d14SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*cfb92d14SAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker */
28*cfb92d14SAndroid Build Coastguard Worker
29*cfb92d14SAndroid Build Coastguard Worker #include "configuration.hpp"
30*cfb92d14SAndroid Build Coastguard Worker
31*cfb92d14SAndroid Build Coastguard Worker #include "platform-posix.h"
32*cfb92d14SAndroid Build Coastguard Worker #include <openthread/platform/radio.h>
33*cfb92d14SAndroid Build Coastguard Worker #include "lib/platform/exit_code.h"
34*cfb92d14SAndroid Build Coastguard Worker #include "utils/parse_cmdline.hpp"
35*cfb92d14SAndroid Build Coastguard Worker
36*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE && !OPENTHREAD_POSIX_CONFIG_CONFIGURATION_FILE_ENABLE
37*cfb92d14SAndroid Build Coastguard Worker #error \
38*cfb92d14SAndroid Build Coastguard Worker "OPENTHREAD_POSIX_CONFIG_CONFIGURATION_FILE_ENABLE is required for OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE"
39*cfb92d14SAndroid Build Coastguard Worker #endif
40*cfb92d14SAndroid Build Coastguard Worker
41*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_POSIX_CONFIG_CONFIGURATION_FILE_ENABLE
42*cfb92d14SAndroid Build Coastguard Worker
43*cfb92d14SAndroid Build Coastguard Worker namespace ot {
44*cfb92d14SAndroid Build Coastguard Worker namespace Posix {
45*cfb92d14SAndroid Build Coastguard Worker
46*cfb92d14SAndroid Build Coastguard Worker const char Configuration::kLogModuleName[] = "Config";
47*cfb92d14SAndroid Build Coastguard Worker
48*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
49*cfb92d14SAndroid Build Coastguard Worker const char Configuration::kKeyCalibratedPower[] = "calibrated_power";
50*cfb92d14SAndroid Build Coastguard Worker #endif
51*cfb92d14SAndroid Build Coastguard Worker const char Configuration::kKeyTargetPower[] = "target_power";
52*cfb92d14SAndroid Build Coastguard Worker const char Configuration::kKeyRegionDomainMapping[] = "region_domain_mapping";
53*cfb92d14SAndroid Build Coastguard Worker const char Configuration::kKeySupportedChannelMask[] = "supported_channel_mask";
54*cfb92d14SAndroid Build Coastguard Worker const char Configuration::kKeyPreferredChannelMask[] = "preferred_channel_mask";
55*cfb92d14SAndroid Build Coastguard Worker const char Configuration::kCommaDelimiter[] = ",";
56*cfb92d14SAndroid Build Coastguard Worker
SetRegion(uint16_t aRegionCode)57*cfb92d14SAndroid Build Coastguard Worker otError Configuration::SetRegion(uint16_t aRegionCode)
58*cfb92d14SAndroid Build Coastguard Worker {
59*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
60*cfb92d14SAndroid Build Coastguard Worker Power::Domain domain;
61*cfb92d14SAndroid Build Coastguard Worker
62*cfb92d14SAndroid Build Coastguard Worker if (GetDomain(aRegionCode, domain) != OT_ERROR_NONE)
63*cfb92d14SAndroid Build Coastguard Worker {
64*cfb92d14SAndroid Build Coastguard Worker // If failed to find the domain for the region, use the world wide region as the default region.
65*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(GetDomain(kRegionCodeWorldWide, domain) == OT_ERROR_NONE, error = OT_ERROR_FAILED);
66*cfb92d14SAndroid Build Coastguard Worker }
67*cfb92d14SAndroid Build Coastguard Worker
68*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = UpdateChannelMasks(domain));
69*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
70*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = UpdateTargetPower(domain));
71*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = UpdateCalibratedPower());
72*cfb92d14SAndroid Build Coastguard Worker #endif
73*cfb92d14SAndroid Build Coastguard Worker
74*cfb92d14SAndroid Build Coastguard Worker mRegionCode = aRegionCode;
75*cfb92d14SAndroid Build Coastguard Worker
76*cfb92d14SAndroid Build Coastguard Worker exit:
77*cfb92d14SAndroid Build Coastguard Worker if (error == OT_ERROR_NONE)
78*cfb92d14SAndroid Build Coastguard Worker {
79*cfb92d14SAndroid Build Coastguard Worker LogInfo("Successfully set region \"%c%c\"", (aRegionCode >> 8) & 0xff, (aRegionCode & 0xff));
80*cfb92d14SAndroid Build Coastguard Worker }
81*cfb92d14SAndroid Build Coastguard Worker else
82*cfb92d14SAndroid Build Coastguard Worker {
83*cfb92d14SAndroid Build Coastguard Worker LogCrit("Failed to set region \"%c%c\": %s", (aRegionCode >> 8) & 0xff, (aRegionCode & 0xff),
84*cfb92d14SAndroid Build Coastguard Worker otThreadErrorToString(error));
85*cfb92d14SAndroid Build Coastguard Worker }
86*cfb92d14SAndroid Build Coastguard Worker
87*cfb92d14SAndroid Build Coastguard Worker return error;
88*cfb92d14SAndroid Build Coastguard Worker }
89*cfb92d14SAndroid Build Coastguard Worker
GetDomain(uint16_t aRegionCode,Power::Domain & aDomain)90*cfb92d14SAndroid Build Coastguard Worker otError Configuration::GetDomain(uint16_t aRegionCode, Power::Domain &aDomain)
91*cfb92d14SAndroid Build Coastguard Worker {
92*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NOT_FOUND;
93*cfb92d14SAndroid Build Coastguard Worker int iterator = 0;
94*cfb92d14SAndroid Build Coastguard Worker char value[kMaxValueSize];
95*cfb92d14SAndroid Build Coastguard Worker char *str;
96*cfb92d14SAndroid Build Coastguard Worker char *psave;
97*cfb92d14SAndroid Build Coastguard Worker
98*cfb92d14SAndroid Build Coastguard Worker while (mProductConfigFile.Get(kKeyRegionDomainMapping, iterator, value, sizeof(value)) == OT_ERROR_NONE)
99*cfb92d14SAndroid Build Coastguard Worker {
100*cfb92d14SAndroid Build Coastguard Worker if ((str = strtok_r(value, kCommaDelimiter, &psave)) == nullptr)
101*cfb92d14SAndroid Build Coastguard Worker {
102*cfb92d14SAndroid Build Coastguard Worker continue;
103*cfb92d14SAndroid Build Coastguard Worker }
104*cfb92d14SAndroid Build Coastguard Worker
105*cfb92d14SAndroid Build Coastguard Worker while ((str = strtok_r(nullptr, kCommaDelimiter, &psave)) != nullptr)
106*cfb92d14SAndroid Build Coastguard Worker {
107*cfb92d14SAndroid Build Coastguard Worker if ((strlen(str) == 2) && (StringToRegionCode(str) == aRegionCode))
108*cfb92d14SAndroid Build Coastguard Worker {
109*cfb92d14SAndroid Build Coastguard Worker ExitNow(error = aDomain.Set(value));
110*cfb92d14SAndroid Build Coastguard Worker }
111*cfb92d14SAndroid Build Coastguard Worker }
112*cfb92d14SAndroid Build Coastguard Worker }
113*cfb92d14SAndroid Build Coastguard Worker
114*cfb92d14SAndroid Build Coastguard Worker exit:
115*cfb92d14SAndroid Build Coastguard Worker if (error != OT_ERROR_NONE)
116*cfb92d14SAndroid Build Coastguard Worker {
117*cfb92d14SAndroid Build Coastguard Worker LogCrit("Failed to get power domain: %s", otThreadErrorToString(error));
118*cfb92d14SAndroid Build Coastguard Worker }
119*cfb92d14SAndroid Build Coastguard Worker
120*cfb92d14SAndroid Build Coastguard Worker return error;
121*cfb92d14SAndroid Build Coastguard Worker }
122*cfb92d14SAndroid Build Coastguard Worker
GetChannelMask(const char * aKey,const Power::Domain & aDomain,uint32_t & aChannelMask)123*cfb92d14SAndroid Build Coastguard Worker otError Configuration::GetChannelMask(const char *aKey, const Power::Domain &aDomain, uint32_t &aChannelMask)
124*cfb92d14SAndroid Build Coastguard Worker {
125*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NOT_FOUND;
126*cfb92d14SAndroid Build Coastguard Worker int iterator = 0;
127*cfb92d14SAndroid Build Coastguard Worker char value[kMaxValueSize];
128*cfb92d14SAndroid Build Coastguard Worker char *str;
129*cfb92d14SAndroid Build Coastguard Worker Power::Domain domain;
130*cfb92d14SAndroid Build Coastguard Worker uint32_t channelMask;
131*cfb92d14SAndroid Build Coastguard Worker char *psave;
132*cfb92d14SAndroid Build Coastguard Worker
133*cfb92d14SAndroid Build Coastguard Worker while (mProductConfigFile.Get(aKey, iterator, value, sizeof(value)) == OT_ERROR_NONE)
134*cfb92d14SAndroid Build Coastguard Worker {
135*cfb92d14SAndroid Build Coastguard Worker if (((str = strtok_r(value, kCommaDelimiter, &psave)) == nullptr) || (aDomain != str))
136*cfb92d14SAndroid Build Coastguard Worker {
137*cfb92d14SAndroid Build Coastguard Worker continue;
138*cfb92d14SAndroid Build Coastguard Worker }
139*cfb92d14SAndroid Build Coastguard Worker
140*cfb92d14SAndroid Build Coastguard Worker if ((str = strtok_r(nullptr, kCommaDelimiter, &psave)) != nullptr)
141*cfb92d14SAndroid Build Coastguard Worker {
142*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = Utils::CmdLineParser::ParseAsUint32(str, channelMask));
143*cfb92d14SAndroid Build Coastguard Worker aChannelMask = channelMask;
144*cfb92d14SAndroid Build Coastguard Worker error = OT_ERROR_NONE;
145*cfb92d14SAndroid Build Coastguard Worker break;
146*cfb92d14SAndroid Build Coastguard Worker }
147*cfb92d14SAndroid Build Coastguard Worker }
148*cfb92d14SAndroid Build Coastguard Worker
149*cfb92d14SAndroid Build Coastguard Worker exit:
150*cfb92d14SAndroid Build Coastguard Worker return error;
151*cfb92d14SAndroid Build Coastguard Worker }
152*cfb92d14SAndroid Build Coastguard Worker
UpdateChannelMasks(const Power::Domain & aDomain)153*cfb92d14SAndroid Build Coastguard Worker otError Configuration::UpdateChannelMasks(const Power::Domain &aDomain)
154*cfb92d14SAndroid Build Coastguard Worker {
155*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
156*cfb92d14SAndroid Build Coastguard Worker
157*cfb92d14SAndroid Build Coastguard Worker if (mProductConfigFile.HasKey(kKeySupportedChannelMask))
158*cfb92d14SAndroid Build Coastguard Worker {
159*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = GetChannelMask(kKeySupportedChannelMask, aDomain, mSupportedChannelMask));
160*cfb92d14SAndroid Build Coastguard Worker }
161*cfb92d14SAndroid Build Coastguard Worker
162*cfb92d14SAndroid Build Coastguard Worker if (mProductConfigFile.HasKey(kKeySupportedChannelMask))
163*cfb92d14SAndroid Build Coastguard Worker {
164*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = GetChannelMask(kKeyPreferredChannelMask, aDomain, mPreferredChannelMask));
165*cfb92d14SAndroid Build Coastguard Worker }
166*cfb92d14SAndroid Build Coastguard Worker
167*cfb92d14SAndroid Build Coastguard Worker exit:
168*cfb92d14SAndroid Build Coastguard Worker if (error != OT_ERROR_NONE)
169*cfb92d14SAndroid Build Coastguard Worker {
170*cfb92d14SAndroid Build Coastguard Worker LogCrit("Failed to update channel mask: %s", otThreadErrorToString(error));
171*cfb92d14SAndroid Build Coastguard Worker }
172*cfb92d14SAndroid Build Coastguard Worker
173*cfb92d14SAndroid Build Coastguard Worker return error;
174*cfb92d14SAndroid Build Coastguard Worker }
175*cfb92d14SAndroid Build Coastguard Worker
176*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
UpdateTargetPower(const Power::Domain & aDomain)177*cfb92d14SAndroid Build Coastguard Worker otError Configuration::UpdateTargetPower(const Power::Domain &aDomain)
178*cfb92d14SAndroid Build Coastguard Worker {
179*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
180*cfb92d14SAndroid Build Coastguard Worker int iterator = 0;
181*cfb92d14SAndroid Build Coastguard Worker Power::TargetPower targetPower;
182*cfb92d14SAndroid Build Coastguard Worker
183*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(mProductConfigFile.HasKey(kKeyTargetPower));
184*cfb92d14SAndroid Build Coastguard Worker
185*cfb92d14SAndroid Build Coastguard Worker while (GetNextTargetPower(aDomain, iterator, targetPower) == OT_ERROR_NONE)
186*cfb92d14SAndroid Build Coastguard Worker {
187*cfb92d14SAndroid Build Coastguard Worker LogInfo("Update target power: %s\r\n", targetPower.ToString().AsCString());
188*cfb92d14SAndroid Build Coastguard Worker
189*cfb92d14SAndroid Build Coastguard Worker for (uint8_t ch = targetPower.GetChannelStart(); ch <= targetPower.GetChannelEnd(); ch++)
190*cfb92d14SAndroid Build Coastguard Worker {
191*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otPlatRadioSetChannelTargetPower(gInstance, ch, targetPower.GetTargetPower()));
192*cfb92d14SAndroid Build Coastguard Worker }
193*cfb92d14SAndroid Build Coastguard Worker }
194*cfb92d14SAndroid Build Coastguard Worker
195*cfb92d14SAndroid Build Coastguard Worker exit:
196*cfb92d14SAndroid Build Coastguard Worker if (error != OT_ERROR_NONE)
197*cfb92d14SAndroid Build Coastguard Worker {
198*cfb92d14SAndroid Build Coastguard Worker LogCrit("Failed to update target power: %s", otThreadErrorToString(error));
199*cfb92d14SAndroid Build Coastguard Worker }
200*cfb92d14SAndroid Build Coastguard Worker
201*cfb92d14SAndroid Build Coastguard Worker return error;
202*cfb92d14SAndroid Build Coastguard Worker }
203*cfb92d14SAndroid Build Coastguard Worker
UpdateCalibratedPower(void)204*cfb92d14SAndroid Build Coastguard Worker otError Configuration::UpdateCalibratedPower(void)
205*cfb92d14SAndroid Build Coastguard Worker {
206*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
207*cfb92d14SAndroid Build Coastguard Worker int iterator = 0;
208*cfb92d14SAndroid Build Coastguard Worker char value[kMaxValueSize];
209*cfb92d14SAndroid Build Coastguard Worker Power::CalibratedPower calibratedPower;
210*cfb92d14SAndroid Build Coastguard Worker ConfigFile *calibrationFile = &mFactoryConfigFile;
211*cfb92d14SAndroid Build Coastguard Worker
212*cfb92d14SAndroid Build Coastguard Worker // If the distribution of output power is large, the factory needs to measure the power calibration data
213*cfb92d14SAndroid Build Coastguard Worker // for each device individually, and the power calibration data will be written to the factory config file.
214*cfb92d14SAndroid Build Coastguard Worker // Otherwise, the power calibration data can be pre-configured in the product config file.
215*cfb92d14SAndroid Build Coastguard Worker if (calibrationFile->Get(kKeyCalibratedPower, iterator, value, sizeof(value)) != OT_ERROR_NONE)
216*cfb92d14SAndroid Build Coastguard Worker {
217*cfb92d14SAndroid Build Coastguard Worker calibrationFile = &mProductConfigFile;
218*cfb92d14SAndroid Build Coastguard Worker }
219*cfb92d14SAndroid Build Coastguard Worker
220*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(calibrationFile->HasKey(kKeyCalibratedPower));
221*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otPlatRadioClearCalibratedPowers(gInstance));
222*cfb92d14SAndroid Build Coastguard Worker
223*cfb92d14SAndroid Build Coastguard Worker iterator = 0;
224*cfb92d14SAndroid Build Coastguard Worker while (calibrationFile->Get(kKeyCalibratedPower, iterator, value, sizeof(value)) == OT_ERROR_NONE)
225*cfb92d14SAndroid Build Coastguard Worker {
226*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = calibratedPower.FromString(value));
227*cfb92d14SAndroid Build Coastguard Worker LogInfo("Update calibrated power: %s\r\n", calibratedPower.ToString().AsCString());
228*cfb92d14SAndroid Build Coastguard Worker
229*cfb92d14SAndroid Build Coastguard Worker for (uint8_t ch = calibratedPower.GetChannelStart(); ch <= calibratedPower.GetChannelEnd(); ch++)
230*cfb92d14SAndroid Build Coastguard Worker {
231*cfb92d14SAndroid Build Coastguard Worker SuccessOrExit(error = otPlatRadioAddCalibratedPower(gInstance, ch, calibratedPower.GetActualPower(),
232*cfb92d14SAndroid Build Coastguard Worker calibratedPower.GetRawPowerSetting().GetData(),
233*cfb92d14SAndroid Build Coastguard Worker calibratedPower.GetRawPowerSetting().GetLength()));
234*cfb92d14SAndroid Build Coastguard Worker }
235*cfb92d14SAndroid Build Coastguard Worker }
236*cfb92d14SAndroid Build Coastguard Worker
237*cfb92d14SAndroid Build Coastguard Worker exit:
238*cfb92d14SAndroid Build Coastguard Worker if (error != OT_ERROR_NONE)
239*cfb92d14SAndroid Build Coastguard Worker {
240*cfb92d14SAndroid Build Coastguard Worker LogCrit("Failed to update calibrated power table: %s", otThreadErrorToString(error));
241*cfb92d14SAndroid Build Coastguard Worker }
242*cfb92d14SAndroid Build Coastguard Worker
243*cfb92d14SAndroid Build Coastguard Worker return error;
244*cfb92d14SAndroid Build Coastguard Worker }
245*cfb92d14SAndroid Build Coastguard Worker
GetNextTargetPower(const Power::Domain & aDomain,int & aIterator,Power::TargetPower & aTargetPower)246*cfb92d14SAndroid Build Coastguard Worker otError Configuration::GetNextTargetPower(const Power::Domain &aDomain,
247*cfb92d14SAndroid Build Coastguard Worker int &aIterator,
248*cfb92d14SAndroid Build Coastguard Worker Power::TargetPower &aTargetPower)
249*cfb92d14SAndroid Build Coastguard Worker {
250*cfb92d14SAndroid Build Coastguard Worker otError error = OT_ERROR_NOT_FOUND;
251*cfb92d14SAndroid Build Coastguard Worker char value[kMaxValueSize];
252*cfb92d14SAndroid Build Coastguard Worker char *domain;
253*cfb92d14SAndroid Build Coastguard Worker char *psave;
254*cfb92d14SAndroid Build Coastguard Worker
255*cfb92d14SAndroid Build Coastguard Worker while (mProductConfigFile.Get(kKeyTargetPower, aIterator, value, sizeof(value)) == OT_ERROR_NONE)
256*cfb92d14SAndroid Build Coastguard Worker {
257*cfb92d14SAndroid Build Coastguard Worker if (((domain = strtok_r(value, kCommaDelimiter, &psave)) == nullptr) || (aDomain != domain))
258*cfb92d14SAndroid Build Coastguard Worker {
259*cfb92d14SAndroid Build Coastguard Worker continue;
260*cfb92d14SAndroid Build Coastguard Worker }
261*cfb92d14SAndroid Build Coastguard Worker
262*cfb92d14SAndroid Build Coastguard Worker if ((error = aTargetPower.FromString(psave)) != OT_ERROR_NONE)
263*cfb92d14SAndroid Build Coastguard Worker {
264*cfb92d14SAndroid Build Coastguard Worker LogCrit("Failed to read target power: %s", otThreadErrorToString(error));
265*cfb92d14SAndroid Build Coastguard Worker }
266*cfb92d14SAndroid Build Coastguard Worker break;
267*cfb92d14SAndroid Build Coastguard Worker }
268*cfb92d14SAndroid Build Coastguard Worker
269*cfb92d14SAndroid Build Coastguard Worker return error;
270*cfb92d14SAndroid Build Coastguard Worker }
271*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
272*cfb92d14SAndroid Build Coastguard Worker
IsValid(void) const273*cfb92d14SAndroid Build Coastguard Worker bool Configuration::IsValid(void) const
274*cfb92d14SAndroid Build Coastguard Worker {
275*cfb92d14SAndroid Build Coastguard Worker bool ret;
276*cfb92d14SAndroid Build Coastguard Worker
277*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(mProductConfigFile.DoesExist(), ret = false);
278*cfb92d14SAndroid Build Coastguard Worker
279*cfb92d14SAndroid Build Coastguard Worker ret = mProductConfigFile.HasKey(kKeySupportedChannelMask) || mProductConfigFile.HasKey(kKeyPreferredChannelMask) ||
280*cfb92d14SAndroid Build Coastguard Worker mProductConfigFile.HasKey(kKeyRegionDomainMapping);
281*cfb92d14SAndroid Build Coastguard Worker VerifyOrExit(!ret);
282*cfb92d14SAndroid Build Coastguard Worker
283*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
284*cfb92d14SAndroid Build Coastguard Worker ret = (mProductConfigFile.HasKey(kKeyCalibratedPower) || mProductConfigFile.HasKey(kKeyTargetPower));
285*cfb92d14SAndroid Build Coastguard Worker #endif
286*cfb92d14SAndroid Build Coastguard Worker
287*cfb92d14SAndroid Build Coastguard Worker exit:
288*cfb92d14SAndroid Build Coastguard Worker return ret;
289*cfb92d14SAndroid Build Coastguard Worker }
290*cfb92d14SAndroid Build Coastguard Worker
291*cfb92d14SAndroid Build Coastguard Worker } // namespace Posix
292*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
293*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_POSIX_CONFIG_CONFIGURATION_FILE_ENABLE
294