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 "dhcp_client_service_impl.h"
17
18 #include <sys/types.h>
19 #include <sys/wait.h>
20 #include <unistd.h>
21 #include <vector>
22
23 #include "dhcp_func.h"
24 #include "securec.h"
25 #include "wifi_logger.h"
26 #include "dhcp_event_subscriber.h"
27
28 DEFINE_WIFILOG_DHCP_LABEL("DhcpClientServiceImpl");
29
30 namespace OHOS {
31 namespace Wifi {
32 std::map<std::string, DhcpResult> DhcpClientServiceImpl::m_mapDhcpResult;
33 std::map<std::string, DhcpServiceInfo> DhcpClientServiceImpl::m_mapDhcpInfo;
DhcpClientServiceImpl()34 DhcpClientServiceImpl::DhcpClientServiceImpl()
35 {
36 isExitDhcpResultHandleThread = false;
37 pDhcpResultHandleThread = nullptr;
38 #ifdef OHOS_ARCH_LITE
39 m_mapDhcpRecvMsgThread.clear();
40 #endif
41 if (!m_mapDhcpResultNotify.empty()) {
42 ReleaseResultNotifyMemory();
43 m_mapDhcpResultNotify.clear();
44 }
45 m_mapEventSubscriber.clear();
46 InitDhcpMgrThread();
47 DhcpFunc::CreateDirs(DHCP_WORK_DIR);
48 }
49
~DhcpClientServiceImpl()50 DhcpClientServiceImpl::~DhcpClientServiceImpl()
51 {
52 std::unique_lock<std::mutex> lock(m_subscriberMutex);
53 if (!m_mapEventSubscriber.empty()) {
54 WIFI_LOGE("DhcpClientServiceImpl destructor mapEventSubscriber is not empty!");
55 if (UnsubscribeAllDhcpEvent() != DHCP_OPT_SUCCESS) {
56 WIFI_LOGE("DhcpClientServiceImpl unregister all dhcp event failed!");
57 }
58 }
59
60 ExitDhcpMgrThread();
61 }
62
ReleaseResultNotifyMemory()63 void DhcpClientServiceImpl::ReleaseResultNotifyMemory()
64 {
65 for (auto& item : m_mapDhcpResultNotify) {
66 auto& secondItem = item.second;
67 for (auto& each : secondItem) {
68 if (each != nullptr) {
69 delete each;
70 each = nullptr;
71 }
72 }
73 }
74 }
75
InitDhcpMgrThread()76 int DhcpClientServiceImpl::InitDhcpMgrThread()
77 {
78 pDhcpResultHandleThread = new std::thread(&DhcpClientServiceImpl::RunDhcpResultHandleThreadFunc, this);
79 if (pDhcpResultHandleThread == nullptr) {
80 WIFI_LOGE("DhcpClientServiceImpl::InitDhcpMgrThread() init pDhcpResultHandleThread failed!");
81 return DHCP_OPT_FAILED;
82 }
83
84 return DHCP_OPT_SUCCESS;
85 }
86
ExitDhcpMgrThread()87 void DhcpClientServiceImpl::ExitDhcpMgrThread()
88 {
89 isExitDhcpResultHandleThread = true;
90
91 if (pDhcpResultHandleThread != nullptr) {
92 pDhcpResultHandleThread->join();
93 delete pDhcpResultHandleThread;
94 pDhcpResultHandleThread = nullptr;
95 }
96
97 if (!m_mapDhcpResultNotify.empty()) {
98 WIFI_LOGE("ExitDhcpMgrThread() error, m_mapDhcpResultNotify is not empty!");
99 ReleaseResultNotifyMemory();
100 m_mapDhcpResultNotify.clear();
101 }
102 #ifdef OHOS_ARCH_LITE
103 if (!m_mapDhcpRecvMsgThread.empty()) {
104 WIFI_LOGE("ExitDhcpMgrThread() error, m_mapDhcpRecvMsgThread is not empty!");
105 for (auto &mapThread : m_mapDhcpRecvMsgThread) {
106 int nStatus = GetDhcpStatus(mapThread.first);
107 WIFI_LOGE("ExitDhcpMgrThread() ifname:%{public}s, status:%{public}d!",
108 (mapThread.first).c_str(), nStatus);
109 }
110 }
111 #endif
112 }
113
CheckTimeout()114 void DhcpClientServiceImpl::CheckTimeout()
115 {
116 uint32_t tempTime = 0;
117 uint32_t curTime = (uint32_t)time(NULL);
118 for (auto &itemNotify : m_mapDhcpResultNotify) {
119 std::string ifname = itemNotify.first;
120 WIFI_LOGI("CheckTimeout() ifname:%{public}s, notify1 second size:%{public}d.",
121 ifname.c_str(),
122 (int)itemNotify.second.size());
123 auto iterReq = itemNotify.second.begin();
124 while (iterReq != itemNotify.second.end()) {
125 if ((*iterReq == nullptr) || ((*iterReq)->pResultNotify == nullptr)) {
126 WIFI_LOGE("DhcpClientServiceImpl::CheckTimeout() error, *iterReq or pResultNotify is nullptr!");
127 return;
128 }
129 tempTime = (*iterReq)->getTimestamp + (*iterReq)->timeouts;
130 if (tempTime <= curTime) {
131 /* get dhcp result timeout */
132 WIFI_LOGW("CheckTimeout() ifname:%{public}s get timeout, getTime:%{public}u,timeout:%{public}d, "
133 "curTime:%{public}u!",
134 ifname.c_str(),
135 (*iterReq)->getTimestamp,
136 (*iterReq)->timeouts,
137 curTime);
138 (*iterReq)->pResultNotify->OnFailed(DHCP_OPT_TIMEOUT, ifname, "get dhcp result timeout!");
139 delete *iterReq;
140 *iterReq = nullptr;
141 iterReq = itemNotify.second.erase(iterReq);
142 } else {
143 ++iterReq;
144 }
145 }
146 }
147 }
148
DhcpResultHandle(uint32_t & second)149 void DhcpClientServiceImpl::DhcpResultHandle(uint32_t &second)
150 {
151 std::unique_lock<std::mutex> lock(mResultNotifyMutex);
152 if (m_mapDhcpResultNotify.empty()) {
153 second = SLEEP_TIME_200_MS;
154 return;
155 }
156
157 /* Check timeout */
158 CheckTimeout();
159 auto iterNotify = m_mapDhcpResultNotify.begin();
160 while (iterNotify != m_mapDhcpResultNotify.end()) {
161 /* Check dhcp result notify size */
162 std::string ifname = iterNotify->first;
163 if (iterNotify->second.size() <= 0) {
164 iterNotify = m_mapDhcpResultNotify.erase(iterNotify);
165 WIFI_LOGI("DhcpResultHandle() ifname:%{public}s, dhcp result notify size:0, erase!", ifname.c_str());
166 continue;
167 }
168
169 /* Check dhcp result */
170 auto iterDhcpResult = DhcpClientServiceImpl::m_mapDhcpResult.find(ifname);
171 if (iterDhcpResult == DhcpClientServiceImpl::m_mapDhcpResult.end()) {
172 WIFI_LOGI("DhcpResultHandle() ifname:%{public}s, dhcp result is getting...", ifname.c_str());
173 ++iterNotify;
174 continue;
175 }
176
177 auto iterReq = iterNotify->second.begin();
178 while (iterReq != iterNotify->second.end()) {
179 if ((*iterReq == nullptr) || ((*iterReq)->pResultNotify == nullptr)) {
180 WIFI_LOGE("DhcpResultHandle() %{public}s iterReq or pResultNotify is nullptr!", ifname.c_str());
181 second = SLEEP_TIME_500_MS;
182 return;
183 }
184
185 /* Handle dhcp result notify */
186 WIFI_LOGI("DhcpResultHandle() ifname:%{public}s, isOptSuc:%{public}d.",
187 ifname.c_str(), (iterDhcpResult->second).isOptSuc);
188 if ((iterDhcpResult->second).isOptSuc) {
189 /* get dhcp result success */
190 WIFI_LOGI("DhcpResultHandle() ifname:%{public}s get dhcp result success!", ifname.c_str());
191 (*iterReq)->pResultNotify->OnSuccess(DHCP_OPT_SUCCESS, ifname, iterDhcpResult->second);
192 } else {
193 /* get dhcp result failed */
194 WIFI_LOGE("DhcpResultHandle() ifname:%{public}s get dhcp result failed!", ifname.c_str());
195 (*iterReq)->pResultNotify->OnFailed(DHCP_OPT_FAILED, ifname, "get dhcp result failed!");
196 }
197 delete *iterReq;
198 *iterReq = nullptr;
199 iterReq = iterNotify->second.erase(iterReq);
200 }
201
202 ++iterNotify;
203 }
204
205 WIFI_LOGI("DhcpResultHandle() dhcp result notify finished.");
206 second = SLEEP_TIME_500_MS;
207 }
208
SubscribeDhcpEvent(const std::string & strAction)209 int DhcpClientServiceImpl::SubscribeDhcpEvent(const std::string &strAction)
210 {
211 if (strAction.empty()) {
212 WIFI_LOGE("SubscribeDhcpEvent error, strAction is empty!");
213 return DHCP_OPT_ERROR;
214 }
215 #ifndef OHOS_ARCH_LITE
216 std::unique_lock<std::mutex> lock(m_subscriberMutex);
217 auto iterSubscriber = m_mapEventSubscriber.find(strAction);
218 if (iterSubscriber == m_mapEventSubscriber.end()) {
219 EventFwk::MatchingSkills matchingSkills;
220 matchingSkills.AddEvent(strAction);
221 EventFwk::CommonEventSubscribeInfo subInfo(matchingSkills);
222 auto dhcpSubscriber = std::make_shared<OHOS::Wifi::DhcpEventSubscriber>(subInfo);
223 if (dhcpSubscriber == nullptr) {
224 WIFI_LOGE("SubscribeDhcpEvent error, dhcpSubscriber is nullptr!");
225 return DHCP_OPT_FAILED;
226 }
227 m_mapEventSubscriber.emplace(std::make_pair(strAction, dhcpSubscriber));
228 }
229 if (m_mapEventSubscriber[strAction] == nullptr) {
230 WIFI_LOGE("SubscribeDhcpEvent mapEventSubscriber %{public}s nullptr!", strAction.c_str());
231 return DHCP_OPT_FAILED;
232 }
233 if (!DhcpFunc::SubscribeDhcpCommonEvent(m_mapEventSubscriber[strAction])) {
234 WIFI_LOGE("SubscribeDhcpEvent SubscribeDhcpCommonEvent %{public}s failed!", strAction.c_str());
235 return DHCP_OPT_FAILED;
236 }
237 WIFI_LOGI("SubscribeDhcpEvent %{public}s success", strAction.c_str());
238 #endif
239 return DHCP_OPT_SUCCESS;
240 }
241
UnsubscribeDhcpEvent(const std::string & strAction)242 int DhcpClientServiceImpl::UnsubscribeDhcpEvent(const std::string &strAction)
243 {
244 if (strAction.empty()) {
245 WIFI_LOGE("UnsubscribeDhcpEvent error, strAction is empty!");
246 return DHCP_OPT_ERROR;
247 }
248 std::unique_lock<std::mutex> lock(m_subscriberMutex);
249 auto iterSubscriber = m_mapEventSubscriber.find(strAction);
250 if (iterSubscriber == m_mapEventSubscriber.end()) {
251 WIFI_LOGI("UnsubscribeDhcpEvent map no exist %{public}s, no need unsubscriber", strAction.c_str());
252 return DHCP_OPT_SUCCESS;
253 }
254
255 if (m_mapEventSubscriber[strAction] == nullptr) {
256 WIFI_LOGE("UnsubscribeDhcpEvent mapEventSubscriber %{public}s nullptr!", strAction.c_str());
257 return DHCP_OPT_FAILED;
258 }
259 #ifndef OHOS_ARCH_LITE
260 if (!DhcpFunc::UnsubscribeDhcpCommonEvent(m_mapEventSubscriber[strAction])) {
261 WIFI_LOGE("UnsubscribeDhcpEvent UnsubscribeDhcpCommonEvent %{public}s failed!", strAction.c_str());
262 return DHCP_OPT_FAILED;
263 }
264 #endif
265 m_mapEventSubscriber.erase(iterSubscriber);
266 WIFI_LOGI("UnsubscribeDhcpEvent %{public}s success", strAction.c_str());
267 return DHCP_OPT_SUCCESS;
268 }
269
UnsubscribeAllDhcpEvent()270 int DhcpClientServiceImpl::UnsubscribeAllDhcpEvent()
271 {
272 #ifndef OHOS_ARCH_LITE
273 for (auto& e : m_mapEventSubscriber) {
274 if (e.second != nullptr) {
275 if (!DhcpFunc::UnsubscribeDhcpCommonEvent(e.second)) {
276 WIFI_LOGE("UnsubscribeDhcpEvent UnsubscribeDhcpCommonEvent %{public}s failed!", e.first.c_str());
277 return DHCP_OPT_FAILED;
278 }
279 }
280 }
281 #endif
282 m_mapEventSubscriber.clear();
283 WIFI_LOGI("UnsubscribeDhcpEvent all dhcp event success!");
284 return DHCP_OPT_SUCCESS;
285 }
286
RunDhcpResultHandleThreadFunc()287 void DhcpClientServiceImpl::RunDhcpResultHandleThreadFunc()
288 {
289 for (; ;) {
290 if (isExitDhcpResultHandleThread) {
291 WIFI_LOGI("RunDhcpResultHandleThreadFunc() isExitDhcpResultHandleThread:1, break!");
292 break;
293 }
294
295 uint32_t uSleepSec = SLEEP_TIME_500_MS;
296 DhcpResultHandle(uSleepSec);
297 usleep(uSleepSec);
298 }
299
300 WIFI_LOGI("DhcpClientServiceImpl::RunDhcpResultHandleThreadFunc() end!");
301 }
302
303 #ifdef OHOS_ARCH_LITE
RunDhcpRecvMsgThreadFunc(const std::string & ifname)304 void DhcpClientServiceImpl::RunDhcpRecvMsgThreadFunc(const std::string &ifname)
305 {
306 if (ifname.empty()) {
307 WIFI_LOGE("DhcpClientServiceImpl::RunDhcpRecvMsgThreadFunc() error, ifname is empty!");
308 return;
309 }
310
311 struct DhcpPacketResult result;
312 std::string strResultFile = DHCP_WORK_DIR + ifname + DHCP_RESULT_FILETYPE;
313 for (; ;) {
314 /* Check break condition. */
315 auto iter = this->m_mapDhcpInfo.find(ifname);
316 if ((iter != this->m_mapDhcpInfo.end()) && ((iter->second).clientRunStatus) != 1) {
317 WIFI_LOGI("RunDhcpRecvMsgThreadFunc() Status != 1, need break, ifname:%{public}s.", ifname.c_str());
318 break;
319 }
320
321 /* Check dhcp result file is or not exist. */
322 if (!DhcpFunc::IsExistFile(strResultFile)) {
323 usleep(SLEEP_TIME_200_MS);
324 continue;
325 }
326
327 if (memset_s(&result, sizeof(result), 0, sizeof(result)) != EOK) {
328 return;
329 }
330 int nGetRet = DhcpFunc::GetDhcpPacketResult(strResultFile, result);
331 if (nGetRet == DHCP_OPT_SUCCESS) {
332 /* Get success, add or reload dhcp packet info. */
333 this->DhcpPacketInfoHandle(ifname, result);
334 usleep(SLEEP_TIME_500_MS);
335 } else if (nGetRet == DHCP_OPT_FAILED) {
336 /* Get failed, print dhcp packet info. */
337 this->DhcpPacketInfoHandle(ifname, result, false);
338 usleep(SLEEP_TIME_500_MS);
339 } else {
340 /* Get null, continue get dhcp packet info. */
341 WIFI_LOGI("RunDhcpRecvMsgThreadFunc() GetDhcpPacketResult NULL, ifname:%{public}s.", ifname.c_str());
342 usleep(SLEEP_TIME_200_MS);
343 }
344
345 continue;
346 }
347 }
348
DhcpPacketInfoHandle(const std::string & ifname,struct DhcpPacketResult & packetResult,bool success)349 void DhcpClientServiceImpl::DhcpPacketInfoHandle(
350 const std::string &ifname, struct DhcpPacketResult &packetResult, bool success)
351 {
352 if (ifname.empty()) {
353 WIFI_LOGE("DhcpClientServiceImpl::DhcpPacketInfoHandle() error, ifname is empty!");
354 return;
355 }
356
357 DhcpResult result;
358 auto iterResult = m_mapDhcpResult.find(ifname);
359 if (!success) {
360 /* get failed */
361 if (iterResult != m_mapDhcpResult.end()) {
362 iterResult->second = result;
363 } else {
364 m_mapDhcpResult.emplace(std::make_pair(ifname, result));
365 }
366 return;
367 }
368
369 /* Check dhcp result add time */
370 if ((iterResult != m_mapDhcpResult.end()) && ((iterResult->second).uAddTime == packetResult.uAddTime)) {
371 return;
372 }
373 WIFI_LOGI("DhcpPacketInfoHandle() DhcpResult %{public}s old %{public}u no equal new %{public}u, need update...",
374 ifname.c_str(), (iterResult->second).uAddTime, packetResult.uAddTime);
375
376 /* get success, add or reload dhcp packet info */
377 auto iterInfo = m_mapDhcpInfo.find(ifname);
378 if (iterInfo != m_mapDhcpInfo.end()) {
379 m_mapDhcpInfo[ifname].serverIp = packetResult.strOptServerId;
380 WIFI_LOGI("DhcpPacketInfoHandle() m_mapDhcpInfo find ifname:%{public}s.", ifname.c_str());
381 }
382
383 result.iptype = 0;
384 result.isOptSuc = true;
385 result.strYourCli = packetResult.strYiaddr;
386 result.strServer = packetResult.strOptServerId;
387 result.strSubnet = packetResult.strOptSubnet;
388 result.strDns1 = packetResult.strOptDns1;
389 result.strDns2 = packetResult.strOptDns2;
390 result.strRouter1 = packetResult.strOptRouter1;
391 result.strRouter2 = packetResult.strOptRouter2;
392 result.strVendor = packetResult.strOptVendor;
393 result.uLeaseTime = packetResult.uOptLeasetime;
394 result.uAddTime = packetResult.uAddTime;
395 result.uGetTime = (uint32_t)time(NULL);
396
397 if (iterResult != m_mapDhcpResult.end()) {
398 iterResult->second = result;
399 } else {
400 m_mapDhcpResult.emplace(std::make_pair(ifname, result));
401 }
402 WIFI_LOGI("DhcpPacketInfoHandle %{public}s, type:%{public}d, opt:%{public}d, cli:%{private}s, server:%{private}s, "
403 "strSubnet:%{private}s, Dns1:%{private}s, Dns2:%{private}s, strRouter1:%{private}s, strRouter2:%{private}s, "
404 "strVendor:%{public}s, uLeaseTime:%{public}u, uAddTime:%{public}u, uGetTime:%{public}u.",
405 ifname.c_str(), result.iptype, result.isOptSuc, result.strYourCli.c_str(), result.strServer.c_str(),
406 result.strSubnet.c_str(), result.strDns1.c_str(), result.strDns2.c_str(), result.strRouter1.c_str(),
407 result.strRouter2.c_str(), result.strVendor.c_str(), result.uLeaseTime, result.uAddTime, result.uGetTime);
408 }
409 #endif
410
ForkExecChildProcess(const std::string & ifname,bool bIpv6,bool bStart)411 int DhcpClientServiceImpl::ForkExecChildProcess(const std::string &ifname, bool bIpv6, bool bStart)
412 {
413 if (bIpv6) {
414 /* get ipv4 and ipv6 */
415 if (bStart) {
416 const char *args[DHCP_CLI_ARGSNUM] = {DHCP_CLIENT_FILE.c_str(), "start", ifname.c_str(), "-a", nullptr};
417 if (execv(args[0], const_cast<char *const *>(args)) == -1) {
418 WIFI_LOGE("execv start v4 v6 failed,errno:%{public}d,ifname:%{public}s", errno, ifname.c_str());
419 }
420 } else {
421 const char *args[DHCP_CLI_ARGSNUM] = {DHCP_CLIENT_FILE.c_str(), "stop", ifname.c_str(), "-a", nullptr};
422 if (execv(args[0], const_cast<char *const *>(args)) == -1) {
423 WIFI_LOGE("execv stop v4 v6 failed,errno:%{public}d,ifname:%{public}s", errno, ifname.c_str());
424 }
425 }
426 } else {
427 /* only get ipv4 */
428 if (bStart) {
429 const char *args[DHCP_CLI_ARGSNUM] = {DHCP_CLIENT_FILE.c_str(), "start", ifname.c_str(), "-4", nullptr};
430 if (execv(args[0], const_cast<char *const *>(args)) == -1) {
431 WIFI_LOGE("execv start v4 failed,errno:%{public}d,ifname:%{public}s", errno, ifname.c_str());
432 }
433 } else {
434 const char *args[DHCP_CLI_ARGSNUM] = {DHCP_CLIENT_FILE.c_str(), "stop", ifname.c_str(), "-4", nullptr};
435 if (execv(args[0], const_cast<char *const *>(args)) == -1) {
436 WIFI_LOGE("execv stop v4 failed,errno:%{public}d,ifname:%{public}s", errno, ifname.c_str());
437 }
438 }
439 }
440 _exit(-1);
441 }
442
ForkExecParentProcess(const std::string & ifname,bool bIpv6,bool bStart,pid_t pid)443 int DhcpClientServiceImpl::ForkExecParentProcess(const std::string &ifname, bool bIpv6, bool bStart, pid_t pid)
444 {
445 std::string strAction = OHOS::Wifi::COMMON_EVENT_DHCP_GET_IPV4 + "." + ifname;
446 if (bStart) {
447 #ifdef OHOS_ARCH_LITE
448 /* check and new receive dhcp packet msg thread */
449 std::unique_lock<std::mutex> lock(mRecvMsgThreadMutex);
450 auto iterRecvMsgThread = m_mapDhcpRecvMsgThread.find(ifname);
451 if (iterRecvMsgThread != m_mapDhcpRecvMsgThread.end()) {
452 WIFI_LOGE("ForkExecParentProcess() RecvMsgThread exist ifname:%{public}s, need erase!", ifname.c_str());
453 return DHCP_OPT_FAILED;
454 }
455 std::thread *pThread = new std::thread(&DhcpClientServiceImpl::RunDhcpRecvMsgThreadFunc, this, ifname);
456 if (pThread == nullptr) {
457 WIFI_LOGE("ForkExecParentProcess() init pThread failed, ifname:%{public}s.", ifname.c_str());
458 return DHCP_OPT_FAILED;
459 }
460 m_mapDhcpRecvMsgThread.emplace(std::make_pair(ifname, pThread));
461 #endif
462 /* normal started, update dhcp client service running status */
463 auto iter = DhcpClientServiceImpl::m_mapDhcpInfo.find(ifname);
464 if (iter != DhcpClientServiceImpl::m_mapDhcpInfo.end()) {
465 DhcpClientServiceImpl::m_mapDhcpInfo[ifname].enableIPv6 = bIpv6;
466 DhcpClientServiceImpl::m_mapDhcpInfo[ifname].clientRunStatus = 1;
467 DhcpClientServiceImpl::m_mapDhcpInfo[ifname].clientProPid = pid;
468 } else {
469 DhcpServiceInfo dhcpInfo;
470 dhcpInfo.enableIPv6 = bIpv6;
471 dhcpInfo.clientRunStatus = 1;
472 dhcpInfo.clientProPid = pid;
473 DhcpClientServiceImpl::m_mapDhcpInfo.emplace(std::make_pair(ifname, dhcpInfo));
474 }
475 /* Subscribe dhcp event. */
476 if (SubscribeDhcpEvent(strAction) != DHCP_OPT_SUCCESS) {
477 return DHCP_OPT_FAILED;
478 }
479 } else {
480 /* Unsubscribe dhcp event. */
481 if (UnsubscribeDhcpEvent(strAction) != DHCP_OPT_SUCCESS) {
482 WIFI_LOGI("ForkExecParentProcess() UnsubscribeDhcpEvent ifname:%{public}s failed.", ifname.c_str());
483 }
484 auto iter = DhcpClientServiceImpl::m_mapDhcpInfo.find(ifname);
485 if (iter != DhcpClientServiceImpl::m_mapDhcpInfo.end()) {
486 /* not start */
487 DhcpClientServiceImpl::m_mapDhcpInfo[ifname].clientRunStatus = 0;
488 DhcpClientServiceImpl::m_mapDhcpInfo[ifname].clientProPid = 0;
489
490 auto iterResult = DhcpClientServiceImpl::m_mapDhcpResult.find(ifname);
491 if (iterResult != DhcpClientServiceImpl::m_mapDhcpResult.end()) {
492 DhcpClientServiceImpl::m_mapDhcpResult.erase(iterResult);
493 WIFI_LOGI("ForkExecParentProcess() m_mapDhcpResult erase ifname:%{public}s success.", ifname.c_str());
494 }
495 #ifdef OHOS_ARCH_LITE
496 std::unique_lock<std::mutex> lock(mRecvMsgThreadMutex);
497 auto iterRecvMsgThreadMap = m_mapDhcpRecvMsgThread.find(ifname);
498 if (iterRecvMsgThreadMap == m_mapDhcpRecvMsgThread.end()) {
499 WIFI_LOGI("ForkExecParentProcess() RecvMsgThread already del ifname:%{public}s.", ifname.c_str());
500 return DHCP_OPT_SUCCESS;
501 }
502 if (iterRecvMsgThreadMap->second != nullptr) {
503 iterRecvMsgThreadMap->second->join();
504 delete iterRecvMsgThreadMap->second;
505 iterRecvMsgThreadMap->second = nullptr;
506 WIFI_LOGI("ForkExecParentProcess() destroy RecvThread success, ifname:%{public}s.", ifname.c_str());
507 }
508 WIFI_LOGI("ForkExecParentProcess() m_mapDhcpRecvMsgThread erase ifname:%{public}s.", ifname.c_str());
509 m_mapDhcpRecvMsgThread.erase(iterRecvMsgThreadMap);
510 #endif
511 }
512 }
513 return DHCP_OPT_SUCCESS;
514 }
515
GetDhcpClientProPid(const std::string & ifname)516 pid_t DhcpClientServiceImpl::GetDhcpClientProPid(const std::string &ifname)
517 {
518 if (ifname.empty()) {
519 WIFI_LOGE("GetDhcpClientProPid() error, ifname is empty!");
520 return 0;
521 }
522
523 auto iter = DhcpClientServiceImpl::m_mapDhcpInfo.find(ifname);
524 if (iter == DhcpClientServiceImpl::m_mapDhcpInfo.end()) {
525 WIFI_LOGI("GetDhcpClientProPid() m_mapDhcpInfo no find ifname:%{public}s.", ifname.c_str());
526 return 0;
527 }
528
529 std::string pidFile = DHCP_WORK_DIR + ifname + DHCP_CLIENT_PID_FILETYPE;
530 pid_t newPid = DhcpFunc::GetPID(pidFile);
531 if ((newPid > 0) && (newPid != (iter->second).clientProPid)) {
532 WIFI_LOGI("GetDhcpClientProPid() GetPID %{public}s new pid:%{public}d, old pid:%{public}d, need update.",
533 pidFile.c_str(), newPid, (iter->second).clientProPid);
534 DhcpClientServiceImpl::m_mapDhcpInfo[ifname].clientProPid = newPid;
535 }
536
537 WIFI_LOGI("GetDhcpClientProPid() m_mapDhcpInfo find ifname:%{public}s, pid:%{public}d.",
538 ifname.c_str(), DhcpClientServiceImpl::m_mapDhcpInfo[ifname].clientProPid);
539 return DhcpClientServiceImpl::m_mapDhcpInfo[ifname].clientProPid;
540 }
541
CheckDhcpClientRunning(const std::string & ifname)542 int DhcpClientServiceImpl::CheckDhcpClientRunning(const std::string &ifname)
543 {
544 if (ifname.empty()) {
545 WIFI_LOGE("CheckDhcpClientRunning param error, ifname is empty!");
546 return DHCP_OPT_ERROR;
547 }
548
549 std::string pidFile = DHCP_WORK_DIR + ifname + DHCP_CLIENT_PID_FILETYPE;
550 pid_t pid = DhcpFunc::GetPID(pidFile);
551 if (pid > 0) {
552 int nRet = DhcpFunc::CheckProRunning(pid, DHCP_CLIENT_FILE);
553 if (nRet == -1) {
554 WIFI_LOGE("CheckDhcpClientRunning %{public}s failed, pid:%{public}d", ifname.c_str(), pid);
555 return DHCP_OPT_FAILED;
556 } else if (nRet == 0) {
557 WIFI_LOGI("CheckDhcpClientRunning %{public}s, %{public}s is not running, need remove %{public}s",
558 ifname.c_str(), DHCP_CLIENT_FILE.c_str(), pidFile.c_str());
559 DhcpFunc::RemoveFile(pidFile);
560 } else {
561 WIFI_LOGI("CheckDhcpClientRunning %{public}s, %{public}s is running, pid:%{public}d",
562 ifname.c_str(), DHCP_CLIENT_FILE.c_str(), pid);
563 }
564 }
565 WIFI_LOGI("CheckDhcpClientRunning %{public}s finished, pid:%{public}d, pro:%{public}s",
566 ifname.c_str(), pid, DHCP_CLIENT_FILE.c_str());
567 return DHCP_OPT_SUCCESS;
568 }
569
GetSuccessIpv4Result(const std::vector<std::string> & splits)570 int DhcpClientServiceImpl::GetSuccessIpv4Result(const std::vector<std::string> &splits)
571 {
572 /* Result format - ifname,time,cliIp,lease,servIp,subnet,dns1,dns2,router1,router2,vendor */
573 if (splits.size() != EVENT_DATA_NUM) {
574 WIFI_LOGE("GetSuccessIpv4Result() splits.size:%{public}d error!", (int)splits.size());
575 return DHCP_OPT_FAILED;
576 }
577
578 /* Check field cliIp. */
579 if (splits[DHCP_NUM_TWO] == INVALID_STRING) {
580 WIFI_LOGE("GetSuccessIpv4Result() cliIp:%{public}s error!", splits[DHCP_NUM_TWO].c_str());
581 return DHCP_OPT_FAILED;
582 }
583
584 DhcpResult result;
585 result.uAddTime = std::stoi(splits[DHCP_NUM_ONE]);
586 std::string ifname = splits[DHCP_NUM_ZERO];
587 auto iter = DhcpClientServiceImpl::m_mapDhcpResult.find(ifname);
588 if ((iter != DhcpClientServiceImpl::m_mapDhcpResult.end()) && ((iter->second).uAddTime == result.uAddTime)) {
589 WIFI_LOGI("GetSuccessIpv4Result() %{public}s old %{public}u equal new %{public}u, no need update.",
590 ifname.c_str(), (iter->second).uAddTime, result.uAddTime);
591 return DHCP_OPT_SUCCESS;
592 }
593
594 if (iter != DhcpClientServiceImpl::m_mapDhcpResult.end()) {
595 WIFI_LOGI("GetSuccessIpv4Result() DhcpResult %{public}s old %{public}u no equal new %{public}u, need update...",
596 ifname.c_str(), (iter->second).uAddTime, result.uAddTime);
597 }
598
599 /* Reload dhcp packet info. */
600 auto iterInfo = DhcpClientServiceImpl::m_mapDhcpInfo.find(ifname);
601 if (iterInfo != DhcpClientServiceImpl::m_mapDhcpInfo.end()) {
602 WIFI_LOGI("GetSuccessIpv4Result() m_mapDhcpInfo find ifname:%{public}s.", ifname.c_str());
603 DhcpClientServiceImpl::m_mapDhcpInfo[ifname].serverIp = splits[DHCP_NUM_FOUR];
604 }
605
606 result.iptype = 0;
607 result.isOptSuc = true;
608 result.strYourCli = splits[DHCP_NUM_TWO];
609 result.uLeaseTime = std::stoi(splits[DHCP_NUM_THREE]);
610 result.strServer = splits[DHCP_NUM_FOUR];
611 result.strSubnet = splits[DHCP_NUM_FIVE];
612 result.strDns1 = splits[DHCP_NUM_SIX];
613 result.strDns2 = splits[DHCP_NUM_SEVEN];
614 result.strRouter1 = splits[DHCP_NUM_EIGHT];
615 result.strRouter2 = splits[DHCP_NUM_NINE];
616 result.strVendor = splits[DHCP_NUM_TEN];
617 result.uGetTime = (uint32_t)time(NULL);
618 if (iter != DhcpClientServiceImpl::m_mapDhcpResult.end()) {
619 iter->second = result;
620 } else {
621 DhcpClientServiceImpl::m_mapDhcpResult.emplace(std::make_pair(ifname, result));
622 }
623 WIFI_LOGI("GetSuccessIpv4Result() %{public}s, %{public}d, opt:%{public}d, cli:%{private}s, server:%{private}s, "
624 "strSubnet:%{private}s, strDns1:%{private}s, Dns2:%{private}s, strRouter1:%{private}s, Router2:%{private}s, "
625 "strVendor:%{public}s, uLeaseTime:%{public}u, uAddTime:%{public}u, uGetTime:%{public}u.",
626 ifname.c_str(), result.iptype, result.isOptSuc, result.strYourCli.c_str(), result.strServer.c_str(),
627 result.strSubnet.c_str(), result.strDns1.c_str(), result.strDns2.c_str(), result.strRouter1.c_str(),
628 result.strRouter2.c_str(), result.strVendor.c_str(), result.uLeaseTime, result.uAddTime, result.uGetTime);
629 return DHCP_OPT_SUCCESS;
630 }
631
GetDhcpEventIpv4Result(const int code,const std::vector<std::string> & splits)632 int DhcpClientServiceImpl::GetDhcpEventIpv4Result(const int code, const std::vector<std::string> &splits)
633 {
634 /* Result format - ifname,time,cliIp,lease,servIp,subnet,dns1,dns2,router1,router2,vendor */
635 if (splits.size() != EVENT_DATA_NUM) {
636 WIFI_LOGE("GetDhcpEventIpv4Result() splits.size:%{public}d error!", (int)splits.size());
637 return DHCP_OPT_FAILED;
638 }
639
640 /* Check field ifname and time. */
641 if (splits[DHCP_NUM_ZERO].empty() || splits[DHCP_NUM_ONE].empty()) {
642 WIFI_LOGE("GetDhcpEventIpv4Result() ifname or time is empty!");
643 return DHCP_OPT_FAILED;
644 }
645
646 /* Check field cliIp. */
647 if (((code == PUBLISH_CODE_SUCCESS) && (splits[DHCP_NUM_TWO] == INVALID_STRING))
648 || ((code == PUBLISH_CODE_FAILED) && (splits[DHCP_NUM_TWO] != INVALID_STRING))) {
649 WIFI_LOGE("GetDhcpEventIpv4Result() code:%{public}d,%{public}s error!", code, splits[DHCP_NUM_TWO].c_str());
650 return DHCP_OPT_FAILED;
651 }
652
653 std::string ifname = splits[DHCP_NUM_ZERO];
654 if (code == PUBLISH_CODE_FAILED) {
655 /* Get failed. */
656 DhcpResult result;
657 result.iptype = 0;
658 result.isOptSuc = false;
659 result.uAddTime = std::stoi(splits[DHCP_NUM_ONE]);
660 auto iterResult = DhcpClientServiceImpl::m_mapDhcpResult.find(ifname);
661 if (iterResult != DhcpClientServiceImpl::m_mapDhcpResult.end()) {
662 iterResult->second = result;
663 } else {
664 m_mapDhcpResult.emplace(std::make_pair(ifname, result));
665 }
666 WIFI_LOGI("GetDhcpEventIpv4Result() ifname:%{public}s result.isOptSuc:false!", ifname.c_str());
667 return DHCP_OPT_SUCCESS;
668 }
669
670 /* Get success. */
671 if (GetSuccessIpv4Result(splits) != DHCP_OPT_SUCCESS) {
672 WIFI_LOGE("GetDhcpEventIpv4Result() GetSuccessIpv4Result failed!");
673 return DHCP_OPT_FAILED;
674 }
675 WIFI_LOGI("GetDhcpEventIpv4Result() ifname:%{public}s result.isOptSuc:true!", ifname.c_str());
676 return DHCP_OPT_SUCCESS;
677 }
678
DhcpEventResultHandle(const int code,const std::string & data)679 int DhcpClientServiceImpl::DhcpEventResultHandle(const int code, const std::string &data)
680 {
681 if (data.empty()) {
682 WIFI_LOGE("DhcpClientServiceImpl::DhcpEventResultHandle() error, data is empty!");
683 return DHCP_OPT_FAILED;
684 }
685 WIFI_LOGI("Enter DhcpEventResultHandle() code:%{public}d,data:%{private}s.", code, data.c_str());
686
687 /* Data format - ipv4:ifname,time,cliIp,lease,servIp,subnet,dns1,dns2,router1,router2,vendor */
688 std::string strData(data);
689 std::string strFlag;
690 std::string strResult;
691 if (strData.find(EVENT_DATA_IPV4) != std::string::npos) {
692 strFlag = strData.substr(0, (int)EVENT_DATA_IPV4.size());
693 if (strFlag != EVENT_DATA_IPV4) {
694 WIFI_LOGE("DhcpEventResultHandle() %{public}s ipv4flag:%{public}s error!", data.c_str(), strFlag.c_str());
695 return DHCP_OPT_FAILED;
696 }
697 /* Skip separator ":" */
698 strResult = strData.substr((int)EVENT_DATA_IPV4.size() + 1);
699 } else if (strData.find(EVENT_DATA_IPV6) != std::string::npos) {
700 strFlag = strData.substr(0, (int)EVENT_DATA_IPV6.size());
701 if (strFlag != EVENT_DATA_IPV6) {
702 WIFI_LOGE("DhcpEventResultHandle() %{public}s ipv6flag:%{public}s error!", data.c_str(), strFlag.c_str());
703 return DHCP_OPT_FAILED;
704 }
705 strResult = strData.substr((int)EVENT_DATA_IPV6.size() + 1);
706 } else {
707 WIFI_LOGE("DhcpEventResultHandle() data:%{public}s error, no find ipflag!", data.c_str());
708 return DHCP_OPT_FAILED;
709 }
710 WIFI_LOGI("DhcpEventResultHandle() flag:%{public}s, result:%{private}s.", strFlag.c_str(), strResult.c_str());
711
712 if (strFlag == EVENT_DATA_IPV4) {
713 std::vector<std::string> vecSplits;
714 if (!DhcpFunc::SplitString(strResult, EVENT_DATA_DELIMITER, EVENT_DATA_NUM, vecSplits)) {
715 WIFI_LOGE("DhcpEventResultHandle() SplitString strResult:%{public}s failed!", strResult.c_str());
716 return DHCP_OPT_FAILED;
717 }
718
719 if (GetDhcpEventIpv4Result(code, vecSplits) != DHCP_OPT_SUCCESS) {
720 WIFI_LOGE("DhcpEventResultHandle() GetDhcpEventIpv4Result failed!");
721 return DHCP_OPT_FAILED;
722 }
723 }
724
725 return DHCP_OPT_SUCCESS;
726 }
727
StartDhcpClient(const std::string & ifname,bool bIpv6)728 int DhcpClientServiceImpl::StartDhcpClient(const std::string &ifname, bool bIpv6)
729 {
730 if (ifname.empty()) {
731 WIFI_LOGE("DhcpClientServiceImpl::StartDhcpClient() error, ifname is empty!");
732 return DHCP_OPT_FAILED;
733 }
734
735 WIFI_LOGI("enter StartDhcpClient()...ifname:%{public}s, bIpv6:%{public}d.", ifname.c_str(), bIpv6);
736
737 /* check config */
738 /* check dhcp client service running status */
739 if (CheckDhcpClientRunning(ifname) != DHCP_OPT_SUCCESS) {
740 WIFI_LOGE("StartDhcpClient CheckDhcpClientRunning ifname:%{public}s failed.", ifname.c_str());
741 return DHCP_OPT_FAILED;
742 }
743 int nStatus = GetDhcpStatus(ifname);
744 if (nStatus == 1) {
745 WIFI_LOGI("StartDhcpClient() running status:%{public}d, service already started, ifname:%{public}s.",
746 nStatus, ifname.c_str());
747 /* reload config */
748 return DHCP_OPT_SUCCESS;
749 }
750
751 /* start dhcp client service */
752 pid_t pid;
753 if ((pid = vfork()) < 0) {
754 WIFI_LOGE("StartDhcpClient() vfork() failed, pid:%{public}d.", pid);
755 return DHCP_OPT_FAILED;
756 }
757 if (pid == 0) {
758 /* Child process */
759 ForkExecChildProcess(ifname, bIpv6, true);
760 } else {
761 /* Parent process */
762 WIFI_LOGI("StartDhcpClient() vfork %{public}d success, parent:%{public}d, begin waitpid...", pid, getpid());
763 pid_t pidRet = waitpid(pid, nullptr, 0);
764 if (pidRet == pid) {
765 WIFI_LOGI("StartDhcpClient() waitpid child:%{public}d success.", pid);
766 } else {
767 WIFI_LOGE("StartDhcpClient() waitpid child:%{public}d failed, pidRet:%{public}d!", pid, pidRet);
768 }
769
770 return ForkExecParentProcess(ifname, bIpv6, true, pid);
771 }
772
773 return DHCP_OPT_SUCCESS;
774 }
775
StopDhcpClient(const std::string & ifname,bool bIpv6)776 int DhcpClientServiceImpl::StopDhcpClient(const std::string &ifname, bool bIpv6)
777 {
778 if (ifname.empty()) {
779 WIFI_LOGE("DhcpClientServiceImpl::StopDhcpClient() error, ifname is empty!");
780 return DHCP_OPT_FAILED;
781 }
782
783 WIFI_LOGI("enter StopDhcpClient()...ifname:%{public}s, bIpv6:%{public}d.", ifname.c_str(), bIpv6);
784
785 /* check dhcp client service running status */
786 bool bExecParentProcess = true;
787 int nStatus = GetDhcpStatus(ifname);
788 if (nStatus == 0) {
789 WIFI_LOGI("StopDhcpClient() status:%{public}d, service already stopped, ifname:%{public}s.",
790 nStatus, ifname.c_str());
791 return DHCP_OPT_SUCCESS;
792 } else if (nStatus == -1) {
793 WIFI_LOGI("StopDhcpClient() status:%{public}d, service not start or started, not need ExecParentProcess, "
794 "ifname:%{public}s.", nStatus, ifname.c_str());
795 bExecParentProcess = false;
796 }
797
798 /* stop dhcp client service */
799 pid_t pid;
800 if ((pid = vfork()) < 0) {
801 WIFI_LOGE("StopDhcpClient() vfork() failed, pid:%{public}d.", pid);
802 return DHCP_OPT_FAILED;
803 }
804 if (pid == 0) {
805 /* Child process */
806 ForkExecChildProcess(ifname, bIpv6);
807 return DHCP_OPT_SUCCESS;
808 } else {
809 /* Parent process */
810 WIFI_LOGI("StopDhcpClient() vfork %{public}d success, parent:%{public}d, begin waitpid...", pid, getpid());
811 pid_t pidRet = waitpid(pid, nullptr, 0);
812 if (pidRet == pid) {
813 WIFI_LOGI("StopDhcpClient() waitpid child:%{public}d success.", pid);
814 } else {
815 WIFI_LOGE("StopDhcpClient() waitpid child:%{public}d failed, pidRet:%{public}d!", pid, pidRet);
816 }
817
818 return bExecParentProcess ? ForkExecParentProcess(ifname, bIpv6) : DHCP_OPT_SUCCESS;
819 }
820 }
821
GetDhcpStatus(const std::string & ifname)822 int DhcpClientServiceImpl::GetDhcpStatus(const std::string &ifname)
823 {
824 if (ifname.empty()) {
825 WIFI_LOGE("DhcpClientServiceImpl::GetDhcpStatus() error, ifname is empty!");
826 return -1;
827 }
828
829 auto iter = DhcpClientServiceImpl::m_mapDhcpInfo.find(ifname);
830 if (iter == DhcpClientServiceImpl::m_mapDhcpInfo.end()) {
831 WIFI_LOGI("DhcpClientServiceImpl::GetDhcpStatus() m_mapDhcpInfo no find ifname:%{public}s.", ifname.c_str());
832 return -1;
833 }
834
835 WIFI_LOGI("GetDhcpStatus() m_mapDhcpInfo find ifname:%{public}s, clientRunStatus:%{public}d.",
836 ifname.c_str(),
837 (iter->second).clientRunStatus);
838 return (iter->second).clientRunStatus;
839 }
840
GetDhcpResult(const std::string & ifname,IDhcpResultNotify * pResultNotify,int timeouts)841 int DhcpClientServiceImpl::GetDhcpResult(const std::string &ifname, IDhcpResultNotify *pResultNotify, int timeouts)
842 {
843 if (ifname.empty()) {
844 WIFI_LOGE("DhcpClientServiceImpl::GetDhcpResult() error, ifname is empty!");
845 return DHCP_OPT_FAILED;
846 }
847
848 if (pResultNotify == nullptr) {
849 WIFI_LOGE("GetDhcpResult() ifname:%{public}s error, pResultNotify is nullptr!", ifname.c_str());
850 return DHCP_OPT_FAILED;
851 }
852
853 DhcpResultReq *pResultReq = new DhcpResultReq;
854 if (pResultReq == nullptr) {
855 WIFI_LOGE("GetDhcpResult() new failed! ifname:%{public}s.", ifname.c_str());
856 return DHCP_OPT_FAILED;
857 }
858 pResultReq->timeouts = timeouts;
859 pResultReq->getTimestamp = (uint32_t)time(NULL);
860 pResultReq->pResultNotify = pResultNotify;
861
862 std::unique_lock<std::mutex> lock(mResultNotifyMutex);
863 auto iter = m_mapDhcpResultNotify.find(ifname);
864 if (iter != m_mapDhcpResultNotify.end()) {
865 iter->second.push_back(pResultReq);
866 } else {
867 std::list<DhcpResultReq *> listDhcpResultReq;
868 listDhcpResultReq.push_back(pResultReq);
869 m_mapDhcpResultNotify.emplace(std::make_pair(ifname, listDhcpResultReq));
870 }
871 WIFI_LOGI("GetDhcpResult() ifname:%{public}s,timeouts:%{public}d, result push_back!", ifname.c_str(), timeouts);
872 return DHCP_OPT_SUCCESS;
873 }
874
RemoveDhcpResult(IDhcpResultNotify * pResultNotify)875 int DhcpClientServiceImpl::RemoveDhcpResult(IDhcpResultNotify *pResultNotify)
876 {
877 if (pResultNotify == nullptr) {
878 WIFI_LOGE("RemoveDhcpResult error, pResultNotify is nullptr!");
879 return DHCP_OPT_FAILED;
880 }
881
882 std::unique_lock<std::mutex> lock(mResultNotifyMutex);
883 for (auto &itemNotify : m_mapDhcpResultNotify) {
884 auto iterReq = itemNotify.second.begin();
885 while (iterReq != itemNotify.second.end()) {
886 if ((*iterReq == nullptr) || ((*iterReq)->pResultNotify == nullptr)) {
887 WIFI_LOGE("DhcpClientServiceImpl::RemoveDhcpResult error, *iterReq or pResultNotify is nullptr!");
888 continue;
889 }
890 if ((*iterReq)->pResultNotify == pResultNotify) {
891 delete *iterReq;
892 *iterReq = nullptr;
893 iterReq = itemNotify.second.erase(iterReq);
894 } else {
895 ++iterReq;
896 }
897 }
898 }
899 WIFI_LOGI("RemoveDhcpResul success!");
900 return DHCP_OPT_SUCCESS;
901 }
902
GetDhcpInfo(const std::string & ifname,DhcpServiceInfo & dhcp)903 int DhcpClientServiceImpl::GetDhcpInfo(const std::string &ifname, DhcpServiceInfo &dhcp)
904 {
905 if (ifname.empty()) {
906 WIFI_LOGE("DhcpClientServiceImpl::GetDhcpInfo() error, ifname is empty!");
907 return DHCP_OPT_FAILED;
908 }
909
910 auto iter = DhcpClientServiceImpl::m_mapDhcpInfo.find(ifname);
911 if (iter != DhcpClientServiceImpl::m_mapDhcpInfo.end()) {
912 dhcp = iter->second;
913 } else {
914 WIFI_LOGE("GetDhcpInfo() failed, m_mapDhcpInfo no find ifname:%{public}s.", ifname.c_str());
915 }
916
917 return DHCP_OPT_SUCCESS;
918 }
919
RenewDhcpClient(const std::string & ifname)920 int DhcpClientServiceImpl::RenewDhcpClient(const std::string &ifname)
921 {
922 WIFI_LOGI("enter DhcpClientServiceImpl::RenewDhcpClient()...ifname:%{public}s.", ifname.c_str());
923 int nStatus = GetDhcpStatus(ifname);
924 if (nStatus != 1) {
925 WIFI_LOGW("RenewDhcpClient() dhcp client service not started, now start ifname:%{public}s.", ifname.c_str());
926
927 /* Start dhcp client service */
928 return StartDhcpClient(ifname, DhcpClientServiceImpl::m_mapDhcpInfo[ifname].enableIPv6);
929 }
930
931 /* Send dhcp renew packet : kill -USR2 <pid> */
932 pid_t pid = GetDhcpClientProPid(ifname);
933 if (pid <= 0) {
934 WIFI_LOGW("RenewDhcpClient() dhcp client process pid:%{public}d error, ifname:%{public}s!",
935 pid, ifname.c_str());
936 return DHCP_OPT_FAILED;
937 }
938
939 if (kill(pid, SIGUSR2) == -1) {
940 WIFI_LOGE("RenewDhcpClient() kill [%{public}d] failed:%{public}d, ifname:%{public}s!",
941 pid, errno, ifname.c_str());
942 return DHCP_OPT_FAILED;
943 }
944 WIFI_LOGI("RenewDhcpClient() kill [%{public}d] success, ifname:%{public}s.", pid, ifname.c_str());
945 return DHCP_OPT_SUCCESS;
946 }
947
ReleaseDhcpClient(const std::string & ifname)948 int DhcpClientServiceImpl::ReleaseDhcpClient(const std::string &ifname)
949 {
950 WIFI_LOGI("enter DhcpClientServiceImpl::ReleaseDhcpClient()...ifname:%{public}s.", ifname.c_str());
951 int nStatus = GetDhcpStatus(ifname);
952 if (nStatus != 1) {
953 WIFI_LOGE("ReleaseDhcpClient() failed, dhcp client service not started, ifname:%{public}s!", ifname.c_str());
954 return DHCP_OPT_FAILED;
955 }
956
957 /* Send dhcp release packet : kill -USR1 <pid> */
958 pid_t pid = GetDhcpClientProPid(ifname);
959 if (pid <= 0) {
960 WIFI_LOGW("ReleaseDhcpClient() dhcp client process pid:%{public}d error, ifname:%{public}s!",
961 pid, ifname.c_str());
962 return DHCP_OPT_FAILED;
963 }
964
965 if (kill(pid, SIGUSR1) == -1) {
966 WIFI_LOGE("ReleaseDhcpClient() kill [%{public}d] failed:%{public}d, ifname:%{public}s!",
967 pid, errno, ifname.c_str());
968 return DHCP_OPT_FAILED;
969 }
970 WIFI_LOGI("ReleaseDhcpClient() kill [%{public}d] success, ifname:%{public}s.", pid, ifname.c_str());
971 return DHCP_OPT_SUCCESS;
972 }
973 } // namespace Wifi
974 } // namespace OHOS
975