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_server_proxy.h"
16#include "dhcp_manager_service_ipc_interface_code.h"
17#include "dhcp_server_callback_stub.h"
18#include "dhcp_c_utils.h"
19#include "dhcp_errcode.h"
20#include "dhcp_logger.h"
21
22DEFINE_DHCPLOG_DHCP_LABEL("DhcpServerProxy");
23
24namespace OHOS {
25namespace DHCP {
26constexpr int MAX_SIZE = 512;
27
28static sptr<DhcpServreCallBackStub> g_dhcpServerCallBackStub =
29    sptr<DhcpServreCallBackStub>(new (std::nothrow)DhcpServreCallBackStub());
30
31DhcpServerProxy::DhcpServerProxy(const sptr<IRemoteObject> &impl) : IRemoteProxy<IDhcpServer>(impl),
32    remote_(nullptr), mRemoteDied(false), deathRecipient_(nullptr)
33{
34    std::lock_guard<std::mutex> lock(mutex_);
35    if (impl) {
36        if (!impl->IsProxyObject()) {
37            DHCP_LOGW("not proxy object!");
38            return;
39        }
40        deathRecipient_ = new (std::nothrow)DhcpServerDeathRecipient(*this);
41        if (deathRecipient_ == nullptr) {
42            DHCP_LOGW("deathRecipient_ is nullptr!");
43        }
44        if (!impl->AddDeathRecipient(deathRecipient_)) {
45            DHCP_LOGW("AddDeathRecipient failed!");
46            return;
47        }
48        remote_ = impl;
49        DHCP_LOGI("AddDeathRecipient success! ");
50    }
51}
52
53DhcpServerProxy::~DhcpServerProxy()
54{
55    DHCP_LOGI("enter ~DhcpServerProxy!");
56    RemoveDeathRecipient();
57}
58
59void DhcpServerProxy::RemoveDeathRecipient(void)
60{
61    DHCP_LOGI("enter RemoveDeathRecipient!");
62    std::lock_guard<std::mutex> lock(mutex_);
63    if (remote_ == nullptr) {
64        DHCP_LOGI("remote_ is nullptr!");
65        return;
66    }
67    if (deathRecipient_ == nullptr) {
68        DHCP_LOGI("deathRecipient_ is nullptr!");
69        return;
70    }
71    remote_->RemoveDeathRecipient(deathRecipient_);
72    remote_ = nullptr;
73}
74
75void DhcpServerProxy::OnRemoteDied(const wptr<IRemoteObject> &remoteObject)
76{
77    DHCP_LOGI("Remote service is died! remoteObject: %{private}p", &remoteObject);
78    mRemoteDied = true;
79    RemoveDeathRecipient();
80    if (g_dhcpServerCallBackStub == nullptr) {
81        DHCP_LOGE("g_dhcpServerCallBackStub is nullptr");
82        return;
83    }
84    if (g_dhcpServerCallBackStub != nullptr) {
85        g_dhcpServerCallBackStub->SetRemoteDied(true);
86    }
87}
88
89bool DhcpServerProxy::IsRemoteDied(void)
90{
91    if (mRemoteDied) {
92        DHCP_LOGI("IsRemoteDied! remote is died now!");
93    }
94    return mRemoteDied;
95}
96
97ErrCode DhcpServerProxy::RegisterDhcpServerCallBack(const std::string& ifname,
98    const sptr<IDhcpServerCallBack> &callback)
99{
100    DHCP_LOGI("DhcpServerProxy enter RegisterDhcpServerCallBack mRemoteDied:%{public}d", mRemoteDied);
101    if (mRemoteDied) {
102        DHCP_LOGE("failed to `%{public}s`,remote service is died!", __func__);
103        return DHCP_E_FAILED;
104    }
105    MessageParcel data, reply;
106    MessageOption option;
107    if (!data.WriteInterfaceToken(GetDescriptor())) {
108        DHCP_LOGE("Write interface token error: %{public}s", __func__);
109        return DHCP_E_FAILED;
110    }
111    data.WriteInt32(0);
112    if (g_dhcpServerCallBackStub == nullptr) {
113        DHCP_LOGE("g_dhcpServerCallBackStub is nullptr");
114        return DHCP_E_FAILED;
115    }
116    g_dhcpServerCallBackStub->RegisterCallBack(callback);
117
118    if (!data.WriteRemoteObject(g_dhcpServerCallBackStub->AsObject())) {
119        DHCP_LOGE("DhcpServerProxy::RegisterCallBack WriteRemoteObject failed!");
120        return DHCP_E_FAILED;
121    }
122
123    int pid = GetCallingPid();
124    int tokenId = GetCallingTokenId();
125    data.WriteInt32(pid);
126    data.WriteInt32(tokenId);
127    data.WriteString(ifname);
128    DHCP_LOGI("%{public}s, calling uid:%{public}d, pid:%{public}d, ifname:%{public}s",
129        __func__, GetCallingUid(), pid, ifname.c_str());
130    int error = Remote()->SendRequest(static_cast<uint32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_REG_CALL_BACK),
131        data, reply, option);
132    if (error != ERR_NONE) {
133        DHCP_LOGE("Set Attr(%{public}d) failed, code is %{public}d",
134            static_cast<int32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_REG_CALL_BACK), error);
135        return DHCP_E_FAILED;
136    }
137    int exception = reply.ReadInt32();
138    if (exception) {
139        DHCP_LOGE("exception failed, exception:%{public}d", exception);
140        return DHCP_E_FAILED;
141    }
142    DHCP_LOGI("DhcpServerProxy RegisterDhcpServerCallBack ok, exception:%{public}d", exception);
143    return DHCP_E_SUCCESS;
144}
145
146ErrCode DhcpServerProxy::StartDhcpServer(const std::string& ifname)
147{
148    DHCP_LOGI("DhcpServerProxy enter StartDhcpServer mRemoteDied:%{public}d", mRemoteDied);
149    if (mRemoteDied) {
150        DHCP_LOGE("failed to `%{public}s`,remote service is died!", __func__);
151        return DHCP_E_FAILED;
152    }
153    MessageParcel data, reply;
154    MessageOption option;
155    if (!data.WriteInterfaceToken(GetDescriptor())) {
156        DHCP_LOGE("Write interface token error: %{public}s", __func__);
157        return DHCP_E_FAILED;
158    }
159    data.WriteInt32(0);
160
161    int pid = GetCallingPid();
162    int tokenId = GetCallingTokenId();
163    data.WriteInt32(pid);
164    data.WriteInt32(tokenId);
165    data.WriteString(ifname);
166    DHCP_LOGI("%{public}s, calling uid:%{public}d, pid:%{public}d, ifname:%{public}s",
167        __func__, GetCallingUid(), pid, ifname.c_str());
168    int error = Remote()->SendRequest(
169        static_cast<uint32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_START_DHCP_SERVER), data, reply, option);
170    if (error != ERR_NONE) {
171        DHCP_LOGE("Set Attr(%{public}d) failed, code is %{public}d",
172            static_cast<int32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_START_DHCP_SERVER), error);
173        return DHCP_E_FAILED;
174    }
175    int exception = reply.ReadInt32();
176    if (exception) {
177        DHCP_LOGE("exception failed, exception:%{public}d", exception);
178        return DHCP_E_FAILED;
179    }
180    DHCP_LOGI("DhcpServerProxy StartDhcpServer ok, exception:%{public}d", exception);
181    return DHCP_E_SUCCESS;
182}
183
184ErrCode DhcpServerProxy::SetDhcpRange(const std::string& ifname, const DhcpRange& range)
185{
186    DHCP_LOGI("DhcpServerProxy enter SetDhcpRange mRemoteDied:%{public}d", mRemoteDied);
187    if (mRemoteDied) {
188        DHCP_LOGE("failed to `%{public}s`,remote service is died!", __func__);
189        return DHCP_E_FAILED;
190    }
191    MessageParcel data, reply;
192    MessageOption option;
193    if (!data.WriteInterfaceToken(GetDescriptor())) {
194        DHCP_LOGE("Write interface token error: %{public}s", __func__);
195        return DHCP_E_FAILED;
196    }
197    data.WriteInt32(0);
198
199    data.WriteInt32(range.iptype);
200    data.WriteInt32(range.leaseHours);
201    data.WriteString(range.strTagName);
202    data.WriteString(range.strStartip);
203    data.WriteString(range.strEndip);
204    data.WriteString(range.strSubnet);
205    data.WriteString(ifname);
206    DHCP_LOGI("%{public}s, LINE :%{public}d ifname:%{public}s iptype %{public}d leaseHours %{public}d"
207        "TagName:%{public}s Startip:%{public}s strEndip:%{public}s strSubnet:%{public}s",
208        __func__, __LINE__, ifname.c_str(), range.iptype, range.leaseHours, range.strTagName.c_str(),
209        range.strStartip.c_str(), range.strEndip.c_str(), range.strSubnet.c_str());
210    int error = Remote()->SendRequest(
211        static_cast<uint32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_SET_DHCP_RANGE), data, reply, option);
212    if (error != ERR_NONE) {
213        DHCP_LOGE("Set Attr(%{public}d) failed, code is %{public}d",
214            static_cast<int32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_SET_DHCP_RANGE), error);
215        return DHCP_E_FAILED;
216    }
217    int exception = reply.ReadInt32();
218    if (exception) {
219        DHCP_LOGE("exception failed, exception:%{public}d", exception);
220        return DHCP_E_FAILED;
221    }
222    DHCP_LOGI("DhcpServerProxy SetDhcpRange ok, exception:%{public}d", exception);
223    return DHCP_E_SUCCESS;
224}
225
226ErrCode DhcpServerProxy::SetDhcpName(const std::string& ifname, const std::string& tagName)
227{
228
229    DHCP_LOGI("DhcpServerProxy enter SetDhcpName mRemoteDied:%{public}d", mRemoteDied);
230    if (mRemoteDied) {
231        DHCP_LOGE("failed to `%{public}s`,remote service is died!", __func__);
232        return DHCP_E_FAILED;
233    }
234    MessageParcel data, reply;
235    MessageOption option;
236    if (!data.WriteInterfaceToken(GetDescriptor())) {
237        DHCP_LOGE("Write interface token error: %{public}s", __func__);
238        return DHCP_E_FAILED;
239    }
240    data.WriteInt32(0);
241
242    data.WriteString(tagName);
243    data.WriteString(ifname);
244     DHCP_LOGI("%{public}s, LINE :%{public}d ifname:%{public}s tagName %{public}s", __func__, __LINE__, ifname.c_str(),
245        tagName.c_str());
246    int error = Remote()->SendRequest(
247        static_cast<uint32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_SET_DHCP_NAME), data, reply, option);
248    if (error != ERR_NONE) {
249        DHCP_LOGE("Set Attr(%{public}d) failed, code is %{public}d",
250            static_cast<int32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_SET_DHCP_NAME), error);
251        return DHCP_E_FAILED;
252    }
253    int exception = reply.ReadInt32();
254    if (exception) {
255        DHCP_LOGE("exception failed, exception:%{public}d", exception);
256        return DHCP_E_FAILED;
257    }
258    DHCP_LOGI("DhcpServerProxy SetDhcpName ok, exception:%{public}d", exception);
259    return DHCP_E_SUCCESS;
260}
261ErrCode DhcpServerProxy::PutDhcpRange(const std::string& tagName, const DhcpRange& range)
262{
263    DHCP_LOGI("DhcpServerProxy enter PutDhcpRange mRemoteDied:%{public}d", mRemoteDied);
264    if (mRemoteDied) {
265        DHCP_LOGE("failed to `%{public}s`,remote service is died!", __func__);
266        return DHCP_E_FAILED;
267    }
268    MessageParcel data, reply;
269    MessageOption option;
270    if (!data.WriteInterfaceToken(GetDescriptor())) {
271        DHCP_LOGE("Write interface token error: %{public}s", __func__);
272        return DHCP_E_FAILED;
273    }
274    data.WriteInt32(0);
275    data.WriteInt32(range.iptype);
276    data.WriteInt32(range.leaseHours);
277    data.WriteString(range.strTagName);
278    data.WriteString(range.strStartip);
279    data.WriteString(range.strEndip);
280    data.WriteString(range.strSubnet);
281    data.WriteString(tagName);
282     DHCP_LOGI("%{public}s, LINE :%{public}d tagName:%{public}s iptype %{public}d  leaseHours %{public}d"
283        "strTagName:%{public}s strStartip:%{public}s strEndip:%{public}s strSubnet:%{public}s",
284        __func__, __LINE__, tagName.c_str(), range.iptype, range.leaseHours, range.strTagName.c_str(),
285        range.strStartip.c_str(), range.strEndip.c_str(), range.strSubnet.c_str());
286    int error = Remote()->SendRequest(
287        static_cast<uint32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_PUT_DHCP_RANGE), data, reply, option);
288    if (error != ERR_NONE) {
289        DHCP_LOGE("Set Attr(%{public}d) failed, code is %{public}d",
290            static_cast<int32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_PUT_DHCP_RANGE), error);
291        return DHCP_E_FAILED;
292    }
293    int exception = reply.ReadInt32();
294    if (exception) {
295        DHCP_LOGE("exception failed, exception:%{public}d", exception);
296        return DHCP_E_FAILED;
297    }
298    DHCP_LOGI("DhcpServerProxy SetDhcpRange ok, exception:%{public}d", exception);
299    return DHCP_E_SUCCESS;
300}
301
302ErrCode DhcpServerProxy::RemoveAllDhcpRange(const std::string& tagName)
303{
304    DHCP_LOGI("DhcpServerProxy enter RemoveAllDhcpRange mRemoteDied:%{public}d", mRemoteDied);
305    if (mRemoteDied) {
306        DHCP_LOGE("failed to `%{public}s`,remote service is died!", __func__);
307        return DHCP_E_FAILED;
308    }
309    MessageParcel data, reply;
310    MessageOption option;
311    if (!data.WriteInterfaceToken(GetDescriptor())) {
312        DHCP_LOGE("Write interface token error: %{public}s", __func__);
313        return DHCP_E_FAILED;
314    }
315    data.WriteInt32(0);
316
317    data.WriteString(tagName);
318    DHCP_LOGI("%{public}s, calling tagName:%{public}s", __func__, tagName.c_str());
319    int error = Remote()->SendRequest(
320        static_cast<uint32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_REMOVE_ALL_DHCP_RANGE), data, reply, option);
321    if (error != ERR_NONE) {
322        DHCP_LOGE("Set Attr(%{public}d) failed, code is %{public}d",
323            static_cast<int32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_REMOVE_ALL_DHCP_RANGE), error);
324        return DHCP_E_FAILED;
325    }
326    int exception = reply.ReadInt32();
327    if (exception) {
328        DHCP_LOGE("exception failed, exception:%{public}d", exception);
329        return DHCP_E_FAILED;
330    }
331    DHCP_LOGI("DhcpServerProxy RemoveAllDhcpRange ok, exception:%{public}d", exception);
332    return DHCP_E_SUCCESS;
333}
334
335ErrCode DhcpServerProxy::UpdateLeasesTime(const std::string& leaseTime)
336{
337    DHCP_LOGI("DhcpServerProxy enter UpdateLeasesTime mRemoteDied:%{public}d", mRemoteDied);
338    if (mRemoteDied) {
339        DHCP_LOGE("failed to `%{public}s`,remote service is died!", __func__);
340        return DHCP_E_FAILED;
341    }
342    MessageParcel data, reply;
343    MessageOption option;
344    if (!data.WriteInterfaceToken(GetDescriptor())) {
345        DHCP_LOGE("Write interface token error: %{public}s", __func__);
346        return DHCP_E_FAILED;
347    }
348    data.WriteInt32(0);
349
350    data.WriteString(leaseTime);
351    DHCP_LOGI("%{public}s, calling  leaseTime:%{public}s", __func__, leaseTime.c_str());
352    int error = Remote()->SendRequest(
353        static_cast<uint32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_UPDATE_RENEW_TIME), data, reply, option);
354    if (error != ERR_NONE) {
355        DHCP_LOGE("Set Attr(%{public}d) failed, code is %{public}d",
356            static_cast<int32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_UPDATE_RENEW_TIME), error);
357        return DHCP_E_FAILED;
358    }
359    int exception = reply.ReadInt32();
360    if (exception) {
361        DHCP_LOGE("exception failed, exception:%{public}d", exception);
362        return DHCP_E_FAILED;
363    }
364    DHCP_LOGI("DhcpServerProxy UpdateLeasesTime ok, exception:%{public}d", exception);
365    return DHCP_E_SUCCESS;
366}
367
368ErrCode DhcpServerProxy::StopDhcpServer(const std::string& ifname)
369{
370    DHCP_LOGI("DhcpServerProxy enter StopDhcpServer mRemoteDied:%{public}d", mRemoteDied);
371    if (mRemoteDied) {
372        DHCP_LOGE("failed to `%{public}s`,remote service is died!", __func__);
373        return DHCP_E_FAILED;
374    }
375    MessageParcel data, reply;
376    MessageOption option;
377    if (!data.WriteInterfaceToken(GetDescriptor())) {
378        DHCP_LOGE("Write interface token error: %{public}s", __func__);
379        return DHCP_E_FAILED;
380    }
381    data.WriteInt32(0);
382    data.WriteString(ifname);
383    DHCP_LOGI("%{public}s, calling tagName:%{public}s", __func__, ifname.c_str());
384    int error = Remote()->SendRequest(
385        static_cast<uint32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_STOP_DHCP_SERVER), data, reply, option);
386    if (error != ERR_NONE) {
387        DHCP_LOGE("Set Attr(%{public}d) failed, code is %{public}d",
388            static_cast<int32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_STOP_DHCP_SERVER), error);
389        return DHCP_E_FAILED;
390    }
391    int exception = reply.ReadInt32();
392    if (exception) {
393        DHCP_LOGE("exception failed, exception:%{public}d", exception);
394        return DHCP_E_FAILED;
395    }
396    DHCP_LOGI("DhcpServerProxy StopDhcpServer ok, exception:%{public}d", exception);
397    return DHCP_E_SUCCESS;
398}
399ErrCode DhcpServerProxy::RemoveDhcpRange(const std::string& tagName, const DhcpRange& range)
400{
401    DHCP_LOGI("DhcpServerProxy enter RemoveDhcpRange mRemoteDied:%{public}d", mRemoteDied);
402    if (mRemoteDied) {
403        DHCP_LOGE("failed to `%{public}s`,remote service is died!", __func__);
404        return DHCP_E_FAILED;
405    }
406    MessageParcel data, reply;
407    MessageOption option;
408    if (!data.WriteInterfaceToken(GetDescriptor())) {
409        DHCP_LOGE("Write interface token error: %{public}s", __func__);
410        return DHCP_E_FAILED;
411    }
412    data.WriteInt32(0);
413    data.WriteInt32(range.iptype);
414    data.WriteInt32(range.leaseHours);
415    data.WriteString(range.strTagName);
416    data.WriteString(range.strStartip);
417    data.WriteString(range.strEndip);
418    data.WriteString(range.strSubnet);
419    data.WriteString(tagName);
420     DHCP_LOGI("%{public}s, LINE :%{public}d ifname:%{public}s iptype %{public}d leaseHours %{public}d"
421        "strTagName:%{public}s strStartip:%{public}s strEndip:%{public}s strSubnet:%{public}s",
422        __func__, __LINE__, tagName.c_str(), range.iptype, range.leaseHours, range.strTagName.c_str(),
423        range.strStartip.c_str(), range.strEndip.c_str(), range.strSubnet.c_str());
424    int error = Remote()->SendRequest(
425        static_cast<uint32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_REMOVE_DHCP_RANGE), data, reply, option);
426    if (error != ERR_NONE) {
427        DHCP_LOGE("Set Attr(%{public}d) failed, code is %{public}d",
428            static_cast<int32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_REMOVE_DHCP_RANGE), error);
429        return DHCP_E_FAILED;
430    }
431    int exception = reply.ReadInt32();
432    if (exception) {
433        DHCP_LOGE("exception failed, exception:%{public}d", exception);
434        return DHCP_E_FAILED;
435    }
436    DHCP_LOGI("DhcpServerProxy SetDhcpRange ok, exception:%{public}d", exception);
437    return DHCP_E_SUCCESS;
438}
439ErrCode DhcpServerProxy::GetDhcpClientInfos(const std::string& ifname, std::vector<std::string>& dhcpClientInfo)
440{
441    DHCP_LOGI("DhcpServerProxy enter GetDhcpClientInfos mRemoteDied:%{public}d", mRemoteDied);
442    if (mRemoteDied) {
443        DHCP_LOGE("failed to `%{public}s`,remote service is died!", __func__);
444        return DHCP_E_FAILED;
445    }
446    MessageParcel data, reply;
447    MessageOption option;
448    if (!data.WriteInterfaceToken(GetDescriptor())) {
449        DHCP_LOGE("Write interface token error: %{public}s", __func__);
450        return DHCP_E_FAILED;
451    }
452    data.WriteInt32(0);
453    data.WriteString(ifname);
454    DHCP_LOGI("%{public}s, LINE :%{public}d %{public}s", __func__, __LINE__, ifname.c_str());
455    int error = Remote()->SendRequest(
456        static_cast<uint32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_GET_DHCP_CLIENT_INFO), data, reply, option);
457    if (error != ERR_NONE) {
458        DHCP_LOGE("Set Attr(%{public}d) failed, code is %{public}d",
459            static_cast<int32_t>(DhcpServerInterfaceCode::DHCP_SERVER_SVR_CMD_GET_DHCP_CLIENT_INFO), error);
460        return DHCP_E_FAILED;
461    }
462    int exception = reply.ReadInt32();
463    if (exception) {
464        DHCP_LOGE("exception failed, exception:%{public}d", exception);
465        return DHCP_E_FAILED;
466    }
467    int ret = reply.ReadInt32();
468    if (ret == DHCP_E_SUCCESS) {
469        int tmpsize = reply.ReadInt32();
470        DHCP_LOGI("DhcpServerProxy GetDhcpClientInfos ok, exception:%{public}d, reply data size:%{public}d", exception,
471            tmpsize);
472        if (tmpsize > MAX_SIZE) {
473            DHCP_LOGE("GetDhcpClientInfos tmpsize error: %{public}d", tmpsize);
474            return DHCP_E_FAILED;
475        }
476        for (int i = 0; i < tmpsize; i++) {
477            std::string str = reply.ReadString();
478            dhcpClientInfo.push_back(str);
479        }
480    }
481    DHCP_LOGI("DhcpServerProxy GetDhcpClientInfos 1");
482    return DHCP_E_SUCCESS;
483}
484}  // namespace DHCP
485}  // namespace OHOS
486