1 /*
2 * Copyright (c) 2021-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
16 #include "socket_module.h"
17
18 #include <cstdint>
19 #include <initializer_list>
20 #include <new>
21 #include <unistd.h>
22 #include <utility>
23
24 #include "bind_context.h"
25 #include "common_context.h"
26 #include "connect_context.h"
27 #include "context_key.h"
28 #include "event_list.h"
29 #include "event_manager.h"
30 #include "local_socket_context.h"
31 #include "local_socket_exec.h"
32 #include "local_socket_server_context.h"
33 #include "module_template.h"
34 #include "multicast_get_loopback_context.h"
35 #include "multicast_get_ttl_context.h"
36 #include "multicast_membership_context.h"
37 #include "multicast_set_loopback_context.h"
38 #include "multicast_set_ttl_context.h"
39 #include "napi/native_api.h"
40 #include "napi/native_common.h"
41 #include "napi_utils.h"
42 #include "net_address.h"
43 #include "netstack_common_utils.h"
44 #include "netstack_log.h"
45 #include "node_api.h"
46 #include "socket_async_work.h"
47 #include "socket_exec.h"
48 #include "tcp_extra_context.h"
49 #include "tcp_send_context.h"
50 #include "tcp_server_common_context.h"
51 #include "tcp_server_extra_context.h"
52 #include "tcp_server_listen_context.h"
53 #include "tcp_server_send_context.h"
54 #include "tlssocket_module.h"
55 #if !defined(CROSS_PLATFORM)
56 #include "tlssocketserver_module.h"
57 #endif
58 #include "udp_extra_context.h"
59 #include "udp_send_context.h"
60
61 static constexpr const char *SOCKET_MODULE_NAME = "net.socket";
62
63 static const char *UDP_BIND_NAME = "UdpBind";
64 static const char *UDP_SEND_NAME = "UdpSend";
65 static const char *UDP_CLOSE_NAME = "UdpClose";
66 static const char *UDP_GET_STATE = "UdpGetState";
67 static const char *UDP_SET_EXTRA_OPTIONS_NAME = "UdpSetExtraOptions";
68 static constexpr const char *UDP_GET_SOCKET_FD = "UdpGetSocketFd";
69
70 static constexpr const char *UDP_ADD_MEMBERSHIP = "UdpAddMembership";
71 static constexpr const char *UDP_DROP_MEMBERSHIP = "UdpDropMembership";
72 static constexpr const char *UDP_SET_MULTICAST_TTL = "UdpSetMulticastTTL";
73 static constexpr const char *UDP_GET_MULTICAST_TTL = "UdpGetMulticastTTL";
74 static constexpr const char *UDP_SET_LOOPBACK_MODE = "UdpSetLoopbackMode";
75 static constexpr const char *UDP_GET_LOOPBACK_MODE = "UdpGetLoopbackMode";
76
77 static constexpr const char *LOCAL_SOCKET_BIND = "LocalSocketBind";
78 static constexpr const char *LOCAL_SOCKET_CONNECT = "LocalSocketConnect";
79 static constexpr const char *LOCAL_SOCKET_SEND = "LocalSocketSend";
80 static constexpr const char *LOCAL_SOCKET_CLOSE = "LocalSocketClose";
81 static constexpr const char *LOCAL_SOCKET_GET_STATE = "LocalSocketGetState";
82 static constexpr const char *LOCAL_SOCKET_GET_SOCKET_FD = "LocalSocketGetSocketFd";
83 static constexpr const char *LOCAL_SOCKET_SET_EXTRA_OPTIONS = "LocalSocketSetExtraOptions";
84 static constexpr const char *LOCAL_SOCKET_GET_EXTRA_OPTIONS = "LocalSocketGetExtraOptions";
85
86 static constexpr const char *LOCAL_SOCKET_SERVER_LISTEN = "LocalSocketServerListen";
87 static constexpr const char *LOCAL_SOCKET_SERVER_GET_STATE = "LocalSocketServerGetState";
88 static constexpr const char *LOCAL_SOCKET_SERVER_SET_EXTRA_OPTIONS = "LocalSocketServerSetExtraOptions";
89 static constexpr const char *LOCAL_SOCKET_SERVER_GET_EXTRA_OPTIONS = "LocalSocketServerGetExtraOptions";
90
91 static constexpr const char *LOCAL_SOCKET_CONNECTION_SEND = "LocalSocketConnectionSend";
92 static constexpr const char *LOCAL_SOCKET_CONNECTION_CLOSE = "LocalSocketConnectionClose";
93
94 static const char *TCP_BIND_NAME = "TcpBind";
95 static const char *TCP_CONNECT_NAME = "TcpConnect";
96 static const char *TCP_SEND_NAME = "TcpSend";
97 static const char *TCP_CLOSE_NAME = "TcpClose";
98 static const char *TCP_GET_STATE = "TcpGetState";
99 static const char *TCP_GET_REMOTE_ADDRESS = "TcpGetRemoteAddress";
100 static const char *TCP_SET_EXTRA_OPTIONS_NAME = "TcpSetExtraOptions";
101 static constexpr const char *TCP_GET_SOCKET_FD = "TcpGetSocketFd";
102
103 static constexpr const char *TCP_SERVER_LISTEN_NAME = "TcpServerListen";
104 static constexpr const char *TCP_SERVER_GET_STATE = "TcpServerGetState";
105 static constexpr const char *TCP_SERVER_SET_EXTRA_OPTIONS_NAME = "TcpServerSetExtraOptions";
106
107 static constexpr const char *TCP_CONNECTION_SEND_NAME = "TcpConnectionSend";
108 static constexpr const char *TCP_CONNECTION_CLOSE_NAME = "TcpConnectionClose";
109 static constexpr const char *TCP_CONNECTION_GET_REMOTE_ADDRESS = "TcpConnectionGetRemoteAddress";
110
111 static constexpr const char *KEY_SOCKET_FD = "socketFd";
112
113 static constexpr int PARAM_COUNT_TWO = 2;
114
115 #define SOCKET_INTERFACE(Context, executor, callback, work, name) \
116 ModuleTemplate::Interface<Context>(env, info, name, work, SocketAsyncWork::executor, SocketAsyncWork::callback)
117
118 namespace OHOS::NetStack::Socket {
Finalize(napi_env,void * data,void *)119 void Finalize(napi_env, void *data, void *)
120 {
121 NETSTACK_LOGI("socket handle is finalized");
122 auto manager = static_cast<EventManager *>(data);
123 if (manager != nullptr) {
124 int sock = static_cast<int>(reinterpret_cast<uint64_t>(manager->GetData()));
125 if (sock != 0) {
126 SocketExec::SingletonSocketConfig::GetInstance().RemoveServerSocket(sock);
127 close(sock);
128 }
129 EventManager::SetInvalid(manager);
130 }
131 }
132
FinalizeLocalsocketServer(napi_env,void * data,void *)133 void FinalizeLocalsocketServer(napi_env, void *data, void *)
134 {
135 EventManager *manager = reinterpret_cast<EventManager *>(data);
136 if (manager != nullptr) {
137 if (auto serverMgr = reinterpret_cast<LocalSocketServerManager *>(manager->GetData()); serverMgr != nullptr) {
138 NETSTACK_LOGI("localsocket server handle is finalized, fd: %{public}d", serverMgr->sockfd_);
139 serverMgr->RemoveAllAccept();
140 serverMgr->RemoveAllEventManager();
141 if (serverMgr->sockfd_ > 0) {
142 close(serverMgr->sockfd_);
143 serverMgr->sockfd_ = 0;
144 }
145 delete serverMgr;
146 }
147 EventManager::SetInvalid(manager);
148 }
149 }
150
FinalizeLocalSocket(napi_env,void * data,void *)151 void FinalizeLocalSocket(napi_env, void *data, void *)
152 {
153 auto manager = static_cast<EventManager *>(data);
154 if (manager != nullptr) {
155 if (auto pMgr = reinterpret_cast<LocalSocketServerManager *>(manager->GetData()); pMgr != nullptr) {
156 NETSTACK_LOGI("localsocket handle is finalized, fd: %{public}d", pMgr->sockfd_);
157 if (pMgr->sockfd_ > 0) {
158 close(pMgr->sockfd_);
159 pMgr->sockfd_ = 0;
160 }
161 delete pMgr;
162 }
163 EventManager::SetInvalid(manager);
164 }
165 }
166
SetSocket(napi_env env,napi_value thisVal,BaseContext * context,int sock)167 static bool SetSocket(napi_env env, napi_value thisVal, BaseContext *context, int sock)
168 {
169 if (sock < 0) {
170 napi_value error = NapiUtils::CreateObject(env);
171 if (NapiUtils::GetValueType(env, error) != napi_object) {
172 return false;
173 }
174 NapiUtils::SetUint32Property(env, error, KEY_ERROR_CODE, errno);
175 context->Emit(EVENT_ERROR, std::make_pair(NapiUtils::GetUndefined(env), error));
176 return false;
177 }
178
179 EventManager *manager = nullptr;
180 if (napi_unwrap(env, thisVal, reinterpret_cast<void **>(&manager)) != napi_ok || manager == nullptr) {
181 return false;
182 }
183
184 manager->SetData(reinterpret_cast<void *>(sock));
185 NapiUtils::SetInt32Property(env, thisVal, KEY_SOCKET_FD, sock);
186 return true;
187 }
188
MakeTcpClientBindSocket(napi_env env,napi_value thisVal,BindContext * context)189 static bool MakeTcpClientBindSocket(napi_env env, napi_value thisVal, BindContext *context)
190 {
191 if (!context->IsParseOK()) {
192 context->SetErrorCode(PARSE_ERROR_CODE);
193 return false;
194 }
195 if (!CommonUtils::HasInternetPermission()) {
196 context->SetPermissionDenied(true);
197 return false;
198 }
199 NETSTACK_LOGD("bind ip family is %{public}d", context->address_.GetSaFamily());
200 if (context->GetManager()->GetData() != nullptr) {
201 NETSTACK_LOGE("tcp connect has been called");
202 return true;
203 }
204 int sock = SocketExec::MakeTcpSocket(context->address_.GetSaFamily());
205 if (!SetSocket(env, thisVal, context, sock)) {
206 return false;
207 }
208 context->SetExecOK(true);
209 return true;
210 }
211
MakeTcpClientConnectSocket(napi_env env,napi_value thisVal,ConnectContext * context)212 static bool MakeTcpClientConnectSocket(napi_env env, napi_value thisVal, ConnectContext *context)
213 {
214 if (!context->IsParseOK()) {
215 context->SetErrorCode(PARSE_ERROR_CODE);
216 return false;
217 }
218 if (!CommonUtils::HasInternetPermission()) {
219 context->SetPermissionDenied(true);
220 return false;
221 }
222 NETSTACK_LOGD("connect ip family is %{public}d", context->options.address.GetSaFamily());
223 if (context->GetManager()->GetData() != nullptr) {
224 NETSTACK_LOGD("tcp bind has been called");
225 return true;
226 }
227 int sock = SocketExec::MakeTcpSocket(context->options.address.GetSaFamily());
228 if (!SetSocket(env, thisVal, context, sock)) {
229 return false;
230 }
231 context->SetExecOK(true);
232 return true;
233 }
234
MakeTcpServerSocket(napi_env env,napi_value thisVal,TcpServerListenContext * context)235 static bool MakeTcpServerSocket(napi_env env, napi_value thisVal, TcpServerListenContext *context)
236 {
237 if (!context->IsParseOK()) {
238 context->SetErrorCode(PARSE_ERROR_CODE);
239 return false;
240 }
241 if (!CommonUtils::HasInternetPermission()) {
242 context->SetPermissionDenied(true);
243 return false;
244 }
245 int sock = SocketExec::MakeTcpSocket(context->address_.GetSaFamily(), false);
246 if (sock <= 0) {
247 return false;
248 }
249 int reuse = 1; // 1 means enable reuseaddr feature
250 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<void *>(&reuse), sizeof(reuse)) < 0) {
251 NETSTACK_LOGE("failed to set tcp server listen socket reuseaddr on, sockfd: %{public}d", sock);
252 }
253 if (!SetSocket(env, thisVal, context, sock)) {
254 return false;
255 }
256 context->SetExecOK(true);
257 return true;
258 }
259
MakeUdpSocket(napi_env env,napi_value thisVal,BindContext * context)260 static bool MakeUdpSocket(napi_env env, napi_value thisVal, BindContext *context)
261 {
262 if (!context->IsParseOK()) {
263 context->SetErrorCode(PARSE_ERROR_CODE);
264 return false;
265 }
266 if (!CommonUtils::HasInternetPermission()) {
267 context->SetPermissionDenied(true);
268 return false;
269 }
270 int sock = SocketExec::MakeUdpSocket(context->address_.GetSaFamily());
271 if (!SetSocket(env, thisVal, context, sock)) {
272 return false;
273 }
274 context->SetExecOK(true);
275 return true;
276 }
277
MakeMulticastUdpSocket(napi_env env,napi_value thisVal,MulticastMembershipContext * context)278 static bool MakeMulticastUdpSocket(napi_env env, napi_value thisVal, MulticastMembershipContext *context)
279 {
280 if (!CommonUtils::HasInternetPermission()) {
281 context->SetPermissionDenied(true);
282 return false;
283 }
284 if (context->GetSocketFd() > 0) {
285 NETSTACK_LOGI("socket exist: %{public}d", context->GetSocketFd());
286 return false;
287 }
288 if (!context->IsParseOK()) {
289 context->SetErrorCode(PARSE_ERROR_CODE);
290 return false;
291 }
292 int sock = SocketExec::MakeUdpSocket(context->address_.GetSaFamily());
293 if (!SetSocket(env, thisVal, context, sock)) {
294 return false;
295 }
296 context->SetExecOK(true);
297 return true;
298 }
299
SetSocketManager(napi_env env,napi_value thisVal,BaseContext * context,SocketBaseManager * mgr)300 static bool SetSocketManager(napi_env env, napi_value thisVal, BaseContext *context, SocketBaseManager *mgr)
301 {
302 if (mgr->sockfd_ <= 0) {
303 NETSTACK_LOGE("SetSocketManager sockfd < 0");
304 napi_value error = NapiUtils::CreateObject(env);
305 if (NapiUtils::GetValueType(env, error) != napi_object) {
306 return false;
307 }
308 NapiUtils::SetUint32Property(env, error, KEY_ERROR_CODE, errno);
309 context->Emit(EVENT_ERROR, std::make_pair(NapiUtils::GetUndefined(env), error));
310 return false;
311 }
312 EventManager *manager = nullptr;
313 if (napi_unwrap(env, thisVal, reinterpret_cast<void **>(&manager)) != napi_ok || manager == nullptr) {
314 NETSTACK_LOGE("SetSocketManager unwrap err");
315 return false;
316 }
317 manager->SetData(reinterpret_cast<void *>(mgr));
318 NapiUtils::SetInt32Property(env, thisVal, KEY_SOCKET_FD, mgr->sockfd_);
319 return true;
320 }
321
MakeLocalSocketBind(napi_env env,napi_value thisVal,LocalSocketBindContext * context)322 static bool MakeLocalSocketBind(napi_env env, napi_value thisVal, LocalSocketBindContext *context)
323 {
324 if (context == nullptr) {
325 return false;
326 }
327 if (context->GetSocketFd() > 0) {
328 NETSTACK_LOGI("socket exist: %{public}d", context->GetSocketFd());
329 return false;
330 }
331 int sock = LocalSocketExec::MakeLocalSocket(SOCK_STREAM);
332 if (sock < 0) {
333 return false;
334 }
335 auto pManager = new (std::nothrow) LocalSocketManager(sock);
336 if (pManager == nullptr) {
337 return false;
338 }
339 if (!SetSocketManager(env, thisVal, context, pManager)) {
340 return false;
341 }
342 context->SetExecOK(true);
343 return true;
344 }
345
MakeLocalSocketConnect(napi_env env,napi_value thisVal,LocalSocketConnectContext * context)346 static bool MakeLocalSocketConnect(napi_env env, napi_value thisVal, LocalSocketConnectContext *context)
347 {
348 if (context == nullptr) {
349 return false;
350 }
351 if (context->GetSocketFd() > 0) {
352 NETSTACK_LOGI("socket exist: %{public}d", context->GetSocketFd());
353 return false;
354 }
355 int sock = LocalSocketExec::MakeLocalSocket(SOCK_STREAM, false);
356 if (sock < 0) {
357 return false;
358 }
359 auto pManager = new (std::nothrow) LocalSocketManager(sock);
360 if (pManager == nullptr) {
361 return false;
362 }
363 if (!SetSocketManager(env, thisVal, context, pManager)) {
364 return false;
365 }
366 context->SetExecOK(true);
367 return true;
368 }
369
MakeLocalServerSocket(napi_env env,napi_value thisVal,LocalSocketServerListenContext * context)370 static bool MakeLocalServerSocket(napi_env env, napi_value thisVal, LocalSocketServerListenContext *context)
371 {
372 if (context == nullptr) {
373 return false;
374 }
375 if (int sock = context->GetSocketFd(); sock > 0) {
376 NETSTACK_LOGI("socket exist: %{public}d", sock);
377 return false;
378 }
379 int sock = LocalSocketExec::MakeLocalSocket(SOCK_STREAM, false);
380 if (sock < 0) {
381 return false;
382 }
383 auto pManager = new (std::nothrow) LocalSocketServerManager(sock);
384 if (pManager == nullptr) {
385 return false;
386 }
387 if (!SetSocketManager(env, thisVal, context, pManager)) {
388 return false;
389 }
390 context->SetExecOK(true);
391 return true;
392 }
393
InitSocketModule(napi_env env,napi_value exports)394 napi_value SocketModuleExports::InitSocketModule(napi_env env, napi_value exports)
395 {
396 TlsSocket::TLSSocketModuleExports::InitTLSSocketModule(env, exports);
397 #if !defined(CROSS_PLATFORM)
398 TlsSocketServer::TLSSocketServerModuleExports::InitTLSSocketServerModule(env, exports);
399 #endif
400 DefineUDPSocketClass(env, exports);
401 DefineMulticastSocketClass(env, exports);
402 DefineTCPServerSocketClass(env, exports);
403 DefineTCPSocketClass(env, exports);
404 DefineLocalSocketClass(env, exports);
405 DefineLocalSocketServerClass(env, exports);
406 InitSocketProperties(env, exports);
407
408 return exports;
409 }
410
ConstructUDPSocketInstance(napi_env env,napi_callback_info info)411 napi_value SocketModuleExports::ConstructUDPSocketInstance(napi_env env, napi_callback_info info)
412 {
413 return ModuleTemplate::NewInstance(env, info, INTERFACE_UDP_SOCKET, Finalize);
414 }
415
ConstructMulticastSocketInstance(napi_env env,napi_callback_info info)416 napi_value SocketModuleExports::ConstructMulticastSocketInstance(napi_env env, napi_callback_info info)
417 {
418 return ModuleTemplate::NewInstance(env, info, INTERFACE_MULTICAST_SOCKET, Finalize);
419 }
420
ConstructLocalSocketInstance(napi_env env,napi_callback_info info)421 napi_value SocketModuleExports::ConstructLocalSocketInstance(napi_env env, napi_callback_info info)
422 {
423 return ModuleTemplate::NewInstance(env, info, INTERFACE_LOCAL_SOCKET, FinalizeLocalSocket);
424 }
425
ConstructLocalSocketServerInstance(napi_env env,napi_callback_info info)426 napi_value SocketModuleExports::ConstructLocalSocketServerInstance(napi_env env, napi_callback_info info)
427 {
428 return ModuleTemplate::NewInstance(env, info, INTERFACE_LOCAL_SOCKET_SERVER, FinalizeLocalsocketServer);
429 }
430
DefineUDPSocketClass(napi_env env,napi_value exports)431 void SocketModuleExports::DefineUDPSocketClass(napi_env env, napi_value exports)
432 {
433 std::initializer_list<napi_property_descriptor> properties = {
434 DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_BIND, UDPSocket::Bind),
435 DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_SEND, UDPSocket::Send),
436 DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_CLOSE, UDPSocket::Close),
437 DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_GET_STATE, UDPSocket::GetState),
438 DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_SET_EXTRA_OPTIONS, UDPSocket::SetExtraOptions),
439 DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_GET_SOCKET_FD, UDPSocket::GetSocketFd),
440 DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_ON, UDPSocket::On),
441 DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_OFF, UDPSocket::Off),
442 };
443 ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_UDP_SOCKET);
444 }
445
DefineMulticastSocketClass(napi_env env,napi_value exports)446 void SocketModuleExports::DefineMulticastSocketClass(napi_env env, napi_value exports)
447 {
448 std::initializer_list<napi_property_descriptor> properties = {
449 DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_BIND, MulticastSocket::Bind),
450 DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_SEND, MulticastSocket::Send),
451 DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_CLOSE, MulticastSocket::Close),
452 DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_GET_STATE, MulticastSocket::GetState),
453 DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_SET_EXTRA_OPTIONS, MulticastSocket::SetExtraOptions),
454 DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_GET_SOCKET_FD, MulticastSocket::GetSocketFd),
455 DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_ON, MulticastSocket::On),
456 DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_OFF, MulticastSocket::Off),
457 DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_ADD_MEMBER_SHIP, MulticastSocket::AddMembership),
458 DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_DROP_MEMBER_SHIP, MulticastSocket::DropMembership),
459 DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_SET_MULTICAST_TTL, MulticastSocket::SetMulticastTTL),
460 DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_GET_MULTICAST_TTL, MulticastSocket::GetMulticastTTL),
461 DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_SET_LOOPBACK_MODE, MulticastSocket::SetLoopbackMode),
462 DECLARE_NAPI_FUNCTION(MulticastSocket::FUNCTION_GET_LOOPBACK_MODE, MulticastSocket::GetLoopbackMode),
463 };
464 ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_MULTICAST_SOCKET);
465 }
466
ConstructTCPSocketInstance(napi_env env,napi_callback_info info)467 napi_value SocketModuleExports::ConstructTCPSocketInstance(napi_env env, napi_callback_info info)
468 {
469 return ModuleTemplate::NewInstance(env, info, INTERFACE_TCP_SOCKET, Finalize);
470 }
471
DefineTCPSocketClass(napi_env env,napi_value exports)472 void SocketModuleExports::DefineTCPSocketClass(napi_env env, napi_value exports)
473 {
474 std::initializer_list<napi_property_descriptor> properties = {
475 DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_BIND, TCPSocket::Bind),
476 DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_CONNECT, TCPSocket::Connect),
477 DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_SEND, TCPSocket::Send),
478 DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_CLOSE, TCPSocket::Close),
479 DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_GET_REMOTE_ADDRESS, TCPSocket::GetRemoteAddress),
480 DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_GET_STATE, TCPSocket::GetState),
481 DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_SET_EXTRA_OPTIONS, TCPSocket::SetExtraOptions),
482 DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_GET_SOCKET_FD, TCPSocket::GetSocketFd),
483 DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_ON, TCPSocket::On),
484 DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_OFF, TCPSocket::Off),
485 };
486 ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_TCP_SOCKET);
487 }
488
DefineLocalSocketClass(napi_env env,napi_value exports)489 void SocketModuleExports::DefineLocalSocketClass(napi_env env, napi_value exports)
490 {
491 std::initializer_list<napi_property_descriptor> properties = {
492 DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_BIND, LocalSocket::Bind),
493 DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_CONNECT, LocalSocket::Connect),
494 DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_SEND, LocalSocket::Send),
495 DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_CLOSE, LocalSocket::Close),
496 DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_GET_STATE, LocalSocket::GetState),
497 DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_SET_EXTRA_OPTIONS, LocalSocket::SetExtraOptions),
498 DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_GET_EXTRA_OPTIONS, LocalSocket::GetExtraOptions),
499 DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_GET_SOCKET_FD, LocalSocket::GetSocketFd),
500 DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_ON, LocalSocket::On),
501 DECLARE_NAPI_FUNCTION(LocalSocket::FUNCTION_OFF, LocalSocket::Off),
502 };
503 ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_LOCAL_SOCKET);
504 }
505
DefineLocalSocketServerClass(napi_env env,napi_value exports)506 void SocketModuleExports::DefineLocalSocketServerClass(napi_env env, napi_value exports)
507 {
508 std::initializer_list<napi_property_descriptor> properties = {
509 DECLARE_NAPI_FUNCTION(LocalSocketServer::FUNCTION_LISTEN, LocalSocketServer::Listen),
510 DECLARE_NAPI_FUNCTION(LocalSocketServer::FUNCTION_GET_STATE, LocalSocketServer::GetState),
511 DECLARE_NAPI_FUNCTION(LocalSocketServer::FUNCTION_SET_EXTRA_OPTIONS, LocalSocketServer::SetExtraOptions),
512 DECLARE_NAPI_FUNCTION(LocalSocketServer::FUNCTION_GET_EXTRA_OPTIONS, LocalSocketServer::GetExtraOptions),
513 DECLARE_NAPI_FUNCTION(LocalSocketServer::FUNCTION_ON, LocalSocketServer::On),
514 DECLARE_NAPI_FUNCTION(LocalSocketServer::FUNCTION_OFF, LocalSocketServer::Off),
515 };
516 ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_LOCAL_SOCKET_SERVER);
517 }
518
ConstructTCPSocketServerInstance(napi_env env,napi_callback_info info)519 napi_value SocketModuleExports::ConstructTCPSocketServerInstance(napi_env env, napi_callback_info info)
520 {
521 return ModuleTemplate::NewInstance(env, info, INTERFACE_TCP_SOCKET_SERVER, Finalize);
522 }
523
DefineTCPServerSocketClass(napi_env env,napi_value exports)524 void SocketModuleExports::DefineTCPServerSocketClass(napi_env env, napi_value exports)
525 {
526 std::initializer_list<napi_property_descriptor> properties = {
527 DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_LISTEN, TCPServerSocket::Listen),
528 DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_GET_STATE, TCPServerSocket::GetState),
529 DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_SET_EXTRA_OPTIONS, TCPServerSocket::SetExtraOptions),
530 DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_ON, TCPServerSocket::On),
531 DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_OFF, TCPServerSocket::Off),
532 };
533 ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_TCP_SOCKET_SERVER);
534 }
535
InitSocketProperties(napi_env env,napi_value exports)536 void SocketModuleExports::InitSocketProperties(napi_env env, napi_value exports)
537 {
538 std::initializer_list<napi_property_descriptor> properties = {
539 DECLARE_NAPI_FUNCTION(FUNCTION_CONSTRUCTOR_UDP_SOCKET_INSTANCE, ConstructUDPSocketInstance),
540 DECLARE_NAPI_FUNCTION(FUNCTION_CONSTRUCTOR_MULTICAST_SOCKET_INSTANCE, ConstructMulticastSocketInstance),
541 DECLARE_NAPI_FUNCTION(FUNCTION_CONSTRUCTOR_TCP_SOCKET_SERVER_INSTANCE, ConstructTCPSocketServerInstance),
542 DECLARE_NAPI_FUNCTION(FUNCTION_CONSTRUCTOR_TCP_SOCKET_INSTANCE, ConstructTCPSocketInstance),
543 DECLARE_NAPI_FUNCTION(FUNCTION_CONSTRUCTOR_LOCAL_SOCKET_INSTANCE, ConstructLocalSocketInstance),
544 DECLARE_NAPI_FUNCTION(FUNCTION_CONSTRUCTOR_LOCAL_SOCKET_SERVER_INSTANCE, ConstructLocalSocketServerInstance),
545 };
546 NapiUtils::DefineProperties(env, exports, properties);
547 }
548
549 /* udp async works */
Bind(napi_env env,napi_callback_info info)550 napi_value SocketModuleExports::UDPSocket::Bind(napi_env env, napi_callback_info info)
551 {
552 return SOCKET_INTERFACE(BindContext, ExecUdpBind, BindCallback, MakeUdpSocket, UDP_BIND_NAME);
553 }
554
Send(napi_env env,napi_callback_info info)555 napi_value SocketModuleExports::UDPSocket::Send(napi_env env, napi_callback_info info)
556 {
557 return ModuleTemplate::InterfaceWithOutAsyncWork<UdpSendContext>(
558 env, info,
559 [](napi_env, napi_value, UdpSendContext *context) -> bool {
560 SocketAsyncWork::ExecUdpSend(context->GetEnv(), context);
561 return true;
562 },
563 UDP_SEND_NAME, SocketAsyncWork::ExecUdpSend, SocketAsyncWork::UdpSendCallback);
564 }
565
Close(napi_env env,napi_callback_info info)566 napi_value SocketModuleExports::UDPSocket::Close(napi_env env, napi_callback_info info)
567 {
568 return SOCKET_INTERFACE(CloseContext, ExecClose, CloseCallback, nullptr, UDP_CLOSE_NAME);
569 }
570
GetState(napi_env env,napi_callback_info info)571 napi_value SocketModuleExports::UDPSocket::GetState(napi_env env, napi_callback_info info)
572 {
573 return SOCKET_INTERFACE(GetStateContext, ExecGetState, GetStateCallback, nullptr, UDP_GET_STATE);
574 }
575
SetExtraOptions(napi_env env,napi_callback_info info)576 napi_value SocketModuleExports::UDPSocket::SetExtraOptions(napi_env env, napi_callback_info info)
577 {
578 return SOCKET_INTERFACE(UdpSetExtraOptionsContext, ExecUdpSetExtraOptions, UdpSetExtraOptionsCallback, nullptr,
579 UDP_SET_EXTRA_OPTIONS_NAME);
580 }
581
GetSocketFd(napi_env env,napi_callback_info info)582 napi_value SocketModuleExports::UDPSocket::GetSocketFd(napi_env env, napi_callback_info info)
583 {
584 return SOCKET_INTERFACE(GetSocketFdContext, ExecUdpGetSocketFd, UdpGetSocketFdCallback, nullptr, UDP_GET_SOCKET_FD);
585 }
586
On(napi_env env,napi_callback_info info)587 napi_value SocketModuleExports::UDPSocket::On(napi_env env, napi_callback_info info)
588 {
589 return ModuleTemplate::On(env, info, {EVENT_MESSAGE, EVENT_LISTENING, EVENT_ERROR, EVENT_CLOSE}, false);
590 }
591
Off(napi_env env,napi_callback_info info)592 napi_value SocketModuleExports::UDPSocket::Off(napi_env env, napi_callback_info info)
593 {
594 return ModuleTemplate::Off(env, info, {EVENT_MESSAGE, EVENT_LISTENING, EVENT_ERROR, EVENT_CLOSE});
595 }
596
597 /* udp multicast */
AddMembership(napi_env env,napi_callback_info info)598 napi_value SocketModuleExports::MulticastSocket::AddMembership(napi_env env, napi_callback_info info)
599 {
600 return SOCKET_INTERFACE(MulticastMembershipContext, ExecUdpAddMembership, UdpAddMembershipCallback,
601 MakeMulticastUdpSocket, UDP_ADD_MEMBERSHIP);
602 }
603
DropMembership(napi_env env,napi_callback_info info)604 napi_value SocketModuleExports::MulticastSocket::DropMembership(napi_env env, napi_callback_info info)
605 {
606 return SOCKET_INTERFACE(MulticastMembershipContext, ExecUdpDropMembership, UdpDropMembershipCallback, nullptr,
607 UDP_DROP_MEMBERSHIP);
608 }
609
SetMulticastTTL(napi_env env,napi_callback_info info)610 napi_value SocketModuleExports::MulticastSocket::SetMulticastTTL(napi_env env, napi_callback_info info)
611 {
612 return SOCKET_INTERFACE(MulticastSetTTLContext, ExecSetMulticastTTL, UdpSetMulticastTTLCallback, nullptr,
613 UDP_SET_MULTICAST_TTL);
614 }
615
GetMulticastTTL(napi_env env,napi_callback_info info)616 napi_value SocketModuleExports::MulticastSocket::GetMulticastTTL(napi_env env, napi_callback_info info)
617 {
618 return SOCKET_INTERFACE(MulticastGetTTLContext, ExecGetMulticastTTL, UdpGetMulticastTTLCallback, nullptr,
619 UDP_GET_MULTICAST_TTL);
620 }
621
SetLoopbackMode(napi_env env,napi_callback_info info)622 napi_value SocketModuleExports::MulticastSocket::SetLoopbackMode(napi_env env, napi_callback_info info)
623 {
624 return SOCKET_INTERFACE(MulticastSetLoopbackContext, ExecSetLoopbackMode, UdpSetLoopbackModeCallback, nullptr,
625 UDP_SET_LOOPBACK_MODE);
626 }
627
GetLoopbackMode(napi_env env,napi_callback_info info)628 napi_value SocketModuleExports::MulticastSocket::GetLoopbackMode(napi_env env, napi_callback_info info)
629 {
630 return SOCKET_INTERFACE(MulticastGetLoopbackContext, ExecGetLoopbackMode, UdpGetLoopbackModeCallback, nullptr,
631 UDP_GET_LOOPBACK_MODE);
632 }
633
634 /* tcp async works */
Bind(napi_env env,napi_callback_info info)635 napi_value SocketModuleExports::TCPSocket::Bind(napi_env env, napi_callback_info info)
636 {
637 return SOCKET_INTERFACE(BindContext, ExecTcpBind, BindCallback, MakeTcpClientBindSocket, TCP_BIND_NAME);
638 }
639
Connect(napi_env env,napi_callback_info info)640 napi_value SocketModuleExports::TCPSocket::Connect(napi_env env, napi_callback_info info)
641 {
642 return SOCKET_INTERFACE(ConnectContext, ExecConnect, ConnectCallback, MakeTcpClientConnectSocket, TCP_CONNECT_NAME);
643 }
644
Send(napi_env env,napi_callback_info info)645 napi_value SocketModuleExports::TCPSocket::Send(napi_env env, napi_callback_info info)
646 {
647 return ModuleTemplate::InterfaceWithOutAsyncWork<TcpSendContext>(
648 env, info,
649 [](napi_env, napi_value, TcpSendContext *context) -> bool {
650 SocketAsyncWork::ExecTcpSend(context->GetEnv(), context);
651 return true;
652 },
653 TCP_SEND_NAME, SocketAsyncWork::ExecTcpSend, SocketAsyncWork::TcpSendCallback);
654 }
655
Close(napi_env env,napi_callback_info info)656 napi_value SocketModuleExports::TCPSocket::Close(napi_env env, napi_callback_info info)
657 {
658 return SOCKET_INTERFACE(CloseContext, ExecClose, CloseCallback, nullptr, TCP_CLOSE_NAME);
659 }
660
GetRemoteAddress(napi_env env,napi_callback_info info)661 napi_value SocketModuleExports::TCPSocket::GetRemoteAddress(napi_env env, napi_callback_info info)
662 {
663 return SOCKET_INTERFACE(GetRemoteAddressContext, ExecGetRemoteAddress, GetRemoteAddressCallback, nullptr,
664 TCP_GET_REMOTE_ADDRESS);
665 }
666
GetState(napi_env env,napi_callback_info info)667 napi_value SocketModuleExports::TCPSocket::GetState(napi_env env, napi_callback_info info)
668 {
669 return SOCKET_INTERFACE(GetStateContext, ExecGetState, GetStateCallback, nullptr, TCP_GET_STATE);
670 }
671
SetExtraOptions(napi_env env,napi_callback_info info)672 napi_value SocketModuleExports::TCPSocket::SetExtraOptions(napi_env env, napi_callback_info info)
673 {
674 return SOCKET_INTERFACE(TcpSetExtraOptionsContext, ExecTcpSetExtraOptions, TcpSetExtraOptionsCallback, nullptr,
675 TCP_SET_EXTRA_OPTIONS_NAME);
676 }
677
GetSocketFd(napi_env env,napi_callback_info info)678 napi_value SocketModuleExports::TCPSocket::GetSocketFd(napi_env env, napi_callback_info info)
679 {
680 return SOCKET_INTERFACE(GetSocketFdContext, ExecTcpGetSocketFd, TcpGetSocketFdCallback, nullptr, TCP_GET_SOCKET_FD);
681 }
682
On(napi_env env,napi_callback_info info)683 napi_value SocketModuleExports::TCPSocket::On(napi_env env, napi_callback_info info)
684 {
685 return ModuleTemplate::On(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE}, false);
686 }
687
Off(napi_env env,napi_callback_info info)688 napi_value SocketModuleExports::TCPSocket::Off(napi_env env, napi_callback_info info)
689 {
690 return ModuleTemplate::Off(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE});
691 }
692
693 /* tcp connection async works */
Send(napi_env env,napi_callback_info info)694 napi_value SocketModuleExports::TCPConnection::Send(napi_env env, napi_callback_info info)
695 {
696 return SOCKET_INTERFACE(
697 TcpServerSendContext, ExecTcpConnectionSend, TcpConnectionSendCallback,
698 [](napi_env theEnv, napi_value thisVal, TcpServerSendContext *context) -> bool {
699 context->clientId_ = NapiUtils::GetInt32Property(theEnv, thisVal, PROPERTY_CLIENT_ID);
700 return true;
701 },
702 TCP_CONNECTION_SEND_NAME);
703 }
704
Close(napi_env env,napi_callback_info info)705 napi_value SocketModuleExports::TCPConnection::Close(napi_env env, napi_callback_info info)
706 {
707 return SOCKET_INTERFACE(
708 TcpServerCloseContext, ExecTcpConnectionClose, TcpConnectionCloseCallback,
709 [](napi_env theEnv, napi_value thisVal, TcpServerCloseContext *context) -> bool {
710 context->clientId_ = NapiUtils::GetInt32Property(theEnv, thisVal, PROPERTY_CLIENT_ID);
711 return true;
712 },
713 TCP_CONNECTION_CLOSE_NAME);
714 }
715
GetRemoteAddress(napi_env env,napi_callback_info info)716 napi_value SocketModuleExports::TCPConnection::GetRemoteAddress(napi_env env, napi_callback_info info)
717 {
718 return SOCKET_INTERFACE(
719 TcpServerGetRemoteAddressContext, ExecTcpConnectionGetRemoteAddress, TcpConnectionGetRemoteAddressCallback,
720 [](napi_env theEnv, napi_value thisVal, TcpServerGetRemoteAddressContext *context) -> bool {
721 context->clientId_ = NapiUtils::GetInt32Property(theEnv, thisVal, PROPERTY_CLIENT_ID);
722 return true;
723 },
724 TCP_CONNECTION_GET_REMOTE_ADDRESS);
725 }
726
On(napi_env env,napi_callback_info info)727 napi_value SocketModuleExports::TCPConnection::On(napi_env env, napi_callback_info info)
728 {
729 napi_value ret = ModuleTemplate::On(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE}, false);
730 SocketExec::NotifyRegisterEvent();
731 return ret;
732 }
733
Off(napi_env env,napi_callback_info info)734 napi_value SocketModuleExports::TCPConnection::Off(napi_env env, napi_callback_info info)
735 {
736 return ModuleTemplate::Off(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE});
737 }
738
739 /* tcp server async works */
Listen(napi_env env,napi_callback_info info)740 napi_value SocketModuleExports::TCPServerSocket::Listen(napi_env env, napi_callback_info info)
741 {
742 return SOCKET_INTERFACE(TcpServerListenContext, ExecTcpServerListen, ListenCallback, MakeTcpServerSocket,
743 TCP_SERVER_LISTEN_NAME);
744 }
745
GetState(napi_env env,napi_callback_info info)746 napi_value SocketModuleExports::TCPServerSocket::GetState(napi_env env, napi_callback_info info)
747 {
748 return SOCKET_INTERFACE(TcpServerGetStateContext, ExecTcpServerGetState, TcpServerGetStateCallback, nullptr,
749 TCP_SERVER_GET_STATE);
750 }
751
SetExtraOptions(napi_env env,napi_callback_info info)752 napi_value SocketModuleExports::TCPServerSocket::SetExtraOptions(napi_env env, napi_callback_info info)
753 {
754 return SOCKET_INTERFACE(TcpServerSetExtraOptionsContext, ExecTcpServerSetExtraOptions,
755 TcpServerSetExtraOptionsCallback, nullptr, TCP_SERVER_SET_EXTRA_OPTIONS_NAME);
756 }
757
On(napi_env env,napi_callback_info info)758 napi_value SocketModuleExports::TCPServerSocket::On(napi_env env, napi_callback_info info)
759 {
760 return ModuleTemplate::On(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE}, false);
761 }
762
Off(napi_env env,napi_callback_info info)763 napi_value SocketModuleExports::TCPServerSocket::Off(napi_env env, napi_callback_info info)
764 {
765 return ModuleTemplate::Off(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE});
766 }
767
768 /* local socket */
Bind(napi_env env,napi_callback_info info)769 napi_value SocketModuleExports::LocalSocket::Bind(napi_env env, napi_callback_info info)
770 {
771 return SOCKET_INTERFACE(LocalSocketBindContext, ExecLocalSocketBind, LocalSocketBindCallback, MakeLocalSocketBind,
772 LOCAL_SOCKET_BIND);
773 }
774
Connect(napi_env env,napi_callback_info info)775 napi_value SocketModuleExports::LocalSocket::Connect(napi_env env, napi_callback_info info)
776 {
777 return SOCKET_INTERFACE(LocalSocketConnectContext, ExecLocalSocketConnect, LocalSocketConnectCallback,
778 MakeLocalSocketConnect, LOCAL_SOCKET_CONNECT);
779 }
780
Send(napi_env env,napi_callback_info info)781 napi_value SocketModuleExports::LocalSocket::Send(napi_env env, napi_callback_info info)
782 {
783 return ModuleTemplate::InterfaceWithOutAsyncWork<LocalSocketSendContext>(
784 env, info,
785 [](napi_env, napi_value, LocalSocketSendContext *context) -> bool {
786 SocketAsyncWork::ExecLocalSocketSend(context->GetEnv(), context);
787 return true;
788 },
789 LOCAL_SOCKET_SEND, SocketAsyncWork::ExecLocalSocketSend, SocketAsyncWork::LocalSocketSendCallback);
790 }
791
Close(napi_env env,napi_callback_info info)792 napi_value SocketModuleExports::LocalSocket::Close(napi_env env, napi_callback_info info)
793 {
794 return SOCKET_INTERFACE(LocalSocketCloseContext, ExecLocalSocketClose, LocalSocketCloseCallback, nullptr,
795 LOCAL_SOCKET_CLOSE);
796 }
797
GetState(napi_env env,napi_callback_info info)798 napi_value SocketModuleExports::LocalSocket::GetState(napi_env env, napi_callback_info info)
799 {
800 return SOCKET_INTERFACE(LocalSocketGetStateContext, ExecLocalSocketGetState, LocalSocketGetStateCallback, nullptr,
801 LOCAL_SOCKET_GET_STATE);
802 }
803
GetSocketFd(napi_env env,napi_callback_info info)804 napi_value SocketModuleExports::LocalSocket::GetSocketFd(napi_env env, napi_callback_info info)
805 {
806 return SOCKET_INTERFACE(LocalSocketGetSocketFdContext, ExecLocalSocketGetSocketFd, LocalSocketGetSocketFdCallback,
807 nullptr, LOCAL_SOCKET_GET_SOCKET_FD);
808 }
809
SetExtraOptions(napi_env env,napi_callback_info info)810 napi_value SocketModuleExports::LocalSocket::SetExtraOptions(napi_env env, napi_callback_info info)
811 {
812 return SOCKET_INTERFACE(LocalSocketSetExtraOptionsContext, ExecLocalSocketSetExtraOptions,
813 LocalSocketSetExtraOptionsCallback, nullptr, LOCAL_SOCKET_SET_EXTRA_OPTIONS);
814 }
815
GetExtraOptions(napi_env env,napi_callback_info info)816 napi_value SocketModuleExports::LocalSocket::GetExtraOptions(napi_env env, napi_callback_info info)
817 {
818 return SOCKET_INTERFACE(LocalSocketGetExtraOptionsContext, ExecLocalSocketGetExtraOptions,
819 LocalSocketGetExtraOptionsCallback, nullptr, LOCAL_SOCKET_GET_EXTRA_OPTIONS);
820 }
821
On(napi_env env,napi_callback_info info)822 napi_value SocketModuleExports::LocalSocket::On(napi_env env, napi_callback_info info)
823 {
824 return ModuleTemplate::On(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE}, false);
825 }
826
Off(napi_env env,napi_callback_info info)827 napi_value SocketModuleExports::LocalSocket::Off(napi_env env, napi_callback_info info)
828 {
829 return ModuleTemplate::Off(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE});
830 }
831
832 /* local socket server */
Listen(napi_env env,napi_callback_info info)833 napi_value SocketModuleExports::LocalSocketServer::Listen(napi_env env, napi_callback_info info)
834 {
835 return SOCKET_INTERFACE(LocalSocketServerListenContext, ExecLocalSocketServerListen,
836 LocalSocketServerListenCallback, MakeLocalServerSocket, LOCAL_SOCKET_SERVER_LISTEN);
837 }
838
GetState(napi_env env,napi_callback_info info)839 napi_value SocketModuleExports::LocalSocketServer::GetState(napi_env env, napi_callback_info info)
840 {
841 return SOCKET_INTERFACE(LocalSocketServerGetStateContext, ExecLocalSocketServerGetState,
842 LocalSocketServerGetStateCallback, nullptr, LOCAL_SOCKET_SERVER_GET_STATE);
843 }
844
SetExtraOptions(napi_env env,napi_callback_info info)845 napi_value SocketModuleExports::LocalSocketServer::SetExtraOptions(napi_env env, napi_callback_info info)
846 {
847 return SOCKET_INTERFACE(LocalSocketServerSetExtraOptionsContext, ExecLocalSocketServerSetExtraOptions,
848 LocalSocketServerSetExtraOptionsCallback, nullptr, LOCAL_SOCKET_SERVER_SET_EXTRA_OPTIONS);
849 }
850
GetExtraOptions(napi_env env,napi_callback_info info)851 napi_value SocketModuleExports::LocalSocketServer::GetExtraOptions(napi_env env, napi_callback_info info)
852 {
853 return SOCKET_INTERFACE(LocalSocketServerGetExtraOptionsContext, ExecLocalSocketServerGetExtraOptions,
854 LocalSocketServerGetExtraOptionsCallback, nullptr, LOCAL_SOCKET_SERVER_GET_EXTRA_OPTIONS);
855 }
856
On(napi_env env,napi_callback_info info)857 napi_value SocketModuleExports::LocalSocketServer::On(napi_env env, napi_callback_info info)
858 {
859 return ModuleTemplate::On(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE}, false);
860 }
861
Off(napi_env env,napi_callback_info info)862 napi_value SocketModuleExports::LocalSocketServer::Off(napi_env env, napi_callback_info info)
863 {
864 return ModuleTemplate::Off(env, info, {EVENT_MESSAGE, EVENT_LISTENING, EVENT_ERROR, EVENT_CLOSE});
865 }
866
867 /* localsocket connection */
Send(napi_env env,napi_callback_info info)868 napi_value SocketModuleExports::LocalSocketConnection::Send(napi_env env, napi_callback_info info)
869 {
870 return SOCKET_INTERFACE(
871 LocalSocketServerSendContext, ExecLocalSocketConnectionSend, LocalSocketConnectionSendCallback,
872 [](napi_env theEnv, napi_value thisVal, LocalSocketServerSendContext *context) -> bool {
873 context->SetClientId(NapiUtils::GetInt32Property(theEnv, thisVal, PROPERTY_CLIENT_ID));
874 return true;
875 },
876 LOCAL_SOCKET_CONNECTION_SEND);
877 }
878
Close(napi_env env,napi_callback_info info)879 napi_value SocketModuleExports::LocalSocketConnection::Close(napi_env env, napi_callback_info info)
880 {
881 return SOCKET_INTERFACE(
882 LocalSocketServerCloseContext, ExecLocalSocketConnectionClose, LocalSocketConnectionCloseCallback,
883 [](napi_env theEnv, napi_value thisVal, LocalSocketServerCloseContext *context) -> bool {
884 context->SetClientId(NapiUtils::GetInt32Property(theEnv, thisVal, PROPERTY_CLIENT_ID));
885 return true;
886 },
887 LOCAL_SOCKET_CONNECTION_CLOSE);
888 }
889
On(napi_env env,napi_callback_info info)890 napi_value SocketModuleExports::LocalSocketConnection::On(napi_env env, napi_callback_info info)
891 {
892 napi_value thisVal = nullptr;
893 size_t paramsCount = MAX_PARAM_NUM;
894 napi_value params[MAX_PARAM_NUM] = {nullptr};
895 NAPI_CALL(env, napi_get_cb_info(env, info, ¶msCount, params, &thisVal, nullptr));
896
897 if (paramsCount != PARAM_COUNT_TWO || NapiUtils::GetValueType(env, params[0]) != napi_string ||
898 NapiUtils::GetValueType(env, params[PARAM_COUNT_TWO - 1]) != napi_function) {
899 NETSTACK_LOGE("localsocket connection on, err param");
900 napi_throw_error(env, std::to_string(PARSE_ERROR_CODE).c_str(), PARSE_ERROR_MSG);
901 return NapiUtils::GetUndefined(env);
902 }
903 std::initializer_list<std::string> events = {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE};
904 std::string event = NapiUtils::GetStringFromValueUtf8(env, params[0]);
905 if (std::find(events.begin(), events.end(), event) == events.end()) {
906 return NapiUtils::GetUndefined(env);
907 }
908 EventManager *manager = nullptr;
909 napi_unwrap(env, thisVal, reinterpret_cast<void **>(&manager));
910 if (manager == nullptr) {
911 NETSTACK_LOGE("failed to unwrap");
912 return NapiUtils::GetUndefined(env);
913 }
914 manager->AddListener(env, event, params[PARAM_COUNT_TWO - 1], false, false);
915 if (event == EVENT_MESSAGE) {
916 if (auto mgr = reinterpret_cast<LocalSocketExec::LocalSocketConnectionData *>(manager->GetData());
917 mgr != nullptr) {
918 mgr->serverManager_->NotifyRegisterEvent();
919 }
920 }
921 return NapiUtils::GetUndefined(env);
922 }
923
Off(napi_env env,napi_callback_info info)924 napi_value SocketModuleExports::LocalSocketConnection::Off(napi_env env, napi_callback_info info)
925 {
926 return ModuleTemplate::Off(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE});
927 }
928
929 static napi_module g_socketModule = {
930 .nm_version = 1,
931 .nm_flags = 0,
932 .nm_filename = nullptr,
933 .nm_register_func = SocketModuleExports::InitSocketModule,
934 .nm_modname = SOCKET_MODULE_NAME,
935 .nm_priv = nullptr,
936 .reserved = {nullptr},
937 };
938 /*
939 * Module register function
940 */
RegisterSocketModule(void)941 extern "C" __attribute__((constructor)) void RegisterSocketModule(void)
942 {
943 napi_module_register(&g_socketModule);
944 }
945 } // namespace OHOS::NetStack::Socket
946