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