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_client_proxy.h"
16 #include "dhcp_manager_service_ipc_interface_code.h"
17 #include "dhcp_client_callback_stub_lite.h"
18 #include "dhcp_c_utils.h"
19 #include "dhcp_errcode.h"
20 #include "dhcp_logger.h"
21
22 DEFINE_DHCPLOG_DHCP_LABEL("DhcpClientProxyLite");
23
24 namespace OHOS {
25 namespace Wifi {
26 static SvcIdentity g_sid;
27 static IpcObjectStub g_objStub;
28 static DhcpClientCallBackStub g_dhcpClientCallBackStub;
29
30 DhcpClientProxy *DhcpClientProxy::g_instance = nullptr;
DhcpClientProxy()31 DhcpClientProxy::DhcpClientProxy() : remoteDied_(false)
32 {
33 DHCP_LOGI("enter ~DhcpClientProxy!");
34 }
35
~DhcpClientProxy()36 DhcpClientProxy::~DhcpClientProxy()
37 {
38 DHCP_LOGI("enter ~DhcpClientProxy!");
39 }
40
GetInstance(void)41 DhcpClientProxy *DhcpClientProxy::GetInstance(void)
42 {
43 if (g_instance != nullptr) {
44 return g_instance;
45 }
46
47 DhcpClientProxy *tempInstance = new(std::nothrow)DhcpClientProxy();
48 g_instance = tempInstance;
49 return g_instance;
50 }
51
ReleaseInstance(void)52 void DhcpClientProxy::ReleaseInstance(void)
53 {
54 if (g_instance != nullptr) {
55 delete g_instance;
56 g_instance = nullptr;
57 }
58 }
59
IpcCallback(void * owner,int code,IpcIo * reply)60 static int IpcCallback(void *owner, int code, IpcIo *reply)
61 {
62 if (code != 0 || owner == nullptr || reply == nullptr) {
63 DHCP_LOGE("Callback error, code:%{public}d, owner:%{public}d, reply:%{public}d",
64 code, owner == nullptr, reply == nullptr);
65 return ERR_FAILED;
66 }
67
68 struct IpcOwner *data = (struct IpcOwner *)owner;
69 (void)ReadInt32(reply, &data->exception);
70 (void)ReadInt32(reply, &data->retCode);
71 if (data->exception != 0 || data->retCode != WIFI_OPT_SUCCESS || data->variable == nullptr) {
72 return ERR_FAILED;
73 }
74 return ERR_NONE;
75 }
76
AsyncCallback(uint32_t code,IpcIo * data,IpcIo * reply,MessageOption option)77 static int AsyncCallback(uint32_t code, IpcIo *data, IpcIo *reply, MessageOption option)
78 {
79 if (data == nullptr) {
80 DHCP_LOGE("AsyncCallback error, data is null");
81 return DHCP_E_FAILED;
82 }
83 return g_dhcpClientCallBackStub.OnRemoteRequest(code, data);
84 }
85
RegisterDhcpClientCallBack(const std::string & ifname,const std::shared_ptr<IDhcpClientCallBack> & callback)86 ErrCode DhcpClientProxy::RegisterDhcpClientCallBack(const std::string& ifname,
87 const std::shared_ptr<IDhcpClientCallBack> &callback)
88 {
89 if (remoteDied_ || remote_ == nullptr) {
90 DHCP_LOGE("failed to %{public}s, remoteDied_: %{public}d, remote_: %{public}d",
91 __func__, remoteDied_, remote_ == nullptr);
92 return DHCP_OPT_FAILED;
93 }
94 g_objStub.func = AsyncCallback;
95 g_objStub.args = nullptr;
96 g_objStub.isRemote = false;
97
98 g_sid.handle = IPC_INVALID_HANDLE;
99 g_sid.token = SERVICE_TYPE_ANONYMOUS;
100 g_sid.cookie = (uintptr_t)&g_objStub;
101
102 IpcIo req;
103 char data[IPC_DATA_SIZE_SMALL];
104 struct IpcOwner owner = {.exception = -1, .retCode = 0, .variable = nullptr};
105
106 IpcIoInit(&req, data, IPC_DATA_SIZE_SMALL, MAX_IPC_OBJ_COUNT);
107 if (!WriteInterfaceToken(&req, DECLARE_INTERFACE_DESCRIPTOR_L1, DECLARE_INTERFACE_DESCRIPTOR_L1_LENGTH)) {
108 DHCP_LOGE("Write interface token error: %{public}s", __func__);
109 return DHCP_OPT_FAILED;
110 }
111 (void)WriteInt32(&req, 0);
112 bool writeRemote = WriteRemoteObject(&req, &g_sid);
113 if (!writeRemote) {
114 DHCP_LOGE("WriteRemoteObject failed.");
115 return DHCP_OPT_FAILED;
116 }
117
118 (void)WriteString(&req, ifname.c_str());
119 owner.funcId = static_cast<int32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_REG_CALL_BACK);
120 int error = remote_->Invoke(remote_,
121 static_cast<int32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_REG_CALL_BACK),
122 &req, &owner, IpcCallback);
123 if (error != EC_SUCCESS) {
124 DHCP_LOGE("Set Attr(%{public}d) failed, code is %{public}d",
125 static_cast<int32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_REG_CALL_BACK), error);
126 return DHCP_E_FAILED;
127 }
128 if (owner.exception) {
129 DHCP_LOGE("exception failed, exception:%{public}d", owner.exception);
130 return DHCP_E_FAILED;
131 }
132 g_dhcpClientCallBackStub.RegisterCallBack(callback);
133 DHCP_LOGI("RegisterDhcpClientCallBack ok, exception:%{public}d", owner.exception);
134 return DHCP_E_SUCCESS;
135 }
136
StartDhcpClient(const std::string & ifname,bool bIpv6)137 ErrCode DhcpClientProxy::StartDhcpClient(const std::string& ifname, bool bIpv6)
138 {
139 if (remoteDied_ || remote_ == nullptr) {
140 DHCP_LOGE("failed to %{public}s, remoteDied_: %{public}d, remote_: %{public}d",
141 __func__, remoteDied_, remote_ == nullptr);
142 return DHCP_OPT_FAILED;
143 }
144
145 IpcIo req;
146 char data[IPC_DATA_SIZE_SMALL];
147 struct IpcOwner owner = {.exception = -1, .retCode = 0, .variable = nullptr};
148
149 IpcIoInit(&req, data, IPC_DATA_SIZE_SMALL, MAX_IPC_OBJ_COUNT);
150 if (!WriteInterfaceToken(&req, DECLARE_INTERFACE_DESCRIPTOR_L1, DECLARE_INTERFACE_DESCRIPTOR_L1_LENGTH)) {
151 DHCP_LOGE("Write interface token error: %{public}s", __func__);
152 return DHCP_OPT_FAILED;
153 }
154
155 (void)WriteInt32(&req, 0);
156 (void)WriteString(&req, ifname.c_str());
157 (void)WriteBool(&req, bIpv6);
158 owner.funcId = static_cast<int32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_START_DHCP_CLIENT);
159 int error = remote_->Invoke(remote_,
160 static_cast<int32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_START_DHCP_CLIENT), &req,
161 &owner, IpcCallback);
162 if (error != EC_SUCCESS) {
163 WIFI_LOGE("Set Attr(%{public}d) failed,error code is %{public}d",
164 static_cast<int32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_START_DHCP_CLIENT), error);
165 return DHCP_E_FAILED;
166 }
167 if (owner.exception) {
168 DHCP_LOGE("exception failed, exception:%{public}d", owner.exception);
169 return DHCP_E_FAILED;
170 }
171 DHCP_LOGI("StartDhcpClient ok, exception:%{public}d", owner.exception);
172 return DHCP_E_SUCCESS;
173 }
174
StopDhcpClient(const std::string & ifname,bool bIpv6)175 ErrCode DhcpClientProxy::StopDhcpClient(const std::string& ifname, bool bIpv6)
176 {
177 if (remoteDied_ || remote_ == nullptr) {
178 DHCP_LOGE("failed to %{public}s, remoteDied_: %{public}d, remote_: %{public}d",
179 __func__, remoteDied_, remote_ == nullptr);
180 return DHCP_OPT_FAILED;
181 }
182 IpcIo req;
183 char data[IPC_DATA_SIZE_SMALL];
184 struct IpcOwner owner = {.exception = -1, .retCode = 0, .variable = nullptr};
185
186 IpcIoInit(&req, data, IPC_DATA_SIZE_SMALL, MAX_IPC_OBJ_COUNT);
187 if (!WriteInterfaceToken(&req, DECLARE_INTERFACE_DESCRIPTOR_L1, DECLARE_INTERFACE_DESCRIPTOR_L1_LENGTH)) {
188 DHCP_LOGE("Write interface token error: %{public}s", __func__);
189 return DHCP_OPT_FAILED;
190 }
191
192 (void)WriteInt32(&req, 0);
193 (void)WriteString(&req, ifname.c_str());
194 (void)WriteBool(&req, bIpv6);
195 owner.funcId = static_cast<int32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_STOP_DHCP_CLIENT);
196 int error = remote_->Invoke(remote_,
197 static_cast<int32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_STOP_DHCP_CLIENT), &req,
198 &owner, IpcCallback);
199 if (error != EC_SUCCESS) {
200 WIFI_LOGE("Set Attr(%{public}d) failed,error code is %{public}d",
201 static_cast<int32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_STOP_DHCP_CLIENT), error);
202 return DHCP_E_FAILED;
203 }
204
205 if (owner.exception) {
206 DHCP_LOGE("exception failed, exception:%{public}d", owner.exception);
207 return DHCP_E_FAILED;
208 }
209 DHCP_LOGI("StopDhcpClient ok, exception:%{public}d", owner.exception);
210 return DHCP_E_SUCCESS;
211 }
212
RenewDhcpClient(const std::string & ifname)213 ErrCode DhcpClientProxy::RenewDhcpClient(const std::string& ifname)
214 {
215 if (mRemoteDied) {
216 DHCP_LOGE("failed to `%{public}s`,remote service is died!", __func__);
217 return DHCP_E_FAILED;
218 }
219
220 IpcIo req;
221 char data[IPC_DATA_SIZE_SMALL];
222 struct IpcOwner owner = {.exception = -1, .retCode = 0, .variable = nullptr};
223
224 IpcIoInit(&req, data, IPC_DATA_SIZE_SMALL, MAX_IPC_OBJ_COUNT);
225 if (!WriteInterfaceToken(&req, DECLARE_INTERFACE_DESCRIPTOR_L1, DECLARE_INTERFACE_DESCRIPTOR_L1_LENGTH)) {
226 DHCP_LOGE("Write interface token error: %{public}s", __func__);
227 return DHCP_OPT_FAILED;
228 }
229
230 (void)WriteInt32(&req, 0);
231 (void)WriteString(&req, ifname.c_str());
232 owner.funcId = static_cast<int32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_RENEW_DHCP_CLIENT);
233 int error = remote_->Invoke(remote_,
234 static_cast<int32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_RENEW_DHCP_CLIENT), &req,
235 &owner, IpcCallback);
236 if (error != EC_SUCCESS) {
237 DHCP_LOGE("Set Attr(%{public}d) failed,error code is %{public}d",
238 static_cast<int32_t>(DhcpClientInterfaceCode::DHCP_CLIENT_SVR_CMD_RENEW_DHCP_CLIENT), error);
239 return DHCP_E_FAILED;
240 }
241
242 if (owner.exception) {
243 DHCP_LOGE("exception failed, exception:%{public}d", owner.exception);
244 return DHCP_E_FAILED;
245 }
246 DHCP_LOGI("RenewDhcpClient ok, exception:%{public}d", owner.exception);
247 return DHCP_E_SUCCESS;
248 }
249 } // namespace Wifi
250 } // namespace OHOS
251