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
179 pStaStateMachine->SendMessage(WIFI_SVR_COM_STA_HILINK_TRIGGER_WPS, bssid);
180 return;
181 }
182
OnBssidChangedCallBack(const std::string & reason,const std::string & bssid)183 void StaMonitor::OnBssidChangedCallBack(const std::string &reason, const std::string &bssid)
184 {
185 WIFI_LOGI("OnBssidChangedCallBack() reason:%{public}s,bssid=%{public}s",
186 reason.c_str(),
187 MacAnonymize(bssid).c_str());
188 if (pStaStateMachine == nullptr) {
189 WIFI_LOGE("The statemachine pointer is null.");
190 return;
191 }
192
193 WifiLinkedInfo linkedInfo;
194 pStaStateMachine->GetLinkedInfo(linkedInfo);
195 if (linkedInfo.bssid == bssid) {
196 WIFI_LOGW("Sta ignored the event for bssid is the same.");
197 return;
198 }
199 pStaStateMachine->OnBssidChangedEvent(reason, bssid);
200 }
201
OnWpaStateChangedCallBack(int status)202 void StaMonitor::OnWpaStateChangedCallBack(int status)
203 {
204 WIFI_LOGI("OnWpaStateChangedCallBack() status:%{public}d\n", status);
205 if (pStaStateMachine == nullptr) {
206 WIFI_LOGE("The statemachine pointer is null.");
207 return;
208 }
209 WriteWifiWpaStateHiSysEvent(status);
210 /* Notification state machine wpa state changed event. */
211 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPA_STATE_CHANGE_EVENT, status);
212 }
213
OnWpaSsidWrongKeyCallBack()214 void StaMonitor::OnWpaSsidWrongKeyCallBack()
215 {
216 WIFI_LOGI("OnWpaSsidWrongKeyCallBack");
217 if (pStaStateMachine == nullptr) {
218 WIFI_LOGE("The statemachine pointer is null.");
219 return;
220 }
221
222 /* Notification state machine wpa password wrong event. */
223 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPA_PASSWD_WRONG_EVENT);
224 }
225
OnWpaConnectionFullCallBack(int status)226 void StaMonitor::OnWpaConnectionFullCallBack(int status)
227 {
228 LOGI("onWpaConnectionFullCallBack() status:%{public}d", status);
229 if (pStaStateMachine == nullptr) {
230 WIFI_LOGE("The statemachine pointer is null.");
231 return;
232 }
233
234 /* Notification state machine wpa password wrong event. */
235 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPA_FULL_CONNECT_EVENT);
236 }
237
OnWpaConnectionRejectCallBack(int status)238 void StaMonitor::OnWpaConnectionRejectCallBack(int status)
239 {
240 LOGI("onWpsConnectionRejectCallBack() status:%{public}d", status);
241 if (pStaStateMachine == nullptr) {
242 WIFI_LOGE("The statemachine pointer is null.");
243 return;
244 }
245
246 /* Notification state machine wpa password wrong event. */
247 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPA_ASSOC_REJECT_EVENT);
248 }
249
OnWpsPbcOverlapCallBack(int status)250 void StaMonitor::OnWpsPbcOverlapCallBack(int status)
251 {
252 WIFI_LOGI("OnWpsPbcOverlapCallBack() status:%{public}d\n", status);
253 if (pStaStateMachine == nullptr) {
254 WIFI_LOGE("The statemachine pointer is null.");
255 return;
256 }
257 /* Notification state machine WPS overlap event. */
258 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPS_OVERLAP_EVENT);
259 }
260
OnWpsTimeOutCallBack(int status)261 void StaMonitor::OnWpsTimeOutCallBack(int status)
262 {
263 WIFI_LOGI("OnWpsTimeOutCallBack() status:%{public}d\n", status);
264 if (pStaStateMachine == nullptr) {
265 WIFI_LOGE("The statemachine pointer is null.");
266 return;
267 }
268 /* Notification state machine WPS timeout event */
269 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPS_TIMEOUT_EVNET, status);
270 }
271
OnWpaAuthTimeOutCallBack()272 void StaMonitor::OnWpaAuthTimeOutCallBack()
273 {
274 WIFI_LOGI("OnWpaAuthTimeOutCallBack");
275 }
276
277 /* SIM authentication data format: [GSM-AUTH][:][Rand1][:][Rand2] or [GSM-AUTH][:][Rand1][:][Rand2][:][Rand3]
278 AKA/AKA authentication data format: [UMTS-AUTH][:][rand][:][autn]
279 */
OnWpaEapSimAuthCallBack(const std::string & notifyParam)280 void StaMonitor::OnWpaEapSimAuthCallBack(const std::string ¬ifyParam)
281 {
282 WIFI_LOGD("OnWpaEapSimAuthCallBack, notifyParam:%{private}s", notifyParam.c_str());
283 if (pStaStateMachine == nullptr) {
284 WIFI_LOGE("The statemachine pointer is null.");
285 return;
286 }
287
288 std::string delimiter = ":";
289 std::vector<std::string> results = getAuthInfo(notifyParam, delimiter);
290 int size = results.size();
291 if (results[0] == "GSM-AUTH") {
292 if ((size != WIFI_SIM_GSM_AUTH_MIN_PARAM_COUNT) && (size != WIFI_SIM_GSM_AUTH_MAX_PARAM_COUNT)) {
293 WIFI_LOGE("invalid GSM-AUTH authentication data, size:%{public}d", size);
294 return;
295 }
296
297 EapSimGsmAuthParam param;
298 for (int i = 0; i < size; i++) {
299 if (i == 0) {
300 continue;
301 }
302 param.rands.push_back(results[i]);
303 WIFI_LOGI("results[%{public}d]:%{public}s", i, results[i].c_str());
304 }
305 WIFI_LOGI("%{public}s size:%{public}zu", __func__, param.rands.size());
306 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPA_EAP_SIM_AUTH_EVENT, param);
307 } else if ((results[0] == "UMTS-AUTH") || (results[0] == "UMTS-AUTS")) {
308 if (size != WIFI_SIM_UMTS_AUTH_PARAM_COUNT) {
309 WIFI_LOGE("invalid UMTS-AUTH authentication data, size:%{public}d", size);
310 return;
311 }
312 EapSimUmtsAuthParam param;
313 param.rand = results[1]; // get rand data
314 param.autn = results[2]; // get autn data
315 WIFI_LOGD("%{public}s rand:%{private}s, autn:%{private}s",
316 __func__, param.rand.c_str(), param.autn.c_str());
317 pStaStateMachine->SendMessage(WIFI_SVR_CMD_STA_WPA_EAP_UMTS_AUTH_EVENT, param);
318 } else {
319 WIFI_LOGE("Invalid authentication type, authType:%{public}s", results[0].c_str());
320 return;
321 }
322 }
323 } // namespace Wifi
324 } // namespace OHOS