1518678f8Sopenharmony_ci/*
2518678f8Sopenharmony_ci * Copyright (C) 2021-2023 Huawei Device Co., Ltd.
3518678f8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4518678f8Sopenharmony_ci * you may not use this file except in compliance with the License.
5518678f8Sopenharmony_ci * You may obtain a copy of the License at
6518678f8Sopenharmony_ci *
7518678f8Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8518678f8Sopenharmony_ci *
9518678f8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10518678f8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11518678f8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12518678f8Sopenharmony_ci * See the License for the specific language governing permissions and
13518678f8Sopenharmony_ci * limitations under the License.
14518678f8Sopenharmony_ci */
15518678f8Sopenharmony_ci#include <unistd.h>
16518678f8Sopenharmony_ci#include "dhcp_client_proxy.h"
17518678f8Sopenharmony_ci#include "dhcp_manager_service_ipc_interface_code.h"
18518678f8Sopenharmony_ci#include "dhcp_client_callback_stub.h"
19518678f8Sopenharmony_ci#include "dhcp_c_utils.h"
20518678f8Sopenharmony_ci#include "dhcp_errcode.h"
21518678f8Sopenharmony_ci#include "dhcp_logger.h"
22518678f8Sopenharmony_ci
23518678f8Sopenharmony_ciDEFINE_DHCPLOG_DHCP_LABEL("DhcpClientProxy");
24518678f8Sopenharmony_ci
25518678f8Sopenharmony_cinamespace OHOS {
26518678f8Sopenharmony_cinamespace DHCP {
27518678f8Sopenharmony_cistatic sptr<DhcpClientCallBackStub> g_dhcpClientCallBackStub =
28518678f8Sopenharmony_ci    sptr<DhcpClientCallBackStub>(new (std::nothrow)DhcpClientCallBackStub());
29518678f8Sopenharmony_ci
30518678f8Sopenharmony_ciDhcpClientProxy::DhcpClientProxy(const sptr<IRemoteObject> &impl) : IRemoteProxy<IDhcpClient>(impl),
31518678f8Sopenharmony_ci    remote_(nullptr), mRemoteDied(false), deathRecipient_(nullptr)
32518678f8Sopenharmony_ci{
33518678f8Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
34518678f8Sopenharmony_ci    if (impl) {
35518678f8Sopenharmony_ci        if (!impl->IsProxyObject()) {
36518678f8Sopenharmony_ci            DHCP_LOGW("not proxy object!");
37518678f8Sopenharmony_ci            return;
38518678f8Sopenharmony_ci        }
39518678f8Sopenharmony_ci        deathRecipient_ = new (std::nothrow)DhcpClientDeathRecipient(*this);
40518678f8Sopenharmony_ci        if (deathRecipient_ == nullptr) {
41518678f8Sopenharmony_ci            DHCP_LOGW("deathRecipient_ is nullptr!");
42518678f8Sopenharmony_ci        }
43518678f8Sopenharmony_ci        if (!impl->AddDeathRecipient(deathRecipient_)) {
44518678f8Sopenharmony_ci            DHCP_LOGW("AddDeathRecipient failed!");
45518678f8Sopenharmony_ci            return;
46518678f8Sopenharmony_ci        }
47518678f8Sopenharmony_ci        remote_ = impl;
48518678f8Sopenharmony_ci        DHCP_LOGI("AddDeathRecipient success! ");
49518678f8Sopenharmony_ci    }
50518678f8Sopenharmony_ci}
51518678f8Sopenharmony_ci
52518678f8Sopenharmony_ciDhcpClientProxy::~DhcpClientProxy()
53518678f8Sopenharmony_ci{
54518678f8Sopenharmony_ci    DHCP_LOGI("enter ~DhcpClientProxy!");
55518678f8Sopenharmony_ci    RemoveDeathRecipient();
56518678f8Sopenharmony_ci}
57518678f8Sopenharmony_ci
58518678f8Sopenharmony_civoid DhcpClientProxy::RemoveDeathRecipient(void)
59518678f8Sopenharmony_ci{
60518678f8Sopenharmony_ci    DHCP_LOGI("enter RemoveDeathRecipient!");
61518678f8Sopenharmony_ci    std::lock_guard<std::mutex> lock(mutex_);
62518678f8Sopenharmony_ci    if (remote_ == nullptr) {
63518678f8Sopenharmony_ci        DHCP_LOGI("remote_ is nullptr!");
64518678f8Sopenharmony_ci        return;
65518678f8Sopenharmony_ci    }
66518678f8Sopenharmony_ci    if (deathRecipient_ == nullptr) {
67518678f8Sopenharmony_ci        DHCP_LOGI("deathRecipient_ is nullptr!");
68518678f8Sopenharmony_ci        return;
69518678f8Sopenharmony_ci    }
70518678f8Sopenharmony_ci    remote_->RemoveDeathRecipient(deathRecipient_);
71518678f8Sopenharmony_ci    remote_ = nullptr;
72518678f8Sopenharmony_ci}
73518678f8Sopenharmony_ci
74518678f8Sopenharmony_civoid DhcpClientProxy::OnRemoteDied(const wptr<IRemoteObject> &remoteObject)
75518678f8Sopenharmony_ci{
76518678f8Sopenharmony_ci    DHCP_LOGW("Remote service is died! remoteObject: %{private}p", &remoteObject);
77518678f8Sopenharmony_ci    mRemoteDied = true;
78518678f8Sopenharmony_ci    RemoveDeathRecipient();
79518678f8Sopenharmony_ci    if (g_dhcpClientCallBackStub == nullptr) {
80518678f8Sopenharmony_ci        DHCP_LOGE("g_deviceCallBackStub is nullptr");
81518678f8Sopenharmony_ci        return;
82518678f8Sopenharmony_ci    }
83518678f8Sopenharmony_ci    if (g_dhcpClientCallBackStub != nullptr) {
84518678f8Sopenharmony_ci        g_dhcpClientCallBackStub->SetRemoteDied(true);
85518678f8Sopenharmony_ci    }
86518678f8Sopenharmony_ci}
87518678f8Sopenharmony_ci
88518678f8Sopenharmony_cibool DhcpClientProxy::IsRemoteDied(void)
89518678f8Sopenharmony_ci{
90518678f8Sopenharmony_ci    if (mRemoteDied) {
91518678f8Sopenharmony_ci        DHCP_LOGW("IsRemoteDied! remote is died now!");
92518678f8Sopenharmony_ci    }
93518678f8Sopenharmony_ci    return mRemoteDied;
94518678f8Sopenharmony_ci}
95518678f8Sopenharmony_ci
96518678f8Sopenharmony_ciErrCode DhcpClientProxy::RegisterDhcpClientCallBack(const std::string& ifname,
97518678f8Sopenharmony_ci    const sptr<IDhcpClientCallBack> &callback)
98518678f8Sopenharmony_ci{
99518678f8Sopenharmony_ci    if (mRemoteDied) {
100518678f8Sopenharmony_ci        DHCP_LOGE("failed to `%{public}s`,remote service is died!", __func__);
101518678f8Sopenharmony_ci        return DHCP_E_FAILED;
102518678f8Sopenharmony_ci    }
103518678f8Sopenharmony_ci    MessageOption option;
104518678f8Sopenharmony_ci    MessageParcel data, reply;
105518678f8Sopenharmony_ci    if (!data.WriteInterfaceToken(GetDescriptor())) {
106518678f8Sopenharmony_ci        DHCP_LOGE("Write interface token error: %{public}s", __func__);
107518678f8Sopenharmony_ci        return DHCP_E_FAILED;
108518678f8Sopenharmony_ci    }
109518678f8Sopenharmony_ci    data.WriteInt32(0);
110518678f8Sopenharmony_ci
111518678f8Sopenharmony_ci    if (g_dhcpClientCallBackStub == nullptr) {
112518678f8Sopenharmony_ci        DHCP_LOGE("g_dhcpClientCallBackStub is nullptr");
113518678f8Sopenharmony_ci        return DHCP_E_FAILED;
114518678f8Sopenharmony_ci    }
115518678f8Sopenharmony_ci    g_dhcpClientCallBackStub->RegisterCallBack(callback);
116518678f8Sopenharmony_ci
117518678f8Sopenharmony_ci    if (!data.WriteRemoteObject(g_dhcpClientCallBackStub->AsObject())) {
118518678f8Sopenharmony_ci        DHCP_LOGE("WriteRemoteObject failed!");
119518678f8Sopenharmony_ci        return DHCP_E_FAILED;
120518678f8Sopenharmony_ci    }
121518678f8Sopenharmony_ci
122518678f8Sopenharmony_ci    data.WriteString(ifname);
123518678f8Sopenharmony_ci    DHCP_LOGI("%{public}s, calling uid:%{public}d, ifname:%{public}s", __func__, GetCallingUid(), ifname.c_str());
124518678f8Sopenharmony_ci    int error = Remote()->SendRequest(static_cast<uint32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_REG_CALL_BACK),
125518678f8Sopenharmony_ci        data, reply, option);
126518678f8Sopenharmony_ci    if (error != ERR_NONE) {
127518678f8Sopenharmony_ci        DHCP_LOGE("Set Attr(%{public}d) failed, code is %{public}d",
128518678f8Sopenharmony_ci            static_cast<int32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_REG_CALL_BACK), error);
129518678f8Sopenharmony_ci        return DHCP_E_FAILED;
130518678f8Sopenharmony_ci    }
131518678f8Sopenharmony_ci    int exception = reply.ReadInt32();
132518678f8Sopenharmony_ci    if (exception) {
133518678f8Sopenharmony_ci        DHCP_LOGE("exception failed, exception:%{public}d", exception);
134518678f8Sopenharmony_ci        return DHCP_E_FAILED;
135518678f8Sopenharmony_ci    }
136518678f8Sopenharmony_ci    DHCP_LOGI("RegisterDhcpClientCallBack ok, exception:%{public}d", exception);
137518678f8Sopenharmony_ci    return DHCP_E_SUCCESS;
138518678f8Sopenharmony_ci}
139518678f8Sopenharmony_ci
140518678f8Sopenharmony_ciErrCode DhcpClientProxy::StartDhcpClient(const std::string& ifname, bool bIpv6)
141518678f8Sopenharmony_ci{
142518678f8Sopenharmony_ci    DHCP_LOGI("DhcpClientProxy enter StartDhcpClient mRemoteDied:%{public}d", mRemoteDied);
143518678f8Sopenharmony_ci    if (mRemoteDied) {
144518678f8Sopenharmony_ci        DHCP_LOGE("failed to `%{public}s`,remote service is died!", __func__);
145518678f8Sopenharmony_ci        return DHCP_E_FAILED;
146518678f8Sopenharmony_ci    }
147518678f8Sopenharmony_ci
148518678f8Sopenharmony_ci    MessageOption option;
149518678f8Sopenharmony_ci    MessageParcel data, reply;
150518678f8Sopenharmony_ci    if (!data.WriteInterfaceToken(GetDescriptor())) {
151518678f8Sopenharmony_ci        DHCP_LOGE("Write interface token error: %{public}s", __func__);
152518678f8Sopenharmony_ci        return DHCP_E_FAILED;
153518678f8Sopenharmony_ci    }
154518678f8Sopenharmony_ci    data.WriteInt32(0);
155518678f8Sopenharmony_ci    data.WriteString(ifname);
156518678f8Sopenharmony_ci    data.WriteBool(bIpv6);
157518678f8Sopenharmony_ci    DHCP_LOGI("%{public}s, calling uid:%{public}d, ifname:%{public}s, bIpv6:%{public}d", __func__, GetCallingUid(),
158518678f8Sopenharmony_ci        ifname.c_str(), bIpv6);
159518678f8Sopenharmony_ci    int error = Remote()->SendRequest(
160518678f8Sopenharmony_ci        static_cast<uint32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_START_DHCP_CLIENT), data, reply, option);
161518678f8Sopenharmony_ci    if (error != ERR_NONE) {
162518678f8Sopenharmony_ci        DHCP_LOGE("Set Attr(%{public}d) failed, code is %{public}d",
163518678f8Sopenharmony_ci            static_cast<int32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_START_DHCP_CLIENT), error);
164518678f8Sopenharmony_ci        return DHCP_E_FAILED;
165518678f8Sopenharmony_ci    }
166518678f8Sopenharmony_ci    int exception = reply.ReadInt32();
167518678f8Sopenharmony_ci    if (exception) {
168518678f8Sopenharmony_ci        DHCP_LOGE("exception failed, exception:%{public}d", exception);
169518678f8Sopenharmony_ci        return DHCP_E_FAILED;
170518678f8Sopenharmony_ci    }
171518678f8Sopenharmony_ci    DHCP_LOGI("StartDhcpClient ok, exception:%{public}d", exception);
172518678f8Sopenharmony_ci    return DHCP_E_SUCCESS;
173518678f8Sopenharmony_ci}
174518678f8Sopenharmony_ci
175518678f8Sopenharmony_ciErrCode DhcpClientProxy::SetConfiguration(const std::string& ifname, const RouterConfig& config)
176518678f8Sopenharmony_ci{
177518678f8Sopenharmony_ci    DHCP_LOGI("DhcpClientProxy enter SetConfiguration mRemoteDied:%{public}d", mRemoteDied);
178518678f8Sopenharmony_ci    if (mRemoteDied) {
179518678f8Sopenharmony_ci        DHCP_LOGE("failed to `%{public}s`,remote service is died!", __func__);
180518678f8Sopenharmony_ci        return DHCP_E_FAILED;
181518678f8Sopenharmony_ci    }
182518678f8Sopenharmony_ci
183518678f8Sopenharmony_ci    MessageOption option;
184518678f8Sopenharmony_ci    MessageParcel data;
185518678f8Sopenharmony_ci    MessageParcel reply;
186518678f8Sopenharmony_ci    if (!data.WriteInterfaceToken(GetDescriptor())) {
187518678f8Sopenharmony_ci        DHCP_LOGE("Write interface token error: %{public}s", __func__);
188518678f8Sopenharmony_ci        return DHCP_E_FAILED;
189518678f8Sopenharmony_ci    }
190518678f8Sopenharmony_ci    data.WriteInt32(0);
191518678f8Sopenharmony_ci    data.WriteString(ifname);
192518678f8Sopenharmony_ci    data.WriteString(config.bssid);
193518678f8Sopenharmony_ci    data.WriteInt32(config.prohibitUseCacheIp);
194518678f8Sopenharmony_ci    DHCP_LOGI("%{public}s, calling uid:%{public}d, ifname:%{public}s", __func__, GetCallingUid(), ifname.c_str());
195518678f8Sopenharmony_ci    int error = Remote()->SendRequest(
196518678f8Sopenharmony_ci        static_cast<uint32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_SET_CONFIG), data, reply, option);
197518678f8Sopenharmony_ci    if (error != ERR_NONE) {
198518678f8Sopenharmony_ci        DHCP_LOGE("Set Attr(%{public}d) failed, code is %{public}d",
199518678f8Sopenharmony_ci            static_cast<int32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_SET_CONFIG), error);
200518678f8Sopenharmony_ci        return DHCP_E_FAILED;
201518678f8Sopenharmony_ci    }
202518678f8Sopenharmony_ci    int exception = reply.ReadInt32();
203518678f8Sopenharmony_ci    if (exception) {
204518678f8Sopenharmony_ci        DHCP_LOGE("exception failed, exception:%{public}d", exception);
205518678f8Sopenharmony_ci        return DHCP_E_FAILED;
206518678f8Sopenharmony_ci    }
207518678f8Sopenharmony_ci    DHCP_LOGI("SetConfiguration ok, exception:%{public}d", exception);
208518678f8Sopenharmony_ci    return DHCP_E_SUCCESS;
209518678f8Sopenharmony_ci}
210518678f8Sopenharmony_ci
211518678f8Sopenharmony_ciErrCode DhcpClientProxy::StopDhcpClient(const std::string& ifname, bool bIpv6)
212518678f8Sopenharmony_ci{
213518678f8Sopenharmony_ci    DHCP_LOGI("DhcpClientProxy enter StopDhcpClient mRemoteDied:%{public}d", mRemoteDied);
214518678f8Sopenharmony_ci    if (mRemoteDied) {
215518678f8Sopenharmony_ci        DHCP_LOGI("failed to `%{public}s`,remote service is died!", __func__);
216518678f8Sopenharmony_ci        return DHCP_E_FAILED;
217518678f8Sopenharmony_ci    }
218518678f8Sopenharmony_ci    MessageOption option;
219518678f8Sopenharmony_ci    MessageParcel data, reply;
220518678f8Sopenharmony_ci    if (!data.WriteInterfaceToken(GetDescriptor())) {
221518678f8Sopenharmony_ci        DHCP_LOGI("Write interface token error: %{public}s", __func__);
222518678f8Sopenharmony_ci        return DHCP_E_FAILED;
223518678f8Sopenharmony_ci    }
224518678f8Sopenharmony_ci    data.WriteInt32(0);
225518678f8Sopenharmony_ci    data.WriteString(ifname);
226518678f8Sopenharmony_ci    data.WriteBool(bIpv6);
227518678f8Sopenharmony_ci    DHCP_LOGI("%{public}s, calling uid:%{public}d, ifname:%{public}s, bIpv6:%{public}d", __func__, GetCallingUid(),
228518678f8Sopenharmony_ci        ifname.c_str(), bIpv6);
229518678f8Sopenharmony_ci    int error = Remote()->SendRequest(
230518678f8Sopenharmony_ci        static_cast<uint32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_STOP_DHCP_CLIENT), data, reply, option);
231518678f8Sopenharmony_ci    if (error != ERR_NONE) {
232518678f8Sopenharmony_ci        DHCP_LOGI("Set Attr(%{public}d) failed, code is %{public}d",
233518678f8Sopenharmony_ci            static_cast<int32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_STOP_DHCP_CLIENT), error);
234518678f8Sopenharmony_ci        return DHCP_E_FAILED;
235518678f8Sopenharmony_ci    }
236518678f8Sopenharmony_ci    int exception = reply.ReadInt32();
237518678f8Sopenharmony_ci    if (exception) {
238518678f8Sopenharmony_ci        DHCP_LOGI("exception failed, exception:%{public}d", exception);
239518678f8Sopenharmony_ci        return DHCP_E_FAILED;
240518678f8Sopenharmony_ci    }
241518678f8Sopenharmony_ci    DHCP_LOGI("StopDhcpClient ok, exception:%{public}d", exception);
242518678f8Sopenharmony_ci    return DHCP_E_SUCCESS;
243518678f8Sopenharmony_ci}
244518678f8Sopenharmony_ci}  // namespace DHCP
245518678f8Sopenharmony_ci}  // namespace OHOS
246