xref: /aosp_15_r20/external/openthread/src/posix/platform/configuration.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
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