• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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