X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fhelper-api.c;h=9d1ec0b71d69b1cddfa545f24c7b20fda4e17751;hb=dde70b62b09f49ad672c104a3f81714bf11047be;hp=a166027a4aa6d638a0d451585e5f6450ea6ba627;hpb=00857f9da5ae802794a4cb94aca576b11bfe6628;p=src%2Fapp-framework-binder.git diff --git a/src/helper-api.c b/src/helper-api.c index a166027a..9d1ec0b7 100644 --- a/src/helper-api.c +++ b/src/helper-api.c @@ -17,88 +17,87 @@ * */ -#include "../include/local-def.h" +#define _GNU_SOURCE + +#include +#include +#include + +/* #include +#include +#include +*/ +#include "local-def.h" +#include "afb-req-itf.h" // handle to hold queryAll values typedef struct { char *msg; - int idx; + size_t idx; size_t len; } queryHandleT; -// Sample Generic Ping Debug API -PUBLIC json_object* getPingTest(AFB_request *request) { - static pingcount = 0; - json_object *response; - char query [256]; - char session[256]; - int len; - - // request all query key/value - len = getQueryAll (request, query, sizeof(query)); - if (len == 0) strncpy (query, "NoSearchQueryList", sizeof(query)); - - // check if we have some post data - if (request->post == NULL) request->post->data="NoData"; - - // return response to caller - response = jsonNewMessage(AFB_SUCCESS, "Ping Binder Daemon count=%d uuid=%s query={%s} session={0x%x} PostData: [%s] " - , pingcount++, request->uuid, query, session, request->post->data); - return (response); -} +// Error code are requested through function to manage json usage count +typedef struct { + int level; + const char* label; + json_object *json; +} AFB_errorT; +static AFB_errorT AFBerr [AFB_UNAUTH+1]; +static json_object *jTypeStatic; + +PUBLIC int verbose; + +static const char *ERROR_LABEL[] = {"false", "true", "fatal", "fail", "warning", "empty", "success", "done", "unauth"}; -// Helper to retrieve argument from connection -PUBLIC const char* getQueryValue(const AFB_request * request, const char *name) { - const char *value; - value = MHD_lookup_connection_value(request->connection, MHD_GET_ARGUMENT_KIND, name); - return (value); +// Helper to retrieve argument from connection +const char* getQueryValue(const AFB_request * request, const char *name) { + return afb_req_argument(*request->areq, name); } -STATIC int getQueryCB (void*handle, enum MHD_ValueKind kind, const char *key, const char *value) { - queryHandleT *query = (queryHandleT*)handle; - - query->idx += snprintf (&query->msg[query->idx],query->len," %s: \'%s\',", key, value); +static int getQueryCB (queryHandleT *query, struct afb_arg arg) { + if (query->idx >= query->len) + return 0; + query->idx += (unsigned)snprintf (&query->msg[query->idx], query->len-query->idx, " %s: %s\'%s\',", arg.name, arg.is_file?"FILE=":"", arg.value); + return 1; /* continue to iterate */ } // Helper to retrieve argument from connection -PUBLIC int getQueryAll(AFB_request * request, char *buffer, size_t len) { +size_t getQueryAll(AFB_request * request, char *buffer, size_t len) { queryHandleT query; buffer[0] = '\0'; // start with an empty string - query.msg= buffer; - query.len= len; - query.idx= 0; - - MHD_get_connection_values (request->connection, MHD_GET_ARGUMENT_KIND, getQueryCB, &query); - return (len); -} + query.msg = buffer; + query.len = len; + query.idx = 0; -// Helper to retrieve POST handle -PUBLIC AFB_PostHandle* getPostHandle (AFB_request *request) { - if (request->post == NULL) return (NULL); - return ((AFB_PostHandle*) request->post->data); + afb_req_iterate(*request->areq, (void*)getQueryCB, &query); + buffer[len-1] = 0; + return query.idx >= len ? len - 1 : query.idx; } -// Helper to retrieve POST file context -PUBLIC AFB_PostCtx* getPostContext (AFB_request *request) { - AFB_PostHandle* postHandle; - if (request->post == NULL) return (NULL); +#if 0 +char* getPostPath (AFB_request *request) { + AFB_PostHandle *postHandle = getPostHandle(request); + AFB_PostCtx *postFileCtx; - postHandle = (AFB_PostHandle*) request->post->data; if (postHandle == NULL) return NULL; - - return ((AFB_PostCtx*) postHandle->ctx); + + postFileCtx = (AFB_PostCtx*) postHandle->ctx; + if (postFileCtx == NULL) return NULL; + + return (postFileCtx->path); } -PUBLIC json_object* getPostFile (AFB_request *request, AFB_PostItem *item, char* destination) { +json_object* getPostFile (AFB_request *request, AFB_PostItem *item, char* destination) { AFB_PostHandle *postHandle = getPostHandle(request); AFB_PostCtx *postFileCtx; char filepath[512]; - int len; + ssize_t len; // This is called after PostForm and then after DonePostForm if (item == NULL) { @@ -112,11 +111,9 @@ PUBLIC json_object* getPostFile (AFB_request *request, AFB_PostItem *item, char* } // We have a context but last Xform iteration fail or application set a message - if (postFileCtx->jresp != NULL) { - jresp = postFileCtx->jresp; // retrieve previous error from postCtx - if (postFileCtx->errcode != 0) request->errcode=postFileCtx->errcode; - } - else jresp = jsonNewMessage(AFB_FAIL,"getPostFile Post Request done"); + if (request->jresp != NULL) { + jresp = request->jresp; // retrieve previous error from postCtx + } else jresp = jsonNewMessage(AFB_SUCCESS,"getPostFile Post Request done"); // Error or not let's free all resources close(postFileCtx->fd); @@ -124,7 +121,7 @@ PUBLIC json_object* getPostFile (AFB_request *request, AFB_PostItem *item, char* free (postFileCtx); return (jresp); } - +#if defined(PLEASE_FIX_ME_THE_ERROR_IS_postFileCtx_NOT_INITIALIZED) // Make sure it's a valid PostForm request if (!request->post && request->post->type != AFB_POST_FORM) { postFileCtx->jresp= jsonNewMessage(AFB_FAIL,"This is not a valid PostForm request\n"); @@ -142,7 +139,7 @@ PUBLIC json_object* getPostFile (AFB_request *request, AFB_PostItem *item, char* postFileCtx->jresp= jsonNewMessage(AFB_FAIL,"Buffer size NULL key=%s]\n", item->key); goto ExitOnError; } - +#endif // Extract Application Context from posthandle [NULL == 1st iteration] postFileCtx = (AFB_PostCtx*) postHandle->ctx; @@ -152,7 +149,6 @@ PUBLIC json_object* getPostFile (AFB_request *request, AFB_PostItem *item, char* // Create an application specific context postFileCtx = calloc (1, sizeof(AFB_PostCtx)); // May place anything here until post->completeCB handle resources liberation - postFileCtx->path = strdup (filepath); // attach application to postHandle postHandle->ctx = (void*) postFileCtx; // May place anything here until post->completeCB handle resources liberation @@ -163,12 +159,12 @@ PUBLIC json_object* getPostFile (AFB_request *request, AFB_PostItem *item, char* strncat (filepath, "/", sizeof(filepath)); strncat (filepath, destination, sizeof(filepath)); } else strncpy (filepath, destination, sizeof(filepath)); - + // make sure destination directory exist destDir = opendir (filepath); if (destDir == NULL) { - if ( 0 <= mkdir(filepath,O_RDWR | S_IRWXU | S_IRGRP)) { + if (mkdir(filepath,O_RDWR | S_IRWXU | S_IRGRP) < 0) { postFileCtx->jresp= jsonNewMessage(AFB_FAIL,"Fail to Create destination directory=[%s] error=%s\n", filepath, strerror(errno)); goto ExitOnError; } @@ -177,6 +173,9 @@ PUBLIC json_object* getPostFile (AFB_request *request, AFB_PostItem *item, char* strncat (filepath, "/", sizeof(filepath)); strncat (filepath, item->filename, sizeof(filepath)); + postFileCtx->path = strdup (filepath); + if (verbose) fprintf(stderr, "getPostFile path=%s\n", filepath); + if((postFileCtx->fd = open(filepath, O_RDWR |O_CREAT, S_IRWXU|S_IRGRP)) <= 0) { postFileCtx->jresp= jsonNewMessage(AFB_FAIL,"Fail to Create destination File=[%s] error=%s\n", filepath, strerror(errno)); goto ExitOnError; @@ -188,7 +187,7 @@ PUBLIC json_object* getPostFile (AFB_request *request, AFB_PostItem *item, char* // Check we successfully wrote full buffer len = write (postFileCtx->fd, item->data, item->len); - if (item->len != len) { + if ((ssize_t)item->len != len) { postFileCtx->jresp= jsonNewMessage(AFB_FAIL,"Fail to write file [%s] at [%s] error=\n", item->filename, strerror(errno)); goto ExitOnError; } @@ -201,3 +200,113 @@ ExitOnError: request->errcode = MHD_HTTP_EXPECTATION_FAILED; return NULL; } + +#endif + +static void jsoninit() +{ + int idx, verbosesav; + + if (jTypeStatic) + return; + + // initialise JSON constant messages and increase reference count to make them permanent + verbosesav = verbose; + verbose = 0; // run initialisation in silent mode + jTypeStatic = json_object_new_string ("AFB_message"); + for (idx = 0; idx <= AFB_UNAUTH; idx++) { + AFBerr[idx].level = idx; + AFBerr[idx].label = ERROR_LABEL [idx]; + AFBerr[idx].json = jsonNewMessage (idx, NULL); + } + verbose = verbosesav; +} + + +// build an ERROR message and return it as a valid json object +json_object *json_add_status (json_object *obj, const char *status, const char *info) +{ + if (obj == NULL) + obj = json_object_new_object(); + json_object_object_add(obj, "status", json_object_new_string(status)); + if (info) + json_object_object_add(obj, "info", json_object_new_string(info)); + return obj; +} + +// build an ERROR message and return it as a valid json object +json_object *json_add_status_v (json_object *obj, const char *status, const char *info, va_list args) +{ + char *message; + if (info == NULL || vasprintf(&message, info, args) < 0) + message = NULL; + obj = json_add_status(obj, status, message); + free(message); + return obj; +} + + +// build an ERROR message and return it as a valid json object +json_object *json_add_status_f (json_object *obj, const char *status, const char *info, ...) +{ + va_list args; + va_start(args, info); + obj = json_add_status_v(obj, status, info, args); + va_end(args); + return obj; +} + + + +// build an ERROR message and return it as a valid json object +struct json_object *jsonNewMessage (AFB_error level, char* format, ...) { + static int count = 0; + json_object * AFBResponse; + va_list args; + char message [512]; + + jsoninit(); + + // format message + if (format != NULL) { + va_start(args, format); + vsnprintf (message, sizeof (message), format, args); + va_end(args); + } + + AFBResponse = json_object_new_object(); + json_object_object_add (AFBResponse, "jtype", json_object_get (jTypeStatic)); + json_object_object_add (AFBResponse, "status" , json_object_new_string (ERROR_LABEL[level])); + if (format != NULL) { + json_object_object_add (AFBResponse, "info" , json_object_new_string (message)); + } + if (verbose) { + fprintf (stderr, "AFB:%-6s [%3d]: ", AFBerr [level].label, count++); + if (format != NULL) { + fprintf (stderr, "%s", message); + } else { + fprintf (stderr, "No Message"); + } + fprintf (stderr, "\n"); + } + + return (AFBResponse); +} + +#if 0 +{ + jtype: "AFB_message" + request: + { + prefix: "", + api: "", + status: "", /* exist, fail, empty, null, processed */ + info: "", + uuid: "", + token: "", + timeout: "" + } + response: ... +} +#endif +