1 /*
2 * Copyright (c) 2025 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 "net_websocket_impl.h"
17
18 #include "netstack_log.h"
19 #include "net_websocket_exec.h"
20
21 namespace OHOS::NetStack::NetWebSocket {
Connect(std::string url,CWebSocketRequestOptions * opt,CJWebsocketProxy * websocketProxy)22 WebSocketConnectContext* CJWebsocketImpl::Connect(std::string url, CWebSocketRequestOptions *opt,
23 CJWebsocketProxy *websocketProxy)
24 {
25 auto context = new (std::nothrow) WebSocketConnectContext(nullptr);
26 if (context == nullptr) {
27 return nullptr;
28 }
29 context->SetWebsocketProxy(websocketProxy);
30 context->ParseParams(url, opt);
31 if (!context->IsParseOK()) {
32 // context.setxxx
33 return context;
34 }
35 NetWebSocketExec::ExecConnect(context);
36 return context;
37 }
38
Send(CArrUI8 data,CJWebsocketProxy * websocketProxy,bool stringType)39 WebSocketSendContext *CJWebsocketImpl::Send(CArrUI8 data, CJWebsocketProxy *websocketProxy, bool stringType)
40 {
41 auto context = new (std::nothrow) WebSocketSendContext(nullptr);
42 if (context == nullptr) {
43 return nullptr;
44 }
45 context->SetWebsocketProxy(websocketProxy);
46 context->ParseParams(data, stringType);
47 if (!context->IsParseOK()) {
48 // context.setxxx
49 return context;
50 }
51 NetWebSocketExec::ExecSend(context);
52 return context;
53 }
54
Close(CWebSocketCloseOptions * opt,CJWebsocketProxy * websocketProxy)55 WebSocketCloseContext *CJWebsocketImpl::Close(CWebSocketCloseOptions *opt, CJWebsocketProxy *websocketProxy)
56 {
57 auto context = new (std::nothrow) WebSocketCloseContext(nullptr);
58 if (context == nullptr) {
59 return nullptr;
60 }
61 context->SetWebsocketProxy(websocketProxy);
62 context->ParseParams(opt);
63 if (!context->IsParseOK()) {
64 // context.setxxx
65 return context;
66 }
67 NetWebSocketExec::ExecClose(context);
68 return context;
69 }
70
OnWithProxy(int32_t typeId,void (* callback)(CWebSocketCallbackData * data),CJWebsocketProxy * websocketProxy)71 bool CJWebsocketImpl::OnWithProxy(int32_t typeId, void (*callback)(CWebSocketCallbackData *data),
72 CJWebsocketProxy *websocketProxy)
73 {
74 websocketProxy->AddCallback2Map(typeId, CJLambda::Create(callback));
75 return true;
76 }
77
OffWithProxy(int32_t typeId,CJWebsocketProxy * websocketProxy)78 bool CJWebsocketImpl::OffWithProxy(int32_t typeId, CJWebsocketProxy *websocketProxy)
79 {
80 websocketProxy->DelCallback(typeId);
81 return true;
82 }
83
GetWebSocketContext()84 std::shared_ptr<NetWebSocket::WebSocketContext> CJWebsocketProxy::GetWebSocketContext()
85 {
86 std::lock_guard<std::mutex> lock(contextMutex_);
87 return webSocketContext_;
88 }
89
SetWebSocketContext(const std::shared_ptr<NetWebSocket::WebSocketContext> & websocketContext)90 void CJWebsocketProxy::SetWebSocketContext(const std::shared_ptr<NetWebSocket::WebSocketContext> &websocketContext)
91 {
92 std::lock_guard<std::mutex> lock(contextMutex_);
93 webSocketContext_ = websocketContext;
94 }
95
EmitCallBack(CWebSocketCallbackData * data)96 void CJWebsocketProxy::EmitCallBack(CWebSocketCallbackData *data)
97 {
98 auto callback = FindCallback(data->typeId);
99 if (callback == std::nullopt) {
100 NETSTACK_LOGI("EmitCallBack failed, %{public}d not find.", data->typeId);
101 return;
102 }
103 callback.value()(data);
104 }
105
GetWebSocketTextData()106 const std::string &CJWebsocketProxy::GetWebSocketTextData()
107 {
108 return webSocketTextData_;
109 }
110
AppendWebSocketTextData(void * data,size_t length)111 void CJWebsocketProxy::AppendWebSocketTextData(void *data, size_t length)
112 {
113 webSocketTextData_.append(reinterpret_cast<char *>(data), length);
114 }
115
GetWebSocketBinaryData()116 const std::string &CJWebsocketProxy::GetWebSocketBinaryData()
117 {
118 return webSocketBinaryData_;
119 }
120
AppendWebSocketBinaryData(void * data,size_t length)121 void CJWebsocketProxy::AppendWebSocketBinaryData(void *data, size_t length)
122 {
123 webSocketBinaryData_.append(reinterpret_cast<char *>(data), length);
124 }
125
SetQueueData(void * data)126 void CJWebsocketProxy::SetQueueData(void *data)
127 {
128 std::lock_guard<std::mutex> lock(dataQueueMutex_);
129 dataQueue_.push(data);
130 }
131
GetQueueData()132 void *CJWebsocketProxy::GetQueueData()
133 {
134 std::lock_guard<std::mutex> lock(dataQueueMutex_);
135 if (!dataQueue_.empty()) {
136 auto data = dataQueue_.front();
137 dataQueue_.pop();
138 return data;
139 }
140 NETSTACK_LOGE("CJWebsocketProxy data queue is empty");
141 return nullptr;
142 }
143
ClearWebSocketTextData()144 void CJWebsocketProxy::ClearWebSocketTextData()
145 {
146 webSocketTextData_.clear();
147 }
148
ClearWebSocketBinaryData()149 void CJWebsocketProxy::ClearWebSocketBinaryData()
150 {
151 webSocketBinaryData_.clear();
152 }
153
AddCallback2Map(int32_t typeId,WebSocketCallback callback)154 void CJWebsocketProxy::AddCallback2Map(int32_t typeId, WebSocketCallback callback)
155 {
156 std::lock_guard<std::mutex> mutex(mutex_);
157 eventMap_[typeId] = callback;
158 }
159
DelCallback(int32_t typeId)160 void CJWebsocketProxy::DelCallback(int32_t typeId)
161 {
162 std::lock_guard<std::mutex> mutex(mutex_);
163 eventMap_.erase(typeId);
164 }
165
FindCallback(int32_t typeId)166 std::optional<WebSocketCallback> CJWebsocketProxy::FindCallback(int32_t typeId)
167 {
168 std::lock_guard<std::mutex> mutex(mutex_);
169 auto iter = eventMap_.find(typeId);
170 if (iter != eventMap_.end()) {
171 return iter->second;
172 }
173
174 return std::nullopt;
175 }
176 }