1 /*
2 * Copyright (c) 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 #include <cstring>
16 #include <iostream>
17
18 #include "net_websocket.h"
19 #include "net_websocket_adapter.h"
20 #include "netstack_log.h"
21 #include "websocket_client_innerapi.h"
22
23 using namespace OHOS::NetStack::WebSocketClient;
24
25 const int MAX_CLIENT_SIZE = 100;
26
OH_NetStack_OnMessageCallback(WebSocketClient * ptrInner,const std::string & data,size_t length)27 void OH_NetStack_OnMessageCallback(WebSocketClient *ptrInner, const std::string &data, size_t length)
28 {
29 NETSTACK_LOGD("websocket CAPI Message Callback");
30 WebSocket *OH_client = GetNdkClientAdapter(ptrInner);
31 if (OH_client == nullptr) {
32 return;
33 }
34 OH_client->onMessage(OH_client, const_cast<char *>(data.c_str()), length);
35 }
36
OH_NetStack_OnCloseCallback(WebSocketClient * ptrInner,CloseResult closeResult)37 void OH_NetStack_OnCloseCallback(WebSocketClient *ptrInner, CloseResult closeResult)
38 {
39 NETSTACK_LOGD("websocket CAPI Close Callback");
40 struct WebSocket_CloseResult OH_CloseResult;
41 Conv2CloseResult(closeResult, &OH_CloseResult);
42 WebSocket *OH_client = GetNdkClientAdapter(ptrInner);
43 if (OH_client == nullptr) {
44 return;
45 }
46 OH_client->onClose(OH_client, OH_CloseResult);
47 }
48
OH_NetStack_OnErrorCallback(WebSocketClient * ptrInner,ErrorResult error)49 void OH_NetStack_OnErrorCallback(WebSocketClient *ptrInner, ErrorResult error)
50 {
51 NETSTACK_LOGD("websocket CAPI Error Callback");
52 struct WebSocket_ErrorResult OH_ErrorResult;
53 Conv2ErrorResult(error, &OH_ErrorResult);
54 WebSocket *OH_client = GetNdkClientAdapter(ptrInner);
55 if (OH_client == nullptr) {
56 return;
57 }
58 OH_client->onError(OH_client, OH_ErrorResult);
59 }
60
OH_NetStack_OnOpenCallback(WebSocketClient * ptrInner,OpenResult openResult)61 void OH_NetStack_OnOpenCallback(WebSocketClient *ptrInner, OpenResult openResult)
62 {
63 NETSTACK_LOGD("websocket CAPI Open Callback");
64 struct WebSocket_OpenResult OH_OpenResult;
65 Conv2OpenResult(openResult, &OH_OpenResult);
66 WebSocket *OH_client = GetNdkClientAdapter(ptrInner);
67 if (OH_client == nullptr) {
68 return;
69 }
70 OH_client->onOpen(OH_client, OH_OpenResult);
71 }
72
OH_WebSocketClient_Constructor(WebSocket_OnOpenCallback onOpen,WebSocket_OnMessageCallback onMessage,WebSocket_OnErrorCallback onError,WebSocket_OnCloseCallback onclose)73 struct WebSocket *OH_WebSocketClient_Constructor(WebSocket_OnOpenCallback onOpen, WebSocket_OnMessageCallback onMessage,
74 WebSocket_OnErrorCallback onError, WebSocket_OnCloseCallback onclose)
75 {
76 WebSocket *OH_client = new WebSocket;
77 WebSocketClient *websocketClient = new WebSocketClient();
78 OH_client->onMessage = onMessage;
79 OH_client->onClose = onclose;
80 OH_client->onError = onError;
81 OH_client->onOpen = onOpen;
82 websocketClient->Registcallback(OH_NetStack_OnOpenCallback, OH_NetStack_OnMessageCallback,
83 OH_NetStack_OnErrorCallback, OH_NetStack_OnCloseCallback);
84 if (g_clientMap.size() == MAX_CLIENT_SIZE) {
85 delete OH_client;
86 OH_client = nullptr;
87 delete websocketClient;
88 websocketClient = nullptr;
89 return nullptr;
90 }
91
92 OH_client->requestOptions.headers = nullptr;
93 g_clientMap[OH_client] = websocketClient;
94 return OH_client;
95 }
96
OH_WebSocketClient_AddHeader(struct WebSocket * client,struct WebSocket_Header header)97 int OH_WebSocketClient_AddHeader(struct WebSocket *client, struct WebSocket_Header header)
98 {
99 NETSTACK_LOGD("websocket CAPI AddHeader");
100 if (client == nullptr) {
101 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NULL;
102 }
103 auto newHeader = std::make_unique<struct WebSocket_Header>();
104 if (newHeader == nullptr) {
105 return WebSocketErrorCode::WEBSOCKET_CONNECTION_ERROR;
106 } else {
107 newHeader->fieldName = header.fieldName;
108 newHeader->fieldValue = header.fieldValue;
109 newHeader->next = NULL;
110 struct WebSocket_Header *currentHeader = client->requestOptions.headers;
111 if (currentHeader == nullptr) {
112 client->requestOptions.headers = newHeader.release();
113 } else {
114 while (currentHeader->next != NULL) {
115 currentHeader = currentHeader->next;
116 }
117 currentHeader->next = newHeader.release();
118 }
119 return 0;
120 }
121 }
122
OH_WebSocketClient_Send(struct WebSocket * client,char * data,size_t length)123 int OH_WebSocketClient_Send(struct WebSocket *client, char *data, size_t length)
124 {
125 int ret;
126 if (client == nullptr) {
127 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NULL;
128 }
129 WebSocketClient *websocketClient = GetInnerClientAdapter(client);
130
131 if (websocketClient == NULL) {
132 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NOT_CREAT;
133 }
134
135 ret = websocketClient->Send(data, length);
136 return ret;
137 }
138
OH_WebSocketClient_Connect(struct WebSocket * client,const char * url,struct WebSocket_RequestOptions options)139 int OH_WebSocketClient_Connect(struct WebSocket *client, const char *url, struct WebSocket_RequestOptions options)
140 {
141 NETSTACK_LOGI("websocket CAPI Connect");
142 int ret = 0;
143 if (client == nullptr) {
144 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NULL;
145 }
146
147 struct OpenOptions openOptions;
148 openOptions.headers = {};
149
150 if (options.headers != nullptr) {
151 Conv2RequestOptions(&openOptions, options);
152 }
153
154 WebSocketClient *websocketClient = GetInnerClientAdapter(client);
155
156 if (websocketClient == NULL) {
157 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NOT_CREAT;
158 }
159
160 std::string connectUrl = std::string(url);
161 ret = websocketClient->Connect(connectUrl, openOptions);
162 NETSTACK_LOGD("websocket CAPI Connect,ret=%{public}d", ret);
163 return ret;
164 }
165
OH_WebSocketClient_Close(struct WebSocket * client,struct WebSocket_CloseOption options)166 int OH_WebSocketClient_Close(struct WebSocket *client, struct WebSocket_CloseOption options)
167 {
168 int ret = 0;
169
170 if (client == nullptr) {
171 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NULL;
172 }
173
174 WebSocketClient *websocketClient = GetInnerClientAdapter(client);
175 if (websocketClient == NULL) {
176 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NOT_CREAT;
177 }
178
179 struct CloseOption closeOption;
180 Conv2CloseOptions(&closeOption, options);
181 ret = websocketClient->Close(closeOption);
182 return ret;
183 }
184
OH_WebSocketClient_FreeHeader(struct WebSocket_Header * header)185 void OH_WebSocketClient_FreeHeader(struct WebSocket_Header *header)
186 {
187 if (header == nullptr) {
188 return;
189 }
190 OH_WebSocketClient_FreeHeader(header->next);
191 free(header);
192 }
193
OH_WebSocketClient_Destroy(struct WebSocket * client)194 int OH_WebSocketClient_Destroy(struct WebSocket *client)
195 {
196 NETSTACK_LOGI("websocket CAPI Destroy");
197 int ret = 0;
198 if (client == nullptr) {
199 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NULL;
200 }
201 WebSocketClient *websocketClient = GetInnerClientAdapter(client);
202 if (websocketClient == NULL) {
203 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NOT_CREAT;
204 }
205 ret = websocketClient->Destroy();
206
207 OH_WebSocketClient_FreeHeader(client->requestOptions.headers);
208
209 g_clientMap.erase(client);
210 return ret;
211 }