1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 
5 #include "linkkit/infra/infra_config.h"
6 
7 #ifdef INFRA_NET
8 #include <stdio.h>
9 #include <string.h>
10 #include "linkkit/infra/infra_defs.h"
11 #include "linkkit/infra/infra_net.h"
12 #include "linkkit/wrappers/wrappers_defs.h"
13 #include "linkkit/wrappers/wrappers.h"
14 #include "linkkit/wrappers/wrappers_defs.h"
15 
16 #ifdef INFRA_LOG
17 #include "linkkit/infra/infra_log.h"
18 #define net_err(...) log_err("infra_net", __VA_ARGS__)
19 #else
20 #define net_err(...)
21 #endif
22 
23 /*** SSL connection ***/
24 #if defined(SUPPORT_TLS)
25 #if defined(AT_SSL_ENABLED)
26 #include "at_ssl.h"
27 
read_ssl(utils_network_pt pNetwork,char * buffer,uint32_t len,uint32_t timeout_ms)28 static int read_ssl(utils_network_pt pNetwork, char *buffer, uint32_t len,
29                     uint32_t timeout_ms)
30 {
31     if (NULL == pNetwork) {
32         net_err("network is null");
33         return -1;
34     }
35 
36     return AT_SSL_Read((uintptr_t)pNetwork->handle, buffer, len, timeout_ms);
37 }
38 
write_ssl(utils_network_pt pNetwork,const char * buffer,uint32_t len,uint32_t timeout_ms)39 static int write_ssl(utils_network_pt pNetwork, const char *buffer,
40                      uint32_t len, uint32_t timeout_ms)
41 {
42     if (NULL == pNetwork) {
43         net_err("network is null");
44         return -1;
45     }
46 
47     return AT_SSL_Write((uintptr_t)pNetwork->handle, buffer, len, timeout_ms);
48 }
49 
disconnect_ssl(utils_network_pt pNetwork)50 static int disconnect_ssl(utils_network_pt pNetwork)
51 {
52     if (NULL == pNetwork) {
53         net_err("network is null");
54         return -1;
55     }
56 
57     AT_SSL_Destroy((uintptr_t)pNetwork->handle);
58     pNetwork->handle = 0;
59 
60     return 0;
61 }
62 
connect_ssl(utils_network_pt pNetwork)63 static int connect_ssl(utils_network_pt pNetwork)
64 {
65     if (NULL == pNetwork) {
66         net_err("network is null");
67         return 1;
68     }
69 
70     pNetwork->handle = (intptr_t)AT_SSL_Establish(
71                   pNetwork->pHostAddress, pNetwork->port, pNetwork->ca_crt,
72                   pNetwork->ca_crt_len + 1);
73     if (pNetwork->handle != 0) {
74         return 0;
75     } else {
76         /* TODO SHOLUD not remove this handle space */
77         /* The space will be freed by calling disconnect_ssl() */
78         /* utils_memory_free((void *)pNetwork->handle); */
79         return -1;
80     }
81 }
82 #else /* AT_SSL_ENABLED */
83 #ifdef INFRA_MEM_STATS
84 #include "linkkit/infra/infra_mem_stats.h"
85 #define NET_MALLOC(size) LITE_malloc(size, MEM_MAGIC, "infra_net")
86 #define NET_FREE(ptr)    LITE_free(ptr)
87 #else
88 #define NET_MALLOC(size) HAL_Malloc(size)
89 #define NET_FREE(ptr)    HAL_Free(ptr)
90 #endif
91 
ssl_malloc(uint32_t size)92 static void *ssl_malloc(uint32_t size)
93 {
94     return NET_MALLOC(size);
95 }
ssl_free(void * ptr)96 static void ssl_free(void *ptr)
97 {
98     NET_FREE(ptr);
99 }
100 
read_ssl(utils_network_pt pNetwork,char * buffer,uint32_t len,uint32_t timeout_ms)101 static int read_ssl(utils_network_pt pNetwork, char *buffer, uint32_t len,
102                     uint32_t timeout_ms)
103 {
104     if (NULL == pNetwork) {
105         net_err("network is null");
106         return -1;
107     }
108 
109     return HAL_SSL_Read((uintptr_t)pNetwork->handle, buffer, len, timeout_ms);
110 }
111 
write_ssl(utils_network_pt pNetwork,const char * buffer,uint32_t len,uint32_t timeout_ms)112 static int write_ssl(utils_network_pt pNetwork, const char *buffer,
113                      uint32_t len, uint32_t timeout_ms)
114 {
115     if (NULL == pNetwork) {
116         net_err("network is null");
117         return -1;
118     }
119 
120     return HAL_SSL_Write((uintptr_t)pNetwork->handle, buffer, len, timeout_ms);
121 }
122 
disconnect_ssl(utils_network_pt pNetwork)123 static int disconnect_ssl(utils_network_pt pNetwork)
124 {
125     if (NULL == pNetwork) {
126         net_err("network is null");
127         return -1;
128     }
129 
130     HAL_SSL_Destroy((uintptr_t)pNetwork->handle);
131     pNetwork->handle = 0;
132 
133     return 0;
134 }
135 
connect_ssl(utils_network_pt pNetwork)136 static int connect_ssl(utils_network_pt pNetwork)
137 {
138     ssl_hooks_t ssl_hooks;
139 
140     if (NULL == pNetwork) {
141         net_err("network is null");
142         return 1;
143     }
144 
145 #ifdef INFRA_MEM_STATS
146     memset(&ssl_hooks, 0, sizeof(ssl_hooks_t));
147     ssl_hooks.malloc = ssl_malloc;
148     ssl_hooks.free = ssl_free;
149 
150     ssl_hooks_set(&ssl_hooks);
151 #else
152     (void)ssl_hooks;
153 #endif
154 
155     pNetwork->handle = (intptr_t)HAL_SSL_Establish(
156                   pNetwork->pHostAddress, pNetwork->port, pNetwork->ca_crt,
157                   pNetwork->ca_crt_len + 1);
158     if (pNetwork->handle != 0) {
159         return 0;
160     } else {
161         /* TODO SHOLUD not remove this handle space */
162         /* The space will be freed by calling disconnect_ssl() */
163         /* utils_memory_free((void *)pNetwork->handle); */
164         return -1;
165     }
166 }
167 #endif /* AT_SSL_ENABLED */
168 #elif defined(AT_TCP_ENABLED)
169 #include "at_tcp.h"
170 /*** TCP connection ***/
read_tcp(utils_network_pt pNetwork,char * buffer,uint32_t len,uint32_t timeout_ms)171 static int read_tcp(utils_network_pt pNetwork, char *buffer, uint32_t len,
172                     uint32_t timeout_ms)
173 {
174     return AT_TCP_Read(pNetwork->handle, buffer, len, timeout_ms);
175 }
176 
write_tcp(utils_network_pt pNetwork,const char * buffer,uint32_t len,uint32_t timeout_ms)177 static int write_tcp(utils_network_pt pNetwork, const char *buffer,
178                      uint32_t len, uint32_t timeout_ms)
179 {
180     return AT_TCP_Write(pNetwork->handle, buffer, len, timeout_ms);
181 }
182 
disconnect_tcp(utils_network_pt pNetwork)183 static int disconnect_tcp(utils_network_pt pNetwork)
184 {
185     if (pNetwork->handle == (uintptr_t)(-1)) {
186         net_err("Network->handle = -1");
187         return -1;
188     }
189 
190     AT_TCP_Destroy(pNetwork->handle);
191     pNetwork->handle = (uintptr_t)(-1);
192     return 0;
193 }
194 
connect_tcp(utils_network_pt pNetwork)195 static int connect_tcp(utils_network_pt pNetwork)
196 {
197     if (NULL == pNetwork) {
198         net_err("network is null");
199         return 1;
200     }
201 
202     pNetwork->handle = AT_TCP_Establish(pNetwork->pHostAddress, pNetwork->port);
203     if (pNetwork->handle == (uintptr_t)(-1)) {
204         return -1;
205     }
206 
207     return 0;
208 }
209 
210 #else
211 /*** TCP connection ***/
read_tcp(utils_network_pt pNetwork,char * buffer,uint32_t len,uint32_t timeout_ms)212 static int read_tcp(utils_network_pt pNetwork, char *buffer, uint32_t len,
213                     uint32_t timeout_ms)
214 {
215     return HAL_TCP_Read(pNetwork->handle, buffer, len, timeout_ms);
216 }
217 
write_tcp(utils_network_pt pNetwork,const char * buffer,uint32_t len,uint32_t timeout_ms)218 static int write_tcp(utils_network_pt pNetwork, const char *buffer,
219                      uint32_t len, uint32_t timeout_ms)
220 {
221     return HAL_TCP_Write(pNetwork->handle, buffer, len, timeout_ms);
222 }
223 
disconnect_tcp(utils_network_pt pNetwork)224 static int disconnect_tcp(utils_network_pt pNetwork)
225 {
226     if (pNetwork->handle == (uintptr_t)(-1)) {
227         net_err("Network->handle = -1");
228         return -1;
229     }
230 
231     HAL_TCP_Destroy(pNetwork->handle);
232     pNetwork->handle = (uintptr_t)(-1);
233     return 0;
234 }
235 
connect_tcp(utils_network_pt pNetwork)236 static int connect_tcp(utils_network_pt pNetwork)
237 {
238     if (NULL == pNetwork) {
239         net_err("network is null");
240         return 1;
241     }
242 
243     pNetwork->handle =
244         HAL_TCP_Establish(pNetwork->pHostAddress, pNetwork->port);
245     if (pNetwork->handle == (uintptr_t)(-1)) {
246         return -1;
247     }
248 
249     return 0;
250 }
251 #endif /* #ifdef SUPPORT_TLS */
252 
253 /****** network interface ******/
utils_net_read(utils_network_pt pNetwork,char * buffer,uint32_t len,uint32_t timeout_ms)254 int utils_net_read(utils_network_pt pNetwork, char *buffer, uint32_t len,
255                    uint32_t timeout_ms)
256 {
257     int ret = 0;
258 #if defined(SUPPORT_TLS)
259     ret = read_ssl(pNetwork, buffer, len, timeout_ms);
260 #else
261     ret = read_tcp(pNetwork, buffer, len, timeout_ms);
262 #endif
263 
264     return ret;
265 }
266 
utils_net_write(utils_network_pt pNetwork,const char * buffer,uint32_t len,uint32_t timeout_ms)267 int utils_net_write(utils_network_pt pNetwork, const char *buffer, uint32_t len,
268                     uint32_t timeout_ms)
269 {
270     int ret = 0;
271 #if defined(SUPPORT_TLS)
272     ret = write_ssl(pNetwork, buffer, len, timeout_ms);
273 #else
274     ret = write_tcp(pNetwork, buffer, len, timeout_ms);
275 #endif
276 
277     return ret;
278 }
279 
iotx_net_disconnect(utils_network_pt pNetwork)280 int iotx_net_disconnect(utils_network_pt pNetwork)
281 {
282     int ret = 0;
283 #if defined(SUPPORT_TLS)
284     ret = disconnect_ssl(pNetwork);
285 #else
286     ret = disconnect_tcp(pNetwork);
287 #endif
288 
289     return ret;
290 }
291 
iotx_net_connect(utils_network_pt pNetwork)292 int iotx_net_connect(utils_network_pt pNetwork)
293 {
294     int ret = 0;
295 #if defined(SUPPORT_TLS)
296     ret = connect_ssl(pNetwork);
297 #else
298     ret = connect_tcp(pNetwork);
299 #endif
300 
301     return ret;
302 }
303 
iotx_net_init(utils_network_pt pNetwork,const char * host,uint16_t port,const char * ca_crt)304 int iotx_net_init(utils_network_pt pNetwork, const char *host, uint16_t port,
305                   const char *ca_crt)
306 {
307     if (!pNetwork || !host) {
308         net_err("parameter error! pNetwork=%p, host = %p", pNetwork, host);
309         return -1;
310     }
311     pNetwork->pHostAddress = host;
312     pNetwork->port = port;
313     pNetwork->ca_crt = ca_crt;
314 
315     if (NULL == ca_crt) {
316         pNetwork->ca_crt_len = 0;
317     } else {
318         pNetwork->ca_crt_len = strlen(ca_crt);
319     }
320 
321     pNetwork->handle = 0;
322     pNetwork->read = utils_net_read;
323     pNetwork->write = utils_net_write;
324     pNetwork->disconnect = iotx_net_disconnect;
325     pNetwork->connect = iotx_net_connect;
326 
327     return 0;
328 }
329 #endif
330