Line data Source code
1 : /*
2 : * Copyright (c) 2021 Project CHIP Authors
3 : * All rights reserved.
4 : *
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * You may obtain a copy of the License at
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 :
18 : /**
19 : * @file
20 : * This file defines the configuration parameters that are required
21 : * for the CHIP Reliable Messaging Protocol.
22 : *
23 : */
24 : #include <messaging/ReliableMessageMgr.h>
25 :
26 : #include <app/icd/server/ICDServerConfig.h>
27 : #include <platform/CHIPDeviceConfig.h>
28 : #include <platform/CHIPDeviceLayer.h>
29 : #include <system/SystemClock.h>
30 :
31 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
32 : #include <app/icd/server/ICDConfigurationData.h> // nogncheck
33 : #endif
34 :
35 : namespace chip {
36 :
37 : using namespace System::Clock::Literals;
38 :
39 : #if CONFIG_BUILD_FOR_HOST_UNIT_TEST
40 : static Optional<System::Clock::Timeout> idleRetransTimeoutOverride = NullOptional;
41 : static Optional<System::Clock::Timeout> activeRetransTimeoutOverride = NullOptional;
42 : static Optional<System::Clock::Timeout> activeThresholdTimeOverride = NullOptional;
43 :
44 7 : void OverrideLocalMRPConfig(System::Clock::Timeout idleRetransTimeout, System::Clock::Timeout activeRetransTimeout,
45 : System::Clock::Timeout activeThresholdTime)
46 : {
47 7 : idleRetransTimeoutOverride.SetValue(idleRetransTimeout);
48 7 : activeRetransTimeoutOverride.SetValue(activeRetransTimeout);
49 7 : activeThresholdTimeOverride.SetValue(activeThresholdTime);
50 7 : }
51 :
52 7 : void ClearLocalMRPConfigOverride()
53 : {
54 7 : activeRetransTimeoutOverride.ClearValue();
55 7 : idleRetransTimeoutOverride.ClearValue();
56 7 : activeThresholdTimeOverride.ClearValue();
57 7 : }
58 : #endif
59 :
60 : #if CHIP_DEVICE_CONFIG_ENABLE_DYNAMIC_MRP_CONFIG
61 : namespace {
62 :
63 : // This is not a static member of ReliableMessageProtocolConfig because the free
64 : // function GetLocalMRPConfig() needs access to it.
65 : Optional<ReliableMessageProtocolConfig> sDynamicLocalMPRConfig;
66 :
67 : } // anonymous namespace
68 :
69 : bool ReliableMessageProtocolConfig::SetLocalMRPConfig(const Optional<ReliableMessageProtocolConfig> & localMRPConfig)
70 : {
71 : auto oldConfig = GetLocalMRPConfig();
72 : sDynamicLocalMPRConfig = localMRPConfig;
73 : return oldConfig != GetLocalMRPConfig();
74 : }
75 : #endif // CHIP_DEVICE_CONFIG_ENABLE_DYNAMIC_MRP_CONFIG
76 :
77 150634 : ReliableMessageProtocolConfig GetDefaultMRPConfig()
78 : {
79 : // Default MRP intervals are defined in spec <4.12.8. Parameters and Constants>
80 : static constexpr const System::Clock::Milliseconds32 idleRetransTimeout = 500_ms32;
81 : static constexpr const System::Clock::Milliseconds32 activeRetransTimeout = 300_ms32;
82 : static constexpr const System::Clock::Milliseconds16 activeThresholdTime = 4000_ms16;
83 : static_assert(activeThresholdTime == kDefaultActiveTime, "Different active defaults?");
84 150634 : return ReliableMessageProtocolConfig(idleRetransTimeout, activeRetransTimeout, activeThresholdTime);
85 : }
86 :
87 8310 : Optional<ReliableMessageProtocolConfig> GetLocalMRPConfig()
88 : {
89 8310 : ReliableMessageProtocolConfig config(CHIP_CONFIG_MRP_LOCAL_IDLE_RETRY_INTERVAL, CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL);
90 :
91 : #if CHIP_DEVICE_CONFIG_ENABLE_DYNAMIC_MRP_CONFIG
92 : if (sDynamicLocalMPRConfig.HasValue())
93 : {
94 : config = sDynamicLocalMPRConfig.Value();
95 : }
96 : #endif // CHIP_DEVICE_CONFIG_ENABLE_DYNAMIC_MRP_CONFIG
97 :
98 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
99 : // TODO ICD LIT shall not advertise the SII key
100 : // Increase local MRP retry intervals by ICD polling intervals. That is, intervals for
101 : // which the device can be at sleep and not be able to receive any messages).
102 : config.mIdleRetransTimeout += ICDConfigurationData::GetInstance().GetSlowPollingInterval();
103 : config.mActiveRetransTimeout += ICDConfigurationData::GetInstance().GetFastPollingInterval();
104 : config.mActiveThresholdTime = ICDConfigurationData::GetInstance().GetActiveModeThreshold();
105 : #endif
106 :
107 : #if CONFIG_BUILD_FOR_HOST_UNIT_TEST
108 8310 : if (idleRetransTimeoutOverride.HasValue())
109 : {
110 47 : config.mIdleRetransTimeout = idleRetransTimeoutOverride.Value();
111 : }
112 :
113 8310 : if (activeRetransTimeoutOverride.HasValue())
114 : {
115 47 : config.mActiveRetransTimeout = activeRetransTimeoutOverride.Value();
116 : }
117 :
118 8310 : if (activeThresholdTimeOverride.HasValue())
119 : {
120 47 : config.mActiveThresholdTime = activeRetransTimeoutOverride.Value();
121 : }
122 : #endif
123 :
124 16620 : return (config == GetDefaultMRPConfig()) ? Optional<ReliableMessageProtocolConfig>::Missing()
125 8310 : : Optional<ReliableMessageProtocolConfig>::Value(config);
126 : }
127 :
128 13576 : System::Clock::Timeout GetRetransmissionTimeout(System::Clock::Timeout activeInterval, System::Clock::Timeout idleInterval,
129 : System::Clock::Timeout lastActivityTime, System::Clock::Timeout activityThreshold)
130 : {
131 13576 : auto timeSinceLastActivity = (System::SystemClock().GetMonotonicTimestamp() - lastActivityTime);
132 :
133 : // Calculate the retransmission timeout and take into account that an active/idle state change can happen
134 : // in the middle.
135 13576 : System::Clock::Timestamp timeout(0);
136 81456 : for (uint8_t i = 0; i < CHIP_CONFIG_RMP_DEFAULT_MAX_RETRANS + 1; i++)
137 : {
138 67880 : auto baseInterval = ((timeSinceLastActivity + timeout) < activityThreshold) ? activeInterval : idleInterval;
139 67880 : timeout += Messaging::ReliableMessageMgr::GetBackoff(baseInterval, i, /* computeMaxPossible */ true);
140 : }
141 :
142 13576 : return timeout;
143 : }
144 :
145 : } // namespace chip
|