• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "websocket_module.h"
17 
18 #include "constant.h"
19 #include "netstack_log.h"
20 #include "module_template.h"
21 #include "netstack_common_utils.h"
22 #include "websocket_async_work.h"
23 
24 namespace OHOS::NetStack::Websocket {
25 static bool g_appIsAtomicService = false;
26 static std::once_flag g_isAtomicServiceFlag;
27 static std::string g_appBundleName;
28 
InitWebSocketModule(napi_env env,napi_value exports)29 napi_value WebSocketModule::InitWebSocketModule(napi_env env, napi_value exports)
30 {
31     DefineWebSocketClass(env, exports);
32 #ifdef NETSTACK_WEBSOCKETSERVER
33     DefineWebSocketServerClass(env, exports);
34 #endif
35     InitWebSocketProperties(env, exports);
36     NapiUtils::SetEnvValid(env);
37     std::call_once(g_isAtomicServiceFlag, []() {
38         g_appIsAtomicService = CommonUtils::IsAtomicService(g_appBundleName);
39         NETSTACK_LOGI("IsAtomicService  bundleName is %{public}s, isAtomicService is %{public}d",
40             g_appBundleName.c_str(), g_appIsAtomicService);
41     });
42     auto envWrapper = new (std::nothrow)napi_env;
43     if (envWrapper == nullptr) {
44         return exports;
45     }
46     *envWrapper = env;
47     napi_add_env_cleanup_hook(env, NapiUtils::HookForEnvCleanup, envWrapper);
48     return exports;
49 }
50 
CreateWebSocket(napi_env env,napi_callback_info info)51 napi_value WebSocketModule::CreateWebSocket(napi_env env, napi_callback_info info)
52 {
53     return ModuleTemplate::NewInstanceWithSharedManager(env, info, INTERFACE_WEB_SOCKET, FinalizeWebSocketInstance);
54 }
55 
CreateWebSocketServer(napi_env env,napi_callback_info info)56 napi_value WebSocketModule::CreateWebSocketServer(napi_env env, napi_callback_info info)
57 {
58 #ifdef NETSTACK_WEBSOCKETSERVER
59     return ModuleTemplate::NewInstanceWithSharedManager(env, info, INTERFACE_WEB_SOCKET_SERVER,
60         FinalizeWebSocketInstance);
61 #else
62     return nullptr;
63 #endif
64 }
65 
DefineWebSocketClass(napi_env env,napi_value exports)66 void WebSocketModule::DefineWebSocketClass(napi_env env, napi_value exports)
67 {
68     std::initializer_list<napi_property_descriptor> properties = {
69         DECLARE_NAPI_FUNCTION(WebSocket::FUNCTION_CONNECT, WebSocket::Connect),
70         DECLARE_NAPI_FUNCTION(WebSocket::FUNCTION_SEND, WebSocket::Send),
71         DECLARE_NAPI_FUNCTION(WebSocket::FUNCTION_CLOSE, WebSocket::Close),
72         DECLARE_NAPI_FUNCTION(WebSocket::FUNCTION_ON, WebSocket::On),
73         DECLARE_NAPI_FUNCTION(WebSocket::FUNCTION_OFF, WebSocket::Off),
74     };
75     ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_WEB_SOCKET);
76 }
77 
78 #ifdef NETSTACK_WEBSOCKETSERVER
DefineWebSocketServerClass(napi_env env,napi_value exports)79 void WebSocketModule::DefineWebSocketServerClass(napi_env env, napi_value exports)
80 {
81     std::initializer_list<napi_property_descriptor> properties = {
82         DECLARE_NAPI_FUNCTION(WebSocketServer::FUNCTION_START, WebSocketServer::Start),
83         DECLARE_NAPI_FUNCTION(WebSocketServer::FUNCTION_LISTALLCONNECTIONS, WebSocketServer::ListAllConnections),
84         DECLARE_NAPI_FUNCTION(WebSocketServer::FUNCTION_CLOSE, WebSocketServer::Close),
85         DECLARE_NAPI_FUNCTION(WebSocketServer::FUNCTION_ON, WebSocketServer::On),
86         DECLARE_NAPI_FUNCTION(WebSocketServer::FUNCTION_OFF, WebSocketServer::Off),
87         DECLARE_NAPI_FUNCTION(WebSocketServer::FUNCTION_SEND, WebSocketServer::Send),
88         DECLARE_NAPI_FUNCTION(WebSocketServer::FUNCTION_STOP, WebSocketServer::Stop),
89     };
90     ModuleTemplate::DefineClass(env, exports, properties, INTERFACE_WEB_SOCKET_SERVER);
91 }
92 #endif
93 
InitWebSocketProperties(napi_env env,napi_value exports)94 void WebSocketModule::InitWebSocketProperties(napi_env env, napi_value exports)
95 {
96     std::initializer_list<napi_property_descriptor> properties = {
97         DECLARE_NAPI_FUNCTION(FUNCTION_CREATE_WEB_SOCKET, CreateWebSocket),
98         DECLARE_NAPI_FUNCTION(FUNCTION_CREATE_WEB_SOCKET_SERVER, CreateWebSocketServer),
99     };
100     NapiUtils::DefineProperties(env, exports, properties);
101 }
102 
FinalizeWebSocketInstance(napi_env env,void * data,void * hint)103 void WebSocketModule::FinalizeWebSocketInstance(napi_env env, void *data, void *hint)
104 {
105     NETSTACK_LOGI("websocket handle is finalized");
106     auto sharedManager = reinterpret_cast<std::shared_ptr<EventManager> *>(data);
107     delete sharedManager;
108 }
109 
Connect(napi_env env,napi_callback_info info)110 napi_value WebSocketModule::WebSocket::Connect(napi_env env, napi_callback_info info)
111 {
112     return ModuleTemplate::InterfaceWithSharedManager<ConnectContext>(
113         env, info, "WebSocketConnect",
114         [](napi_env, napi_value, ConnectContext *context) -> bool {
115             context->SetAtomicService(g_appIsAtomicService);
116             context->SetBundleName(g_appBundleName);
117             return true;
118         },
119         WebSocketAsyncWork::ExecConnect, WebSocketAsyncWork::ConnectCallback);
120 }
121 
Send(napi_env env,napi_callback_info info)122 napi_value WebSocketModule::WebSocket::Send(napi_env env, napi_callback_info info)
123 {
124     return ModuleTemplate::InterfaceWithSharedManager<SendContext>(
125         env, info, "WebSocketSend", nullptr, WebSocketAsyncWork::ExecSend, WebSocketAsyncWork::SendCallback);
126 }
127 
Close(napi_env env,napi_callback_info info)128 napi_value WebSocketModule::WebSocket::Close(napi_env env, napi_callback_info info)
129 {
130     return ModuleTemplate::InterfaceWithSharedManager<CloseContext>(
131         env, info, "WebSocketClose", nullptr, WebSocketAsyncWork::ExecClose, WebSocketAsyncWork::CloseCallback);
132 }
133 
On(napi_env env,napi_callback_info info)134 napi_value WebSocketModule::WebSocket::On(napi_env env, napi_callback_info info)
135 {
136     ModuleTemplate::OnSharedManager(env, info,
137                                     {EventName::EVENT_OPEN, EventName::EVENT_MESSAGE, EventName::EVENT_CLOSE}, true);
138     return ModuleTemplate::OnSharedManager(
139         env, info, {EventName::EVENT_ERROR, EventName::EVENT_HEADER_RECEIVE, EventName::EVENT_DATA_END}, false);
140 }
141 
Off(napi_env env,napi_callback_info info)142 napi_value WebSocketModule::WebSocket::Off(napi_env env, napi_callback_info info)
143 {
144     return ModuleTemplate::OffSharedManager(env, info,
145                                             {EventName::EVENT_OPEN, EventName::EVENT_MESSAGE, EventName::EVENT_CLOSE,
146                                              EventName::EVENT_ERROR, EventName::EVENT_DATA_END,
147                                              EventName::EVENT_HEADER_RECEIVE});
148 }
149 
150 #ifdef NETSTACK_WEBSOCKETSERVER
Start(napi_env env,napi_callback_info info)151 napi_value WebSocketModule::WebSocketServer::Start(napi_env env, napi_callback_info info)
152 {
153     return ModuleTemplate::InterfaceWithSharedManager<ServerStartContext>(
154         env, info, "WebSocketServerStart", nullptr, WebSocketAsyncWork::ExecServerStart,
155             WebSocketAsyncWork::ServerStartCallback);
156 }
157 
ListAllConnections(napi_env env,napi_callback_info info)158 napi_value WebSocketModule::WebSocketServer::ListAllConnections(napi_env env, napi_callback_info info)
159 {
160     return ModuleTemplate::InterfaceWithSharedManager<ListAllConnectionsContext>(
161         env, info, "WebSocketServerListAllConnections", nullptr, WebSocketAsyncWork::ExecListAllConnections,
162             WebSocketAsyncWork::ListAllConnectionsCallback);
163 }
164 
Close(napi_env env,napi_callback_info info)165 napi_value WebSocketModule::WebSocketServer::Close(napi_env env, napi_callback_info info)
166 {
167     return ModuleTemplate::InterfaceWithSharedManager<ServerCloseContext>(
168         env, info, "WebSocketServerClose", nullptr, WebSocketAsyncWork::ExecServerClose,
169             WebSocketAsyncWork::ServerCloseCallback);
170 }
171 
Send(napi_env env,napi_callback_info info)172 napi_value WebSocketModule::WebSocketServer::Send(napi_env env, napi_callback_info info)
173 {
174     return ModuleTemplate::InterfaceWithSharedManager<ServerSendContext>(
175         env, info, "WebSocketServerSend", nullptr, WebSocketAsyncWork::ExecServerSend,
176             WebSocketAsyncWork::ServerSendCallback);
177 }
178 
Stop(napi_env env,napi_callback_info info)179 napi_value WebSocketModule::WebSocketServer::Stop(napi_env env, napi_callback_info info)
180 {
181     return ModuleTemplate::InterfaceWithSharedManager<ServerStopContext>(
182         env, info, "WebSocketServerStop", nullptr, WebSocketAsyncWork::ExecServerStop,
183             WebSocketAsyncWork::ServerStopCallback);
184 }
185 
On(napi_env env,napi_callback_info info)186 napi_value WebSocketModule::WebSocketServer::On(napi_env env, napi_callback_info info)
187 {
188     return ModuleTemplate::OnSharedManager(env, info,
189         {EventName::EVENT_SERVER_CONNECT, EventName::EVENT_SERVER_MESSAGE_RECEIVE,
190         EventName::EVENT_SERVER_ERROR, EventName::EVENT_SERVER_CLOSE}, false);
191 }
192 
Off(napi_env env,napi_callback_info info)193 napi_value WebSocketModule::WebSocketServer::Off(napi_env env, napi_callback_info info)
194 {
195     return ModuleTemplate::OffSharedManager(env, info,
196         {EventName::EVENT_SERVER_ERROR, EventName::EVENT_SERVER_CONNECT,
197          EventName::EVENT_SERVER_CLOSE, EventName::EVENT_SERVER_MESSAGE_RECEIVE});
198 }
199 #endif
200 
201 static napi_module g_websocketModule = {
202     .nm_version = 1,
203     .nm_flags = 0,
204     .nm_filename = nullptr,
205     .nm_register_func = WebSocketModule::InitWebSocketModule,
206     .nm_modname = "net.webSocket",
207     .nm_priv = nullptr,
208     .reserved = {nullptr},
209 };
210 
RegisterWebSocketModule(void)211 extern "C" __attribute__((constructor)) void RegisterWebSocketModule(void)
212 {
213     napi_module_register(&g_websocketModule);
214 }
215 } // namespace OHOS::NetStack::Websocket
216