network/http_server/requests/json_parser.c

/*******************************************************************************
* # License
* Copyright 2019 Silicon Laboratories Inc. www.silabs.com
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/
#include "gos.h"
#include "common.h"
#define READ_POST_DATA_TIMEOUT 1000
extern bool led_value;
/*************************************************************************************************
* This handles a POST request with JSON formated data
* POST http://<domain>/json_parser
*
* {
* "light" : <true/false>,
* "msg" : "<msg_str>",
* "retval": "<retval_str>"
* }
*/
gos_result_t json_parser_request(const gos_hs_request_t *request, const char *arg)
{
gos_result_t result;
uint8_t body_data[256];
gos_buffer_t post_buffer = {
.size = sizeof(body_data)-1,
.data = body_data,
};
{
return gos_hs_return_status_code(request, 405, "<h1>Invalid Request Method. Must be POST</h1>");
}
else if (GOS_FAILED(result, gos_hs_read_post_data(request, &post_buffer, READ_POST_DATA_TIMEOUT)))
{
return gos_hs_return_status_code(request, 500, "<h1>Failed to read JSON data</h1>");
}
else if (post_buffer.size == 0)
{
return gos_hs_return_status_code(request, 400, "<h1>Invalid JSON data</h1>");
}
{
.buffer = post_buffer.data,
.buffer_len = (uint16_t)post_buffer.size,
};
gos_json_parse_context_init(&context, &cfg);
if (GOS_FAILED(result, gos_json_parse_chunked(context, NULL)))
{
gos_hs_return_status_code(request, 400, "<h1>Failed to parse JSON</h1>");
goto exit;
}
const gos_json_tok_t *msg_tok = gos_json_context_get_token(context, "msg", NULL);
const gos_json_tok_t *light_tok = gos_json_context_get_token(context, "light", NULL);
const gos_json_tok_t *retval_tok = gos_json_context_get_token(context, "retval", NULL);
if ((msg_tok == NULL) || (msg_tok->next == NULL) ||
(light_tok == NULL) || (light_tok->next == NULL) ||
(retval_tok == NULL) || (retval_tok->next == NULL))
{
gos_hs_return_status_code(request, 400, "<h1>JSON not formatted correctly</h1>" \
"Must be of the form:<br />" \
"{\"light\":<true/false>,\"msg\":\"<msg_str>\",\"retval\":\"<retval_str>\"}");
goto exit;
}
led_value = light_tok->next->data.boolean;
gos_gpio_set(PLATFORM_STD_LED, led_value ? PLATFORM_LED_ACTIVE_STATE : !PLATFORM_LED_ACTIVE_STATE);
GOS_LOG("New LED value: %d", led_value);
GOS_LOG("Msg: %s", msg_tok->next->data.str);
char buffer[64];
int len = snprintf(buffer, sizeof(buffer), "<h1>Led value: %d</h1>", led_value);
len += snprintf(buffer + len, sizeof(buffer)-len, "Retval: %s", retval_tok->next->data.str);
if (GOS_FAILED(result, gos_hs_write_reply_header(request, "text/html", len, GOS_HS_RESPONSE_FLAG_NONE)))
{
}
else if (GOS_FAILED(result, gos_hs_write_data(request, buffer, len, true)))
{
}
exit:
return result;
}