@@ -1608,7 +1608,6 @@ int lua_handler_fn(lua_State *L, const char *fcn, const char *parms)
TRACE("Script : no %s in script, exiting", fcn);
return -1;
}
- TRACE("Prepared to run %s", fcn);
/*
* passing arguments
@@ -1629,7 +1628,8 @@ int lua_handler_fn(lua_State *L, const char *fcn, const char *parms)
lua_pop(L, 1); /* clear stack */
- TRACE("Script returns %d", ret);
+ if (loglevel >= DEBUGLEVEL)
+ TRACE("Script returns %d", ret);
return ret;
}
@@ -35,16 +35,47 @@ struct wsconn {
#define TEXTRANGE_TO_STR(f) (f.first == NULL ? NULL : substring(f.first, 0, f.afterLast - f.first))
-static int callback_ws_swupdate(struct lws *wsi, enum lws_callback_reasons reason,
- void *user, void *in, size_t len)
+static void swupdate_web_answer(struct wsconn *ws, void *in, size_t len)
{
- struct wsconn *ws = (struct wsconn *)user;
struct json_tokener *json_tokenizer;
enum json_tokener_error json_res;
struct json_object *json_root;
- switch (reason) {
+ json_tokenizer = json_tokener_new();
+
+ do {
+ json_root = json_tokener_parse_ex(
+ json_tokenizer, in, len);
+ } while ((json_res = json_tokener_get_error(json_tokenizer)) ==
+ json_tokener_continue);
+ if (json_res != json_tokener_success) {
+ ERROR("Error while parsing answer from %s returned JSON data: %s",
+ ws ? ws->conn->url : "", json_tokener_error_desc(json_res));
+ } else {
+ const char *reply_result = json_get_value(json_root, "type");
+ if (reply_result && !strcmp(reply_result, "status")) {
+ const char *status = json_get_value(json_root, "status");
+ if (!strcmp(status, "SUCCESS"))
+ ws->conn->SWUpdateStatus = SUCCESS;
+ if (!strcmp(status, "FAILURE"))
+ ws->conn->SWUpdateStatus = FAILURE;
+ TRACE("Change status on %s : %s", ws->conn->url,
+ status);
+ }
+ if (reply_result && !strcmp(reply_result, "message")) {
+ const char *text = json_get_value(json_root, "text");
+ TRACE("%s : %s", ws->conn->url, text);
+ }
+ }
+ json_tokener_free(json_tokenizer);
+}
+
+static int callback_ws_swupdate(struct lws *wsi, enum lws_callback_reasons reason,
+ void *user, void *in, size_t len)
+{
+ struct wsconn *ws = (struct wsconn *)user;
+ switch (reason) {
/* because we are protocols[0] ... */
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
ERROR("WS Client Connection Error to : %s", ws->conn->url);
@@ -58,33 +89,45 @@ static int callback_ws_swupdate(struct lws *wsi, enum lws_callback_reasons reaso
break;
case LWS_CALLBACK_CLIENT_RECEIVE:
- json_tokenizer = json_tokener_new();
-
- do {
- json_root = json_tokener_parse_ex(
- json_tokenizer, in, len);
- } while ((json_res = json_tokener_get_error(json_tokenizer)) ==
- json_tokener_continue);
- if (json_res != json_tokener_success) {
- ERROR("Error while parsing answer from %s returned JSON data: %s",
- ws ? ws->conn->url : "", json_tokener_error_desc(json_res));
- } else {
- const char *reply_result = json_get_value(json_root, "type");
- if (reply_result && !strcmp(reply_result, "status")) {
- const char *status = json_get_value(json_root, "status");
- if (!strcmp(status, "SUCCESS"))
+ /*
+ * If it is not connected to SWUpdate's Webserver
+ * call a custom Lua function that should be loaded
+ * in advance
+ */
+ if (ws->conn->fnparser && strlen(ws->conn->fnparser)) {
+ /*
+ * First convert the incoming data
+ * to a "data" stucture (string)
+ * that is passed to the script.
+ * Raw / Binary data aren't supported
+ */
+ char *data = (char *) calloc(1, len + 1);
+ if (!data) {
+ ERROR("OOM when allocating buffer for Lua Custom Script");
+ ws->conn->SWUpdateStatus = FAILURE;
+ } else {
+ int ret;
+ memcpy(data, in, len);
+ ret = lua_handler_fn(ws->conn->L, ws->conn->fnparser, data);
+ switch (ret) {
+ case RUN:
+ break;
+ case FAILURE:
+ ws->conn->SWUpdateStatus = FAILURE;
+ break;
+ case SUCCESS:
ws->conn->SWUpdateStatus = SUCCESS;
- if (!strcmp(status, "FAILURE"))
+ break;
+ default:
+ WARN("Error parsing answer from Webserver, %d", ret);
ws->conn->SWUpdateStatus = FAILURE;
- TRACE("Change status on %s : %s", ws->conn->url,
- status);
- }
- if (reply_result && !strcmp(reply_result, "message")) {
- const char *text = json_get_value(json_root, "text");
- TRACE("%s : %s", ws->conn->url, text);
+ break;
+ }
+ free(data);
}
+ } else {
+ swupdate_web_answer(ws, in, len);
}
- json_tokener_free(json_tokenizer);
break;
case LWS_CALLBACK_CLIENT_CLOSED:
@@ -293,6 +293,7 @@ static int install_remote_swu(struct img_type *img,
struct dict_list_elem *url;
struct dict_list *urls;
int index = 0;
+ const char *fn_parse_answer = NULL;
pthread_attr_t attr;
int thread_ret = -1;
@@ -317,6 +318,17 @@ static int install_remote_swu(struct img_type *img,
return -EINVAL;
}
+ /*
+ * Check if a custom function is set to parse the
+ * answer form the Webserver
+ */
+ fn_parse_answer = dict_get_value(&img->properties, "parser-function");
+ if (fn_parse_answer && !img->L) {
+ ERROR("Custom parser requires to enable Lua, exiting..");
+ ret = FAILURE;
+ goto handler_exit;
+ }
+
/* Reset list of connections */
LIST_INIT(&priv.conns);
@@ -344,9 +356,14 @@ static int install_remote_swu(struct img_type *img,
goto handler_exit;
}
+ /*
+ * Set parameters to each connection structure
+ */
conn->url = url->value;
conn->total_bytes = img->size;
conn->SWUpdateStatus = IDLE;
+ conn->L = img->L;
+ conn->fnparser = fn_parse_answer;
LIST_INSERT_HEAD(&priv.conns, conn, next);
@@ -12,6 +12,7 @@
#include "bsdqueue.h"
#include "channel_curl.h"
#include "channel.h"
+#include "lua_util.h"
/*
* The Webserver in SWUpdate expets a custom header
@@ -52,6 +53,8 @@ struct curlconn {
size_t total_bytes; /* size of SWU image */
int fifo[2]; /* Pipe for IPC */
char *url; /* URL for forwarding */
+ const char *fnparser; /* Parser for the answer via ws */
+ lua_State *L; /* Required if fnparser is set */
bool gotMsg; /* set if the remote board has sent a new msg */
RECOVERY_STATUS SWUpdateStatus; /* final status of update */
channel_op_res_t response;
The handler is used to push a SWU to other systems running SWUpdate. This patch introduce the concept of generic uploader, and the handler can upload an artifact (not only a SWU) to a URL. The handler will still connect via Websocket to the webserver, and it will parse the answer. To make it generic, the answer can be parsed by a custom Lua function, that should be loaded previously via embedded-script or via a script, or even via swupdate_handlers.lua at the startup. Signed-off-by: Stefano Babic <stefano.babic@swupdate.org> --- corelib/lua_interface.c | 4 +- handlers/swuforward-ws.c | 97 +++++++++++++++++++++++++---------- handlers/swuforward_handler.c | 17 ++++++ handlers/swuforward_handler.h | 3 ++ 4 files changed, 92 insertions(+), 29 deletions(-) -- 2.34.1