• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #include "sta_network_check.h"
16 #include "if_config.h"
17 #include "wifi_logger.h"
18 
19 DEFINE_WIFILOG_LABEL("StaNetworkCheck");
20 
21 namespace OHOS {
22 namespace Wifi {
23 constexpr int NET_ERR_OK = 200;
24 constexpr int NET_ERR_CREATED = 201;
25 constexpr int NET_ERR_NO_CONTENT = 204;
26 constexpr int NET_ERR_BAD_REQUEST = 400;
27 
28 constexpr int NET_ERR_REDIRECT_CLASS_MAX = 399;
29 constexpr int NET_ERR_REQUEST_ERROR_CLASS_MAX = 499;
30 
StaNetworkCheck(NetStateHandler handle)31 StaNetworkCheck::StaNetworkCheck(NetStateHandler handle)
32 {
33     pDealNetCheckThread = nullptr;
34     netStateHandler = handle;
35     lastNetState = NETWORK_STATE_UNKNOWN;
36     isStopNetCheck = true;
37     isExitNetCheckThread = false;
38 }
39 
~StaNetworkCheck()40 StaNetworkCheck::~StaNetworkCheck()
41 {
42     WIFI_LOGI("StaNetworkCheck::~StaNetworkCheck enter\n");
43     ExitNetCheckThread();
44     WIFI_LOGI("StaNetworkCheck::~StaNetworkCheck complete\n");
45 }
46 
HttpDetection()47 bool StaNetworkCheck::HttpDetection()
48 {
49     WIFI_LOGI("Enter httpDetection");
50     /* Detect portal hotspot and send message to InterfaceSeervice if result is yes. */
51     HttpRequest httpRequest;
52     std::string httpReturn;
53     std::string httpMsg(DEFAULT_PORTAL_HTTPS_URL);
54     const std::string genStr("generate_204");
55     const std::string contStr("Content-Length:");
56 
57     if (httpRequest.HttpGet(httpMsg, httpReturn) == 0) {
58         int retCode = httpReturn.find("HTTP/");
59         int codeNum = 0;
60         if (retCode >= 0) {
61             constexpr int NET_ERROR_POS = 8;
62             constexpr int NET_ERROR_LEN = 5;
63             codeNum = std::atoi(httpReturn.substr(retCode + NET_ERROR_POS, NET_ERROR_LEN).c_str());
64         }
65 
66         int contLenStr = httpReturn.find(contStr);
67         int contLenNum = 0;
68         if (contLenStr > 0) {
69             constexpr int NET_CONTENT_LENGTH = 6;
70             contLenNum = std::atoi(httpReturn.substr(contLenStr + contStr.length(), NET_CONTENT_LENGTH).c_str());
71         }
72 
73         constexpr int PORTAL_CONTENT_LENGTH_MIN = 4;
74         if (codeNum == NET_ERR_NO_CONTENT) {
75             WIFI_LOGE("This network is normal!");
76             if ((lastNetState != NETWORK_STATE_WORKING) && (isExitNetCheckThread == false) &&
77                 (isStopNetCheck == false)) {
78                 netStateHandler(StaNetState::NETWORK_STATE_WORKING, "");
79             }
80             lastNetState = NETWORK_STATE_WORKING;
81             return true;
82         } else if (codeNum != NET_ERR_NO_CONTENT &&
83             (codeNum >= NET_ERR_CREATED && codeNum <= NET_ERR_REDIRECT_CLASS_MAX)) {
84             /* Callback result to InterfaceService. */
85             WIFI_LOGI("This network is portal AP, need certification!");
86             std::string urlTmp;
87             const std::string locStr("Location: ");
88             int startStr = httpReturn.find(locStr);
89             if (startStr > 0) {
90                 startStr += locStr.length();
91                 int endstr = httpReturn.find(genStr, startStr);
92                 if (endstr > 0) {
93                     endstr += genStr.length();
94                     urlTmp = httpReturn.substr(startStr, endstr-startStr);
95                 }
96                 netStateHandler(StaNetState::NETWORK_CHECK_PORTAL, urlTmp);
97             }
98             return false;
99         } else if ((codeNum == NET_ERR_OK ||
100             (codeNum >= NET_ERR_BAD_REQUEST && codeNum <= NET_ERR_REQUEST_ERROR_CLASS_MAX)) &&
101             contLenNum > PORTAL_CONTENT_LENGTH_MIN) {
102             WIFI_LOGI("This network is portal AP, need certification!");
103             std::string urlTmp;
104             const std::string locStr("http");
105             int startStr = httpReturn.find(locStr);
106             if (startStr > 0) {
107                 int endstr = httpReturn.find(genStr, startStr);
108                 if (endstr > 0) {
109                     endstr += genStr.length();
110                     urlTmp = httpReturn.substr(startStr, endstr-startStr);
111                 }
112                 netStateHandler(StaNetState::NETWORK_CHECK_PORTAL, urlTmp);
113             }
114             return false;
115         } else {
116             WIFI_LOGE("http msg error[%s]!", httpReturn.c_str());
117             netStateHandler(StaNetState::NETWORK_STATE_NOWORKING, "");
118             lastNetState = NETWORK_STATE_NOWORKING;
119             return true;
120         }
121     }
122     WIFI_LOGE("This network can't online!");
123     if ((lastNetState != NETWORK_STATE_NOWORKING) && (isExitNetCheckThread == false) && (isStopNetCheck == false)) {
124         netStateHandler(StaNetState::NETWORK_STATE_NOWORKING, "");
125     }
126     lastNetState = NETWORK_STATE_NOWORKING;
127     return true;
128 }
129 
RunNetCheckThreadFunc()130 void StaNetworkCheck::RunNetCheckThreadFunc()
131 {
132     WIFI_LOGI("enter RunNetCheckThreadFunc!\n");
133     int timeoutMs = 3000;
134     for (;;) {
135         while (isStopNetCheck && !isExitNetCheckThread) {
136             LOGI("waiting for signal.\n");
137             std::unique_lock<std::mutex> lck(mMutex);
138             mCondition.wait(lck);
139         }
140 
141         if (isExitNetCheckThread) {
142             WIFI_LOGI("break the loop\n");
143             break;
144         }
145 
146         if (!HttpDetection()) {
147             isStopNetCheck = true;
148         }
149 
150         if (!isExitNetCheckThread) {
151             std::unique_lock<std::mutex> lck(mMutex);
152             if (mCondition_timeout.wait_for(lck, std::chrono::milliseconds(timeoutMs)) == std::cv_status::timeout) {
153                 LOGD("mCondition_timeout timeout.\n");
154             } else {
155                 LOGD("Wake up, break the loop.\n");
156                 break;
157             }
158         }
159     }
160 }
161 
InitNetCheckThread()162 ErrCode StaNetworkCheck::InitNetCheckThread()
163 {
164     pDealNetCheckThread = new (std::nothrow) std::thread(&StaNetworkCheck::RunNetCheckThreadFunc, this);
165     if (pDealNetCheckThread == nullptr) {
166         WIFI_LOGE("In StaNetworkCheck start NetCheck thread failed!\n");
167         return ErrCode::WIFI_OPT_FAILED;
168     }
169     return ErrCode::WIFI_OPT_SUCCESS;
170 }
171 
StopNetCheckThread()172 void StaNetworkCheck::StopNetCheckThread()
173 {
174     WIFI_LOGI("enter StopNetCheckThread!\n");
175     std::unique_lock<std::mutex> lck(mMutex);
176     isStopNetCheck = true;
177 }
178 
SignalNetCheckThread()179 void StaNetworkCheck::SignalNetCheckThread()
180 {
181     WIFI_LOGI("enter SignalNetCheckThread!\n");
182     std::unique_lock<std::mutex> lck(mMutex);
183     lastNetState = NETWORK_STATE_UNKNOWN;
184     isStopNetCheck = false;
185     mCondition.notify_one();
186 }
187 
ExitNetCheckThread()188 void StaNetworkCheck::ExitNetCheckThread()
189 {
190     {
191         std::unique_lock<std::mutex> lck(mMutex);
192         isStopNetCheck = false;
193         isExitNetCheckThread = true;
194         mCondition.notify_one();
195         mCondition_timeout.notify_one();
196     }
197 
198     if (pDealNetCheckThread != nullptr) {
199         LOGD("pDealNetCheckThread->join();");
200         pDealNetCheckThread->join();
201         delete pDealNetCheckThread;
202         pDealNetCheckThread = nullptr;
203         LOGD("pDealNetCheckThread = nullptr; done");
204     }
205 }
206 }  // namespace Wifi
207 }  // namespace OHOS
208