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