1 /*
2 * Copyright (C) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <cstring>
17 #include "sta_monitor.h"
18 #include "sta_define.h"
19 #include "wifi_logger.h"
20 #include "wifi_supplicant_hal_interface.h"
21 #include "wifi_sta_hal_interface.h"
22 #include "wifi_common_util.h"
23 #include "wifi_hisysevent.h"
24 #include "wifi_event_callback.h"
25 #include "wifi_config_center.h"
26
27 DEFINE_WIFILOG_LABEL("StaMonitor");
28
29 namespace OHOS {
30 namespace Wifi {
StaMonitor(int instId)31 StaMonitor::StaMonitor(int instId) : pStaStateMachine(nullptr), m_instId(instId)
32 {
33 WIFI_LOGI("StaMonitor constuctor insId %{public}d", instId);
34 }
35
~StaMonitor()36 StaMonitor::~StaMonitor()
37 {
38 WIFI_LOGI("~StaMonitor");
39 }
40
InitStaMonitor()41 ErrCode StaMonitor::InitStaMonitor()
42 {
43 WIFI_LOGI("Enter InitStaMonitor.\n");
44 using namespace std::placeholders;
45 WifiEventCallback callBack = {
46 [this](int status, int networkId, const std::string &bssid) {
47 this->OnConnectChangedCallBack(status, networkId, bssid);
48 },
49 [this](const std::string &reason, const std::string &bssid) { this->OnBssidChangedCallBack(reason, bssid); },
50 [this](int status) { this->OnWpaStateChangedCallBack(status); },
51 [this]() { this->OnWpaSsidWrongKeyCallBack(); },
52 [this](int status) { this->OnWpsPbcOverlapCallBack(status); },
53 [this](int status) { this->OnWpsTimeOutCallBack(status); },
54 [this]() { this->OnWpaAuthTimeOutCallBack(); },
55 [this](int status) { this->OnWpaConnectionFullCallBack(status); },
56 [this](int status) { this->OnWpaConnectionRejectCallBack(status); },
57 [this](const std::string ¬ifyParam) { this->OnWpaStaNotifyCallBack(notifyParam); },
58 [this](int reason, const std::string &bssid) { this->OnReportDisConnectReasonCallBack(reason, bssid); },
59 };
60
61 std::string ifaceName = WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId);
62 if (WifiStaHalInterface::GetInstance().RegisterStaEventCallback(callBack, ifaceName) != WIFI_HAL_OPT_OK) {
63 WIFI_LOGE("InitStaMonitor RegisterStaEventCallback failed!");
64 return WIFI_OPT_FAILED;
65 }
66 return WIFI_OPT_SUCCESS;
67 }
68
UnInitStaMonitor() const69 NO_SANITIZE("cfi") ErrCode StaMonitor::UnInitStaMonitor() const
70 {
71 WIFI_LOGI("Enter UnInitStaMonitor.\n");
72 WifiEventCallback callBack;
73 std::string ifaceName = WifiConfigCenter::GetInstance().GetStaIfaceName(m_instId);
74 if (WifiStaHalInterface::GetInstance().RegisterStaEventCallback(callBack, ifaceName) != WIFI_HAL_OPT_OK) {
75 WIFI_LOGE("~StaMonitor RegisterStaEventCallback failed!");
76 return WIFI_OPT_FAILED;
77 }
78 return WIFI_OPT_SUCCESS;
79 }
80
SetStateMachine(StaStateMachine * paraStaStateMachine)81 void StaMonitor::SetStateMachine(StaStateMachine *paraStaStateMachine)
82 {
83 if (paraStaStateMachine == nullptr) {
84 WIFI_LOGE("The statemachine pointer is null.");
85 return;
86 }
87 pStaStateMachine = paraStaStateMachine;
88 return;
89 }
90
OnReportDisConnectReasonCallBack(int reason,const std::string & bssid)91 void StaMonitor::OnReportDisConnectReasonCallBack(int reason, const std::string &bssid)
92 {
93 WIFI_LOGI("OnReportDisConnectReasonCallBack() reason=%{public}d, bssid=%{public}s",
94 reason, MacAnonymize(bssid).c_str());
95 if (pStaStateMachine == nullptr) {
96 WIFI_LOGE("OnReportDisConnectReasonCallBack pStaStateMachine is nullptr");
97 return;
98 }
99
100 InternalMessagePtr msg = pStaStateMachine->CreateMessage();
101 if (msg == nullptr) {
102 WIFI_LOGE("OnReportDisConnectReasonCallBack CreateMessage failed");
103 return;
104 }
105 msg->SetMessageName(static_cast<int>(WIFI_SVR_CMD_STA_REPORT_DISCONNECT_REASON_EVENT));
106 msg->AddStringMessageBody(bssid);
107 msg->AddIntMessageBody(reason);
108 pStaStateMachine->SendMessage(msg);
109 }
110
OnConnectChangedCallBack(int status,int networkId,const std::string & bssid)111 void StaMonitor::OnConnectChangedCallBack(int status, int networkId, const std::string &bssid)
112 {
113 WIFI_LOGI("OnConnectChangedCallBack status:%{public}d, networkId=%{public}d, bssid=%{public}s, instId=%{public}d",
114 status, networkId, MacAnonymize(bssid).c_str(), m_instId);
115 if (pStaStateMachine == nullptr) {
116 WIFI_LOGE("The statemachine pointer is null.");
117 return;
118 }
119 if (status == HAL_WPA_CB_ASSOCIATING || status == HAL_WPA_CB_ASSOCIATED) {
120 pStaStateMachine->OnNetworkHiviewEvent(status);
121 }
122
123 switch (status) {
124 case HAL_WPA_CB_CONNECTED: {
125 pStaStateMachine->OnNetworkConnectionEvent(networkId, bssid);
126 break;
127 }
128 case HAL_WPA_CB_DISCONNECTED: {
129 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_NETWORK_DISCONNECTION_EVENT, bssid);
130 pStaStateMachine->OnNetworkDisconnectEvent(networkId);
131 break;
132 }
133 case HAL_WPA_CB_ASSOCIATING:
134 case HAL_WPA_CB_ASSOCIATED:
135 pStaStateMachine->OnNetworkAssocEvent(status, bssid, pStaStateMachine);
136 break;
137 default:
138 break;
139 }
140 }
141
OnWpaStaNotifyCallBack(const std::string & notifyParam)142 void StaMonitor::OnWpaStaNotifyCallBack(const std::string ¬ifyParam)
143 {
144 WIFI_LOGI("OnWpaStaNotifyCallBack() enter, notifyParam=%{private}s", notifyParam.c_str());
145 if (notifyParam.empty()) {
146 WIFI_LOGI("OnWpaStaNotifyCallBack() notifyParam is empty");
147 return;
148 }
149
150 std::string::size_type begPos = 0;
151 if ((begPos = notifyParam.find(":")) == std::string::npos) {
152 WIFI_LOGI("OnWpaStaNotifyCallBack() notifyParam not find :");
153 return;
154 }
155 std::string type = notifyParam.substr(0, begPos);
156 int num = CheckDataLegal(type);
157 std::string data = notifyParam.substr(begPos + 1);
158 if (data.empty()) {
159 WIFI_LOGI("OnWpaStaNotifyCallBack() data is empty");
160 return;
161 }
162 switch (num) {
163 case static_cast<int>(WpaEventCallback::HILINK_NUM):
164 OnWpaHilinkCallBack(data);
165 break;
166 case static_cast<int>(WpaEventCallback::EAP_SIM_NUM):
167 OnWpaEapSimAuthCallBack(data);
168 break;
169 default:
170 WIFI_LOGI("OnWpaStaNotifyCallBack() undefine event:%{public}d", num);
171 break;
172 }
173 }
174
OnWpaHilinkCallBack(const std::string & bssid)175 void StaMonitor::OnWpaHilinkCallBack(const std::string &bssid)
176 {
177 WIFI_LOGI("OnWpaHilinkCallBack() enter");
178 pStaStateMachine->SendMessage(WIFI_SVR_COM_STA_HILINK_TRIGGER_WPS, bssid);
179 return;
180 }
181
OnBssidChangedCallBack(const std::string & reason,const std::string & bssid)182 void StaMonitor::OnBssidChangedCallBack(const std::string &reason, const std::string &bssid)
183 {
184 WIFI_LOGI("OnBssidChangedCallBack() reason:%{public}s,bssid=%{public}s",
185 reason.c_str(),
186 MacAnonymize(bssid).c_str());
187 if (pStaStateMachine == nullptr) {
188 WIFI_LOGE("The statemachine pointer is null.");
189 return;
190 }
191
192 WifiLinkedInfo linkedInfo;
193 pStaStateMachine->GetLinkedInfo(linkedInfo);
194 if (linkedInfo.bssid == bssid) {
195 WIFI_LOGW("Sta ignored the event for bssid is the same.");
196 return;
197 }
198 pStaStateMachine->OnBssidChangedEvent(reason, bssid);
199 }
200
OnWpaStateChangedCallBack(int status)201 void StaMonitor::OnWpaStateChangedCallBack(int status)
202 {
203 WIFI_LOGI("OnWpaStateChangedCallBack() status:%{public}d\n", status);
204 if (pStaStateMachine == nullptr) {
205 WIFI_LOGE("The statemachine pointer is null.");
206 return;
207 }
208 WriteWifiWpaStateHiSysEvent(status);
209 /* Notification state machine wpa state changed event. */
210 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPA_STATE_CHANGE_EVENT, status);
211 }
212
OnWpaSsidWrongKeyCallBack()213 void StaMonitor::OnWpaSsidWrongKeyCallBack()
214 {
215 WIFI_LOGI("OnWpaSsidWrongKeyCallBack");
216 if (pStaStateMachine == nullptr) {
217 WIFI_LOGE("The statemachine pointer is null.");
218 return;
219 }
220
221 /* Notification state machine wpa password wrong event. */
222 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPA_PASSWD_WRONG_EVENT);
223 }
224
OnWpaConnectionFullCallBack(int status)225 void StaMonitor::OnWpaConnectionFullCallBack(int status)
226 {
227 LOGI("onWpaConnectionFullCallBack() status:%{public}d", status);
228 if (pStaStateMachine == nullptr) {
229 WIFI_LOGE("The statemachine pointer is null.");
230 return;
231 }
232
233 /* Notification state machine wpa password wrong event. */
234 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPA_FULL_CONNECT_EVENT);
235 }
236
OnWpaConnectionRejectCallBack(int status)237 void StaMonitor::OnWpaConnectionRejectCallBack(int status)
238 {
239 LOGI("onWpsConnectionRejectCallBack() status:%{public}d", status);
240 if (pStaStateMachine == nullptr) {
241 WIFI_LOGE("The statemachine pointer is null.");
242 return;
243 }
244
245 /* Notification state machine wpa password wrong event. */
246 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPA_ASSOC_REJECT_EVENT);
247 }
248
OnWpsPbcOverlapCallBack(int status)249 void StaMonitor::OnWpsPbcOverlapCallBack(int status)
250 {
251 WIFI_LOGI("OnWpsPbcOverlapCallBack() status:%{public}d\n", status);
252 if (pStaStateMachine == nullptr) {
253 WIFI_LOGE("The statemachine pointer is null.");
254 return;
255 }
256 /* Notification state machine WPS overlap event. */
257 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPS_OVERLAP_EVENT);
258 }
259
OnWpsTimeOutCallBack(int status)260 void StaMonitor::OnWpsTimeOutCallBack(int status)
261 {
262 WIFI_LOGI("OnWpsTimeOutCallBack() status:%{public}d\n", status);
263 if (pStaStateMachine == nullptr) {
264 WIFI_LOGE("The statemachine pointer is null.");
265 return;
266 }
267 /* Notification state machine WPS timeout event */
268 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPS_TIMEOUT_EVNET, status);
269 }
270
OnWpaAuthTimeOutCallBack()271 void StaMonitor::OnWpaAuthTimeOutCallBack()
272 {
273 WIFI_LOGI("OnWpaAuthTimeOutCallBack");
274 }
275
276 /* SIM authentication data format: [GSM-AUTH][:][Rand1][:][Rand2] or [GSM-AUTH][:][Rand1][:][Rand2][:][Rand3]
277 AKA/AKA authentication data format: [UMTS-AUTH][:][rand][:][autn]
278 */
OnWpaEapSimAuthCallBack(const std::string & notifyParam)279 void StaMonitor::OnWpaEapSimAuthCallBack(const std::string ¬ifyParam)
280 {
281 WIFI_LOGD("OnWpaEapSimAuthCallBack, notifyParam:%{private}s", notifyParam.c_str());
282 if (pStaStateMachine == nullptr) {
283 WIFI_LOGE("The statemachine pointer is null.");
284 return;
285 }
286
287 std::string delimiter = ":";
288 std::vector<std::string> results = getAuthInfo(notifyParam, delimiter);
289 int size = results.size();
290 if (results[0] == "GSM-AUTH") {
291 if ((size != WIFI_SIM_GSM_AUTH_MIN_PARAM_COUNT) && (size != WIFI_SIM_GSM_AUTH_MAX_PARAM_COUNT)) {
292 WIFI_LOGE("invalid GSM-AUTH authentication data, size:%{public}d", size);
293 return;
294 }
295
296 EapSimGsmAuthParam param;
297 for (int i = 0; i < size; i++) {
298 if (i == 0) {
299 continue;
300 }
301 param.rands.push_back(results[i]);
302 WIFI_LOGI("results[%{public}d]:%{public}s", i, results[i].c_str());
303 }
304 WIFI_LOGI("%{public}s size:%{public}zu", __func__, param.rands.size());
305 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPA_EAP_SIM_AUTH_EVENT, param);
306 } else if ((results[0] == "UMTS-AUTH") || (results[0] == "UMTS-AUTS")) {
307 if (size != WIFI_SIM_UMTS_AUTH_PARAM_COUNT) {
308 WIFI_LOGE("invalid UMTS-AUTH authentication data, size:%{public}d", size);
309 return;
310 }
311 EapSimUmtsAuthParam param;
312 param.rand = results[1]; // get rand data
313 param.autn = results[2]; // get autn data
314 WIFI_LOGD("%{public}s rand:%{private}s, autn:%{private}s",
315 __func__, param.rand.c_str(), param.autn.c_str());
316 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPA_EAP_UMTS_AUTH_EVENT, param);
317 } else {
318 WIFI_LOGE("Invalid authentication type, authType:%{public}s", results[0].c_str());
319 return;
320 }
321 }
322 } // namespace Wifi
323 } // namespace OHOS