596 lines
14 KiB
C
Executable File
596 lines
14 KiB
C
Executable File
/*
|
|
* Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the
|
|
* distribution.
|
|
* 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of
|
|
* its contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#if PRJCONF_NET_EN
|
|
|
|
#include "cmd_util.h"
|
|
#include "net/HTTPClient/HTTPCUsr_api.h"
|
|
#include "mbedtls/mbedtls.h"
|
|
|
|
#define HTTPC_THREAD_STACK_SIZE (4 * 1024)
|
|
|
|
struct cmd_httpc_common {
|
|
OS_Thread_t thread;
|
|
char arg_buf[1024];
|
|
security_client user_param;
|
|
};
|
|
|
|
static struct cmd_httpc_common cmd_httpc;
|
|
|
|
extern const char mbedtls_test_cas_pem[];
|
|
extern const size_t mbedtls_test_cas_pem_len;
|
|
|
|
void *get_certs(void)
|
|
{
|
|
memset(&cmd_httpc.user_param, 0, sizeof(cmd_httpc.user_param));
|
|
cmd_httpc.user_param.pCa = (char *)mbedtls_test_cas_pem;
|
|
cmd_httpc.user_param.nCa = mbedtls_test_cas_pem_len;
|
|
return &cmd_httpc.user_param;
|
|
}
|
|
|
|
static unsigned char data_checksum;
|
|
static int cmd_data_process_init(void)
|
|
{
|
|
data_checksum = 0;
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_data_process(void *buffer, int length)
|
|
{
|
|
unsigned char *cal = (unsigned char *)buffer;
|
|
while (length != 0) {
|
|
data_checksum += cal[--length];
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int cmd_data_process_deinit(void)
|
|
{
|
|
printf("[httpc cmd test]:checksum = %#x\n", data_checksum);
|
|
data_checksum = 0;
|
|
return 0;
|
|
}
|
|
|
|
static int httpc_get(char *url)
|
|
{
|
|
int ret = -1;
|
|
int recvSize = 0;
|
|
char *buf = NULL;
|
|
unsigned int toReadLength = 4096;
|
|
HTTPParameters *clientParams = NULL;
|
|
|
|
clientParams = malloc(sizeof(HTTPParameters));
|
|
if (clientParams == NULL) {
|
|
goto exit0;
|
|
}
|
|
memset(clientParams, 0, sizeof(HTTPParameters));
|
|
|
|
buf = malloc(toReadLength);
|
|
if (buf == NULL) {
|
|
goto exit0;
|
|
}
|
|
memset(buf, 0, toReadLength);
|
|
|
|
strcpy(clientParams->Uri, url);
|
|
cmd_data_process_init();
|
|
do {
|
|
ret = HTTPC_get(clientParams, buf, 4096, (INT32 *)&recvSize);
|
|
if ((ret != HTTP_CLIENT_SUCCESS) && (ret != HTTP_CLIENT_EOS)) {
|
|
CMD_ERR("Transfer err...ret:%d\n", ret);
|
|
ret = -1;
|
|
break;
|
|
}
|
|
cmd_data_process(buf, recvSize);
|
|
if (ret == HTTP_CLIENT_EOS) {
|
|
CMD_DBG("The end..\n");
|
|
ret = 0;
|
|
break;
|
|
}
|
|
} while (1);
|
|
cmd_data_process_deinit();
|
|
|
|
exit0:
|
|
free(buf);
|
|
free(clientParams);
|
|
return ret;
|
|
}
|
|
|
|
static int httpc_get_fresh(char *url, char *user_name, char *password,
|
|
int use_ssl)
|
|
{
|
|
int ret = -1;
|
|
char *buf = NULL;
|
|
unsigned int toReadLength = 4096;
|
|
unsigned int Received = 0;
|
|
HTTP_CLIENT httpClient;
|
|
HTTPParameters *clientParams = NULL;
|
|
|
|
clientParams = malloc(sizeof(HTTPParameters));
|
|
if (clientParams == NULL) {
|
|
goto exit0;
|
|
}
|
|
memset(clientParams, 0, sizeof(HTTPParameters));
|
|
|
|
buf = malloc(toReadLength);
|
|
if (buf == NULL) {
|
|
goto exit0;
|
|
}
|
|
memset(buf, 0, toReadLength);
|
|
|
|
memset(&httpClient, 0, sizeof(httpClient));
|
|
clientParams->HttpVerb = VerbGet;
|
|
strcpy(clientParams->Uri, url);
|
|
if ((user_name) && (password)) {
|
|
cmd_strlcpy(clientParams->UserName, user_name,
|
|
sizeof(clientParams->UserName));
|
|
cmd_strlcpy(clientParams->Password, password,
|
|
sizeof(clientParams->Password));
|
|
clientParams->AuthType = AuthSchemaDigest;
|
|
}
|
|
|
|
if (use_ssl) {
|
|
HTTPC_Register_user_certs(get_certs);
|
|
//HTTPC_set_ssl_verify_mode(MBEDTLS_SSL_VERIFY_OPTIONAL);
|
|
}
|
|
|
|
ret = HTTPC_open(clientParams);
|
|
if (ret != 0) {
|
|
CMD_ERR("http open err..\n");
|
|
goto exit0;
|
|
}
|
|
|
|
ret = HTTPC_request(clientParams, NULL);
|
|
if (ret != 0) {
|
|
CMD_ERR("http request err..\n");
|
|
goto exit1;
|
|
}
|
|
|
|
ret = HTTPC_get_request_info(clientParams, &httpClient);
|
|
if (ret != 0) {
|
|
CMD_ERR("http get request info err..\n");
|
|
goto exit1;
|
|
}
|
|
|
|
cmd_data_process_init();
|
|
if (httpClient.TotalResponseBodyLength != 0) {
|
|
do {
|
|
ret = HTTPC_read(clientParams, buf, toReadLength,
|
|
(void *)&Received);
|
|
if ((ret != HTTP_CLIENT_SUCCESS) && (ret != HTTP_CLIENT_EOS)) {
|
|
CMD_ERR("Transfer err...ret:%d\n", ret);
|
|
ret = -1;
|
|
break;
|
|
}
|
|
cmd_data_process(buf, Received);
|
|
if (ret == HTTP_CLIENT_EOS) {
|
|
CMD_DBG("The end..\n");
|
|
ret = 0;
|
|
break;
|
|
}
|
|
} while (1);
|
|
}
|
|
cmd_data_process_deinit();
|
|
|
|
exit1:
|
|
HTTPC_close(clientParams);
|
|
exit0:
|
|
free(buf);
|
|
free(clientParams);
|
|
return ret;
|
|
}
|
|
|
|
static int httpc_post(char *url, char *credentials, int use_ssl)
|
|
{
|
|
int ret = 0;
|
|
char *buf = NULL;
|
|
unsigned int toReadLength = 4096;
|
|
unsigned int Received = 0;
|
|
HTTP_CLIENT httpClient;
|
|
HTTPParameters *clientParams = NULL;
|
|
|
|
clientParams = malloc(sizeof(HTTPParameters));
|
|
if (clientParams == NULL) {
|
|
goto exit0;
|
|
}
|
|
memset(clientParams, 0, sizeof(HTTPParameters));
|
|
|
|
buf = malloc(toReadLength);
|
|
if (buf == NULL) {
|
|
goto exit0;
|
|
}
|
|
memset(buf, 0, toReadLength);
|
|
|
|
memset(&httpClient, 0, sizeof(httpClient));
|
|
clientParams->HttpVerb = VerbPost;
|
|
clientParams->pData = buf;
|
|
strcpy(clientParams->Uri, url);
|
|
clientParams->pLength = strlen(credentials);
|
|
memcpy(buf, credentials, strlen(credentials));
|
|
|
|
request:
|
|
ret = HTTPC_open(clientParams);
|
|
if (ret != 0) {
|
|
CMD_ERR("http open err..\n");
|
|
goto exit0;
|
|
}
|
|
|
|
ret = HTTPC_request(clientParams, NULL);
|
|
if (ret != 0) {
|
|
CMD_ERR("http request err..\n");
|
|
goto exit1;
|
|
}
|
|
|
|
ret = HTTPC_get_request_info(clientParams, &httpClient);
|
|
if (ret != 0) {
|
|
CMD_ERR("http get request info err..\n");
|
|
goto exit1;
|
|
}
|
|
|
|
if (httpClient.HTTPStatusCode != HTTP_STATUS_OK) {
|
|
if ((httpClient.HTTPStatusCode == HTTP_STATUS_OBJECT_MOVED) ||
|
|
(httpClient.HTTPStatusCode == HTTP_STATUS_OBJECT_MOVED_PERMANENTLY)) {
|
|
CMD_DBG("Redirect url..\n");
|
|
HTTPC_close(clientParams);
|
|
memset(clientParams, 0, sizeof(*clientParams));
|
|
clientParams->HttpVerb = VerbGet;
|
|
if (httpClient.RedirectUrl->nLength < sizeof(clientParams->Uri)) {
|
|
strncpy(clientParams->Uri, httpClient.RedirectUrl->pParam,
|
|
httpClient.RedirectUrl->nLength);
|
|
} else {
|
|
goto exit0;
|
|
}
|
|
CMD_DBG("go to request.\n");
|
|
goto request;
|
|
|
|
} else {
|
|
ret = -1;
|
|
CMD_DBG("get result not correct.\n");
|
|
goto exit1;
|
|
}
|
|
}
|
|
cmd_data_process_init();
|
|
if (httpClient.TotalResponseBodyLength != 0
|
|
|| (httpClient.HttpFlags & HTTP_CLIENT_FLAG_CHUNKED)) {
|
|
do {
|
|
ret = HTTPC_read(clientParams, buf, toReadLength,
|
|
(void *)&Received);
|
|
if ((ret != HTTP_CLIENT_SUCCESS) && (ret != HTTP_CLIENT_EOS)) {
|
|
CMD_ERR("Transfer err...ret:%d\n", ret);
|
|
ret = -1;
|
|
break;
|
|
}
|
|
cmd_data_process(buf, Received);
|
|
if (ret == HTTP_CLIENT_EOS) {
|
|
CMD_DBG("The end..\n");
|
|
ret = 0;
|
|
break;
|
|
}
|
|
} while (1);
|
|
}
|
|
cmd_data_process_deinit();
|
|
|
|
exit1:
|
|
HTTPC_close(clientParams);
|
|
exit0:
|
|
free(buf);
|
|
free(clientParams);
|
|
return ret;
|
|
}
|
|
|
|
static int httpc_muti_get(char *url0, char *url1)
|
|
{
|
|
int ret = -1;
|
|
char *buf = NULL;
|
|
char *pUrl0 = url0;
|
|
char *pUrl1 = url1;
|
|
unsigned int toReadLength = 4096;
|
|
unsigned int Received = 0;
|
|
HTTP_CLIENT httpClient;
|
|
HTTPParameters *clientParams = NULL;
|
|
|
|
clientParams = malloc(sizeof(HTTPParameters));
|
|
if (clientParams == NULL) {
|
|
goto exit0;
|
|
}
|
|
memset(clientParams, 0, sizeof(HTTPParameters));
|
|
|
|
buf = malloc(toReadLength);
|
|
if (buf == NULL) {
|
|
goto exit0;
|
|
}
|
|
memset(buf, 0, toReadLength);
|
|
|
|
memset(&httpClient, 0, sizeof(httpClient));
|
|
clientParams->HttpVerb = VerbGet;
|
|
clientParams->Flags |= HTTP_CLIENT_FLAG_KEEP_ALIVE;
|
|
cmd_strlcpy(clientParams->Uri, pUrl0, sizeof(clientParams->Uri));
|
|
|
|
ret = HTTPC_open(clientParams);
|
|
if (ret != 0) {
|
|
CMD_ERR("http open err..\n");
|
|
goto exit0;
|
|
}
|
|
pUrl0 = NULL;
|
|
goto direct_request;
|
|
set_url1:
|
|
HTTPC_reset_session(clientParams);
|
|
cmd_strlcpy(clientParams->Uri, pUrl1, sizeof(clientParams->Uri));
|
|
CMD_DBG("http test get url1..\n");
|
|
pUrl1 = NULL;
|
|
direct_request:
|
|
ret = HTTPC_request(clientParams, NULL);
|
|
if (ret != 0) {
|
|
CMD_ERR("http request err..\n");
|
|
goto exit1;
|
|
}
|
|
|
|
ret = HTTPC_get_request_info(clientParams, &httpClient);
|
|
if (ret != 0) {
|
|
CMD_ERR("http get request info err..\n");
|
|
goto exit1;
|
|
}
|
|
|
|
cmd_data_process_init();
|
|
if (httpClient.TotalResponseBodyLength != 0) {
|
|
do {
|
|
ret = HTTPC_read(clientParams, buf, toReadLength,
|
|
(void *)&Received);
|
|
if ((ret != HTTP_CLIENT_SUCCESS) && (ret != HTTP_CLIENT_EOS)) {
|
|
CMD_ERR("Transfer err...ret:%d\n", ret);
|
|
ret = -1;
|
|
break;
|
|
}
|
|
cmd_data_process(buf, Received);
|
|
if (ret == HTTP_CLIENT_EOS) {
|
|
CMD_DBG("The end..\n");
|
|
ret = 0;
|
|
break;
|
|
}
|
|
} while (1);
|
|
}
|
|
cmd_data_process_deinit();
|
|
|
|
if ((ret == 0) && (pUrl1 != NULL)) {
|
|
goto set_url1;
|
|
}
|
|
|
|
exit1:
|
|
HTTPC_close(clientParams);
|
|
exit0:
|
|
free(buf);
|
|
free(clientParams);
|
|
return ret;
|
|
}
|
|
|
|
static enum cmd_status cmd_httpc_get(char *cmd)
|
|
{
|
|
int ret;
|
|
|
|
ret = httpc_get(cmd);
|
|
if (ret != 0) {
|
|
return CMD_STATUS_FAIL;
|
|
} else {
|
|
return CMD_STATUS_OK;
|
|
}
|
|
}
|
|
|
|
static enum cmd_status cmd_httpc_post(char *cmd)
|
|
{
|
|
int ret;
|
|
int argc = 0;
|
|
char *argv[2];
|
|
|
|
argc = cmd_parse_argv(cmd, argv, 2);
|
|
if (argc < 2) {
|
|
CMD_ERR("invalid httpc cmd(post), argc %d\n", argc);
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
|
|
ret = httpc_post(argv[0], argv[1], 0);
|
|
if (ret != 0) {
|
|
return CMD_STATUS_FAIL;
|
|
} else {
|
|
return CMD_STATUS_OK;
|
|
}
|
|
}
|
|
|
|
static enum cmd_status cmd_httpc_get_fresh(char *cmd)
|
|
{
|
|
int ret;
|
|
|
|
ret = httpc_get_fresh(cmd, NULL, NULL, 0);
|
|
if (ret != 0) {
|
|
return CMD_STATUS_FAIL;
|
|
} else {
|
|
return CMD_STATUS_OK;
|
|
}
|
|
}
|
|
|
|
static enum cmd_status cmd_httpc_head(char *cmd)
|
|
{
|
|
return CMD_STATUS_OK;
|
|
}
|
|
|
|
static enum cmd_status cmd_httpc_auth_get(char *cmd)
|
|
{
|
|
int ret;
|
|
int argc = 0;
|
|
char *argv[3];
|
|
|
|
argc = cmd_parse_argv(cmd, argv, 3);
|
|
if (argc < 3) {
|
|
CMD_ERR("invalid httpc cmd(auth-get), argc %d\n", argc);
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
|
|
ret = httpc_get_fresh(argv[0], argv[1], argv[2], 0);
|
|
if (ret != 0) {
|
|
return CMD_STATUS_FAIL;
|
|
} else {
|
|
return CMD_STATUS_OK;
|
|
}
|
|
}
|
|
|
|
static enum cmd_status cmd_httpc_ssl_get(char *cmd)
|
|
{
|
|
int ret;
|
|
|
|
ret = httpc_get_fresh(cmd, NULL, NULL, 1);
|
|
if (ret != 0) {
|
|
return CMD_STATUS_FAIL;
|
|
} else {
|
|
return CMD_STATUS_OK;
|
|
}
|
|
}
|
|
|
|
static enum cmd_status cmd_httpc_ssl_post(char *cmd)
|
|
{
|
|
int ret;
|
|
int argc = 0;
|
|
char *argv[2];
|
|
|
|
argc = cmd_parse_argv(cmd, argv, 2);
|
|
if (argc < 2) {
|
|
CMD_ERR("invalid httpc cmd(post), argc %d\n", argc);
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
|
|
ret = httpc_post(argv[0], argv[1], 1);
|
|
if (ret != 0) {
|
|
return CMD_STATUS_FAIL;
|
|
} else {
|
|
return CMD_STATUS_OK;
|
|
}
|
|
}
|
|
|
|
static enum cmd_status cmd_httpc_multi_get(char *cmd)
|
|
{
|
|
int ret;
|
|
int argc = 0;
|
|
char *argv[2];
|
|
|
|
argc = cmd_parse_argv(cmd, argv, 2);
|
|
if (argc < 2) {
|
|
CMD_ERR("invalid httpc cmd(multi-get), argc %d\n", argc);
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
|
|
ret = httpc_muti_get(argv[0], argv[1]);
|
|
if (ret != 0) {
|
|
return CMD_STATUS_FAIL;
|
|
} else {
|
|
return CMD_STATUS_OK;
|
|
}
|
|
}
|
|
|
|
static enum cmd_status cmd_httpc_multi_post(char *cmd)
|
|
{
|
|
return CMD_STATUS_OK;
|
|
}
|
|
|
|
static const struct cmd_data g_httpc_cmds[] = {
|
|
{ "get", cmd_httpc_get },
|
|
{ "post", cmd_httpc_post },
|
|
{ "-get", cmd_httpc_get_fresh },
|
|
{ "head", cmd_httpc_head },
|
|
{ "auth-get", cmd_httpc_auth_get },
|
|
{ "ssl-get", cmd_httpc_ssl_get },
|
|
{ "ssl-post", cmd_httpc_ssl_post },
|
|
{ "multi-get", cmd_httpc_multi_get },
|
|
{ "multi-post", cmd_httpc_multi_post },
|
|
};
|
|
|
|
void httpc_cmd_task(void *arg)
|
|
{
|
|
enum cmd_status status;
|
|
char *cmd = (char *)arg;
|
|
|
|
CMD_LOG(1, "<net> <httpc> <request> <cmd : %s>\n", cmd);
|
|
status = cmd_exec(cmd, g_httpc_cmds, cmd_nitems(g_httpc_cmds));
|
|
if (status != CMD_STATUS_OK)
|
|
CMD_LOG(1, "<net> <httpc> <response : fail> <%s>\n", cmd);
|
|
else {
|
|
CMD_LOG(1, "<net> <httpc> <response : success> <%s>\n", cmd);
|
|
}
|
|
OS_ThreadDelete(&cmd_httpc.thread);
|
|
}
|
|
|
|
#if CMD_DESCRIBE
|
|
#define httpc_help_info \
|
|
"[*] net httpc <cmd> <url> file=<file_test> <user> <password>\n"\
|
|
"[*] cmd: {get | -get | post | auth-get | ssl-get | ssl-post}\n"\
|
|
"[*] get: get method\n"\
|
|
"[*] -get: same as get method, but use new interfaces\n"\
|
|
"[*] post: post method\n"\
|
|
"[*] auth-get: get method with login, at this time <user> and <password> are valid, otherwise, this parameter need not be written\n"\
|
|
"[*] ssl-get: get method with ssl\n"\
|
|
"[*] ssl-post: post method with ssl\n"\
|
|
"[*] url: server url\n"\
|
|
"[*] file_test: only used in post method and represents the file sent to the server\n"\
|
|
"[*] user: username, used only in auth-get method\n"\
|
|
"[*] password: password, used only in auth-get method"
|
|
#endif /* CMD_DESCRIBE */
|
|
|
|
static enum cmd_status cmd_httpc_help_exec(char *cmd)
|
|
{
|
|
#if CMD_DESCRIBE
|
|
CMD_LOG(1, "%s\n", httpc_help_info);
|
|
#endif
|
|
return CMD_STATUS_ACKED;
|
|
}
|
|
|
|
enum cmd_status cmd_httpc_exec(char *cmd)
|
|
{
|
|
if (cmd_strcmp(cmd, "help") == 0) {
|
|
cmd_write_respond(CMD_STATUS_OK, "OK");
|
|
return cmd_httpc_help_exec(cmd);
|
|
}
|
|
|
|
if (OS_ThreadIsValid(&cmd_httpc.thread)) {
|
|
CMD_ERR("httpc task is running\n");
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
|
|
memset(cmd_httpc.arg_buf, 0, sizeof(cmd_httpc.arg_buf));
|
|
cmd_strlcpy(cmd_httpc.arg_buf, cmd, sizeof(cmd_httpc.arg_buf));
|
|
|
|
if (OS_ThreadCreate(&cmd_httpc.thread,
|
|
"httpc",
|
|
httpc_cmd_task,
|
|
(void *)cmd_httpc.arg_buf,
|
|
OS_THREAD_PRIO_APP,
|
|
HTTPC_THREAD_STACK_SIZE) != OS_OK) {
|
|
CMD_ERR("httpc task create failed\n");
|
|
return CMD_STATUS_FAIL;
|
|
}
|
|
return CMD_STATUS_OK;
|
|
}
|
|
|
|
#endif /* PRJCONF_NET_EN */
|