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 }