-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathWifiInterfaceAbstraction.cpp
210 lines (180 loc) · 7.34 KB
/
WifiInterfaceAbstraction.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*
*
* Copyright (c) 2022 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// SL MATTER WI-FI INTERFACE
#include "silabs_utils.h"
#include <app/icd/server/ICDServerConfig.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/silabs/wifi/WifiInterfaceAbstraction.h>
#if CHIP_CONFIG_ENABLE_ICD_SERVER
#include <platform/silabs/wifi/icd/WifiSleepManager.h>
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace chip;
using namespace chip::DeviceLayer;
#define CONVERT_SEC_TO_MS(TimeInS) (TimeInS * 1000)
// TODO: This is a workaround because we depend on the platform lib which depends on the platform implementation.
// As such we can't depend on the platform here as well
extern void HandleWFXSystemEvent(wfx_event_base_t eventBase, sl_wfx_generic_message_t * eventData);
// TODO: We shouldn't need to have access to a global variable in the interface here
extern WfxRsi_t wfx_rsi;
namespace {
constexpr uint8_t kWlanMinRetryIntervalsInSec = 1;
constexpr uint8_t kWlanMaxRetryIntervalsInSec = 60;
uint8_t retryInterval = kWlanMinRetryIntervalsInSec;
osTimerId_t sRetryTimer;
/*
* Notifications to the upper-layer
* All done in the context of the RSI/WiFi task (rsi_if.c)
*/
void RetryConnectionTimerHandler(void * arg)
{
if (wfx_connect_to_ap() != SL_STATUS_OK)
{
ChipLogError(DeviceLayer, "wfx_connect_to_ap() failed.");
}
}
} // namespace
/***********************************************************************************
* @fn sl_matter_wifi_task_started(void)
* @brief
* Wifi device started notification
* @param[in]: None
* @return None
*************************************************************************************/
void sl_matter_wifi_task_started(void)
{
sl_wfx_startup_ind_t evt;
sl_wfx_mac_address_t mac;
// Creating a timer which will be used to retry connection with AP
sRetryTimer = osTimerNew(RetryConnectionTimerHandler, osTimerOnce, NULL, NULL);
VerifyOrReturn(sRetryTimer != NULL);
memset(&evt, 0, sizeof(evt));
evt.header.id = SL_WFX_STARTUP_IND_ID;
evt.header.length = sizeof evt;
evt.body.status = 0;
wfx_get_wifi_mac_addr(SL_WFX_STA_INTERFACE, &mac);
memcpy(&evt.body.mac_addr[0], &mac.octet[0], MAC_ADDRESS_FIRST_OCTET);
HandleWFXSystemEvent(WIFI_EVENT, (sl_wfx_generic_message_t *) &evt);
}
/***********************************************************************************
* @fn void wfx_connected_notify(int32_t status, sl_wfx_mac_address_t *ap)
* @brief
* For now we are not notifying anything other than AP Mac -
* Other stuff such as DTIM etc. may be required for later
* @param[in] status:
* @param[in] ap: access point
* @return None
*************************************************************************************/
void wfx_connected_notify(int32_t status, sl_wfx_mac_address_t * ap)
{
sl_wfx_connect_ind_t evt;
VerifyOrReturn(status == SUCCESS_STATUS);
memset(&evt, 0, sizeof(evt));
evt.header.id = SL_WFX_CONNECT_IND_ID;
evt.header.length = sizeof evt;
#ifdef RS911X_WIFI
evt.body.channel = wfx_rsi.ap_chan;
#endif
memcpy(&evt.body.mac[0], &ap->octet[0], MAC_ADDRESS_FIRST_OCTET);
HandleWFXSystemEvent(WIFI_EVENT, (sl_wfx_generic_message_t *) &evt);
}
/**************************************************************************************
* @fn void wfx_disconnected_notify(int32_t status)
* @brief
* notification of disconnection
* @param[in] status:
* @return None
*************************************************************************************/
void wfx_disconnected_notify(int32_t status)
{
sl_wfx_disconnect_ind_t evt;
memset(&evt, 0, sizeof(evt));
evt.header.id = SL_WFX_DISCONNECT_IND_ID;
evt.header.length = sizeof evt;
evt.body.reason = status;
HandleWFXSystemEvent(WIFI_EVENT, (sl_wfx_generic_message_t *) &evt);
}
/**************************************************************************************
* @fn void wfx_ipv6_notify(int got_ip)
* @brief
* notification of ipv6
* @param[in] got_ip:
* @return None
*************************************************************************************/
void wfx_ipv6_notify(int got_ip)
{
sl_wfx_generic_message_t eventData;
memset(&eventData, 0, sizeof(eventData));
eventData.header.id = got_ip ? IP_EVENT_GOT_IP6 : IP_EVENT_STA_LOST_IP;
eventData.header.length = sizeof(eventData.header);
HandleWFXSystemEvent(IP_EVENT, &eventData);
}
/**************************************************************************************
* @fn void wfx_ip_changed_notify(int got_ip)
* @brief
* notification of ip change
* @param[in] got_ip:
* @return None
*************************************************************************************/
void wfx_ip_changed_notify(int got_ip)
{
sl_wfx_generic_message_t eventData;
memset(&eventData, 0, sizeof(eventData));
eventData.header.id = got_ip ? IP_EVENT_STA_GOT_IP : IP_EVENT_STA_LOST_IP;
eventData.header.length = sizeof(eventData.header);
HandleWFXSystemEvent(IP_EVENT, &eventData);
}
/**************************************************************************************
* @fn void wfx_retry_connection(uint16_t retryAttempt)
* @brief
* During commissioning, we retry to join the network MAX_JOIN_RETRIES_COUNT times.
* If DUT is disconnected from the AP or device is power cycled, then retry connection
* with AP continously after a certain time interval.
* @param[in] retryAttempt
* @return None
*************************************************************************************/
void wfx_retry_connection(uint16_t retryAttempt)
{
if (retryInterval > kWlanMaxRetryIntervalsInSec)
{
retryInterval = kWlanMaxRetryIntervalsInSec;
}
if (osTimerStart(sRetryTimer, pdMS_TO_TICKS(CONVERT_SEC_TO_MS(retryInterval))) != osOK)
{
ChipLogProgress(DeviceLayer, "Failed to start retry timer");
// Sending the join command if retry timer failed to start
if (wfx_connect_to_ap() != SL_STATUS_OK)
{
ChipLogError(DeviceLayer, "wfx_connect_to_ap() failed.");
}
#if CHIP_CONFIG_ENABLE_ICD_SERVER
// Remove High performance request before giving up due to a timer start error to save battery life
Silabs::WifiSleepManager::GetInstance().RemoveHighPerformanceRequest();
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
return;
}
#if CHIP_CONFIG_ENABLE_ICD_SERVER
Silabs::WifiSleepManager::GetInstance().RemoveHighPerformanceRequest();
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
ChipLogProgress(DeviceLayer, "wfx_retry_connection : Next attempt after %d Seconds", retryInterval);
retryInterval += retryInterval;
}