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