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 &notifyParam) { 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 &notifyParam)
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 &notifyParam)
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