1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <stddef.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <fcntl.h>
8 #include <sys/time.h>
9 #include <sys/types.h>
10 #include <aos/kernel.h>
11 #include <sys/socket.h>
12 #include <netdb.h>
13 
14 #include <errno.h>
15 #include "aiot_state_api.h"
16 #include "aiot_sysdep_api.h"
17 
18 /* socket建联时间默认最大值 */
19 #define CORE_SYSDEP_DEFAULT_CONNECT_TIMEOUT_MS (10 * 1000)
20 
21 /*
22  *  CORE_SYSDEP_MBEDTLS_ENABLED 不是一个用户需要关心的编译开关
23  *
24  *  大多数情况下, 就保持它如下的设置即可
25  *  只有少数时候, SDK的用户关心对接层代码的ROM尺寸, 并且也没有选择用TLS连接服务器
26  *  那时才会出现, 将 CORE_SYSDEP_MBEDTLS_ENABLED 宏定义关闭的改动, 以减小对接尺寸
27  *
28  *  我们不建议去掉 #define CORE_SYSDEP_MBEDTLS_ENABLED 这行代码
29  *  虽然物联网平台接收TCP方式的连接, 但我们不推荐这样做, TLS是更安全的通信方式
30  *
31  */
32 #define CORE_SYSDEP_MBEDTLS_ENABLED
33 
34 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
35     #include "mbedtls/sha256.h"
36     #include "mbedtls/net_sockets.h"
37     #include "mbedtls/ssl.h"
38     #include "mbedtls/ctr_drbg.h"
39     #include "mbedtls/debug.h"
40     #include "mbedtls/platform.h"
41     #include "mbedtls/timing.h"
42     #include "mbedtls/x509_crt.h"
43 #endif
44 
45 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
46 typedef struct {
47     mbedtls_net_context          net_ctx;
48     mbedtls_ssl_context          ssl_ctx;
49     mbedtls_ssl_config           ssl_config;
50     mbedtls_timing_delay_context timer_delay_ctx;
51     mbedtls_x509_crt             x509_server_cert;
52     mbedtls_x509_crt             x509_client_cert;
53     mbedtls_pk_context           x509_client_pk;
54 } core_sysdep_mbedtls_t;
55 #endif
56 
57 typedef struct {
58     int fd;
59     core_sysdep_socket_type_t socket_type;
60     aiot_sysdep_network_cred_t *cred;
61     char *host;
62     char backup_ip[16];
63     uint16_t port;
64     uint32_t connect_timeout_ms;
65 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
66     core_sysdep_psk_t psk;
67     core_sysdep_mbedtls_t mbedtls;
68 #endif
69 } core_network_handle_t;
70 
71 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
72 #define MBEDTLS_MEM_INFO_MAGIC  (0x12345678)
73 
74 static unsigned int g_mbedtls_total_mem_used = 0;
75 static unsigned int g_mbedtls_max_mem_used = 0;
76 
77 typedef struct {
78     int magic;
79     int size;
80 } mbedtls_mem_info_t;
81 
_core_mbedtls_calloc(size_t n,size_t size)82 static void *_core_mbedtls_calloc(size_t n, size_t size)
83 {
84     unsigned char *buf = NULL;
85     mbedtls_mem_info_t *mem_info = NULL;
86 
87     if (n == 0 || size == 0) {
88         return NULL;
89     }
90 
91     buf = (unsigned char *)malloc(n * size + sizeof(mbedtls_mem_info_t));
92     if (NULL == buf) {
93         return NULL;
94     } else {
95         memset(buf, 0, n * size + sizeof(mbedtls_mem_info_t));
96     }
97 
98     mem_info = (mbedtls_mem_info_t *)buf;
99     mem_info->magic = MBEDTLS_MEM_INFO_MAGIC;
100     mem_info->size = n * size;
101     buf += sizeof(mbedtls_mem_info_t);
102 
103     g_mbedtls_total_mem_used += mem_info->size;
104     if (g_mbedtls_total_mem_used > g_mbedtls_max_mem_used) {
105         g_mbedtls_max_mem_used = g_mbedtls_total_mem_used;
106     }
107 
108     /* printf("INFO -- mbedtls malloc: %p %d  total used: %d  max used: %d\r\n",
109                        buf, (int)size, g_mbedtls_total_mem_used, g_mbedtls_max_mem_used); */
110 
111     return buf;
112 }
113 
_core_mbedtls_free(void * ptr)114 static void _core_mbedtls_free(void *ptr)
115 {
116     mbedtls_mem_info_t *mem_info = NULL;
117     if (NULL == ptr) {
118         return;
119     }
120 
121     mem_info = (mbedtls_mem_info_t *)((unsigned char *)ptr - sizeof(mbedtls_mem_info_t));
122     if (mem_info->magic != MBEDTLS_MEM_INFO_MAGIC) {
123         printf("Warning - invalid mem info magic: 0x%x\r\n", mem_info->magic);
124         return;
125     }
126 
127     g_mbedtls_total_mem_used -= mem_info->size;
128     /* printf("INFO -- mbedtls free: %p %d  total used: %d  max used: %d\r\n",
129                        ptr, mem_info->size, g_mbedtls_total_mem_used, g_mbedtls_max_mem_used); */
130 
131     aos_free(mem_info);
132 }
133 #endif
134 
core_sysdep_malloc(uint32_t size,char * name)135 void *core_sysdep_malloc(uint32_t size, char *name)
136 {
137     return aos_malloc(size);
138 }
139 
core_sysdep_free(void * ptr)140 void core_sysdep_free(void *ptr)
141 {
142     aos_free(ptr);
143 }
144 
core_sysdep_time(void)145 uint64_t core_sysdep_time(void)
146 {
147     struct timeval time;
148 
149     memset(&time, 0, sizeof(struct timeval));
150     gettimeofday(&time, NULL);
151 
152     return (time.tv_sec * 1000 + time.tv_usec / 1000);
153 }
154 
core_sysdep_sleep(uint64_t time_ms)155 void core_sysdep_sleep(uint64_t time_ms)
156 {
157     aos_msleep(time_ms);
158 }
159 
core_sysdep_network_init(void)160 void *core_sysdep_network_init(void)
161 {
162     core_network_handle_t *handle = NULL;
163 
164     handle = aos_malloc(sizeof(core_network_handle_t));
165     if (handle == NULL) {
166         return NULL;
167     }
168     memset(handle, 0, sizeof(core_network_handle_t));
169 
170     handle->connect_timeout_ms = CORE_SYSDEP_DEFAULT_CONNECT_TIMEOUT_MS;
171 
172     return handle;
173 }
174 
core_sysdep_network_setopt(void * handle,core_sysdep_network_option_t option,void * data)175 int32_t core_sysdep_network_setopt(void *handle, core_sysdep_network_option_t option, void *data)
176 {
177     core_network_handle_t *network_handle = (core_network_handle_t *)handle;
178 
179     if (handle == NULL || data == NULL) {
180         return STATE_PORT_INPUT_NULL_POINTER;
181     }
182 
183     if (option >= CORE_SYSDEP_NETWORK_MAX) {
184         return STATE_PORT_INPUT_OUT_RANGE;
185     }
186 
187     switch (option) {
188         case CORE_SYSDEP_NETWORK_SOCKET_TYPE: {
189             network_handle->socket_type = *(core_sysdep_socket_type_t *)data;
190         }
191         break;
192         case CORE_SYSDEP_NETWORK_HOST: {
193             network_handle->host = aos_malloc(strlen(data) + 1);
194             if (network_handle->host == NULL) {
195                 printf("malloc failed\n");
196                 return STATE_PORT_MALLOC_FAILED;
197             }
198             memset(network_handle->host, 0, strlen(data) + 1);
199             memcpy(network_handle->host, data, strlen(data));
200         }
201         break;
202         case CORE_SYSDEP_NETWORK_BACKUP_IP: {
203             memcpy(network_handle->backup_ip, data, strlen(data));
204         }
205         break;
206         case CORE_SYSDEP_NETWORK_PORT: {
207             network_handle->port = *(uint16_t *)data;
208         }
209         break;
210         case CORE_SYSDEP_NETWORK_CONNECT_TIMEOUT_MS: {
211             network_handle->connect_timeout_ms = *(uint32_t *)data;
212         }
213         break;
214 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
215         case CORE_SYSDEP_NETWORK_CRED: {
216             network_handle->cred = aos_malloc(sizeof(aiot_sysdep_network_cred_t));
217             if (network_handle->cred == NULL) {
218                 printf("malloc failed\n");
219                 return STATE_PORT_MALLOC_FAILED;
220             }
221             memset(network_handle->cred, 0, sizeof(aiot_sysdep_network_cred_t));
222             memcpy(network_handle->cred, data, sizeof(aiot_sysdep_network_cred_t));
223         }
224         break;
225         case CORE_SYSDEP_NETWORK_PSK: {
226             core_sysdep_psk_t *psk = (core_sysdep_psk_t *)data;
227             network_handle->psk.psk_id = aos_malloc(strlen(psk->psk_id) + 1);
228             if (network_handle->psk.psk_id == NULL) {
229                 printf("malloc failed\n");
230                 return STATE_PORT_MALLOC_FAILED;
231             }
232             memset(network_handle->psk.psk_id, 0, strlen(psk->psk_id) + 1);
233             memcpy(network_handle->psk.psk_id, psk->psk_id, strlen(psk->psk_id));
234             network_handle->psk.psk = aos_malloc(strlen(psk->psk) + 1);
235             if (network_handle->psk.psk == NULL) {
236                 aos_free(network_handle->psk.psk_id);
237                 printf("malloc failed\n");
238                 return STATE_PORT_MALLOC_FAILED;
239             }
240             memset(network_handle->psk.psk, 0, strlen(psk->psk) + 1);
241             memcpy(network_handle->psk.psk, psk->psk, strlen(psk->psk));
242         }
243         break;
244 #endif
245         default: {
246             printf("unknown option\n");
247         }
248     }
249 
250     return STATE_SUCCESS;
251 }
252 
_port_uint2str(uint16_t input,char * output)253 static void _port_uint2str(uint16_t input, char *output)
254 {
255     uint8_t i = 0, j = 0;
256     char temp[6] = {0};
257 
258     do {
259         temp[i++] = input % 10 + '0';
260     } while ((input /= 10) > 0);
261 
262     do {
263         output[--i] = temp[j++];
264     } while (i > 0);
265 }
266 
_core_sysdep_network_connect(char * host,uint16_t port,int family,int socktype,int protocol,uint32_t timeout_ms,int * fd_out)267 static int32_t _core_sysdep_network_connect(char *host, uint16_t port, int family, int socktype, int protocol, uint32_t timeout_ms, int *fd_out)
268 {
269     int32_t res = STATE_SUCCESS;
270     int fd = 0, sock_option = 0;
271     char service[6] = {0};
272     struct addrinfo hints;
273     struct addrinfo *addrInfoList = NULL, *pos = NULL;
274 
275     memset(&hints, 0, sizeof(struct addrinfo));
276     hints.ai_family = family; /* only IPv4 */
277     hints.ai_socktype = socktype;
278     hints.ai_protocol = protocol;
279     hints.ai_flags = 0;
280     _port_uint2str(port, service);
281 
282     res = getaddrinfo(host, service, &hints, &addrInfoList);
283     if (res == 0) {
284         for (pos = addrInfoList; pos != NULL; pos = pos->ai_next) {
285             fd = socket(pos->ai_family, pos->ai_socktype, pos->ai_protocol);
286             if (fd < 0) {
287                 printf("create socket error\n");
288                 res = STATE_PORT_NETWORK_SOCKET_CREATE_FAILED;
289                 continue;
290             }
291 
292             res = fcntl(fd, F_GETFL, 0);
293             if (res != -1) {
294                 res = fcntl(fd, F_SETFL, sock_option | O_NONBLOCK);
295             }
296 
297             if (res == -1) {
298                 /* block connect */
299                 if (connect(fd, pos->ai_addr, pos->ai_addrlen) == 0) {
300                     *fd_out = fd;
301                     res = STATE_SUCCESS;
302                     break;
303                 } else {
304                     res = STATE_PORT_NETWORK_CONNECT_FAILED;
305                 }
306             } else {
307                 /* non-block connect */
308                 fd_set write_sets;
309                 struct timeval timeselect;
310 
311                 FD_ZERO(&write_sets);
312                 FD_SET(fd, &write_sets);
313 
314                 timeselect.tv_sec = timeout_ms / 1000;
315                 timeselect.tv_usec = timeout_ms % 1000 * 1000;
316 
317                 if (connect(fd, pos->ai_addr, pos->ai_addrlen) == 0) {
318                     *fd_out = fd;
319                     res = STATE_SUCCESS;
320                     break;
321                 } else if (errno != EINPROGRESS) {
322                     res = STATE_PORT_NETWORK_CONNECT_FAILED;
323                 } else {
324                     res = select(fd + 1, NULL, &write_sets, NULL, &timeselect);
325                     if (res == 0 ) {
326                         res = STATE_MQTT_LOG_CONNECT_TIMEOUT;
327                     } else if (res < 0) {
328                         res = STATE_PORT_NETWORK_CONNECT_FAILED;
329                     } else {
330                         if (FD_ISSET(fd, &write_sets)) {
331                             res = connect(fd, pos->ai_addr, pos->ai_addrlen);
332                             if ((res != 0 && errno == EISCONN) || res == 0) {
333                                 *fd_out = fd;
334                                 res = STATE_SUCCESS;
335                                 break;
336                             } else {
337                                 res = STATE_PORT_NETWORK_CONNECT_FAILED;
338                             }
339                         }
340                     }
341                 }
342             }
343 
344             close(fd);
345             printf("connect error, errno: %d\n", errno);
346         }
347     } else {
348         res = STATE_PORT_NETWORK_DNS_FAILED;
349     }
350 
351     if (res < 0) {
352         printf("fail to establish tcp\n");
353     } else {
354         printf("success to establish tcp, fd=%d\n", *fd_out);
355         res = STATE_SUCCESS;
356     }
357     freeaddrinfo(addrInfoList);
358     return res;
359 }
360 
_core_sysdep_network_tcp_establish(core_network_handle_t * network_handle)361 static int32_t _core_sysdep_network_tcp_establish(core_network_handle_t *network_handle)
362 {
363     int32_t res = STATE_SUCCESS;
364 
365     printf("establish tcp connection with server(host='%s', port=[%u])\n", network_handle->host, network_handle->port);
366 
367     res = _core_sysdep_network_connect(network_handle->host, network_handle->port,
368             AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, network_handle->connect_timeout_ms, &network_handle->fd);
369     if (res == STATE_PORT_NETWORK_DNS_FAILED && strlen(network_handle->backup_ip) > 0) {
370         printf("using backup ip: %s\n", network_handle->backup_ip);
371         res = _core_sysdep_network_connect(network_handle->backup_ip, network_handle->port,
372                 AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, network_handle->connect_timeout_ms, &network_handle->fd);
373     }
374 
375     return res;
376 }
377 
_core_sysdep_network_udp_server_establish(core_network_handle_t * network_handle)378 static int32_t _core_sysdep_network_udp_server_establish(core_network_handle_t *network_handle)
379 {
380     int32_t sockfd;
381     struct sockaddr_in servaddr;
382     int opt_val = 1;
383 
384     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
385     if (sockfd < 0) {
386         printf("create socket error, errno: %d\n", errno);
387         perror("create socket error");
388         return STATE_PORT_NETWORK_SOCKET_CREATE_FAILED;
389     }
390 
391     if (0 != setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt_val, sizeof(opt_val))) {
392         printf("setsockopt(SO_REUSEADDR) falied, errno: %d\n", errno);
393         perror("setsockopt(SO_REUSEADDR) error");
394         close(sockfd);
395         return STATE_PORT_NETWORK_SOCKET_CONFIG_FAILED;
396     }
397 
398     memset(&servaddr, 0, sizeof(struct sockaddr_in));
399     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
400     servaddr.sin_family = AF_INET;
401     servaddr.sin_port = htons(network_handle->port);
402 
403     if (-1 == bind(sockfd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_in))) {
404         printf("bind(%d) falied, errno: %d\n", (int)sockfd, errno);
405         perror("bind(%d) error");
406         close(sockfd);
407         return STATE_PORT_NETWORK_SOCKET_BIND_FAILED;
408     }
409 
410     network_handle->fd = sockfd;
411     printf("success to establish udp, fd=%d\n", (int)sockfd);
412 
413     return 0;
414 }
415 
416 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
417 void core_sysdep_rand(uint8_t *output, uint32_t output_len);
_mbedtls_random(void * handle,unsigned char * output,size_t output_len)418 static int _mbedtls_random(void *handle, unsigned char *output, size_t output_len)
419 {
420     core_sysdep_rand(output, output_len);
421     return 0;
422 }
423 
_host_is_ip(char * host)424 static uint8_t _host_is_ip(char *host)
425 {
426     uint32_t idx = 0;
427 
428     if (strlen(host) >= 16) {
429         return 0;
430     }
431 
432     for (idx = 0;idx < strlen(host);idx++) {
433         if ((host[idx] != '.') && (host[idx] < '0' || host[idx] > '9')) {
434             return 0;
435         }
436     }
437 
438     return 1;
439 }
440 
_mbedtls_debug(void * ctx,int level,const char * file,int line,const char * str)441 static void _mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str)
442 {
443     ((void) level);
444     if (NULL != ctx) {
445         printf("%s\n", str);
446     }
447 }
448 
_core_sysdep_network_mbedtls_establish(core_network_handle_t * network_handle)449 static int32_t _core_sysdep_network_mbedtls_establish(core_network_handle_t *network_handle)
450 {
451     int32_t res = 0;
452     char port_str[6] = {0};
453 
454 #if defined(MBEDTLS_DEBUG_C)
455     mbedtls_debug_set_threshold(0);
456 #endif /* #if defined(MBEDTLS_DEBUG_C) */
457     mbedtls_net_init(&network_handle->mbedtls.net_ctx);
458     mbedtls_ssl_init(&network_handle->mbedtls.ssl_ctx);
459     mbedtls_ssl_config_init(&network_handle->mbedtls.ssl_config);
460     /*mbedtls_platform_set_calloc_free(_core_mbedtls_calloc, _core_mbedtls_free);*/
461     g_mbedtls_total_mem_used = g_mbedtls_max_mem_used = 0;
462 
463     if (network_handle->cred->max_tls_fragment == 0) {
464         printf("invalid max_tls_fragment parameter\n");
465         return STATE_PORT_TLS_INVALID_MAX_FRAGMENT;
466     }
467 
468     printf("establish mbedtls connection with server(host='%s', port=[%u])\n", network_handle->host, network_handle->port);
469 
470     _port_uint2str(network_handle->port, port_str);
471 
472     if (network_handle->cred->max_tls_fragment <= 512) {
473         res = mbedtls_ssl_conf_max_frag_len(&network_handle->mbedtls.ssl_config, MBEDTLS_SSL_MAX_FRAG_LEN_512);
474     } else if (network_handle->cred->max_tls_fragment <= 1024) {
475         res = mbedtls_ssl_conf_max_frag_len(&network_handle->mbedtls.ssl_config, MBEDTLS_SSL_MAX_FRAG_LEN_1024);
476     } else if (network_handle->cred->max_tls_fragment <= 2048) {
477         res = mbedtls_ssl_conf_max_frag_len(&network_handle->mbedtls.ssl_config, MBEDTLS_SSL_MAX_FRAG_LEN_2048);
478     } else if (network_handle->cred->max_tls_fragment <= 4096) {
479         res = mbedtls_ssl_conf_max_frag_len(&network_handle->mbedtls.ssl_config, MBEDTLS_SSL_MAX_FRAG_LEN_4096);
480     } else {
481         res = mbedtls_ssl_conf_max_frag_len(&network_handle->mbedtls.ssl_config, MBEDTLS_SSL_MAX_FRAG_LEN_NONE);
482     }
483 
484     if (res < 0) {
485         printf("mbedtls_ssl_conf_max_frag_len error, res: -0x%04X\n", -res);
486         return res;
487     }
488 
489     if (network_handle->socket_type == CORE_SYSDEP_SOCKET_TCP_CLIENT) {
490         res = _core_sysdep_network_connect(network_handle->host, network_handle->port,
491                 AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, network_handle->connect_timeout_ms, &network_handle->mbedtls.net_ctx.fd);
492     } else if (network_handle->socket_type == CORE_SYSDEP_SOCKET_UDP_CLIENT) {
493         res = _core_sysdep_network_connect(network_handle->host, network_handle->port,
494                 AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, network_handle->connect_timeout_ms, &network_handle->mbedtls.net_ctx.fd);
495     }
496 
497     if (res == STATE_PORT_NETWORK_DNS_FAILED && (strlen(network_handle->backup_ip) > 0)) {
498         printf("using backup ip: %s\n", network_handle->backup_ip);
499         if (network_handle->socket_type == CORE_SYSDEP_SOCKET_TCP_CLIENT) {
500             res = _core_sysdep_network_connect(network_handle->host, network_handle->port,
501                     AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, network_handle->connect_timeout_ms, &network_handle->mbedtls.net_ctx.fd);
502         } else if (network_handle->socket_type == CORE_SYSDEP_SOCKET_UDP_CLIENT) {
503             res = _core_sysdep_network_connect(network_handle->host, network_handle->port,
504                     AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, network_handle->connect_timeout_ms, &network_handle->mbedtls.net_ctx.fd);
505         }
506     }
507 
508     if (res < STATE_SUCCESS) {
509         return res;
510     }
511 
512     if (network_handle->socket_type == CORE_SYSDEP_SOCKET_TCP_CLIENT) {
513         res = mbedtls_ssl_config_defaults(&network_handle->mbedtls.ssl_config, MBEDTLS_SSL_IS_CLIENT,
514                                         MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
515     } else if (network_handle->socket_type == CORE_SYSDEP_SOCKET_UDP_CLIENT) {
516         res = mbedtls_ssl_config_defaults(&network_handle->mbedtls.ssl_config, MBEDTLS_SSL_IS_CLIENT,
517                                         MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT);
518     }
519 
520     if (res < 0) {
521         printf("mbedtls_ssl_config_defaults error, res: -0x%04X\n", -res);
522         return res;
523     }
524 
525     mbedtls_ssl_conf_max_version(&network_handle->mbedtls.ssl_config, MBEDTLS_SSL_MAJOR_VERSION_3,
526                                  MBEDTLS_SSL_MINOR_VERSION_3);
527     mbedtls_ssl_conf_min_version(&network_handle->mbedtls.ssl_config, MBEDTLS_SSL_MAJOR_VERSION_3,
528                                  MBEDTLS_SSL_MINOR_VERSION_3);
529     // mbedtls_ssl_conf_handshake_timeout(&network_handle->mbedtls.ssl_config,(MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN * 2),
530     //                             (MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN * 2 * 4));
531     mbedtls_ssl_conf_rng(&network_handle->mbedtls.ssl_config, _mbedtls_random, NULL);
532     mbedtls_ssl_conf_dbg(&network_handle->mbedtls.ssl_config, _mbedtls_debug, stdout);
533 
534     if (network_handle->cred->option == AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA) {
535         if (network_handle->cred->x509_server_cert == NULL && network_handle->cred->x509_server_cert_len == 0) {
536             printf("invalid x509 server cert\n");
537             return STATE_PORT_TLS_INVALID_SERVER_CERT;
538         }
539         mbedtls_x509_crt_init(&network_handle->mbedtls.x509_server_cert);
540 
541         res = mbedtls_x509_crt_parse(&network_handle->mbedtls.x509_server_cert,
542                                      (const unsigned char *)network_handle->cred->x509_server_cert, (size_t)network_handle->cred->x509_server_cert_len + 1);
543         if (res < 0) {
544             printf("mbedtls_x509_crt_parse server cert error, res: -0x%04X\n", -res);
545             return STATE_PORT_TLS_INVALID_SERVER_CERT;
546         }
547 
548         if (network_handle->cred->x509_client_cert != NULL && network_handle->cred->x509_client_cert_len > 0 &&
549             network_handle->cred->x509_client_privkey != NULL && network_handle->cred->x509_client_privkey_len > 0) {
550             mbedtls_x509_crt_init(&network_handle->mbedtls.x509_client_cert);
551             mbedtls_pk_init(&network_handle->mbedtls.x509_client_pk);
552             res = mbedtls_x509_crt_parse(&network_handle->mbedtls.x509_client_cert,
553                                          (const unsigned char *)network_handle->cred->x509_client_cert, (size_t)network_handle->cred->x509_client_cert_len + 1);
554             if (res < 0) {
555                 printf("mbedtls_x509_crt_parse client cert error, res: -0x%04X\n", -res);
556                 return STATE_PORT_TLS_INVALID_CLIENT_CERT;
557             }
558             res = mbedtls_pk_parse_key(&network_handle->mbedtls.x509_client_pk,
559                                        (const unsigned char *)network_handle->cred->x509_client_privkey,
560                                        (size_t)network_handle->cred->x509_client_privkey_len + 1, NULL, 0);
561             if (res < 0) {
562                 printf("mbedtls_pk_parse_key client pk error, res: -0x%04X\n", -res);
563                 return STATE_PORT_TLS_INVALID_CLIENT_KEY;
564             }
565             res = mbedtls_ssl_conf_own_cert(&network_handle->mbedtls.ssl_config, &network_handle->mbedtls.x509_client_cert,
566                                             &network_handle->mbedtls.x509_client_pk);
567             if (res < 0) {
568                 printf("mbedtls_ssl_conf_own_cert error, res: -0x%04X\n", -res);
569                 return STATE_PORT_TLS_INVALID_CLIENT_CERT;
570             }
571         }
572 
573         mbedtls_ssl_conf_ca_chain(&network_handle->mbedtls.ssl_config, &network_handle->mbedtls.x509_server_cert, NULL);
574     } else if (network_handle->cred->option == AIOT_SYSDEP_NETWORK_CRED_SVRCERT_PSK) {
575         static const int ciphersuites[1] = {MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA};
576         res = mbedtls_ssl_conf_psk(&network_handle->mbedtls.ssl_config,
577                                    (const unsigned char *)network_handle->psk.psk, (size_t)strlen(network_handle->psk.psk),
578                                    (const unsigned char *)network_handle->psk.psk_id, (size_t)strlen(network_handle->psk.psk_id));
579         if (res < 0) {
580             printf("mbedtls_ssl_conf_psk error, res = -0x%04X\n", -res);
581             return STATE_PORT_TLS_CONFIG_PSK_FAILED;
582         }
583         mbedtls_ssl_conf_ciphersuites(&network_handle->mbedtls.ssl_config, ciphersuites);
584     } else {
585         printf("unsupported security option\n");
586         return STATE_PORT_TLS_INVALID_CRED_OPTION;
587     }
588 
589     res = mbedtls_ssl_setup(&network_handle->mbedtls.ssl_ctx, &network_handle->mbedtls.ssl_config);
590     if (res < 0) {
591         printf("mbedtls_ssl_setup error, res: -0x%04X\n", -res);
592         return res;
593     }
594 
595     if (_host_is_ip(network_handle->host) == 0) {
596         res = mbedtls_ssl_set_hostname(&network_handle->mbedtls.ssl_ctx, network_handle->host);
597         if (res < 0) {
598             printf("mbedtls_ssl_set_hostname error, res: -0x%04X\n", -res);
599             return res;
600         }
601     }
602 
603     if (network_handle->socket_type == CORE_SYSDEP_SOCKET_UDP_CLIENT) {
604         mbedtls_ssl_set_timer_cb(&network_handle->mbedtls.ssl_ctx, (void *)&network_handle->mbedtls.timer_delay_ctx,
605                             mbedtls_timing_set_delay, mbedtls_timing_get_delay);
606     }
607 
608     mbedtls_ssl_set_bio(&network_handle->mbedtls.ssl_ctx, &network_handle->mbedtls.net_ctx, mbedtls_net_send,
609                         mbedtls_net_recv, mbedtls_net_recv_timeout);
610     mbedtls_ssl_conf_read_timeout(&network_handle->mbedtls.ssl_config, network_handle->connect_timeout_ms);
611 
612     while ((res = mbedtls_ssl_handshake(&network_handle->mbedtls.ssl_ctx)) != 0) {
613         if ((res != MBEDTLS_ERR_SSL_WANT_READ) && (res != MBEDTLS_ERR_SSL_WANT_WRITE)) {
614             printf("mbedtls_ssl_handshake error, res: -0x%04X\n", -res);
615             if (res == MBEDTLS_ERR_SSL_INVALID_RECORD) {
616                 res = STATE_PORT_TLS_INVALID_RECORD;
617             } else {
618                 res = STATE_PORT_TLS_INVALID_HANDSHAKE;
619             }
620             return res;
621         }
622     }
623 
624     res = mbedtls_ssl_get_verify_result(&network_handle->mbedtls.ssl_ctx);
625     if (res < 0) {
626         printf("mbedtls_ssl_get_verify_result error, res: -0x%04X\n", -res);
627         return res;
628     }
629 
630     printf("success to establish mbedtls connection, fd = %d(cost %d bytes in total, max used %d bytes)\n",
631            (int)network_handle->mbedtls.net_ctx.fd,
632            g_mbedtls_total_mem_used, g_mbedtls_max_mem_used);
633 
634     return 0;
635 }
636 #endif
637 
core_sysdep_network_establish(void * handle)638 int32_t core_sysdep_network_establish(void *handle)
639 {
640     core_network_handle_t *network_handle = (core_network_handle_t *)handle;
641 
642     if (handle == NULL) {
643         return STATE_PORT_INPUT_NULL_POINTER;
644     }
645 
646     if (network_handle->socket_type == CORE_SYSDEP_SOCKET_TCP_CLIENT) {
647         if (network_handle->host == NULL) {
648             return STATE_PORT_MISSING_HOST;
649         }
650         if (network_handle->cred == NULL) {
651             return _core_sysdep_network_tcp_establish(network_handle);
652         } else {
653             if (network_handle->cred->option == AIOT_SYSDEP_NETWORK_CRED_NONE) {
654                 return _core_sysdep_network_tcp_establish(network_handle);
655             }
656 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
657             else {
658                 return _core_sysdep_network_mbedtls_establish(network_handle);
659             }
660 #endif
661         }
662 
663     } else if (network_handle->socket_type == CORE_SYSDEP_SOCKET_TCP_SERVER) {
664         return STATE_PORT_TCP_SERVER_NOT_IMPLEMENT;
665     } else if (network_handle->socket_type == CORE_SYSDEP_SOCKET_UDP_CLIENT) {
666         if (network_handle->host == NULL) {
667             return STATE_PORT_MISSING_HOST;
668         }
669         if (network_handle->cred == NULL) {
670             return STATE_PORT_UDP_CLIENT_NOT_IMPLEMENT;
671         } else {
672             if (network_handle->cred->option == AIOT_SYSDEP_NETWORK_CRED_NONE) {
673                 return STATE_PORT_UDP_CLIENT_NOT_IMPLEMENT;
674             }
675 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
676             else {
677                 return _core_sysdep_network_mbedtls_establish(network_handle);
678             }
679 #endif
680         }
681     } else if (network_handle->socket_type == CORE_SYSDEP_SOCKET_UDP_SERVER) {
682         return _core_sysdep_network_udp_server_establish(network_handle);
683     }
684 
685     printf("unknown nwk type or tcp host absent\n");
686 
687     return STATE_PORT_NETWORK_UNKNOWN_SOCKET_TYPE;
688 }
689 
_core_sysdep_network_tcp_recv(core_network_handle_t * network_handle,uint8_t * buffer,uint32_t len,uint32_t timeout_ms)690 static int32_t _core_sysdep_network_tcp_recv(core_network_handle_t *network_handle, uint8_t *buffer, uint32_t len,
691         uint32_t timeout_ms)
692 {
693     int res = 0;
694     int32_t recv_bytes = 0;
695     ssize_t recv_res = 0;
696     uint64_t timestart_ms = 0, timenow_ms = 0, timeselect_ms = 0;
697     fd_set recv_sets;
698     struct timeval timestart, timenow, timeselect;
699 
700     FD_ZERO(&recv_sets);
701     FD_SET(network_handle->fd, &recv_sets);
702 
703     /* Start Time */
704     gettimeofday(&timestart, NULL);
705     timestart_ms = timestart.tv_sec * 1000 + timestart.tv_usec / 1000;
706     timenow_ms = timestart_ms;
707 
708     do {
709         gettimeofday(&timenow, NULL);
710         timenow_ms = timenow.tv_sec * 1000 + timenow.tv_usec / 1000;
711 
712         if (timenow_ms - timestart_ms >= timenow_ms ||
713             timeout_ms - (timenow_ms - timestart_ms) > timeout_ms) {
714             break;
715         }
716 
717         timeselect_ms = timeout_ms - (timenow_ms - timestart_ms);
718         timeselect.tv_sec = timeselect_ms / 1000;
719         timeselect.tv_usec = timeselect_ms % 1000 * 1000;
720 
721         res = select(network_handle->fd + 1, &recv_sets, NULL, NULL, &timeselect);
722         if (res == 0) {
723             /* printf("_core_sysdep_network_tcp_recv, nwk select timeout\n"); */
724             continue;
725         } else if (res < 0) {
726             printf("_core_sysdep_network_tcp_recv, errno: %d\n", errno);
727             perror("_core_sysdep_network_tcp_recv, nwk select failed: ");
728             return STATE_PORT_NETWORK_SELECT_FAILED;
729         } else {
730             if (FD_ISSET(network_handle->fd, &recv_sets)) {
731                 recv_res = recv(network_handle->fd, buffer + recv_bytes, len - recv_bytes, 0);
732                 if (recv_res == 0) {
733                     printf("_core_sysdep_network_tcp_recv, nwk connection closed\n");
734                     return STATE_PORT_NETWORK_RECV_CONNECTION_CLOSED;
735                 } else if (recv_res < 0) {
736                     printf("_core_sysdep_network_tcp_recv, errno: %d\n", errno);
737                     perror("_core_sysdep_network_tcp_recv, nwk recv error: ");
738                     if (errno == EINTR) {
739                         continue;
740                     }
741                     return STATE_PORT_NETWORK_RECV_FAILED;
742                 } else {
743                     recv_bytes += recv_res;
744                     /* printf("recv_bytes: %d, len: %d\n",recv_bytes,len); */
745                     if (recv_bytes == len) {
746                         break;
747                     }
748                 }
749             }
750         }
751     } while (((timenow_ms - timestart_ms) < timeout_ms) && (recv_bytes < len));
752 
753     /* printf("%s: recv over\n",__FUNCTION__); */
754     return recv_bytes;
755 }
756 
_core_sysdep_network_udp_recv(core_network_handle_t * network_handle,uint8_t * buffer,uint32_t len,uint32_t timeout_ms,core_sysdep_addr_t * addr)757 static int32_t _core_sysdep_network_udp_recv(core_network_handle_t *network_handle, uint8_t *buffer, uint32_t len, uint32_t timeout_ms, core_sysdep_addr_t *addr)
758 {
759     int res;
760     struct sockaddr_in cliaddr;
761     socklen_t addr_len = sizeof(cliaddr);
762     fd_set read_fds;
763     struct timeval timeout = {timeout_ms / 1000, (timeout_ms % 1000) * 1000};
764 
765     FD_ZERO(&read_fds);
766     FD_SET(network_handle->fd, &read_fds);
767 
768     res = select(network_handle->fd + 1, &read_fds, NULL, NULL, &timeout);
769     if (res == 0) {
770         printf("select timeout\n");
771         return 0;
772     }
773     else if (res < 0) {
774         printf("_linux_nwk_udp_read select errno: %d\n", errno);
775         perror("_linux_nwk_udp_read select error: ");
776         return STATE_PORT_NETWORK_SELECT_FAILED;
777     }
778 
779     res = recvfrom(network_handle->fd, buffer, len, 0, (struct sockaddr *)&cliaddr, &addr_len);
780     if (res >= 0) {
781         if (NULL != addr) {
782             addr->port = ntohs(cliaddr.sin_port);
783             strncpy((char *)addr->addr, inet_ntoa(cliaddr.sin_addr), sizeof(addr->addr));
784         }
785 
786         return res;
787     } else {
788         printf("_linux_nwk_udp_read errno: %d\n", errno);
789         perror("_linux_nwk_udp_read error: ");
790         return STATE_PORT_NETWORK_RECV_FAILED;
791     }
792     return res;
793 }
794 
795 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
_core_sysdep_network_mbedtls_recv(core_network_handle_t * network_handle,uint8_t * buffer,uint32_t len,uint32_t timeout_ms)796 static int32_t _core_sysdep_network_mbedtls_recv(core_network_handle_t *network_handle, uint8_t *buffer, uint32_t len,
797         uint32_t timeout_ms)
798 {
799     int res = 0;
800     int32_t recv_bytes = 0;
801 
802     mbedtls_ssl_conf_read_timeout(&network_handle->mbedtls.ssl_config, timeout_ms);
803     do {
804         res = mbedtls_ssl_read(&network_handle->mbedtls.ssl_ctx, buffer + recv_bytes, len - recv_bytes);
805         if (res < 0) {
806             if (res == MBEDTLS_ERR_SSL_TIMEOUT) {
807                 break;
808             } else if (res != MBEDTLS_ERR_SSL_WANT_READ &&
809                        res != MBEDTLS_ERR_SSL_WANT_WRITE &&
810                        res != MBEDTLS_ERR_SSL_CLIENT_RECONNECT) {
811                 if (recv_bytes == 0) {
812                     printf("mbedtls_ssl_recv error, res: -0x%04X\n", -res);
813                     if (res == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
814                         return STATE_PORT_TLS_RECV_CONNECTION_CLOSED;
815                     } else if (res == MBEDTLS_ERR_SSL_INVALID_RECORD) {
816                         return STATE_PORT_TLS_INVALID_RECORD;
817                     } else {
818                         return STATE_PORT_TLS_RECV_FAILED;
819                     }
820                 }
821                 break;
822             }
823         } else if (res == 0) {
824             break;
825         } else {
826             recv_bytes += res;
827         }
828     } while (recv_bytes < len);
829 
830     return recv_bytes;
831 }
832 #endif
833 
core_sysdep_network_recv(void * handle,uint8_t * buffer,uint32_t len,uint32_t timeout_ms,core_sysdep_addr_t * addr)834 int32_t core_sysdep_network_recv(void *handle, uint8_t *buffer, uint32_t len, uint32_t timeout_ms,
835                                  core_sysdep_addr_t *addr)
836 {
837     core_network_handle_t *network_handle = (core_network_handle_t *)handle;
838 
839     if (handle == NULL || buffer == NULL) {
840         return STATE_PORT_INPUT_NULL_POINTER;
841     }
842 
843     if (len == 0 || timeout_ms == 0) {
844         return STATE_PORT_INPUT_OUT_RANGE;
845     }
846 
847     if (network_handle->socket_type == CORE_SYSDEP_SOCKET_TCP_CLIENT) {
848         if (network_handle->cred == NULL) {
849             return _core_sysdep_network_tcp_recv(network_handle, buffer, len, timeout_ms);
850         } else {
851             if (network_handle->cred->option == AIOT_SYSDEP_NETWORK_CRED_NONE) {
852                 return _core_sysdep_network_tcp_recv(network_handle, buffer, len, timeout_ms);
853             }
854 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
855             else {
856                 return _core_sysdep_network_mbedtls_recv(network_handle, buffer, len, timeout_ms);
857             }
858 #endif
859         }
860     } else if (network_handle->socket_type == CORE_SYSDEP_SOCKET_TCP_SERVER) {
861         return STATE_PORT_TCP_SERVER_NOT_IMPLEMENT;
862     } else if (network_handle->socket_type == CORE_SYSDEP_SOCKET_UDP_CLIENT) {
863         if (network_handle->cred == NULL) {
864             return STATE_PORT_UDP_CLIENT_NOT_IMPLEMENT;
865         } else {
866             if (network_handle->cred->option == AIOT_SYSDEP_NETWORK_CRED_NONE) {
867                 return STATE_PORT_UDP_CLIENT_NOT_IMPLEMENT;
868             }
869 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
870             else {
871                 return _core_sysdep_network_mbedtls_recv(network_handle, buffer, len, timeout_ms);
872             }
873 #endif
874         }
875     } else if (network_handle->socket_type == CORE_SYSDEP_SOCKET_UDP_SERVER) {
876         return _core_sysdep_network_udp_recv(network_handle, buffer, len, timeout_ms, addr);
877     }
878 
879     printf("unknown nwk type\n");
880 
881     return STATE_PORT_NETWORK_UNKNOWN_SOCKET_TYPE;
882 }
883 
_core_sysdep_network_tcp_send(core_network_handle_t * network_handle,uint8_t * buffer,uint32_t len,uint32_t timeout_ms)884 int32_t _core_sysdep_network_tcp_send(core_network_handle_t *network_handle, uint8_t *buffer, uint32_t len,
885                                       uint32_t timeout_ms)
886 {
887     int res = 0;
888     int32_t send_bytes = 0;
889     ssize_t send_res = 0;
890     uint64_t timestart_ms = 0, timenow_ms = 0, timeselect_ms = 0;
891     fd_set send_sets;
892     struct timeval timestart, timenow, timeselect;
893 
894     FD_ZERO(&send_sets);
895     FD_SET(network_handle->fd, &send_sets);
896 
897     /* Start Time */
898     gettimeofday(&timestart, NULL);
899     timestart_ms = timestart.tv_sec * 1000 + timestart.tv_usec / 1000;
900     timenow_ms = timestart_ms;
901 
902     do {
903         gettimeofday(&timenow, NULL);
904         timenow_ms = timenow.tv_sec * 1000 + timenow.tv_usec / 1000;
905 
906         if (timenow_ms - timestart_ms >= timenow_ms ||
907             timeout_ms - (timenow_ms - timestart_ms) > timeout_ms) {
908             break;
909         }
910 
911         timeselect_ms = timeout_ms - (timenow_ms - timestart_ms);
912         timeselect.tv_sec = timeselect_ms / 1000;
913         timeselect.tv_usec = timeselect_ms % 1000 * 1000;
914 
915         res = select(network_handle->fd + 1, NULL, &send_sets, NULL, &timeselect);
916         if (res == 0) {
917             printf("_core_sysdep_network_tcp_send, nwk select timeout\n");
918             continue;
919         } else if (res < 0) {
920             printf("_core_sysdep_network_tcp_send, errno: %d\n", errno);
921             perror("_core_sysdep_network_tcp_send, nwk select failed: ");
922             return STATE_PORT_NETWORK_SELECT_FAILED;
923         } else {
924             if (FD_ISSET(network_handle->fd, &send_sets)) {
925                 send_res = send(network_handle->fd, buffer + send_bytes, len - send_bytes, 0);
926                 if (send_res == 0) {
927                     printf("_core_sysdep_network_tcp_send, nwk connection closed\n");
928                     return STATE_PORT_NETWORK_SEND_CONNECTION_CLOSED;
929                 } else if (send_res < 0) {
930                     printf("_core_sysdep_network_tcp_send, errno: %d\n", errno);
931                     perror("_core_sysdep_network_tcp_send, nwk recv error: ");
932                     if (errno == EINTR) {
933                         continue;
934                     }
935                     return STATE_PORT_NETWORK_SEND_FAILED;
936                 } else {
937                     send_bytes += send_res;
938                     if (send_bytes == len) {
939                         break;
940                     }
941                 }
942             }
943         }
944     } while (((timenow_ms - timestart_ms) < timeout_ms) && (send_bytes < len));
945 
946     return send_bytes;
947 }
948 
949 
_core_sysdep_network_udp_send(core_network_handle_t * network_handle,uint8_t * buffer,uint32_t len,uint32_t timeout_ms,core_sysdep_addr_t * addr)950 int32_t _core_sysdep_network_udp_send(core_network_handle_t *network_handle, uint8_t *buffer, uint32_t len, uint32_t timeout_ms, core_sysdep_addr_t *addr)
951 {
952     int res;
953     struct sockaddr_in cliaddr;
954     fd_set write_fds;
955     struct timeval timeout = {timeout_ms / 1000, (timeout_ms % 1000) * 1000};
956 
957     if (addr == NULL) {
958         printf("invalid parameter addr\n");
959         return STATE_PORT_NETWORK_SEND_FAILED;
960     }
961 
962     FD_ZERO(&write_fds);
963     FD_SET(network_handle->fd, &write_fds);
964 
965     res = select(network_handle->fd + 1, NULL, &write_fds, NULL, &timeout);
966     if (res == 0) {
967         printf("select timeout\n");
968         return 0;
969     } else if (res < 0) {
970         printf("_linux_nwk_udp_write select errno: %d\n", errno);
971         perror("_linux_nwk_udp_write select error");
972         return STATE_PORT_NETWORK_SELECT_FAILED;
973     }
974 
975     res = inet_aton((char *)addr->addr, &cliaddr.sin_addr);
976     if (res < 0) {
977         printf("sys_nwk_write, addr error\r\n");
978         return STATE_PORT_NETWORK_SEND_FAILED;
979     }
980 
981     cliaddr.sin_family = AF_INET;
982     cliaddr.sin_port = htons(addr->port);
983 
984     res = sendto(network_handle->fd, buffer, len, 0, (struct sockaddr *)&cliaddr, sizeof(struct sockaddr_in));
985     if (res < 0) {
986         printf("_linux_nwk_udp_write errno: %d\n", errno);
987         perror("_linux_nwk_udp_write error");
988         return STATE_PORT_NETWORK_SEND_FAILED;
989     }
990 
991     return res;
992 }
993 
994 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
_core_sysdep_network_mbedtls_send(core_network_handle_t * network_handle,uint8_t * buffer,uint32_t len,uint32_t timeout_ms)995 int32_t _core_sysdep_network_mbedtls_send(core_network_handle_t *network_handle, uint8_t *buffer, uint32_t len,
996         uint32_t timeout_ms)
997 {
998     int32_t res = 0;
999     int32_t send_bytes = 0;
1000     uint64_t timestart_ms = 0, timenow_ms = 0;
1001     struct timeval timestart, timenow, timeout;
1002 
1003     /* timeout */
1004     timeout.tv_sec = timeout_ms / 1000;
1005     timeout.tv_usec = (timeout_ms % 1000) * 1000;
1006 
1007     /* Start Time */
1008     gettimeofday(&timestart, NULL);
1009     timestart_ms = timestart.tv_sec * 1000 + timestart.tv_usec / 1000;
1010     timenow_ms = timestart_ms;
1011 
1012     res = setsockopt(network_handle->mbedtls.net_ctx.fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout));
1013     if (res < 0) {
1014         printf("setsockopt error, errno: %d\r\n", errno);
1015         return STATE_PORT_TLS_SEND_FAILED;
1016     }
1017 
1018     do {
1019         gettimeofday(&timenow, NULL);
1020         timenow_ms = timenow.tv_sec * 1000 + timenow.tv_usec / 1000;
1021 
1022         if (timenow_ms - timestart_ms >= timenow_ms ||
1023             timeout_ms - (timenow_ms - timestart_ms) > timeout_ms) {
1024             break;
1025         }
1026 
1027         res = mbedtls_ssl_write(&network_handle->mbedtls.ssl_ctx, buffer + send_bytes, len - send_bytes);
1028         if (res < 0) {
1029             if (res != MBEDTLS_ERR_SSL_WANT_READ &&
1030                 res != MBEDTLS_ERR_SSL_WANT_WRITE) {
1031                 if (send_bytes == 0) {
1032                     printf("mbedtls_ssl_send error, res: -0x%04X\n", -res);
1033                     if (res == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
1034                         return STATE_PORT_TLS_SEND_CONNECTION_CLOSED;
1035                     } else if (res == MBEDTLS_ERR_SSL_INVALID_RECORD) {
1036                         return STATE_PORT_TLS_INVALID_RECORD;
1037                     } else {
1038                         return STATE_PORT_TLS_SEND_FAILED;
1039                     }
1040                 }
1041                 break;
1042             }
1043         } else if (res == 0) {
1044             break;
1045         } else {
1046             send_bytes += res;
1047         }
1048     } while (((timenow_ms - timestart_ms) < timeout_ms) && (send_bytes < len));
1049 
1050     return send_bytes;
1051 }
1052 #endif
1053 
core_sysdep_network_send(void * handle,uint8_t * buffer,uint32_t len,uint32_t timeout_ms,core_sysdep_addr_t * addr)1054 int32_t core_sysdep_network_send(void *handle, uint8_t *buffer, uint32_t len, uint32_t timeout_ms,
1055                                  core_sysdep_addr_t *addr)
1056 {
1057     core_network_handle_t *network_handle = (core_network_handle_t *)handle;
1058 
1059     if (handle == NULL || buffer == NULL) {
1060         printf("invalid parameter\n");
1061         return STATE_PORT_INPUT_NULL_POINTER;
1062     }
1063     if (len == 0 || timeout_ms == 0) {
1064         return STATE_PORT_INPUT_OUT_RANGE;
1065     }
1066 
1067     if (network_handle->socket_type == CORE_SYSDEP_SOCKET_TCP_CLIENT) {
1068         if (network_handle->cred == NULL) {
1069             return _core_sysdep_network_tcp_send(network_handle, buffer, len, timeout_ms);
1070         } else {
1071             if (network_handle->cred->option == AIOT_SYSDEP_NETWORK_CRED_NONE) {
1072                 return _core_sysdep_network_tcp_send(network_handle, buffer, len, timeout_ms);
1073             }
1074 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
1075             else {
1076                 return _core_sysdep_network_mbedtls_send(network_handle, buffer, len, timeout_ms);
1077             }
1078 #endif
1079         }
1080     } else if (network_handle->socket_type == CORE_SYSDEP_SOCKET_TCP_SERVER) {
1081         return STATE_PORT_TCP_SERVER_NOT_IMPLEMENT;
1082     } else if (network_handle->socket_type == CORE_SYSDEP_SOCKET_UDP_CLIENT) {
1083         if (network_handle->cred == NULL) {
1084             return STATE_PORT_UDP_CLIENT_NOT_IMPLEMENT;
1085         } else {
1086             if (network_handle->cred->option == AIOT_SYSDEP_NETWORK_CRED_NONE) {
1087                 return STATE_PORT_UDP_CLIENT_NOT_IMPLEMENT;
1088             }
1089 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
1090             else {
1091                 return _core_sysdep_network_mbedtls_send(network_handle, buffer, len, timeout_ms);
1092             }
1093 #endif
1094         }
1095     } else if (network_handle->socket_type == CORE_SYSDEP_SOCKET_UDP_SERVER) {
1096         return _core_sysdep_network_udp_send(network_handle, buffer, len, timeout_ms, addr);
1097     }
1098 
1099     printf("unknown nwk type\n");
1100 
1101     return STATE_PORT_NETWORK_UNKNOWN_SOCKET_TYPE;
1102 }
1103 
_core_sysdep_network_tcp_disconnect(core_network_handle_t * network_handle)1104 static void _core_sysdep_network_tcp_disconnect(core_network_handle_t *network_handle)
1105 {
1106     shutdown(network_handle->fd, 2);
1107     close(network_handle->fd);
1108 }
1109 
1110 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
_core_sysdep_network_mbedtls_disconnect(core_network_handle_t * network_handle)1111 static void _core_sysdep_network_mbedtls_disconnect(core_network_handle_t *network_handle)
1112 {
1113     mbedtls_ssl_close_notify(&network_handle->mbedtls.ssl_ctx);
1114     mbedtls_net_free(&network_handle->mbedtls.net_ctx);
1115     if (network_handle->cred->option == AIOT_SYSDEP_NETWORK_CRED_SVRCERT_CA) {
1116         mbedtls_x509_crt_free(&network_handle->mbedtls.x509_server_cert);
1117         mbedtls_x509_crt_free(&network_handle->mbedtls.x509_client_cert);
1118         mbedtls_pk_free(&network_handle->mbedtls.x509_client_pk);
1119     }
1120     mbedtls_ssl_free(&network_handle->mbedtls.ssl_ctx);
1121     mbedtls_ssl_config_free(&network_handle->mbedtls.ssl_config);
1122     g_mbedtls_total_mem_used = g_mbedtls_max_mem_used = 0;
1123 }
1124 #endif
1125 
core_sysdep_network_deinit(void ** handle)1126 int32_t core_sysdep_network_deinit(void **handle)
1127 {
1128     core_network_handle_t *network_handle = NULL;
1129 
1130     if (handle == NULL || *handle == NULL) {
1131         return STATE_PORT_INPUT_NULL_POINTER;
1132     }
1133 
1134     network_handle = *(core_network_handle_t **)handle;
1135 
1136     /* Shutdown both send and receive operations. */
1137     if ((network_handle->socket_type == CORE_SYSDEP_SOCKET_TCP_CLIENT ||
1138             network_handle->socket_type == CORE_SYSDEP_SOCKET_UDP_CLIENT) && network_handle->host != NULL) {
1139         if (network_handle->cred == NULL) {
1140             _core_sysdep_network_tcp_disconnect(network_handle);
1141         } else {
1142             if (network_handle->cred->option == AIOT_SYSDEP_NETWORK_CRED_NONE) {
1143                 _core_sysdep_network_tcp_disconnect(network_handle);
1144             }
1145 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
1146             else {
1147                 _core_sysdep_network_mbedtls_disconnect(network_handle);
1148             }
1149 #endif
1150         }
1151     }
1152 
1153     if (network_handle->host != NULL) {
1154         aos_free(network_handle->host);
1155         network_handle->host = NULL;
1156     }
1157     if (network_handle->cred != NULL) {
1158         aos_free(network_handle->cred);
1159         network_handle->cred = NULL;
1160     }
1161 #ifdef CORE_SYSDEP_MBEDTLS_ENABLED
1162     if (network_handle->psk.psk_id != NULL) {
1163         aos_free(network_handle->psk.psk_id);
1164         network_handle->psk.psk_id = NULL;
1165     }
1166     if (network_handle->psk.psk != NULL) {
1167         aos_free(network_handle->psk.psk);
1168         network_handle->psk.psk = NULL;
1169     }
1170 #endif
1171 
1172     aos_free(network_handle);
1173     *handle = NULL;
1174 
1175     return 0;
1176 }
1177 
core_sysdep_rand(uint8_t * output,uint32_t output_len)1178 void core_sysdep_rand(uint8_t *output, uint32_t output_len)
1179 {
1180     uint32_t idx = 0, bytes = 0, rand_num = 0;
1181     struct timeval time;
1182 
1183     memset(&time, 0, sizeof(struct timeval));
1184     gettimeofday(&time, NULL);
1185 
1186     aos_srand((unsigned int)(time.tv_sec * 1000 + time.tv_usec / 1000) + aos_rand());
1187 
1188     for (idx = 0; idx < output_len;) {
1189         if (output_len - idx < 4) {
1190             bytes = output_len - idx;
1191         } else {
1192             bytes = 4;
1193         }
1194         rand_num = aos_rand();
1195         while (bytes-- > 0) {
1196             output[idx++] = (uint8_t)(rand_num >> bytes * 8);
1197         }
1198     }
1199 }
1200 
core_sysdep_mutex_init(void)1201 void *core_sysdep_mutex_init(void)
1202 {
1203     int res = 0;
1204     aos_mutex_t mutex;
1205     res =  aos_mutex_new(&mutex);
1206     if(res != 0) {
1207         return NULL;
1208     }
1209 
1210     return mutex;
1211 }
1212 
core_sysdep_mutex_lock(void * hdl)1213 void core_sysdep_mutex_lock(void *hdl)
1214 {
1215     aos_mutex_t mutex;
1216     if (hdl == NULL) {
1217         return;
1218     }
1219     mutex = (aos_mutex_t)hdl;
1220     aos_mutex_lock(&mutex, -1);
1221 }
1222 
core_sysdep_mutex_unlock(void * hdl)1223 void core_sysdep_mutex_unlock(void *hdl)
1224 {
1225     aos_mutex_t mutex;
1226     if (hdl == NULL) {
1227         return;
1228     }
1229     mutex = (aos_mutex_t)hdl;
1230     aos_mutex_unlock(&mutex);
1231 }
1232 
core_sysdep_mutex_deinit(void ** hdl)1233 void core_sysdep_mutex_deinit(void **hdl)
1234 {
1235     aos_mutex_t mutex;
1236     if (hdl == NULL) {
1237         return;
1238     }
1239     mutex = (aos_mutex_t)(*hdl);
1240     aos_mutex_free(&mutex);
1241     *hdl = NULL;
1242 }
1243 
1244 aiot_sysdep_portfile_t g_aiot_sysdep_portfile = {
1245     core_sysdep_malloc,
1246     core_sysdep_free,
1247     core_sysdep_time,
1248     core_sysdep_sleep,
1249     core_sysdep_network_init,
1250     core_sysdep_network_setopt,
1251     core_sysdep_network_establish,
1252     core_sysdep_network_recv,
1253     core_sysdep_network_send,
1254     core_sysdep_network_deinit,
1255     core_sysdep_rand,
1256     core_sysdep_mutex_init,
1257     core_sysdep_mutex_lock,
1258     core_sysdep_mutex_unlock,
1259     core_sysdep_mutex_deinit,
1260 };
1261 
1262