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, ×elect);
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(×tart, 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, ×elect);
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(×tart, 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, ×elect);
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(×tart, 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