1 /**
2 * @file aiot_http_api.c
3 * @brief HTTP模块实现, 其中包含了向物联网平台认证和上报数据的API接口
4 * @date 2019-12-27
5 *
6 * @copyright Copyright (C) 2015-2018 Alibaba Group Holding Limited
7 *
8 */
9
10 #include "core_http.h"
11
_core_http_exec_inc(core_http_handle_t * http_handle)12 static void _core_http_exec_inc(core_http_handle_t *http_handle)
13 {
14 http_handle->sysdep->core_sysdep_mutex_lock(http_handle->data_mutex);
15 http_handle->core_exec_count++;
16 http_handle->sysdep->core_sysdep_mutex_unlock(http_handle->data_mutex);
17 }
18
_core_http_exec_dec(core_http_handle_t * http_handle)19 static void _core_http_exec_dec(core_http_handle_t *http_handle)
20 {
21 http_handle->sysdep->core_sysdep_mutex_lock(http_handle->data_mutex);
22 http_handle->core_exec_count--;
23 http_handle->sysdep->core_sysdep_mutex_unlock(http_handle->data_mutex);
24 }
25
_core_http_sysdep_return(int32_t sysdep_code,int32_t core_code)26 static int32_t _core_http_sysdep_return(int32_t sysdep_code, int32_t core_code)
27 {
28 if (sysdep_code >= (STATE_PORT_BASE - 0x00FF) && sysdep_code < (STATE_PORT_BASE)) {
29 return sysdep_code;
30 } else {
31 return core_code;
32 }
33 }
34
_core_http_connect(core_http_handle_t * http_handle)35 static int32_t _core_http_connect(core_http_handle_t *http_handle)
36 {
37 int32_t res = STATE_SUCCESS;
38
39 /* disconnect first if network is already established */
40 if (http_handle->network_handle != NULL) {
41 http_handle->sysdep->core_sysdep_network_deinit(&http_handle->network_handle);
42 }
43
44 /* establish network connection */
45 core_sysdep_socket_type_t socket_type = CORE_SYSDEP_SOCKET_TCP_CLIENT;
46
47 if (http_handle->host == NULL) {
48 return STATE_USER_INPUT_MISSING_HOST;
49 }
50
51 http_handle->network_handle = http_handle->sysdep->core_sysdep_network_init();
52 if (http_handle->network_handle == NULL) {
53 return STATE_SYS_DEPEND_MALLOC_FAILED;
54 }
55
56 if ((res = http_handle->sysdep->core_sysdep_network_setopt(http_handle->network_handle, CORE_SYSDEP_NETWORK_SOCKET_TYPE,
57 &socket_type)) < 0 ||
58 (res = http_handle->sysdep->core_sysdep_network_setopt(http_handle->network_handle, CORE_SYSDEP_NETWORK_HOST,
59 http_handle->host)) < 0 ||
60 (res = http_handle->sysdep->core_sysdep_network_setopt(http_handle->network_handle, CORE_SYSDEP_NETWORK_PORT,
61 &http_handle->port)) < 0 ||
62 (res = http_handle->sysdep->core_sysdep_network_setopt(http_handle->network_handle,
63 CORE_SYSDEP_NETWORK_CONNECT_TIMEOUT_MS,
64 &http_handle->connect_timeout_ms)) < 0) {
65 http_handle->sysdep->core_sysdep_network_deinit(&http_handle->network_handle);
66 return _core_http_sysdep_return(res, STATE_SYS_DEPEND_NWK_INVALID_OPTION);
67 }
68
69 if (http_handle->cred != NULL) {
70 res = http_handle->sysdep->core_sysdep_network_setopt(http_handle->network_handle, CORE_SYSDEP_NETWORK_CRED,
71 http_handle->cred);
72 if (res < STATE_SUCCESS) {
73 http_handle->sysdep->core_sysdep_network_deinit(&http_handle->network_handle);
74 return _core_http_sysdep_return(res, STATE_SYS_DEPEND_NWK_INVALID_CRED);
75 }
76 }
77
78 res = http_handle->sysdep->core_sysdep_network_establish(http_handle->network_handle);
79 if (res < STATE_SUCCESS) {
80 http_handle->sysdep->core_sysdep_network_deinit(&http_handle->network_handle);
81 return _core_http_sysdep_return(res, STATE_SYS_DEPEND_NWK_EST_FAILED);
82 }
83
84 return STATE_SUCCESS;
85 }
86
_core_http_send(core_http_handle_t * http_handle,uint8_t * buffer,uint32_t len,uint32_t timeout_ms)87 static int32_t _core_http_send(core_http_handle_t *http_handle, uint8_t *buffer, uint32_t len, uint32_t timeout_ms)
88 {
89 int32_t res = STATE_SUCCESS;
90
91 if (http_handle->network_handle != NULL) {
92 res = http_handle->sysdep->core_sysdep_network_send(http_handle->network_handle, buffer, len, timeout_ms, NULL);
93 if (res < STATE_SUCCESS) {
94 http_handle->sysdep->core_sysdep_network_deinit(&http_handle->network_handle);
95 core_log(http_handle->sysdep, STATE_HTTP_LOG_DISCONNECT, "HTTP network error when sending data, disconnect\r\n");
96 res = _core_http_sysdep_return(res, STATE_SYS_DEPEND_NWK_SEND_ERR);
97 } else if (res != len) {
98 res = STATE_SYS_DEPEND_NWK_WRITE_LESSDATA;
99 }
100 } else {
101 res = STATE_SYS_DEPEND_NWK_CLOSED;
102 }
103
104 return res;
105 }
106
_core_http_send_body(core_http_handle_t * http_handle,uint8_t * content,uint32_t len)107 static int32_t _core_http_send_body(core_http_handle_t *http_handle, uint8_t *content, uint32_t len)
108 {
109 int32_t res = STATE_SUCCESS;
110
111 core_log_hexdump(STATE_HTTP_LOG_SEND_CONTENT, '>', content, len);
112
113 http_handle->sysdep->core_sysdep_mutex_lock(http_handle->send_mutex);
114 res = _core_http_send(http_handle, content, len, http_handle->send_timeout_ms);
115 http_handle->sysdep->core_sysdep_mutex_unlock(http_handle->send_mutex);
116
117 return res;
118 }
119
_core_http_header_print(core_http_handle_t * http_handle,char * prefix,char * header,uint32_t header_len)120 static void _core_http_header_print(core_http_handle_t *http_handle, char *prefix, char *header, uint32_t header_len)
121 {
122 char *prev = header, *pos = header;
123 uint32_t line_len = 0;
124 while (pos != header + header_len) {
125 if (*(pos) == '\n' && *(pos - 1) == '\r') {
126 line_len = (uint32_t)(pos - prev + 1);
127 core_log3(http_handle->sysdep, STATE_HTTP_LOG_SEND_HEADER, "%s %.*s", prefix, &line_len, prev);
128 prev = pos + 1;
129 }
130 pos++;
131 }
132 }
133
_core_http_send_header(core_http_handle_t * http_handle,char * method,char * path,char * host,char * header,char * content_lenstr)134 static int32_t _core_http_send_header(core_http_handle_t *http_handle, char *method, char *path, char *host,
135 char *header, char *content_lenstr)
136 {
137 int32_t res = STATE_SUCCESS;
138 char *combine_header = NULL;
139 char *combine_header_src[] = { method, path, host, header, content_lenstr};
140 uint32_t combine_header_len = 0;
141
142 res = core_sprintf(http_handle->sysdep, &combine_header, "%s %s HTTP/1.1\r\nHost: %s\r\n%sContent-Length: %s\r\n\r\n",
143 combine_header_src, sizeof(combine_header_src) / sizeof(char *), CORE_HTTP_MODULE_NAME);
144 if (res < STATE_SUCCESS) {
145 return res;
146 }
147 combine_header_len = (uint32_t)strlen(combine_header);
148
149 _core_http_header_print(http_handle, ">", combine_header, combine_header_len);
150
151 http_handle->sysdep->core_sysdep_mutex_lock(http_handle->send_mutex);
152 res = _core_http_send(http_handle, (uint8_t *)combine_header, combine_header_len, http_handle->send_timeout_ms);
153 http_handle->sysdep->core_sysdep_mutex_unlock(http_handle->send_mutex);
154
155 http_handle->sysdep->core_sysdep_free(combine_header);
156
157 return res;
158 }
159
core_http_init(void)160 void *core_http_init(void)
161 {
162 core_http_handle_t *http_handle = NULL;
163 aiot_sysdep_portfile_t *sysdep = NULL;
164
165 sysdep = aiot_sysdep_get_portfile();
166 if (sysdep == NULL) {
167 return NULL;
168 }
169
170 http_handle = sysdep->core_sysdep_malloc(sizeof(core_http_handle_t), CORE_HTTP_MODULE_NAME);
171 if (http_handle == NULL) {
172 return NULL;
173 }
174 memset(http_handle, 0, sizeof(core_http_handle_t));
175
176 http_handle->sysdep = sysdep;
177 http_handle->connect_timeout_ms = CORE_HTTP_DEFAULT_CONNECT_TIMEOUT_MS;
178 http_handle->send_timeout_ms = CORE_HTTP_DEFAULT_SEND_TIMEOUT_MS;
179 http_handle->recv_timeout_ms = CORE_HTTP_DEFAULT_RECV_TIMEOUT_MS;
180 http_handle->header_line_max_len = CORE_HTTP_DEFAULT_HEADER_LINE_MAX_LEN;
181 http_handle->body_buffer_max_len = CORE_HTTP_DEFAULT_BODY_MAX_LEN;
182 http_handle->deinit_timeout_ms = CORE_HTTP_DEFAULT_DEINIT_TIMEOUT_MS;
183
184 http_handle->data_mutex = http_handle->sysdep->core_sysdep_mutex_init();
185 http_handle->send_mutex = http_handle->sysdep->core_sysdep_mutex_init();
186 http_handle->recv_mutex = http_handle->sysdep->core_sysdep_mutex_init();
187
188 http_handle->core_exec_enabled = 1;
189
190 return http_handle;
191 }
192
core_http_setopt(void * handle,core_http_option_t option,void * data)193 int32_t core_http_setopt(void *handle, core_http_option_t option, void *data)
194 {
195 int32_t res = STATE_SUCCESS;
196 core_http_handle_t *http_handle = (core_http_handle_t *)handle;
197
198 if (http_handle == NULL || data == NULL) {
199 return STATE_USER_INPUT_NULL_POINTER;
200 }
201
202 if (option >= CORE_HTTPOPT_MAX) {
203 return STATE_USER_INPUT_OUT_RANGE;
204 }
205
206 if (http_handle->core_exec_enabled == 0) {
207 return STATE_USER_INPUT_EXEC_DISABLED;
208 }
209
210 _core_http_exec_inc(http_handle);
211
212 http_handle->sysdep->core_sysdep_mutex_lock(http_handle->data_mutex);
213 switch (option) {
214 case CORE_HTTPOPT_HOST: {
215 res = core_strdup(http_handle->sysdep, &http_handle->host, (char *)data, CORE_HTTP_MODULE_NAME);
216 }
217 break;
218 case CORE_HTTPOPT_PORT: {
219 http_handle->port = *(uint16_t *)data;
220 }
221 break;
222 case CORE_HTTPOPT_NETWORK_CRED: {
223 if (http_handle->cred != NULL) {
224 http_handle->sysdep->core_sysdep_free(http_handle->cred);
225 http_handle->cred = NULL;
226 }
227 http_handle->cred = http_handle->sysdep->core_sysdep_malloc(sizeof(aiot_sysdep_network_cred_t), CORE_HTTP_MODULE_NAME);
228 if (http_handle->cred != NULL) {
229 memset(http_handle->cred, 0, sizeof(aiot_sysdep_network_cred_t));
230 memcpy(http_handle->cred, data, sizeof(aiot_sysdep_network_cred_t));
231 } else {
232 res = STATE_SYS_DEPEND_MALLOC_FAILED;
233 }
234
235 }
236 break;
237 case CORE_HTTPOPT_CONNECT_TIMEOUT_MS: {
238 http_handle->connect_timeout_ms = *(uint32_t *)data;
239 }
240 break;
241 case CORE_HTTPOPT_SEND_TIMEOUT_MS: {
242 http_handle->send_timeout_ms = *(uint32_t *)data;
243 }
244 break;
245 case CORE_HTTPOPT_RECV_TIMEOUT_MS: {
246 http_handle->recv_timeout_ms = *(uint32_t *)data;
247 }
248 break;
249 case CORE_HTTPOPT_DEINIT_TIMEOUT_MS: {
250 http_handle->deinit_timeout_ms = *(uint32_t *)data;
251 }
252 break;
253 case CORE_HTTPOPT_HEADER_LINE_MAX_LEN: {
254 http_handle->header_line_max_len = *(uint32_t *)data;
255 }
256 break;
257 case CORE_HTTPOPT_BODY_BUFFER_MAX_LEN: {
258 http_handle->body_buffer_max_len = *(uint32_t *)data;
259 }
260 break;
261 case CORE_HTTPOPT_EVENT_HANDLER: {
262 http_handle->event_handler = (aiot_http_event_handler_t)data;
263 }
264 break;
265 case CORE_HTTPOPT_USERDATA: {
266 http_handle->core_userdata = data;
267 }
268 break;
269 case CORE_HTTPOPT_RECV_HANDLER: {
270 http_handle->core_recv_handler = (aiot_http_recv_handler_t)data;
271 }
272 break;
273 default: {
274 res = STATE_USER_INPUT_UNKNOWN_OPTION;
275 }
276 break;
277 }
278 http_handle->sysdep->core_sysdep_mutex_unlock(http_handle->data_mutex);
279
280 _core_http_exec_dec(http_handle);
281
282 return res;
283 }
284
core_http_connect(void * handle)285 int32_t core_http_connect(void *handle)
286 {
287 int32_t res = STATE_SUCCESS;
288 core_http_handle_t *http_handle = (core_http_handle_t *)handle;
289
290 if (http_handle == NULL) {
291 return STATE_USER_INPUT_NULL_POINTER;
292 }
293
294 if (http_handle->core_exec_enabled == 0) {
295 return STATE_USER_INPUT_EXEC_DISABLED;
296 }
297
298 _core_http_exec_inc(http_handle);
299
300 /* connect to host */
301 http_handle->sysdep->core_sysdep_mutex_lock(http_handle->send_mutex);
302 http_handle->sysdep->core_sysdep_mutex_lock(http_handle->recv_mutex);
303 res = _core_http_connect(http_handle);
304 http_handle->sysdep->core_sysdep_mutex_unlock(http_handle->recv_mutex);
305 http_handle->sysdep->core_sysdep_mutex_unlock(http_handle->send_mutex);
306
307 _core_http_exec_dec(http_handle);
308
309 return res;
310 }
311
core_http_send(void * handle,const core_http_request_t * request)312 int32_t core_http_send(void *handle, const core_http_request_t *request)
313 {
314 int32_t res = STATE_SUCCESS;
315 char content_lenstr[11] = {0};
316 core_http_handle_t *http_handle = (core_http_handle_t *)handle;
317
318 if (http_handle == NULL || request == NULL ||
319 request->path == NULL || request->method == NULL) {
320 return STATE_USER_INPUT_NULL_POINTER;
321 }
322
323 if (http_handle->host == NULL) {
324 return STATE_USER_INPUT_MISSING_HOST;
325 }
326
327 if (http_handle->network_handle == NULL) {
328 return STATE_SYS_DEPEND_NWK_CLOSED;
329 }
330
331 if (http_handle->core_exec_enabled == 0) {
332 return STATE_USER_INPUT_EXEC_DISABLED;
333 }
334
335 memset(&http_handle->session, 0, sizeof(core_http_session_t));
336
337 _core_http_exec_inc(http_handle);
338
339 /* send http header */
340 core_uint2str(request->content_len, content_lenstr, NULL);
341 res = _core_http_send_header(http_handle, request->method, request->path, http_handle->host, request->header,
342 content_lenstr);
343 if (res < STATE_SUCCESS) {
344 _core_http_exec_dec(http_handle);
345 return res;
346 } else {
347 res = STATE_SUCCESS;
348 }
349
350 /* send http content */
351 if (request->content != NULL && request->content_len > 0) {
352 res = _core_http_send_body(http_handle, request->content, request->content_len);
353 if (res < STATE_SUCCESS) {
354 _core_http_exec_dec(http_handle);
355 return res;
356 }
357 }
358
359 _core_http_exec_dec(http_handle);
360
361 return res;
362 }
363
_core_http_recv_status_code(core_http_handle_t * http_handle,uint32_t status_code)364 static void _core_http_recv_status_code(core_http_handle_t *http_handle, uint32_t status_code)
365 {
366 aiot_http_recv_t packet;
367
368 if (http_handle->core_recv_handler == NULL) {
369 return;
370 }
371
372 memset(&packet, 0, sizeof(aiot_http_recv_t));
373 packet.type = AIOT_HTTPRECV_STATUS_CODE;
374 packet.data.status_code.code = status_code;
375
376 http_handle->core_recv_handler(http_handle, &packet, http_handle->core_userdata);
377 }
378
_core_http_recv_header_pair(core_http_handle_t * http_handle,char * key,uint32_t key_len,char * value,uint32_t value_len)379 static void _core_http_recv_header_pair(core_http_handle_t *http_handle, char *key, uint32_t key_len, char *value,
380 uint32_t value_len)
381 {
382 char *pair_key = NULL, *pair_value = NULL;
383 aiot_http_recv_t packet;
384
385 if (http_handle->core_recv_handler == NULL) {
386 return;
387 }
388
389 pair_key = http_handle->sysdep->core_sysdep_malloc(key_len + 1, CORE_HTTP_MODULE_NAME);
390 if (pair_key == NULL) {
391 return;
392 }
393 memset(pair_key, 0, key_len + 1);
394 memcpy(pair_key, key, key_len);
395
396 pair_value = http_handle->sysdep->core_sysdep_malloc(value_len + 1, CORE_HTTP_MODULE_NAME);
397 if (pair_value == NULL) {
398 http_handle->sysdep->core_sysdep_free(pair_key);
399 return;
400 }
401 memset(pair_value, 0, value_len + 1);
402 memcpy(pair_value, value, value_len);
403
404 packet.type = AIOT_HTTPRECV_HEADER;
405 packet.data.header.key = pair_key;
406 packet.data.header.value = pair_value;
407
408 http_handle->core_recv_handler(http_handle, &packet, http_handle->core_userdata);
409
410 http_handle->sysdep->core_sysdep_free(pair_key);
411 http_handle->sysdep->core_sysdep_free(pair_value);
412 }
413
_core_http_recv(core_http_handle_t * http_handle,uint8_t * buffer,uint32_t len,uint32_t timeout_ms)414 static int32_t _core_http_recv(core_http_handle_t *http_handle, uint8_t *buffer, uint32_t len, uint32_t timeout_ms)
415 {
416 int32_t res = STATE_SUCCESS;
417
418 if (http_handle->network_handle != NULL) {
419 res = http_handle->sysdep->core_sysdep_network_recv(http_handle->network_handle, buffer, len, timeout_ms, NULL);
420 if (res < STATE_SUCCESS) {
421 http_handle->sysdep->core_sysdep_network_deinit(&http_handle->network_handle);
422 core_log(http_handle->sysdep, STATE_HTTP_LOG_DISCONNECT, "HTTP network error when receving data, disconnect\r\n");
423 res = _core_http_sysdep_return(res, STATE_SYS_DEPEND_NWK_RECV_ERR);
424 }
425 } else {
426 res = STATE_SYS_DEPEND_NWK_CLOSED;
427 }
428
429 return res;
430 }
431
_core_http_recv_header(core_http_handle_t * http_handle,uint32_t * body_total_len)432 static int32_t _core_http_recv_header(core_http_handle_t *http_handle, uint32_t *body_total_len)
433 {
434 int32_t res = STATE_SUCCESS;
435 char *line = NULL;
436 uint32_t idx = 0, line_max_len = http_handle->header_line_max_len;
437 uint64_t timenow_ms = 0;
438
439 line = http_handle->sysdep->core_sysdep_malloc(line_max_len, CORE_HTTP_MODULE_NAME);
440 if (line == NULL) {
441 return STATE_SYS_DEPEND_MALLOC_FAILED;
442 }
443 memset(line, 0, line_max_len);
444
445 timenow_ms = http_handle->sysdep->core_sysdep_time();
446 for (idx = 0; idx < line_max_len;) {
447 if (timenow_ms > http_handle->sysdep->core_sysdep_time()) {
448 timenow_ms = http_handle->sysdep->core_sysdep_time();
449 }
450 if (http_handle->sysdep->core_sysdep_time() - timenow_ms >= http_handle->recv_timeout_ms) {
451 res = STATE_HTTP_HEADER_INVALID;
452 break;
453 }
454 if (idx + 2 > line_max_len) {
455 res = STATE_HTTP_HEADER_BUFFER_TOO_SHORT;
456 break;
457 }
458 /* read http header, "\r\n" in the end */
459 if ((res = _core_http_recv(http_handle, (uint8_t *)&line[idx], 1,
460 http_handle->recv_timeout_ms)) < STATE_SUCCESS) {
461 break;
462 }
463 idx++;
464 if (res == 0 || (line[idx - 1] != '\r')) {
465 continue;
466 }
467 if ((res = _core_http_recv(http_handle, (uint8_t *)&line[idx], 1,
468 http_handle->recv_timeout_ms)) < STATE_SUCCESS) {
469 break;
470 }
471 idx++;
472 if (res == 0 || (line[idx - 1] != '\n')) {
473 continue;
474 }
475
476 core_log2(http_handle->sysdep, STATE_HTTP_LOG_RECV_HEADER, "< %.*s", &idx, line);
477 /* next line should be http response body */
478 if (idx == 2) {
479 break;
480 }
481 /* status code */
482 if ((idx > (strlen("HTTP/1.1 ") + 3)) && (memcmp(line, "HTTP/1.1 ", strlen("HTTP/1.1 "))) == 0) {
483 uint32_t status_code = 0, code_idx = 0;
484 for (code_idx = strlen("HTTP/1.1 "); code_idx < idx; code_idx++) {
485 if (line[code_idx] < '0' || line[code_idx] > '9') {
486 break;
487 }
488 }
489 res = core_str2uint(&line[strlen("HTTP/1.1 ")], (code_idx - strlen("HTTP/1.1 ")), &status_code);
490 if (res < STATE_SUCCESS) {
491 res = STATE_HTTP_STATUS_LINE_INVALID;
492 break;
493 }
494 _core_http_recv_status_code(http_handle, status_code);
495 }
496 /* header */
497 {
498 uint32_t deli_idx = 0;
499 for (deli_idx = 0; deli_idx < idx; deli_idx++) {
500 if (line[deli_idx] == ':' && line[deli_idx + 1] == ' ') {
501 if ((deli_idx + 2 == strlen("Content-Length: ")) && (memcmp(line, "Content-Length: ", deli_idx + 2) == 0)) {
502 core_str2uint(&line[deli_idx + 2], (uint32_t)(idx - deli_idx - 4), body_total_len);
503 }
504 _core_http_recv_header_pair(http_handle, line, deli_idx, &line[deli_idx + 2], (uint32_t)(idx - deli_idx - 4));
505 }
506 }
507 }
508 idx = 0;
509 memset(line, 0, line_max_len);
510 }
511
512 http_handle->sysdep->core_sysdep_free(line);
513
514 return res;
515 }
516
_core_http_recv_body(core_http_handle_t * http_handle,uint32_t body_total_len)517 static int32_t _core_http_recv_body(core_http_handle_t *http_handle, uint32_t body_total_len)
518 {
519 int32_t res = STATE_SUCCESS;
520 char *buffer = NULL;
521 uint32_t remaining_len = 0, buffer_len = 0;
522
523 if (http_handle->session.body_total_len == 0 && body_total_len == 0) {
524 return STATE_HTTP_READ_BODY_EMPTY;
525 }
526
527 if (body_total_len != 0) {
528 http_handle->session.body_total_len = body_total_len;
529 remaining_len = body_total_len;
530 } else {
531 remaining_len = http_handle->session.body_total_len - http_handle->session.body_read_len;
532 }
533
534 if (remaining_len == 0) {
535 return STATE_HTTP_READ_BODY_FINISHED;
536 }
537
538 buffer_len = (remaining_len < http_handle->body_buffer_max_len) ? (remaining_len) : (http_handle->body_buffer_max_len);
539
540 buffer = http_handle->sysdep->core_sysdep_malloc(buffer_len, CORE_HTTP_MODULE_NAME);
541 if (buffer == NULL) {
542 return STATE_SYS_DEPEND_MALLOC_FAILED;
543 }
544 memset(buffer, 0, buffer_len);
545
546 http_handle->sysdep->core_sysdep_mutex_lock(http_handle->recv_mutex);
547 res = _core_http_recv(http_handle, (uint8_t *)buffer, buffer_len, http_handle->recv_timeout_ms);
548 http_handle->sysdep->core_sysdep_mutex_unlock(http_handle->recv_mutex);
549 if (res > 0) {
550 aiot_http_recv_t packet;
551
552 core_log_hexdump(STATE_HTTP_LOG_RECV_CONTENT, '<', (uint8_t *)buffer, res);
553
554 if (http_handle->core_recv_handler != NULL) {
555 http_handle->session.body_read_len += res;
556 memset(&packet, 0, sizeof(aiot_http_recv_t));
557 packet.type = AIOT_HTTPRECV_BODY;
558 packet.data.body.buffer = (uint8_t *)buffer;
559 packet.data.body.len = res;
560
561 http_handle->core_recv_handler(http_handle, &packet, http_handle->core_userdata);
562 }
563 }
564 http_handle->sysdep->core_sysdep_free(buffer);
565
566 return res;
567 }
568
core_http_recv(void * handle)569 int32_t core_http_recv(void *handle)
570 {
571 int32_t res = STATE_SUCCESS;
572 uint32_t body_total_len = 0;
573 core_http_handle_t *http_handle = (core_http_handle_t *)handle;
574
575 if (http_handle == NULL) {
576 return STATE_USER_INPUT_NULL_POINTER;
577 }
578
579 if (http_handle->network_handle == NULL) {
580 return STATE_SYS_DEPEND_NWK_CLOSED;
581 }
582
583 if (http_handle->core_exec_enabled == 0) {
584 return STATE_USER_INPUT_EXEC_DISABLED;
585 }
586
587 _core_http_exec_inc(http_handle);
588
589 if (http_handle->session.sm == CORE_HTTP_SM_READ_HEADER) {
590 http_handle->sysdep->core_sysdep_mutex_lock(http_handle->recv_mutex);
591 res = _core_http_recv_header(http_handle, &body_total_len);
592 http_handle->sysdep->core_sysdep_mutex_unlock(http_handle->recv_mutex);
593 if (res < STATE_SUCCESS) {
594 _core_http_exec_dec(http_handle);
595 return res;
596 }
597 }
598 http_handle->session.sm = CORE_HTTP_SM_READ_BODY;
599
600 res = _core_http_recv_body(http_handle, body_total_len);
601 if (res == STATE_HTTP_READ_BODY_FINISHED || res == STATE_HTTP_READ_BODY_EMPTY) {
602 memset(&http_handle->session, 0, sizeof(core_http_session_t));
603 }
604
605 _core_http_exec_dec(http_handle);
606
607 return res;
608 }
609
core_http_deinit(void ** p_handle)610 int32_t core_http_deinit(void **p_handle)
611 {
612 uint32_t deinit_timeout_ms = 0;
613 core_http_handle_t *http_handle = NULL;
614
615 if (p_handle == NULL || *p_handle == NULL) {
616 return STATE_USER_INPUT_NULL_POINTER;
617 }
618
619 http_handle = *(core_http_handle_t **)p_handle;
620
621 if (http_handle->core_exec_enabled == 0) {
622 return STATE_USER_INPUT_EXEC_DISABLED;
623 }
624
625 http_handle->exec_enabled = 0;
626 deinit_timeout_ms = http_handle->deinit_timeout_ms;
627 do {
628 if (http_handle->exec_count == 0) {
629 break;
630 }
631 http_handle->sysdep->core_sysdep_sleep(CORE_HTTP_DEINIT_INTERVAL_MS);
632 } while ((deinit_timeout_ms > CORE_HTTP_DEINIT_INTERVAL_MS) && (deinit_timeout_ms - CORE_HTTP_DEINIT_INTERVAL_MS > 0));
633
634 if (http_handle->exec_count != 0) {
635 return STATE_HTTP_DEINIT_TIMEOUT;
636 }
637
638 if (http_handle->network_handle != NULL) {
639 http_handle->sysdep->core_sysdep_network_deinit(&http_handle->network_handle);
640 }
641
642 if (http_handle->host != NULL) {
643 http_handle->sysdep->core_sysdep_free(http_handle->host);
644 }
645 if (http_handle->cred != NULL) {
646 http_handle->sysdep->core_sysdep_free(http_handle->cred);
647 }
648
649 http_handle->sysdep->core_sysdep_mutex_deinit(&http_handle->data_mutex);
650 http_handle->sysdep->core_sysdep_mutex_deinit(&http_handle->send_mutex);
651 http_handle->sysdep->core_sysdep_mutex_deinit(&http_handle->recv_mutex);
652
653 http_handle->sysdep->core_sysdep_free(http_handle);
654
655 *p_handle = NULL;
656
657 return STATE_SUCCESS;
658 }
659
660