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