1 /*
2  *  Copyright (c) 2022, 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 #include <openthread/platform/radio.h>
30 
31 #include "test_platform.h"
32 #include "test_util.h"
33 
34 #if OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE && OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
35 
36 namespace ot {
37 
TestPowerCalibration(void)38 void TestPowerCalibration(void)
39 {
40     otInstance *instance;
41     uint8_t     rawPowerSetting[2];
42     uint16_t    rawPowerSettingLength;
43 
44     struct CalibratedPowerEntry
45     {
46         uint8_t  mChannel;
47         int16_t  mActualPower;
48         uint8_t  mRawPowerSetting[1];
49         uint16_t mRawPowerSettingLength;
50     };
51 
52     constexpr CalibratedPowerEntry kCalibratedPowerTable[] = {
53         {11, 15000, {0x02}, 1},
54         {11, 5000, {0x00}, 1},
55         {11, 10000, {0x01}, 1},
56     };
57 
58     instance = static_cast<otInstance *>(testInitInstance());
59     VerifyOrQuit(instance != nullptr, "Null OpenThread instance");
60 
61     for (const CalibratedPowerEntry &calibratedPower : kCalibratedPowerTable)
62     {
63         SuccessOrQuit(otPlatRadioAddCalibratedPower(instance, calibratedPower.mChannel, calibratedPower.mActualPower,
64                                                     calibratedPower.mRawPowerSetting,
65                                                     calibratedPower.mRawPowerSettingLength));
66     }
67 
68     SuccessOrQuit(otPlatRadioSetChannelTargetPower(instance, 11, 4999));
69     rawPowerSettingLength = sizeof(rawPowerSetting);
70     SuccessOrQuit(otPlatRadioGetRawPowerSetting(instance, 11, rawPowerSetting, &rawPowerSettingLength));
71     VerifyOrQuit(rawPowerSettingLength == 1);
72     VerifyOrQuit(rawPowerSetting[0] == 0x00);
73 
74     SuccessOrQuit(otPlatRadioSetChannelTargetPower(instance, 11, 5000));
75     rawPowerSettingLength = sizeof(rawPowerSetting);
76     SuccessOrQuit(otPlatRadioGetRawPowerSetting(instance, 11, rawPowerSetting, &rawPowerSettingLength));
77     VerifyOrQuit(rawPowerSettingLength == 1);
78     VerifyOrQuit(rawPowerSetting[0] == 0x00);
79 
80     SuccessOrQuit(otPlatRadioSetChannelTargetPower(instance, 11, 9999));
81     rawPowerSettingLength = sizeof(rawPowerSetting);
82     SuccessOrQuit(otPlatRadioGetRawPowerSetting(instance, 11, rawPowerSetting, &rawPowerSettingLength));
83     VerifyOrQuit(rawPowerSettingLength == 1);
84     VerifyOrQuit(rawPowerSetting[0] == 0x00);
85 
86     SuccessOrQuit(otPlatRadioSetChannelTargetPower(instance, 11, 10000));
87     rawPowerSettingLength = sizeof(rawPowerSetting);
88     SuccessOrQuit(otPlatRadioGetRawPowerSetting(instance, 11, rawPowerSetting, &rawPowerSettingLength));
89     VerifyOrQuit(rawPowerSettingLength == 1);
90     VerifyOrQuit(rawPowerSetting[0] == 0x01);
91 
92     SuccessOrQuit(otPlatRadioSetChannelTargetPower(instance, 11, 14999));
93     rawPowerSettingLength = sizeof(rawPowerSetting);
94     SuccessOrQuit(otPlatRadioGetRawPowerSetting(instance, 11, rawPowerSetting, &rawPowerSettingLength));
95     VerifyOrQuit(rawPowerSettingLength == 1);
96     VerifyOrQuit(rawPowerSetting[0] == 0x01);
97 
98     SuccessOrQuit(otPlatRadioSetChannelTargetPower(instance, 11, 15000));
99     rawPowerSettingLength = sizeof(rawPowerSetting);
100     SuccessOrQuit(otPlatRadioGetRawPowerSetting(instance, 11, rawPowerSetting, &rawPowerSettingLength));
101     VerifyOrQuit(rawPowerSettingLength == 1);
102     VerifyOrQuit(rawPowerSetting[0] == 0x02);
103 
104     SuccessOrQuit(otPlatRadioSetChannelTargetPower(instance, 11, 15001));
105     rawPowerSettingLength = sizeof(rawPowerSetting);
106     SuccessOrQuit(otPlatRadioGetRawPowerSetting(instance, 11, rawPowerSetting, &rawPowerSettingLength));
107     VerifyOrQuit(rawPowerSettingLength == 1);
108     VerifyOrQuit(rawPowerSetting[0] == 0x02);
109 
110     rawPowerSettingLength = sizeof(rawPowerSetting);
111     VerifyOrQuit(otPlatRadioGetRawPowerSetting(instance, 12, rawPowerSetting, &rawPowerSettingLength) ==
112                  OT_ERROR_NOT_FOUND);
113 
114     SuccessOrQuit(otPlatRadioClearCalibratedPowers(instance));
115     rawPowerSettingLength = sizeof(rawPowerSetting);
116     VerifyOrQuit(otPlatRadioGetRawPowerSetting(instance, 11, rawPowerSetting, &rawPowerSettingLength) ==
117                  OT_ERROR_NOT_FOUND);
118 
119     for (const CalibratedPowerEntry &calibratedPower : kCalibratedPowerTable)
120     {
121         SuccessOrQuit(otPlatRadioAddCalibratedPower(instance, calibratedPower.mChannel, calibratedPower.mActualPower,
122                                                     calibratedPower.mRawPowerSetting,
123                                                     calibratedPower.mRawPowerSettingLength));
124     }
125 
126     SuccessOrQuit(otPlatRadioSetChannelTargetPower(instance, 11, 15000));
127     rawPowerSettingLength = sizeof(rawPowerSetting);
128     SuccessOrQuit(otPlatRadioGetRawPowerSetting(instance, 11, rawPowerSetting, &rawPowerSettingLength));
129     VerifyOrQuit(rawPowerSettingLength == 1);
130     VerifyOrQuit(rawPowerSetting[0] == 0x02);
131 
132     VerifyOrQuit(
133         otPlatRadioAddCalibratedPower(instance, kCalibratedPowerTable[0].mChannel,
134                                       kCalibratedPowerTable[0].mActualPower, kCalibratedPowerTable[0].mRawPowerSetting,
135                                       kCalibratedPowerTable[0].mRawPowerSettingLength) == OT_ERROR_INVALID_ARGS);
136 
137     testFreeInstance(instance);
138 }
139 } // namespace ot
140 
141 #endif // OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE && OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
142 
main(void)143 int main(void)
144 {
145 #if OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE && OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
146     ot::TestPowerCalibration();
147     printf("All tests passed\n");
148 #else
149     printf("Power calibration is not enabled\n");
150 #endif
151     return 0;
152 }
153