• 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 "module_template.h"
31 #include "napi/native_api.h"
32 #include "napi/native_common.h"
33 #include "napi_utils.h"
34 #include "net_address.h"
35 #include "netstack_common_utils.h"
36 #include "netstack_log.h"
37 #include "node_api.h"
38 #include "socket_async_work.h"
39 #include "socket_exec.h"
40 #include "tcp_extra_context.h"
41 #include "tcp_send_context.h"
42 #include "tcp_server_common_context.h"
43 #include "tcp_server_extra_context.h"
44 #include "tcp_server_listen_context.h"
45 #include "tcp_server_send_context.h"
46 #include "tlssocket_module.h"
47 #if !defined(CROSS_PLATFORM)
48 #include "tlssocketserver_module.h"
49 #endif
50 #include "udp_extra_context.h"
51 #include "udp_send_context.h"
52 
53 static constexpr const char *SOCKET_MODULE_NAME = "net.socket";
54 
55 static const char *UDP_BIND_NAME = "UdpBind";
56 static const char *UDP_SEND_NAME = "UdpSend";
57 static const char *UDP_CLOSE_NAME = "UdpClose";
58 static const char *UDP_GET_STATE = "UdpGetState";
59 static const char *UDP_SET_EXTRA_OPTIONS_NAME = "UdpSetExtraOptions";
60 static constexpr const char *UDP_GET_SOCKET_FD = "UdpGetSocketFd";
61 
62 static const char *TCP_BIND_NAME = "TcpBind";
63 static const char *TCP_CONNECT_NAME = "TcpConnect";
64 static const char *TCP_SEND_NAME = "TcpSend";
65 static const char *TCP_CLOSE_NAME = "TcpClose";
66 static const char *TCP_GET_STATE = "TcpGetState";
67 static const char *TCP_GET_REMOTE_ADDRESS = "TcpGetRemoteAddress";
68 static const char *TCP_SET_EXTRA_OPTIONS_NAME = "TcpSetExtraOptions";
69 static constexpr const char *TCP_GET_SOCKET_FD = "TcpGetSocketFd";
70 
71 static constexpr const char *TCP_SERVER_LISTEN_NAME = "TcpServerListen";
72 static constexpr const char *TCP_SERVER_GET_STATE = "TcpServerGetState";
73 static constexpr const char *TCP_SERVER_SET_EXTRA_OPTIONS_NAME = "TcpServerSetExtraOptions";
74 
75 static constexpr const char *TCP_CONNECTION_SEND_NAME = "TcpConnectionSend";
76 static constexpr const char *TCP_CONNECTION_CLOSE_NAME = "TcpConnectionClose";
77 static constexpr const char *TCP_CONNECTION_GET_REMOTE_ADDRESS = "TcpConnectionGetRemoteAddress";
78 
79 static constexpr const char *KEY_SOCKET_FD = "socketFd";
80 
81 #define SOCKET_INTERFACE(Context, executor, callback, work, name) \
82     ModuleTemplate::Interface<Context>(env, info, name, work, SocketAsyncWork::executor, SocketAsyncWork::callback)
83 
84 namespace OHOS::NetStack::Socket {
Finalize(napi_env,void * data,void *)85 void Finalize(napi_env, void *data, void *)
86 {
87     NETSTACK_LOGI("socket handle is finalized");
88     auto manager = static_cast<EventManager *>(data);
89     if (manager != nullptr) {
90         int sock = static_cast<int>(reinterpret_cast<uint64_t>(manager->GetData()));
91         if (sock != 0) {
92             close(sock);
93         }
94         EventManager::SetInvalid(manager);
95     }
96 }
97 
SetSocket(napi_env env,napi_value thisVal,BaseContext * context,int sock)98 static bool SetSocket(napi_env env, napi_value thisVal, BaseContext *context, int sock)
99 {
100     if (sock < 0) {
101         napi_value error = NapiUtils::CreateObject(env);
102         if (NapiUtils::GetValueType(env, error) != napi_object) {
103             return false;
104         }
105         NapiUtils::SetUint32Property(env, error, KEY_ERROR_CODE, errno);
106         context->Emit(EVENT_ERROR, std::make_pair(NapiUtils::GetUndefined(env), error));
107         return false;
108     }
109 
110     EventManager *manager = nullptr;
111     if (napi_unwrap(env, thisVal, reinterpret_cast<void **>(&manager)) != napi_ok || manager == nullptr) {
112         return false;
113     }
114 
115     manager->SetData(reinterpret_cast<void *>(sock));
116     NapiUtils::SetInt32Property(env, thisVal, KEY_SOCKET_FD, sock);
117     return true;
118 }
119 
MakeTcpClientBindSocket(napi_env env,napi_value thisVal,BindContext * context)120 static bool MakeTcpClientBindSocket(napi_env env, napi_value thisVal, BindContext *context)
121 {
122     if (!context->IsParseOK()) {
123         context->SetErrorCode(PARSE_ERROR_CODE);
124         return false;
125     }
126     if (!CommonUtils::HasInternetPermission()) {
127         context->SetPermissionDenied(true);
128         return false;
129     }
130     NETSTACK_LOGD("bind ip family is %{public}d", context->address_.GetSaFamily());
131     if (context->GetManager()->GetData() != nullptr) {
132         NETSTACK_LOGE("tcp connect has been called");
133         return true;
134     }
135     int sock = SocketExec::MakeTcpSocket(context->address_.GetSaFamily());
136     if (!SetSocket(env, thisVal, context, sock)) {
137         return false;
138     }
139     context->SetExecOK(true);
140     return true;
141 }
142 
MakeTcpClientConnectSocket(napi_env env,napi_value thisVal,ConnectContext * context)143 static bool MakeTcpClientConnectSocket(napi_env env, napi_value thisVal, ConnectContext *context)
144 {
145     if (!context->IsParseOK()) {
146         context->SetErrorCode(PARSE_ERROR_CODE);
147         return false;
148     }
149     if (!CommonUtils::HasInternetPermission()) {
150         context->SetPermissionDenied(true);
151         return false;
152     }
153     NETSTACK_LOGD("connect ip family is %{public}d", context->options.address.GetSaFamily());
154     if (context->GetManager()->GetData() != nullptr) {
155         NETSTACK_LOGD("tcp bind has been called");
156         return true;
157     }
158     int sock = SocketExec::MakeTcpSocket(context->options.address.GetSaFamily());
159     if (!SetSocket(env, thisVal, context, sock)) {
160         return false;
161     }
162     context->SetExecOK(true);
163     return true;
164 }
165 
MakeTcpServerSocket(napi_env env,napi_value thisVal,TcpServerListenContext * context)166 static bool MakeTcpServerSocket(napi_env env, napi_value thisVal, TcpServerListenContext *context)
167 {
168     if (!context->IsParseOK()) {
169         context->SetErrorCode(PARSE_ERROR_CODE);
170         return false;
171     }
172     if (!CommonUtils::HasInternetPermission()) {
173         context->SetPermissionDenied(true);
174         return false;
175     }
176     int sock = SocketExec::MakeTcpSocket(context->address_.GetSaFamily());
177     if (!SetSocket(env, thisVal, context, sock)) {
178         return false;
179     }
180     context->SetExecOK(true);
181     return true;
182 }
183 
MakeUdpSocket(napi_env env,napi_value thisVal,BindContext * context)184 static bool MakeUdpSocket(napi_env env, napi_value thisVal, BindContext *context)
185 {
186     if (!context->IsParseOK()) {
187         context->SetErrorCode(PARSE_ERROR_CODE);
188         return false;
189     }
190     if (!CommonUtils::HasInternetPermission()) {
191         context->SetPermissionDenied(true);
192         return false;
193     }
194     int sock = SocketExec::MakeUdpSocket(context->address_.GetSaFamily());
195     if (!SetSocket(env, thisVal, context, sock)) {
196         return false;
197     }
198     context->SetExecOK(true);
199     return true;
200 }
201 
InitSocketModule(napi_env env,napi_value exports)202 napi_value SocketModuleExports::InitSocketModule(napi_env env, napi_value exports)
203 {
204     TlsSocket::TLSSocketModuleExports::InitTLSSocketModule(env, exports);
205 #if !defined(CROSS_PLATFORM)
206     TlsSocketServer::TLSSocketServerModuleExports::InitTLSSocketServerModule(env, exports);
207 #endif
208     DefineUDPSocketClass(env, exports);
209     DefineTCPServerSocketClass(env, exports);
210     DefineTCPSocketClass(env, exports);
211     InitSocketProperties(env, exports);
212 
213     return exports;
214 }
215 
ConstructUDPSocketInstance(napi_env env,napi_callback_info info)216 napi_value SocketModuleExports::ConstructUDPSocketInstance(napi_env env, napi_callback_info info)
217 {
218     return ModuleTemplate::NewInstance(env, info, INTERFACE_UDP_SOCKET, Finalize);
219 }
220 
DefineUDPSocketClass(napi_env env,napi_value exports)221 void SocketModuleExports::DefineUDPSocketClass(napi_env env, napi_value exports)
222 {
223     std::initializer_list<napi_property_descriptor> properties = {
224         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_BIND, UDPSocket::Bind),
225         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_SEND, UDPSocket::Send),
226         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_CLOSE, UDPSocket::Close),
227         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_GET_STATE, UDPSocket::GetState),
228         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_SET_EXTRA_OPTIONS, UDPSocket::SetExtraOptions),
229         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_GET_SOCKET_FD, UDPSocket::GetSocketFd),
230         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_ON, UDPSocket::On),
231         DECLARE_NAPI_FUNCTION(UDPSocket::FUNCTION_OFF, UDPSocket::Off),
232     };
233     ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_UDP_SOCKET);
234 }
235 
ConstructTCPSocketInstance(napi_env env,napi_callback_info info)236 napi_value SocketModuleExports::ConstructTCPSocketInstance(napi_env env, napi_callback_info info)
237 {
238     return ModuleTemplate::NewInstance(env, info, INTERFACE_TCP_SOCKET, Finalize);
239 }
240 
DefineTCPSocketClass(napi_env env,napi_value exports)241 void SocketModuleExports::DefineTCPSocketClass(napi_env env, napi_value exports)
242 {
243     std::initializer_list<napi_property_descriptor> properties = {
244         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_BIND, TCPSocket::Bind),
245         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_CONNECT, TCPSocket::Connect),
246         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_SEND, TCPSocket::Send),
247         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_CLOSE, TCPSocket::Close),
248         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_GET_REMOTE_ADDRESS, TCPSocket::GetRemoteAddress),
249         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_GET_STATE, TCPSocket::GetState),
250         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_SET_EXTRA_OPTIONS, TCPSocket::SetExtraOptions),
251         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_GET_SOCKET_FD, TCPSocket::GetSocketFd),
252         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_ON, TCPSocket::On),
253         DECLARE_NAPI_FUNCTION(TCPSocket::FUNCTION_OFF, TCPSocket::Off),
254     };
255     ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_TCP_SOCKET);
256 }
257 
ConstructTCPSocketServerInstance(napi_env env,napi_callback_info info)258 napi_value SocketModuleExports::ConstructTCPSocketServerInstance(napi_env env, napi_callback_info info)
259 {
260     return ModuleTemplate::NewInstance(env, info, INTERFACE_TCP_SOCKET_SERVER, Finalize);
261 }
262 
DefineTCPServerSocketClass(napi_env env,napi_value exports)263 void SocketModuleExports::DefineTCPServerSocketClass(napi_env env, napi_value exports)
264 {
265     std::initializer_list<napi_property_descriptor> properties = {
266         DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_LISTEN, TCPServerSocket::Listen),
267         DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_GET_STATE, TCPServerSocket::GetState),
268         DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_SET_EXTRA_OPTIONS, TCPServerSocket::SetExtraOptions),
269         DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_ON, TCPServerSocket::On),
270         DECLARE_NAPI_FUNCTION(TCPServerSocket::FUNCTION_OFF, TCPServerSocket::Off),
271     };
272     ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_TCP_SOCKET_SERVER);
273 }
274 
InitSocketProperties(napi_env env,napi_value exports)275 void SocketModuleExports::InitSocketProperties(napi_env env, napi_value exports)
276 {
277     std::initializer_list<napi_property_descriptor> properties = {
278         DECLARE_NAPI_FUNCTION(FUNCTION_CONSTRUCTOR_UDP_SOCKET_INSTANCE, ConstructUDPSocketInstance),
279         DECLARE_NAPI_FUNCTION(FUNCTION_CONSTRUCTOR_TCP_SOCKET_SERVER_INSTANCE, ConstructTCPSocketServerInstance),
280         DECLARE_NAPI_FUNCTION(FUNCTION_CONSTRUCTOR_TCP_SOCKET_INSTANCE, ConstructTCPSocketInstance),
281     };
282     NapiUtils::DefineProperties(env, exports, properties);
283 }
284 
285 /* udp async works */
Bind(napi_env env,napi_callback_info info)286 napi_value SocketModuleExports::UDPSocket::Bind(napi_env env, napi_callback_info info)
287 {
288     return SOCKET_INTERFACE(BindContext, ExecUdpBind, BindCallback, MakeUdpSocket, UDP_BIND_NAME);
289 }
290 
Send(napi_env env,napi_callback_info info)291 napi_value SocketModuleExports::UDPSocket::Send(napi_env env, napi_callback_info info)
292 {
293     return ModuleTemplate::InterfaceWithOutAsyncWork<UdpSendContext>(
294         env, info,
295         [](napi_env, napi_value, UdpSendContext *context) -> bool {
296 #ifdef ENABLE_EVENT_HANDLER
297             auto manager = context->GetManager();
298             if (!manager->InitNetstackEventHandler()) {
299                 return false;
300             }
301 #endif
302             SocketAsyncWork::ExecUdpSend(context->GetEnv(), context);
303             return true;
304         },
305         UDP_SEND_NAME, SocketAsyncWork::ExecUdpSend, SocketAsyncWork::UdpSendCallback);
306 }
307 
Close(napi_env env,napi_callback_info info)308 napi_value SocketModuleExports::UDPSocket::Close(napi_env env, napi_callback_info info)
309 {
310     return SOCKET_INTERFACE(CloseContext, ExecClose, CloseCallback, nullptr, UDP_CLOSE_NAME);
311 }
312 
GetState(napi_env env,napi_callback_info info)313 napi_value SocketModuleExports::UDPSocket::GetState(napi_env env, napi_callback_info info)
314 {
315     return SOCKET_INTERFACE(GetStateContext, ExecGetState, GetStateCallback, nullptr, UDP_GET_STATE);
316 }
317 
SetExtraOptions(napi_env env,napi_callback_info info)318 napi_value SocketModuleExports::UDPSocket::SetExtraOptions(napi_env env, napi_callback_info info)
319 {
320     return SOCKET_INTERFACE(UdpSetExtraOptionsContext, ExecUdpSetExtraOptions, UdpSetExtraOptionsCallback, nullptr,
321                             UDP_SET_EXTRA_OPTIONS_NAME);
322 }
323 
GetSocketFd(napi_env env,napi_callback_info info)324 napi_value SocketModuleExports::UDPSocket::GetSocketFd(napi_env env, napi_callback_info info)
325 {
326     return SOCKET_INTERFACE(GetSocketFdContext, ExecUdpGetSocketFd, UdpGetSocketFdCallback, nullptr, UDP_GET_SOCKET_FD);
327 }
328 
On(napi_env env,napi_callback_info info)329 napi_value SocketModuleExports::UDPSocket::On(napi_env env, napi_callback_info info)
330 {
331     return ModuleTemplate::On(env, info, {EVENT_MESSAGE, EVENT_LISTENING, EVENT_ERROR, EVENT_CLOSE}, false);
332 }
333 
Off(napi_env env,napi_callback_info info)334 napi_value SocketModuleExports::UDPSocket::Off(napi_env env, napi_callback_info info)
335 {
336     return ModuleTemplate::Off(env, info, {EVENT_MESSAGE, EVENT_LISTENING, EVENT_ERROR, EVENT_CLOSE});
337 }
338 
339 /* tcp async works */
Bind(napi_env env,napi_callback_info info)340 napi_value SocketModuleExports::TCPSocket::Bind(napi_env env, napi_callback_info info)
341 {
342     return SOCKET_INTERFACE(BindContext, ExecTcpBind, BindCallback, MakeTcpClientBindSocket, TCP_BIND_NAME);
343 }
344 
Connect(napi_env env,napi_callback_info info)345 napi_value SocketModuleExports::TCPSocket::Connect(napi_env env, napi_callback_info info)
346 {
347     return SOCKET_INTERFACE(ConnectContext, ExecConnect, ConnectCallback, MakeTcpClientConnectSocket, TCP_CONNECT_NAME);
348 }
349 
Send(napi_env env,napi_callback_info info)350 napi_value SocketModuleExports::TCPSocket::Send(napi_env env, napi_callback_info info)
351 {
352     return ModuleTemplate::InterfaceWithOutAsyncWork<TcpSendContext>(
353         env, info,
354         [](napi_env, napi_value, TcpSendContext *context) -> bool {
355 #ifdef ENABLE_EVENT_HANDLER
356             auto manager = context->GetManager();
357             if (!manager->InitNetstackEventHandler()) {
358                 return false;
359             }
360 #endif
361             SocketAsyncWork::ExecTcpSend(context->GetEnv(), context);
362             return true;
363         },
364         TCP_SEND_NAME, SocketAsyncWork::ExecTcpSend, SocketAsyncWork::TcpSendCallback);
365 }
366 
Close(napi_env env,napi_callback_info info)367 napi_value SocketModuleExports::TCPSocket::Close(napi_env env, napi_callback_info info)
368 {
369     return SOCKET_INTERFACE(CloseContext, ExecClose, CloseCallback, nullptr, TCP_CLOSE_NAME);
370 }
371 
GetRemoteAddress(napi_env env,napi_callback_info info)372 napi_value SocketModuleExports::TCPSocket::GetRemoteAddress(napi_env env, napi_callback_info info)
373 {
374     return SOCKET_INTERFACE(GetRemoteAddressContext, ExecGetRemoteAddress, GetRemoteAddressCallback, nullptr,
375                             TCP_GET_REMOTE_ADDRESS);
376 }
377 
GetState(napi_env env,napi_callback_info info)378 napi_value SocketModuleExports::TCPSocket::GetState(napi_env env, napi_callback_info info)
379 {
380     return SOCKET_INTERFACE(GetStateContext, ExecGetState, GetStateCallback, nullptr, TCP_GET_STATE);
381 }
382 
SetExtraOptions(napi_env env,napi_callback_info info)383 napi_value SocketModuleExports::TCPSocket::SetExtraOptions(napi_env env, napi_callback_info info)
384 {
385     return SOCKET_INTERFACE(TcpSetExtraOptionsContext, ExecTcpSetExtraOptions, TcpSetExtraOptionsCallback, nullptr,
386                             TCP_SET_EXTRA_OPTIONS_NAME);
387 }
388 
GetSocketFd(napi_env env,napi_callback_info info)389 napi_value SocketModuleExports::TCPSocket::GetSocketFd(napi_env env, napi_callback_info info)
390 {
391     return SOCKET_INTERFACE(GetSocketFdContext, ExecTcpGetSocketFd, TcpGetSocketFdCallback, nullptr, TCP_GET_SOCKET_FD);
392 }
393 
On(napi_env env,napi_callback_info info)394 napi_value SocketModuleExports::TCPSocket::On(napi_env env, napi_callback_info info)
395 {
396     return ModuleTemplate::On(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE}, false);
397 }
398 
Off(napi_env env,napi_callback_info info)399 napi_value SocketModuleExports::TCPSocket::Off(napi_env env, napi_callback_info info)
400 {
401     return ModuleTemplate::Off(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE});
402 }
403 
404 /* tcp connection async works */
Send(napi_env env,napi_callback_info info)405 napi_value SocketModuleExports::TCPConnection::Send(napi_env env, napi_callback_info info)
406 {
407     return SOCKET_INTERFACE(
408         TcpServerSendContext, ExecTcpConnectionSend, TcpConnectionSendCallback,
409         [](napi_env theEnv, napi_value thisVal, TcpServerSendContext *context) -> bool {
410             context->clientId_ = NapiUtils::GetInt32Property(theEnv, thisVal, PROPERTY_CLIENT_ID);
411             return true;
412         },
413         TCP_CONNECTION_SEND_NAME);
414 }
415 
Close(napi_env env,napi_callback_info info)416 napi_value SocketModuleExports::TCPConnection::Close(napi_env env, napi_callback_info info)
417 {
418     return SOCKET_INTERFACE(
419         TcpServerCloseContext, ExecTcpConnectionClose, TcpConnectionCloseCallback,
420         [](napi_env theEnv, napi_value thisVal, TcpServerCloseContext *context) -> bool {
421             context->clientId_ = NapiUtils::GetInt32Property(theEnv, thisVal, PROPERTY_CLIENT_ID);
422             return true;
423         },
424         TCP_CONNECTION_CLOSE_NAME);
425 }
426 
GetRemoteAddress(napi_env env,napi_callback_info info)427 napi_value SocketModuleExports::TCPConnection::GetRemoteAddress(napi_env env, napi_callback_info info)
428 {
429     return SOCKET_INTERFACE(
430         TcpServerGetRemoteAddressContext, ExecTcpConnectionGetRemoteAddress, TcpConnectionGetRemoteAddressCallback,
431         [](napi_env theEnv, napi_value thisVal, TcpServerGetRemoteAddressContext *context) -> bool {
432             context->clientId_ = NapiUtils::GetInt32Property(theEnv, thisVal, PROPERTY_CLIENT_ID);
433             return true;
434         },
435         TCP_CONNECTION_GET_REMOTE_ADDRESS);
436 }
437 
On(napi_env env,napi_callback_info info)438 napi_value SocketModuleExports::TCPConnection::On(napi_env env, napi_callback_info info)
439 {
440     return ModuleTemplate::On(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE}, false);
441 }
442 
Off(napi_env env,napi_callback_info info)443 napi_value SocketModuleExports::TCPConnection::Off(napi_env env, napi_callback_info info)
444 {
445     return ModuleTemplate::Off(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE});
446 }
447 
448 /* tcp server async works */
Listen(napi_env env,napi_callback_info info)449 napi_value SocketModuleExports::TCPServerSocket::Listen(napi_env env, napi_callback_info info)
450 {
451     return SOCKET_INTERFACE(TcpServerListenContext, ExecTcpServerListen, ListenCallback, MakeTcpServerSocket,
452                             TCP_SERVER_LISTEN_NAME);
453 }
454 
GetState(napi_env env,napi_callback_info info)455 napi_value SocketModuleExports::TCPServerSocket::GetState(napi_env env, napi_callback_info info)
456 {
457     return SOCKET_INTERFACE(TcpServerGetStateContext, ExecTcpServerGetState, TcpServerGetStateCallback, nullptr,
458                             TCP_SERVER_GET_STATE);
459 }
460 
SetExtraOptions(napi_env env,napi_callback_info info)461 napi_value SocketModuleExports::TCPServerSocket::SetExtraOptions(napi_env env, napi_callback_info info)
462 {
463     return SOCKET_INTERFACE(TcpServerSetExtraOptionsContext, ExecTcpServerSetExtraOptions,
464                             TcpServerSetExtraOptionsCallback, nullptr, TCP_SERVER_SET_EXTRA_OPTIONS_NAME);
465 }
466 
On(napi_env env,napi_callback_info info)467 napi_value SocketModuleExports::TCPServerSocket::On(napi_env env, napi_callback_info info)
468 {
469     return ModuleTemplate::On(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE}, false);
470 }
471 
Off(napi_env env,napi_callback_info info)472 napi_value SocketModuleExports::TCPServerSocket::Off(napi_env env, napi_callback_info info)
473 {
474     return ModuleTemplate::Off(env, info, {EVENT_MESSAGE, EVENT_CONNECT, EVENT_ERROR, EVENT_CLOSE});
475 }
476 
477 static napi_module g_socketModule = {
478     .nm_version = 1,
479     .nm_flags = 0,
480     .nm_filename = nullptr,
481     .nm_register_func = SocketModuleExports::InitSocketModule,
482     .nm_modname = SOCKET_MODULE_NAME,
483     .nm_priv = nullptr,
484     .reserved = {nullptr},
485 };
486 /*
487  * Module register function
488  */
RegisterSocketModule(void)489 extern "C" __attribute__((constructor)) void RegisterSocketModule(void)
490 {
491     napi_module_register(&g_socketModule);
492 }
493 } // namespace OHOS::NetStack::Socket
494