• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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