From 00f91241b2466332bceffcaf6d1eb50b8fa5b7de Mon Sep 17 00:00:00 2001 From: Mateusz Lubecki Date: Mon, 21 Mar 2022 21:35:58 +0100 Subject: [PATCH] http client initialization --- system/include/http_client/http_client.h | 10 +- .../http_client/http_client_rx_callback.h | 1 + system/src/http_client/http_client.c | 97 ++++++++++++++++++- .../src/http_client/http_client_rx_callback.c | 16 ++- 4 files changed, 112 insertions(+), 12 deletions(-) diff --git a/system/include/http_client/http_client.h b/system/include/http_client/http_client.h index 5b11819..67a2fd8 100644 --- a/system/include/http_client/http_client.h +++ b/system/include/http_client/http_client.h @@ -23,6 +23,10 @@ #define HEADER_BUFFER_LN 64 +#define HTTP_CLIENT_RET_UNITIALIZED 1 +#define HTTP_CLIENT_RET_TCPIP_BSY 2 +#define HTTP_CLIENT_RET_WRONG_URL 3 + /** * HTTP code returned by the latest query. It is zeroed after each successful call to async * function. This indicate that a request is currently in progress. Negative values means some @@ -51,9 +55,9 @@ extern char http_client_header_buffer[HEADER_BUFFER_LN]; */ extern uint8_t http_client_header_index; -void http_client_init(gsm_sim800_state_t * state, srl_context_t * serial_context); -uint8_t http_client_async_get(char * url, uint8_t url_ln, uint16_t response_ln_limit); -uint8_t http_client_async_post(char * url, uint8_t url_ln, char * data_to_post, uint8_t data_ln); +void http_client_init(gsm_sim800_state_t * state, srl_context_t * serial_context, uint8_t ignore_content_on_http_error); +uint8_t http_client_async_get(char * url, uint8_t url_ln, uint16_t response_ln_limit, uint8_t force_disconnect_on_busy); +uint8_t http_client_async_post(char * url, uint8_t url_ln, char * data_to_post, uint8_t data_ln, uint8_t force_disconnect_on_busy); char * http_client_get_server_response(); uint16_t http_client_get_latest_http_code(); diff --git a/system/include/http_client/http_client_rx_callback.h b/system/include/http_client/http_client_rx_callback.h index 2f5c8f4..0849033 100644 --- a/system/include/http_client/http_client_rx_callback.h +++ b/system/include/http_client/http_client_rx_callback.h @@ -11,6 +11,7 @@ #include extern uint16_t http_client_content_start_index; +extern uint16_t http_client_content_end_index; void http_client_rx_done_callback_init(); uint8_t http_client_rx_done_callback(uint8_t current_data, const uint8_t * const rx_buffer, uint16_t rx_bytes_counter); diff --git a/system/src/http_client/http_client.c b/system/src/http_client/http_client.c index af59552..6aede4c 100644 --- a/system/src/http_client/http_client.c +++ b/system/src/http_client/http_client.c @@ -3,6 +3,16 @@ #include +typedef enum http_client_state { + HTTP_CLIENT_UNITIALIZED, + HTTP_CLIENT_READY, + HTTP_CLIENT_CONNECTED_IDLE, + HTTP_CLIENT_WAITING_POST, + HTTP_CLIENT_WAITING_GET +} http_client_state_t; + +http_client_state_t http_client_state = HTTP_CLIENT_UNITIALIZED; + /** * Content lenght received from HTTP response headers or chunked encoding */ @@ -25,17 +35,96 @@ char http_client_header_buffer[HEADER_BUFFER_LN]; */ uint8_t http_client_header_index = 0; +/** + * SIM800 state and serial context used to communication with gsm module. + */ +gsm_sim800_state_t * http_client_deticated_sim800_state; +srl_context_t * http_client_deticated_serial_context; -void http_client_init(gsm_sim800_state_t * state, srl_context_t * serial_context) { +/** + * If this is set to non zero, the library will stop response processing after HTTP code different from <200, 299> + */ +uint8_t http_client_ignore_content_on_http_error; + +/** + * Default port for http + */ +const char * http_client_default_port = "80"; + +/** + * This functions splits the URL string into hostname and path + * + * It return a split point index which in case of + * http://pogoda.cc:8080/meteo_backend/station/z_gss_zar/summary + * will return an index of '/' after 8080 + * + * */ +static uint16_t http_client_split_hostname_and_path(char * input, uint16_t input_ln) { + + uint16_t out = 0xFFFF; + + uint16_t iterator = 7; + + // check if URL starts correctly + if (*input == 'h' && *(input + 1) == 't' && *(input + 2) == 't' && *(input + 3) == 'p' && *(input + 4) == ':' && *(input + 5) == '/' && *(input + 6) == '/') { + for (; iterator < input_ln; iterator++) { + if (*(input + iterator) == '/') { + + out = iterator; + + break; + } + } + } + + return out; +} + +static void http_client_get_port_from_url(char * input, uint16_t input_ln, char * port, uint16_t port_ln) { + + uint16_t split_point = http_client_split_hostname_and_path(input, input_ln); } +void http_client_init(gsm_sim800_state_t * state, srl_context_t * serial_context, uint8_t ignore_content_on_http_error) { -uint8_t http_client_async_get(char * url, uint8_t url_ln, uint16_t response_ln_limit) { - return 0; + http_client_deticated_sim800_state = state; + + http_client_state = HTTP_CLIENT_READY; } -uint8_t http_client_async_post(char * url, uint8_t url_ln, char * data_to_post, uint8_t data_ln) { + +uint8_t http_client_async_get(char * url, uint8_t url_ln, uint16_t response_ln_limit, uint8_t force_disconnect_on_busy) { + + uint16_t split_point = http_client_split_hostname_and_path(url, url_ln); + + uint8_t out = 0; + + // simple check if url seems to be corrected or not + if (split_point != 0xFFFF && http_client_state == HTTP_CLIENT_READY ) { + + // check if module is busy on other TCP/IP connection + if (*http_client_deticated_sim800_state == SIM800_TCP_CONNECTED && force_disconnect_on_busy != 0) { + // if client is connected end a user wants to force disconnect + gsm_sim800_tcpip_close(http_client_deticated_serial_context, http_client_deticated_sim800_state); + } + else if (*http_client_deticated_sim800_state == SIM800_TCP_CONNECTED && force_disconnect_on_busy == 0) { + out = HTTP_CLIENT_RET_TCPIP_BSY; + } + + gsm_sim800_tcpip_connect(url, url_ln, url, http_client_http_code, http_client_deticated_serial_context, http_client_deticated_sim800_state); + } + else if (split_point == 0xFFFF) { + out = HTTP_CLIENT_RET_WRONG_URL; + } + else if (http_client_state != HTTP_CLIENT_READY) { + out = HTTP_CLIENT_RET_UNITIALIZED; + } + + return out; +} + +uint8_t http_client_async_post(char * url, uint8_t url_ln, char * data_to_post, uint8_t data_ln, uint8_t force_disconnect_on_busy) { return 0; } diff --git a/system/src/http_client/http_client_rx_callback.c b/system/src/http_client/http_client_rx_callback.c index 9b80901..5bfba5f 100644 --- a/system/src/http_client/http_client_rx_callback.c +++ b/system/src/http_client/http_client_rx_callback.c @@ -33,16 +33,18 @@ typedef enum http_client_header_field { HEADER_UNKNOWN } http_client_header_field_t; +// an index where the first byte of response occurs +uint16_t http_client_content_start_index = 0; + +// an index of last byte of +uint16_t http_client_content_end_index = 0; + // set to one if we are still parsing HTTP response header static uint8_t http_client_response_header_processing = 1; - // amount of bytes (octets) of a content of the HTTP response received so far static uint16_t http_client_content_received_so_far = 0; -// an index where the first byte of response occurs -uint16_t http_client_content_start_index = 0; - /** * This function is responsible for checking what HTTP header has been received */ @@ -99,7 +101,7 @@ uint8_t http_client_rx_done_callback(uint8_t current_data, const uint8_t * const // if this is maybe the last character of 'CLOSED' if ((char)current_data == 'D') { // check 6 previous characters - compare_result = strncmp(DISCONNECTED, (const char *) (rx_buffer + rx_bytes_counter - 6), 6); + compare_result = strncmp(DISCONNECTED, (const char *) (rx_buffer + rx_bytes_counter - 5), 6); // terminate reception if 'CLOSED' has been found. if (compare_result == 0) { @@ -206,9 +208,13 @@ uint8_t http_client_rx_done_callback(uint8_t current_data, const uint8_t * const // check if all bytes defined by chunk size or 'HEADER_CONTENT_LN' have been received if (http_client_content_received_so_far >= http_client_content_lenght) { + http_client_content_end_index = rx_bytes_counter; + out = 1; } else if (http_client_max_content_ln != 0 && (http_client_content_received_so_far > http_client_max_content_ln)) { + http_client_content_end_index = rx_bytes_counter; + out = 1; } }