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