1 /*
2  * Copyright (C) 2021-2023 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 "dhcp_event.h"
16 #include "dhcp_logger.h"
17 
18 DEFINE_DHCPLOG_DHCP_LABEL("DhcpSAEvent");
19 
DhcpClientCallBack()20 DhcpClientCallBack::DhcpClientCallBack()
21 {
22     DHCP_LOGI("DhcpClientCallBack");
23 }
24 
~DhcpClientCallBack()25 DhcpClientCallBack::~DhcpClientCallBack()
26 {
27     DHCP_LOGI("~DhcpClientCallBack");
28 }
29 
ResultInfoCopy(DhcpResult &dhcpResult, OHOS::DHCP::DhcpResult& result)30 void DhcpClientCallBack::ResultInfoCopy(DhcpResult &dhcpResult, OHOS::DHCP::DhcpResult& result)
31 {
32     if (strcpy_s(dhcpResult.strOptClientId, DHCP_MAX_FILE_BYTES, result.strYourCli.c_str()) != EOK) {
33         DHCP_LOGE("ResultInfoCopy strOptClientId strcpy_s failed!");
34     }
35     if (strcpy_s(dhcpResult.strOptServerId, DHCP_MAX_FILE_BYTES, result.strServer.c_str()) != EOK) {
36         DHCP_LOGE("ResultInfoCopy strOptServerId strcpy_s failed!");
37     }
38     if (strcpy_s(dhcpResult.strOptSubnet, DHCP_MAX_FILE_BYTES, result.strSubnet.c_str()) != EOK) {
39         DHCP_LOGE("ResultInfoCopy strOptSubnet strcpy_s failed!");
40     }
41     if (strcpy_s(dhcpResult.strOptDns1, DHCP_MAX_FILE_BYTES, result.strDns1.c_str()) != EOK) {
42         DHCP_LOGE("ResultInfoCopy strOptDns1 strcpy_s failed!");
43     }
44     if (strcpy_s(dhcpResult.strOptDns2, DHCP_MAX_FILE_BYTES, result.strDns2.c_str()) != EOK) {
45         DHCP_LOGE("ResultInfoCopy strOptDns2 strcpy_s failed!");
46     }
47     if (strcpy_s(dhcpResult.strOptRouter1, DHCP_MAX_FILE_BYTES, result.strRouter1.c_str()) != EOK) {
48         DHCP_LOGE("ResultInfoCopy strOptRouter1 strcpy_s failed!");
49     }
50     if (strcpy_s(dhcpResult.strOptRouter2, DHCP_MAX_FILE_BYTES, result.strRouter2.c_str()) != EOK) {
51         DHCP_LOGE("ResultInfoCopy strOptRouter2 strcpy_s failed!");
52     }
53     if (strcpy_s(dhcpResult.strOptVendor, DHCP_MAX_FILE_BYTES, result.strVendor.c_str()) != EOK) {
54         DHCP_LOGE("ResultInfoCopy strOptVendor strcpy_s failed!");
55     }
56     if (strcpy_s(dhcpResult.strOptLinkIpv6Addr, DHCP_MAX_FILE_BYTES, result.strLinkIpv6Addr.c_str()) != EOK) {
57         DHCP_LOGE("ResultInfoCopy strOptLinkIpv6Addr strcpy_s failed!");
58     }
59     if (strcpy_s(dhcpResult.strOptRandIpv6Addr, DHCP_MAX_FILE_BYTES, result.strRandIpv6Addr.c_str()) != EOK) {
60         DHCP_LOGE("ResultInfoCopy strOptRandIpv6Addr strcpy_s failed!");
61     }
62     if (strcpy_s(dhcpResult.strOptLocalAddr1, DHCP_MAX_FILE_BYTES, result.strLocalAddr1.c_str()) != EOK) {
63         DHCP_LOGE("ResultInfoCopy strOptLocalAddr1 strcpy_s failed!");
64     }
65     if (strcpy_s(dhcpResult.strOptLocalAddr2, DHCP_MAX_FILE_BYTES, result.strLocalAddr2.c_str()) != EOK) {
66         DHCP_LOGE("ResultInfoCopy strOptLocalAddr2 strcpy_s failed!");
67     }
68     for (size_t i = 0; i < result.vectorDnsAddr.size(); i++) {
69         if (i >= DHCP_DNS_MAX_NUMBER) {
70             DHCP_LOGE("ResultInfoCopy break, i:%{public}zu, dns max number:%{public}d", i, DHCP_DNS_MAX_NUMBER);
71             break;
72         }
73         if (strncpy_s(dhcpResult.dnsList.dnsAddr[i], DHCP_DNS_DATA_MAX_LEN, result.vectorDnsAddr[i].c_str(),
74             result.vectorDnsAddr[i].length()) != EOK) {
75             DHCP_LOGE("ResultInfoCopy, strncpy_s failed, i:%{public}zu", i);
76         } else {
77             dhcpResult.dnsList.dnsNumber++;
78         }
79     }
80 }
81 
OnIpSuccessChanged(int status, const std::string& ifname, OHOS::DHCP::DhcpResult& result)82 void DhcpClientCallBack::OnIpSuccessChanged(int status, const std::string& ifname, OHOS::DHCP::DhcpResult& result)
83     __attribute__((no_sanitize("cfi")))
84 {
85     DHCP_LOGI("OnIpSuccessChanged status:%{public}d,ifname:%{public}s", status, ifname.c_str());
86     DhcpResult dhcpResult;
87     dhcpResult.iptype = result.iptype;
88     dhcpResult.isOptSuc = result.isOptSuc;
89     dhcpResult.uOptLeasetime = result.uLeaseTime;
90     dhcpResult.uAddTime = result.uAddTime;
91     dhcpResult.uGetTime = result.uGetTime;
92     ResultInfoCopy(dhcpResult, result);
93     DHCP_LOGI("ResultInfoCopy dstDnsNumber:%{public}u srcDnsNumber:%{public}zu", dhcpResult.dnsList.dnsNumber,
94         result.vectorDnsAddr.size());
95 
96     std::lock_guard<std::mutex> autoLock(callBackMutex);
97     auto iter = mapClientCallBack.find(ifname);
98     if ((iter != mapClientCallBack.end()) && (iter->second != nullptr) &&
99         (iter->second->OnIpSuccessChanged != nullptr)) {
100         DHCP_LOGI("OnIpSuccessChanged callbackEvent status:%{public}d", status);
101         iter->second->OnIpSuccessChanged(status, ifname.c_str(), &dhcpResult);
102     } else {
103         DHCP_LOGE("OnIpSuccessChanged callbackEvent failed!");
104     }
105 }
106 
OnIpFailChanged(int status, const std::string& ifname, const std::string& reason)107 void DhcpClientCallBack::OnIpFailChanged(int status, const std::string& ifname, const std::string& reason)
108     __attribute__((no_sanitize("cfi")))
109 {
110     DHCP_LOGI("OnIpFailChanged status:%{public}d, ifname:%{public}s, reason:%{public}s", status, ifname.c_str(),
111         reason.c_str());
112     std::lock_guard<std::mutex> autoLock(callBackMutex);
113     auto iter = mapClientCallBack.find(ifname);
114     if ((iter != mapClientCallBack.end()) && (iter->second != nullptr) && (iter->second->OnIpFailChanged != nullptr)) {
115         DHCP_LOGI("OnIpFailChanged callbackEvent status:%{public}d", status);
116         iter->second->OnIpFailChanged(status, ifname.c_str(), reason.c_str());
117     } else {
118         DHCP_LOGE("OnIpFailChanged callbackEvent failed!");
119     }
120 }
121 #ifndef OHOS_ARCH_LITE
OnDhcpOfferReport(int status, const std::string& ifname, OHOS::DHCP::DhcpResult& result)122 void DhcpClientCallBack::OnDhcpOfferReport(int status, const std::string& ifname, OHOS::DHCP::DhcpResult& result)
123 {
124     DHCP_LOGI("OnDhcpOfferReport status:%{public}d,ifname:%{public}s", status, ifname.c_str());
125     DhcpResult dhcpResult;
126     dhcpResult.iptype = result.iptype;
127     dhcpResult.isOptSuc = result.isOptSuc;
128     dhcpResult.uOptLeasetime = result.uLeaseTime;
129     dhcpResult.uAddTime = result.uAddTime;
130     dhcpResult.uGetTime = result.uGetTime;
131     ResultInfoCopy(dhcpResult, result);
132     std::lock_guard<std::mutex> autoLock(mapReportMutex_);
133     auto iter = mapDhcpClientReport_.find(ifname);
134     if ((iter != mapDhcpClientReport_.end()) && (iter->second != nullptr) &&
135         (iter->second->OnDhcpClientReport != nullptr)) {
136         iter->second->OnDhcpClientReport(status, ifname.c_str(), &dhcpResult);
137     } else {
138         DHCP_LOGE("OnDhcpOfferReport callbackEvent failed!");
139     }
140 }
141 
AsObject()142 OHOS::sptr<OHOS::IRemoteObject> DhcpClientCallBack::AsObject()
143 {
144     DHCP_LOGI("DhcpClientCallBack AsObject!");
145     return nullptr;
146 }
147 #endif
RegisterCallBack(const std::string& ifname, const ClientCallBack *event)148 void DhcpClientCallBack::RegisterCallBack(const std::string& ifname, const ClientCallBack *event)
149 {
150     if (event == nullptr) {
151         DHCP_LOGE("DhcpClientCallBack event is nullptr!");
152         return;
153     }
154     std::lock_guard<std::mutex> autoLock(callBackMutex);
155     auto iter = mapClientCallBack.find(ifname);
156     if (iter != mapClientCallBack.end()) {
157         iter->second = event;
158         DHCP_LOGI("Client RegisterCallBack update event, ifname:%{public}s", ifname.c_str());
159     } else {
160         mapClientCallBack.emplace(std::make_pair(ifname, event));
161         DHCP_LOGI("Client RegisterCallBack add event, ifname:%{public}s", ifname.c_str());
162     }
163 }
164 
MatchSubStr(const std::string &key, const std::string &pattern)165 static bool MatchSubStr(const std::string &key, const std::string &pattern)
166 {
167     return key.find(pattern) != std::string::npos;
168 }
169 
UnRegisterCallBack(const std::string& ifname)170 void DhcpClientCallBack::UnRegisterCallBack(const std::string& ifname)
171 {
172     if (ifname.empty()) {
173         DHCP_LOGE("Client UnRegisterCallBack ifname is empty!");
174         return;
175     }
176     std::lock_guard<std::mutex> autoLock(callBackMutex);
177     auto iter = mapClientCallBack.find(ifname);
178     if (iter != mapClientCallBack.end()) {
179         mapClientCallBack.erase(iter);
180         DHCP_LOGI("Client UnRegisterCallBack erase ifname:%{public}s", ifname.c_str());
181     } else {
182         auto it = std::find_if(mapClientCallBack.begin(), mapClientCallBack.end(),
183             [&](const auto &kv) { return MatchSubStr(kv.first, ifname); });
184         if (it != mapClientCallBack.end()) {
185             DHCP_LOGI("Client UnRegisterCallBack find match ifname:%{public}s key:%{public}s",
186                 ifname.c_str(), it->first.c_str());
187             mapClientCallBack.erase(it);
188         } else {
189             DHCP_LOGI("Client UnRegisterCallBack no match ifname:%{public}s", ifname.c_str());
190         }
191     }
192 }
193 
RegisterDhcpClientReportCallBack(const std::string& ifname, const DhcpClientReport *event)194 void DhcpClientCallBack::RegisterDhcpClientReportCallBack(const std::string& ifname, const DhcpClientReport *event)
195 {
196     if (event == nullptr) {
197         DHCP_LOGE("RegisterDhcpClientReportCallBack event is nullptr!");
198         return;
199     }
200     std::lock_guard<std::mutex> autoLock(mapReportMutex_);
201     auto iter = mapDhcpClientReport_.find(ifname);
202     if (iter != mapDhcpClientReport_.end()) {
203         iter->second = event;
204         DHCP_LOGI("RegisterDhcpClientReportCallBack update event, ifname:%{public}s", ifname.c_str());
205     } else {
206         mapDhcpClientReport_.emplace(std::make_pair(ifname, event));
207         DHCP_LOGI("RegisterDhcpClientReportCallBack add event, ifname:%{public}s", ifname.c_str());
208     }
209 }
210 
DhcpServerCallBack()211 DhcpServerCallBack::DhcpServerCallBack()
212 {
213     DHCP_LOGI("DhcpServerCallBack");
214 }
215 
~DhcpServerCallBack()216 DhcpServerCallBack::~DhcpServerCallBack()
217 {
218     DHCP_LOGI("~DhcpServerCallBack");
219 }
220 
OnServerStatusChanged(int status)221 void DhcpServerCallBack::OnServerStatusChanged(int status)
222 {
223     DHCP_LOGI("DhcpServerCallBack OnServerStatusChanged status:%{public}d", status);
224 }
225 
OnServerLeasesChanged(const std::string& ifname, std::vector<std::string>& leases)226 void DhcpServerCallBack::OnServerLeasesChanged(const std::string& ifname, std::vector<std::string>& leases)
227 {
228     DHCP_LOGI("DhcpServerCallBack OnServerLeasesChanged ifname:%{public}s", ifname.c_str());
229 }
230 
OnServerSerExitChanged(const std::string& ifname)231 void DhcpServerCallBack::OnServerSerExitChanged(const std::string& ifname)
232 {
233     DHCP_LOGI("DhcpServerCallBack OnServerSerExitChanged ifname:%{public}s", ifname.c_str());
234 }
235 
OnServerSuccess(const std::string& ifname, std::vector<DhcpStationInfo>& stationInfos)236 void DhcpServerCallBack::OnServerSuccess(const std::string& ifname, std::vector<DhcpStationInfo>& stationInfos)
237 {
238     size_t size = stationInfos.size();
239     DHCP_LOGI("DhcpServerCallBack OnServerSuccess ifname:%{public}s size:%{public}zu", ifname.c_str(), size);
240     std::lock_guard<std::mutex> autoLock(callBackServerMutex);
241     auto iter = mapServerCallBack.find(ifname);
242     if ((iter != mapServerCallBack.end()) && (iter->second != nullptr) && (iter->second->OnServerSuccess != nullptr) &&
243         (size > 0)) {
244         DhcpStationInfo *infos = (struct DhcpStationInfo*)malloc(size * sizeof(DhcpStationInfo));
245         if (infos == nullptr) {
246             DHCP_LOGE("malloc failed");
247             return;
248         }
249         for (size_t i = 0; i < size; i++) {
250             if (strcpy_s(infos[i].ipAddr, sizeof(infos[i].ipAddr), stationInfos[i].ipAddr) != EOK) {
251                 DHCP_LOGE("OnServerSuccess strcpy_s ipAddr failed!");
252                 free(infos);
253                 infos = nullptr;
254                 return;
255             }
256             if (strcpy_s(infos[i].macAddr, sizeof(infos[i].macAddr), stationInfos[i].macAddr) != EOK) {
257                 DHCP_LOGE("OnServerSuccess strcpy_s macAddr failed!");
258                 free(infos);
259                 infos = nullptr;
260                 return;
261             }
262             if (strcpy_s(infos[i].deviceName, sizeof(infos[i].deviceName), stationInfos[i].deviceName) != EOK) {
263                 DHCP_LOGE("OnServerSuccess strcpy_s deviceName failed!");
264                 free(infos);
265                 infos = nullptr;
266                 return;
267             }
268         }
269         iter->second->OnServerSuccess(ifname.c_str(), infos, size);
270         free(infos);
271         infos = nullptr;
272         DHCP_LOGI("OnServerSuccess callbackEvent ok!");
273     } else {
274         DHCP_LOGE("OnServerSuccess not find callback!");
275     }
276 }
277 
278 #ifndef OHOS_ARCH_LITE
AsObject()279 OHOS::sptr<OHOS::IRemoteObject> DhcpServerCallBack::AsObject()
280 {
281     DHCP_LOGI("DhcpServerCallBack AsObject!");
282     return nullptr;
283 }
284 #endif
RegisterCallBack(const std::string& ifname, const ServerCallBack *event)285 void DhcpServerCallBack::RegisterCallBack(const std::string& ifname, const ServerCallBack *event)
286 {
287     if (event == nullptr) {
288         DHCP_LOGE("DhcpServerCallBack event is nullptr!");
289         return;
290     }
291     std::lock_guard<std::mutex> autoLock(callBackServerMutex);
292     auto iter = mapServerCallBack.find(ifname);
293     if (iter != mapServerCallBack.end()) {
294         iter->second = event;
295         DHCP_LOGI("Server RegisterCallBack update event, ifname:%{public}s", ifname.c_str());
296     } else {
297         mapServerCallBack.emplace(std::make_pair(ifname, event));
298         DHCP_LOGI("Server RegisterCallBack add event, ifname:%{public}s", ifname.c_str());
299     }
300 }
301 
UnRegisterCallBack(const std::string& ifname)302 void DhcpServerCallBack::UnRegisterCallBack(const std::string& ifname)
303 {
304     if (ifname.empty()) {
305         DHCP_LOGE("Server UnRegisterCallBack ifname is empty!");
306         return;
307     }
308     std::lock_guard<std::mutex> autoLock(callBackServerMutex);
309     auto iter = mapServerCallBack.find(ifname);
310     if (iter != mapServerCallBack.end()) {
311         mapServerCallBack.erase(iter);
312         DHCP_LOGI("Server UnRegisterCallBack erase ifname:%{public}s", ifname.c_str());
313     } else {
314         DHCP_LOGI("Server UnRegisterCallBack not find, ifname:%{public}s", ifname.c_str());
315     }
316 }
317