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