1 /*
2 * Copyright (c) 2023-2024 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 "local_socket_context.h"
16
17 #include "context_key.h"
18 #include "event_manager.h"
19 #include "napi_utils.h"
20 #include "netstack_log.h"
21 #include "socket_constant.h"
22
23 namespace OHOS::NetStack::Socket {
GetSocketFd() const24 int LocalSocketBaseContext::GetSocketFd() const
25 {
26 if (manager_ == nullptr) {
27 return -1;
28 }
29 LocalSocketManager *pMgr = reinterpret_cast<LocalSocketManager *>(manager_->GetData());
30 return (pMgr != nullptr) ? pMgr->sockfd_ : -1;
31 }
32
SetSocketFd(int sock)33 void LocalSocketBaseContext::SetSocketFd(int sock)
34 {
35 if (manager_ == nullptr) {
36 return;
37 }
38 if (auto pMgr = reinterpret_cast<LocalSocketManager *>(manager_->GetData()); pMgr != nullptr) {
39 pMgr->sockfd_ = sock;
40 }
41 }
42
GetErrorCode() const43 int32_t LocalSocketBaseContext::GetErrorCode() const
44 {
45 auto err = BaseContext::GetErrorCode();
46 if (err == PARSE_ERROR_CODE) {
47 return PARSE_ERROR_CODE;
48 }
49
50 if (BaseContext::IsPermissionDenied()) {
51 return PERMISSION_DENIED_CODE;
52 }
53
54 #if defined(IOS_PLATFORM)
55 err = ErrCodePlatformAdapter::GetOHOSErrCode(err);
56 #endif
57 return err + SOCKET_ERROR_CODE_BASE;
58 }
59
GetErrorMessage() const60 std::string LocalSocketBaseContext::GetErrorMessage() const
61 {
62 if (BaseContext::IsPermissionDenied()) {
63 return PERMISSION_DENIED_MSG;
64 }
65
66 auto errCode = BaseContext::GetErrorCode();
67 if (errCode == PARSE_ERROR_CODE) {
68 return PARSE_ERROR_MSG;
69 }
70 #if defined(IOS_PLATFORM)
71 std::string errMessage;
72 ErrCodePlatformAdapter::GetOHOSErrMessage(errCode, errMessage);
73 return errMessage;
74 #else
75 char err[MAX_ERR_NUM] = {0};
76 (void)strerror_r(errCode, err, MAX_ERR_NUM);
77 return err;
78 #endif
79 }
80
CheckParamsWithOptions(napi_value * params,size_t paramsCount)81 bool LocalSocketBaseContext::CheckParamsWithOptions(napi_value *params, size_t paramsCount)
82 {
83 if (paramsCount == PARAM_JUST_OPTIONS) {
84 if (NapiUtils::GetValueType(GetEnv(), params[0]) != napi_object) {
85 NETSTACK_LOGE("first param is not object");
86 SetNeedThrowException(true);
87 SetError(PARSE_ERROR_CODE, PARSE_ERROR_MSG);
88 return false;
89 }
90 } else if (paramsCount == PARAM_OPTIONS_AND_CALLBACK) {
91 if (NapiUtils::GetValueType(GetEnv(), params[0]) != napi_object) {
92 NETSTACK_LOGE("first param is not object");
93 SetNeedThrowException(true);
94 SetError(PARSE_ERROR_CODE, PARSE_ERROR_MSG);
95 return false;
96 }
97 if (NapiUtils::GetValueType(GetEnv(), params[1]) != napi_function) {
98 NETSTACK_LOGE("second param is not function");
99 return false;
100 }
101 } else {
102 NETSTACK_LOGE("invalid param count");
103 return false;
104 }
105 return true;
106 }
107
CheckParamsWithoutOptions(napi_value * params,size_t paramsCount)108 bool LocalSocketBaseContext::CheckParamsWithoutOptions(napi_value *params, size_t paramsCount)
109 {
110 if (paramsCount == PARAM_NONE) {
111 return true;
112 }
113 if (paramsCount == PARAM_JUST_CALLBACK) {
114 if (NapiUtils::GetValueType(GetEnv(), params[0]) == napi_function) {
115 return true;
116 } else {
117 NETSTACK_LOGE("only one param and it is not callback");
118 SetNeedThrowException(true);
119 SetError(PARSE_ERROR_CODE, PARSE_ERROR_MSG);
120 }
121 }
122 return false;
123 }
124
ParseParams(napi_value * params,size_t paramsCount)125 void LocalSocketBindContext::ParseParams(napi_value *params, size_t paramsCount)
126 {
127 if (!CheckParamsWithOptions(params, paramsCount)) {
128 return;
129 }
130 if (NapiUtils::HasNamedProperty(GetEnv(), params[0], KEY_ADDRESS)) {
131 socketPath_ = NapiUtils::GetStringPropertyUtf8(GetEnv(), params[0], KEY_ADDRESS);
132 NETSTACK_LOGD("LocalSocketBindContext parse, path: %{public}s", socketPath_.c_str());
133 } else {
134 NETSTACK_LOGE("params do not contain socket path");
135 }
136 if (socketPath_.empty()) {
137 NETSTACK_LOGE("socket path is empty");
138 }
139 if (paramsCount == PARAM_OPTIONS_AND_CALLBACK) {
140 SetParseOK(SetCallback(params[1]) == napi_ok);
141 return;
142 }
143 SetParseOK(true);
144 }
145
GetSocketPath() const146 const std::string &LocalSocketBindContext::GetSocketPath() const
147 {
148 return socketPath_;
149 }
150
ParseParams(napi_value * params,size_t paramsCount)151 void LocalSocketConnectContext::ParseParams(napi_value *params, size_t paramsCount)
152 {
153 if (!CheckParamsWithOptions(params, paramsCount)) {
154 return;
155 }
156 if (!NapiUtils::HasNamedProperty(GetEnv(), params[0], KEY_ADDRESS)) {
157 NETSTACK_LOGE("no property named address");
158 }
159 napi_value netAddress = NapiUtils::GetNamedProperty(GetEnv(), params[0], KEY_ADDRESS);
160 if (!NapiUtils::HasNamedProperty(GetEnv(), netAddress, KEY_ADDRESS)) {
161 NETSTACK_LOGE("address is empty");
162 }
163 socketPath_ = NapiUtils::GetStringPropertyUtf8(GetEnv(), netAddress, KEY_ADDRESS);
164 if (NapiUtils::HasNamedProperty(GetEnv(), params[0], KEY_TIMEOUT)) {
165 timeout_ = NapiUtils::GetInt32Property(GetEnv(), params[0], KEY_TIMEOUT);
166 }
167 if (paramsCount == PARAM_OPTIONS_AND_CALLBACK) {
168 SetParseOK(SetCallback(params[1]) == napi_ok);
169 return;
170 }
171 SetParseOK(true);
172 }
173
GetSocketPath() const174 const std::string &LocalSocketConnectContext::GetSocketPath() const
175 {
176 return socketPath_;
177 }
178
GetTimeoutMs() const179 int LocalSocketConnectContext::GetTimeoutMs() const
180 {
181 return timeout_;
182 }
183
GetData(napi_value sendOptions)184 bool LocalSocketSendContext::GetData(napi_value sendOptions)
185 {
186 if (!NapiUtils::HasNamedProperty(GetEnv(), sendOptions, KEY_DATA)) {
187 return false;
188 }
189 napi_value jsData = NapiUtils::GetNamedProperty(GetEnv(), sendOptions, KEY_DATA);
190 if (NapiUtils::GetValueType(GetEnv(), jsData) == napi_string) {
191 std::string data = NapiUtils::GetStringFromValueUtf8(GetEnv(), jsData);
192 if (data.empty()) {
193 NETSTACK_LOGE("string data is empty");
194 return true;
195 }
196 options_.SetBuffer(data);
197 return true;
198 }
199
200 if (NapiUtils::ValueIsArrayBuffer(GetEnv(), jsData)) {
201 size_t length = 0;
202 void *data = NapiUtils::GetInfoFromArrayBufferValue(GetEnv(), jsData, &length);
203 if (data == nullptr || length == 0) {
204 NETSTACK_LOGE("arraybuffer data is empty");
205 return true;
206 }
207 options_.SetBuffer(data, length);
208 return true;
209 }
210 return false;
211 }
212
ParseParams(napi_value * params,size_t paramsCount)213 void LocalSocketSendContext::ParseParams(napi_value *params, size_t paramsCount)
214 {
215 if (!CheckParamsWithOptions(params, paramsCount)) {
216 return;
217 }
218 if (NapiUtils::HasNamedProperty(GetEnv(), params[0], KEY_ENCODING)) {
219 std::string encoding = NapiUtils::GetStringPropertyUtf8(GetEnv(), params[0], KEY_ENCODING);
220 options_.SetEncoding(encoding);
221 }
222 if (!GetData(params[0])) {
223 return;
224 }
225 if (paramsCount == PARAM_OPTIONS_AND_CALLBACK) {
226 SetParseOK(SetCallback(params[1]) == napi_ok);
227 return;
228 }
229 SetParseOK(true);
230 }
231
GetOptionsRef()232 LocalSocketOptions &LocalSocketSendContext::GetOptionsRef()
233 {
234 return options_;
235 }
236
ParseParams(napi_value * params,size_t paramsCount)237 void LocalSocketCloseContext::ParseParams(napi_value *params, size_t paramsCount)
238 {
239 if (!CheckParamsWithoutOptions(params, paramsCount)) {
240 return;
241 }
242 if (paramsCount != PARAM_NONE) {
243 SetParseOK(SetCallback(params[0]) == napi_ok);
244 return;
245 }
246 SetParseOK(true);
247 }
248
ParseParams(napi_value * params,size_t paramsCount)249 void LocalSocketGetStateContext::ParseParams(napi_value *params, size_t paramsCount)
250 {
251 if (!CheckParamsWithoutOptions(params, paramsCount)) {
252 return;
253 }
254 if (paramsCount != PARAM_NONE) {
255 SetParseOK(SetCallback(params[0]) == napi_ok);
256 return;
257 }
258 SetParseOK(true);
259 }
260
GetStateRef()261 SocketStateBase &LocalSocketGetStateContext::GetStateRef()
262 {
263 return state_;
264 }
265
ParseParams(napi_value * params,size_t paramsCount)266 void LocalSocketGetSocketFdContext::ParseParams(napi_value *params, size_t paramsCount)
267 {
268 if (!CheckParamsWithoutOptions(params, paramsCount)) {
269 return;
270 }
271 if (paramsCount != PARAM_NONE) {
272 SetParseOK(SetCallback(params[0]) == napi_ok);
273 return;
274 }
275 SetParseOK(true);
276 }
277
ParseParams(napi_value * params,size_t paramsCount)278 void LocalSocketSetExtraOptionsContext::ParseParams(napi_value *params, size_t paramsCount)
279 {
280 if (!CheckParamsWithOptions(params, paramsCount)) {
281 return;
282 }
283 if (NapiUtils::HasNamedProperty(GetEnv(), params[0], KEY_RECEIVE_BUFFER_SIZE)) {
284 options_.SetReceiveBufferSize(NapiUtils::GetUint32Property(GetEnv(), params[0], KEY_RECEIVE_BUFFER_SIZE));
285 options_.SetRecvBufSizeFlag(true);
286 }
287 if (NapiUtils::HasNamedProperty(GetEnv(), params[0], KEY_SEND_BUFFER_SIZE)) {
288 options_.SetSendBufferSize(NapiUtils::GetUint32Property(GetEnv(), params[0], KEY_SEND_BUFFER_SIZE));
289 options_.SetSendBufSizeFlag(true);
290 }
291 if (NapiUtils::HasNamedProperty(GetEnv(), params[0], KEY_SOCKET_TIMEOUT)) {
292 options_.SetSocketTimeout(NapiUtils::GetUint32Property(GetEnv(), params[0], KEY_SOCKET_TIMEOUT));
293 options_.SetTimeoutFlag(true);
294 }
295 if (paramsCount == PARAM_OPTIONS_AND_CALLBACK) {
296 SetParseOK(SetCallback(params[1]) == napi_ok);
297 return;
298 }
299 SetParseOK(true);
300 }
301
GetOptionsRef()302 LocalExtraOptions &LocalSocketSetExtraOptionsContext::GetOptionsRef()
303 {
304 return options_;
305 }
306
ParseParams(napi_value * params,size_t paramsCount)307 void LocalSocketGetExtraOptionsContext::ParseParams(napi_value *params, size_t paramsCount)
308 {
309 if (!CheckParamsWithoutOptions(params, paramsCount)) {
310 return;
311 }
312 if (paramsCount != PARAM_NONE) {
313 SetParseOK(SetCallback(params[0]) == napi_ok);
314 return;
315 }
316 SetParseOK(true);
317 }
318
GetOptionsRef()319 LocalExtraOptions &LocalSocketGetExtraOptionsContext::GetOptionsRef()
320 {
321 return options_;
322 }
323
ParseParams(napi_value * params,size_t paramsCount)324 void LocalSocketGetLocalAddressContext::ParseParams(napi_value *params, size_t paramsCount)
325 {
326 if (paramsCount != PARAM_NONE) {
327 NETSTACK_LOGE("get local address param error");
328 SetNeedThrowException(true);
329 SetError(PARSE_ERROR_CODE, PARSE_ERROR_MSG);
330 return;
331 }
332 SetParseOK(true);
333 }
334
SetSocketPath(const std::string socketPath)335 void LocalSocketGetLocalAddressContext::SetSocketPath(const std::string socketPath)
336 {
337 socketPath_ = socketPath;
338 }
339
GetSocketPath()340 std::string LocalSocketGetLocalAddressContext::GetSocketPath()
341 {
342 return socketPath_;
343 }
344 } // namespace OHOS::NetStack::Socket
345