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 OH_client = nullptr;
87 return OH_client;
88 }
89
90 OH_client->requestOptions.headers = nullptr;
91 g_clientMap[OH_client] = websocketClient;
92 return OH_client;
93 }
94
OH_WebSocketClient_AddHeader(struct WebSocket * client,struct WebSocket_Header header)95 int OH_WebSocketClient_AddHeader(struct WebSocket *client, struct WebSocket_Header header)
96 {
97 NETSTACK_LOGD("websocket CAPI AddHeader");
98 if (client == nullptr) {
99 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NULL;
100 }
101 auto newHeader = std::make_unique<struct WebSocket_Header>();
102 if (newHeader == nullptr) {
103 return WebSocketErrorCode::WEBSOCKET_CONNECTION_ERROR;
104 } else {
105 newHeader->fieldName = header.fieldName;
106 newHeader->fieldValue = header.fieldValue;
107 newHeader->next = NULL;
108 struct WebSocket_Header *currentHeader = client->requestOptions.headers;
109 if (currentHeader == nullptr) {
110 client->requestOptions.headers = newHeader.release();
111 } else {
112 while (currentHeader->next != NULL) {
113 currentHeader = currentHeader->next;
114 }
115 currentHeader->next = newHeader.release();
116 }
117 return 0;
118 }
119 }
120
OH_WebSocketClient_Send(struct WebSocket * client,char * data,size_t length)121 int OH_WebSocketClient_Send(struct WebSocket *client, char *data, size_t length)
122 {
123 int ret;
124 if (client == nullptr) {
125 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NULL;
126 }
127 WebSocketClient *websocketClient = GetInnerClientAdapter(client);
128
129 if (websocketClient == NULL) {
130 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NOT_CREAT;
131 }
132
133 ret = websocketClient->Send(data, length);
134 return ret;
135 }
136
OH_WebSocketClient_Connect(struct WebSocket * client,const char * url,struct WebSocket_RequestOptions options)137 int OH_WebSocketClient_Connect(struct WebSocket *client, const char *url, struct WebSocket_RequestOptions options)
138 {
139 NETSTACK_LOGI("websocket CAPI Connect");
140 int ret = 0;
141 if (client == nullptr) {
142 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NULL;
143 }
144
145 struct OpenOptions openOptions;
146 openOptions.headers = {};
147
148 if (options.headers != nullptr) {
149 Conv2RequestOptions(&openOptions, options);
150 }
151
152 WebSocketClient *websocketClient = GetInnerClientAdapter(client);
153
154 if (websocketClient == NULL) {
155 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NOT_CREAT;
156 }
157
158 std::string connectUrl = std::string(url);
159 ret = websocketClient->Connect(connectUrl, openOptions);
160 NETSTACK_LOGD("websocket CAPI Connect,ret=%{public}d", ret);
161 return ret;
162 }
163
OH_WebSocketClient_Close(struct WebSocket * client,struct WebSocket_CloseOption options)164 int OH_WebSocketClient_Close(struct WebSocket *client, struct WebSocket_CloseOption options)
165 {
166 int ret = 0;
167
168 if (client == nullptr) {
169 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NULL;
170 }
171
172 WebSocketClient *websocketClient = GetInnerClientAdapter(client);
173 if (websocketClient == NULL) {
174 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NOT_CREAT;
175 }
176
177 struct CloseOption closeOption;
178 Conv2CloseOptions(&closeOption, options);
179 ret = websocketClient->Close(closeOption);
180 return ret;
181 }
182
OH_WebSocketClient_FreeHeader(struct WebSocket_Header * header)183 void OH_WebSocketClient_FreeHeader(struct WebSocket_Header *header)
184 {
185 if (header == nullptr) {
186 return;
187 }
188 OH_WebSocketClient_FreeHeader(header->next);
189 free(header);
190 }
191
OH_WebSocketClient_Destroy(struct WebSocket * client)192 int OH_WebSocketClient_Destroy(struct WebSocket *client)
193 {
194 NETSTACK_LOGI("websocket CAPI Destroy");
195 int ret = 0;
196 if (client == nullptr) {
197 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NULL;
198 }
199 WebSocketClient *websocketClient = GetInnerClientAdapter(client);
200 if (websocketClient == NULL) {
201 return WebSocketErrorCode::WEBSOCKET_CLIENT_IS_NOT_CREAT;
202 }
203 ret = websocketClient->Destroy();
204
205 OH_WebSocketClient_FreeHeader(client->requestOptions.headers);
206
207 g_clientMap.erase(client);
208 return ret;
209 }