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