From 1dc25c6396d8dbb6b1505751babaa499d4a68315 Mon Sep 17 00:00:00 2001 From: Fulup Ar Foll Date: Sun, 13 Dec 2015 10:21:46 +0100 Subject: [PATCH] Fixed Session Context Free with ctxFreeCB --- include/local-def.h | 42 ++++++++++++++++++++---------------------- include/proto-def.h | 4 ++-- src/afbs-api.c | 13 ++++++++++--- src/alsa-api.c | 6 +++--- src/dbus-api.c | 3 +-- src/radio-api.c | 10 +++++----- src/rest-api.c | 23 +++++++++++++++-------- src/session.c | 13 +++++++------ 8 files changed, 63 insertions(+), 51 deletions(-) diff --git a/include/local-def.h b/include/local-def.h index b37cd757..2f8fd202 100644 --- a/include/local-def.h +++ b/include/local-def.h @@ -169,26 +169,37 @@ typedef struct { AFB_privateApi *private; } AFB_restapi; +// Plugin definition +typedef struct { + AFB_pluginT type; + char *info; + char *prefix; + size_t prefixlen; + json_object *jtype; + AFB_restapi *apis; + void *handle; + int ctxCount; + AFB_apiCB freeCtxCB; // callback to free application context [null for standard free] +} AFB_plugin; + // User Client Session Context typedef struct { - int cid; // index 0 if global - char uuid[37]; // long term authentication of remote client - char token[37]; // short term authentication of remote client - time_t timeStamp; // last time token was refresh - int restfull; // client does not use cookie - void *handle; // application specific context - AFB_apiCB freeHandleCB; // callback to free application handle [null for standard free] + int cid; // index 0 if global + char uuid[37]; // long term authentication of remote client + char token[37]; // short term authentication of remote client + time_t timeStamp; // last time token was refresh + int restfull; // client does not use cookie + void *ctx; // application specific context + AFB_plugin *plugin; // provide callback and easy access to plugin } AFB_clientCtx; - // MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "value"); typedef struct { const char *url; char *plugin; char *api; char *post; - int loa; json_object *jresp; AFB_clientCtx *client; // needed because libmicrohttp cannot create an empty response int restfull; // request is resfull [uuid token provided] @@ -199,19 +210,6 @@ typedef struct { } AFB_request; -// Plugin definition -typedef struct { - AFB_pluginT type; - char *info; - char *prefix; - size_t prefixlen; - json_object *jtype; - AFB_restapi *apis; - void *handle; - int ctxCount; -} AFB_plugin; - - typedef struct { AFB_config *config; // pointer to current config // List of commands to execute diff --git a/include/proto-def.h b/include/proto-def.h index b6cdb94e..55585e7b 100644 --- a/include/proto-def.h +++ b/include/proto-def.h @@ -22,7 +22,7 @@ // Rest-api -PUBLIC json_object* apiPingTest(AFB_request *request, void *pluginHandle); +PUBLIC json_object* apiPingTest(AFB_request *request); PUBLIC const char* getQueryValue (AFB_request * request, char *name); PUBLIC int getQueryAll(AFB_request * request, char *query, size_t len); @@ -48,7 +48,7 @@ PUBLIC AFB_error ctxTokenRefresh (AFB_request *request); PUBLIC AFB_error ctxTokenCreate (AFB_request *request); PUBLIC AFB_error ctxTokenCheck (AFB_request *request); PUBLIC AFB_error ctxTokenReset (AFB_request *request); -PUBLIC AFB_error ctxClientGet (AFB_request *request); +PUBLIC AFB_error ctxClientGet (AFB_request *request, AFB_plugin *plugin); diff --git a/src/afbs-api.c b/src/afbs-api.c index 44fa0334..344377b2 100644 --- a/src/afbs-api.c +++ b/src/afbs-api.c @@ -34,7 +34,7 @@ STATIC json_object* clientContextCreate (AFB_request *request) { AFB_clientCtx *client=request->client; // get client context from request // check we do not already have a session - if ((client != NULL) && (client->handle != NULL)) { + if ((client != NULL) && (client->ctx != NULL)) { request->errcode=MHD_HTTP_FORBIDDEN; return (jsonNewMessage(AFB_FAIL, "Token exist use refresh")); } @@ -53,8 +53,8 @@ STATIC json_object* clientContextCreate (AFB_request *request) { return (jresp); } - // add a client handle to session - client->handle = malloc (sizeof (MyClientApplicationHandle)); + // add a client context to session + client->ctx = malloc (sizeof (MyClientApplicationHandle)); // Send response to UI jresp = json_object_new_object(); @@ -112,6 +112,12 @@ STATIC json_object* clientContextReset (AFB_request *request) { return (jresp); } +// This function is call when Client Session Context is removed +// Note: when freeCtxCB==NULL standard free/malloc is called +STATIC void clientContextFree(AFB_clientCtx *client) { + fprintf (stderr,"Plugin[%s] Closing Session uuid=[%s]\n", client->plugin->prefix, client->uuid); + free (client->ctx); +} STATIC AFB_restapi pluginApis[]= { {"ping" , (AFB_apiCB)apiPingTest ,"Ping Rest Test Service"}, @@ -129,6 +135,7 @@ PUBLIC AFB_plugin *afsvRegister () { plugin->prefix= "afbs"; // url base plugin->apis = pluginApis; plugin->handle= (void*) "What ever you want"; + plugin->freeCtxCB= (void*) clientContextFree; return (plugin); }; \ No newline at end of file diff --git a/src/alsa-api.c b/src/alsa-api.c index 61c79533..23964a68 100644 --- a/src/alsa-api.c +++ b/src/alsa-api.c @@ -27,7 +27,7 @@ STATIC json_object* wrongApi (AFB_request *request, void* handle) { impossible=bug/zero; } -STATIC json_object* pingSample (AFB_request *request, void* handle) { +STATIC json_object* pingSample (AFB_request *request) { static pingcount = 0; json_object *response; char query [512]; @@ -39,7 +39,8 @@ STATIC json_object* pingSample (AFB_request *request, void* handle) { if (request->post == NULL) request->post="NoData"; // return response to caller - response = jsonNewMessage(AFB_SUCCESS, "Ping Binder Daemon %d query={%s} handle=[%s] PostData: \'%s\' ", pingcount++, query, handle, request->post); + response = jsonNewMessage(AFB_SUCCESS, "Ping Binder Daemon %d query={%s} handle=[%s] PostData: \'%s\' " + , pingcount++, query, request->post); if (verbose) fprintf(stderr, "%d: \n", pingcount); return (response); @@ -65,6 +66,5 @@ PUBLIC AFB_plugin *alsaRegister () { plugin->info = "Application Framework Binder Service"; plugin->prefix= "alsa"; plugin->apis = pluginApis; - plugin->handle= "bla bla bla"; return (plugin); }; \ No newline at end of file diff --git a/src/dbus-api.c b/src/dbus-api.c index d7097fc7..f7b071bd 100644 --- a/src/dbus-api.c +++ b/src/dbus-api.c @@ -57,7 +57,7 @@ STATIC json_object* pingBug (AFB_request *request) { // For samples https://linuxprograms.wordpress.com/2010/05/20/json-c-libjson-tutorial/ -STATIC json_object* pingJson (AFB_session *session, AFB_request *request, void* handle) { +STATIC json_object* pingJson (AFB_session *session, AFB_request *request) { json_object *jresp, *embed; jresp = json_object_new_object(); @@ -91,6 +91,5 @@ PUBLIC AFB_plugin *dbusRegister () { plugin->info = "Application Framework Binder Service"; plugin->prefix= "dbus"; plugin->apis = pluginApis; - plugin->handle= (void*) "Any you Want"; return (plugin); }; \ No newline at end of file diff --git a/src/radio-api.c b/src/radio-api.c index eb040a15..35cab388 100644 --- a/src/radio-api.c +++ b/src/radio-api.c @@ -554,7 +554,7 @@ STATIC AFB_error releaseRadio (pluginHandleT* handle, AFB_clientCtx *client) { handle->radios[client->idx].used = FALSE; // stop related threads and free attached resources - radio_stop (client->radio); + radio_stop (&client->radio); // May be some further cleanup ???? @@ -581,7 +581,7 @@ STATIC clientHandleT *reserveRadio (pluginHandleT* handle) { client = calloc (1, sizeof (clientHandleT)); // stop related threads and free attached resources - radio_start (client->radio); + radio_start (&client->radio); // May be some things to do ???? @@ -597,10 +597,10 @@ STATIC freeRadio (clientHandleT *client) { } -STATIC json_object* powerOnOff (AFB_session *session, AFB_request *request, void* handle) { +STATIC json_object* powerOnOff (AFB_session *session, AFB_request *request) { json_object *jresp; - dev_ctx *dev_ctx = (dev_ctx *)handle; AFB_clientCtx *client=request->client; // get client context from request + dev_ctx *dev_ctx = (dev_ctx *)client->ctx; // Make sure binder was started with client session if ((client != NULL) { @@ -655,7 +655,7 @@ PUBLIC AFB_plugin *radioRegister (AFB_session *session) { plugin->apis = pluginApis; plugin->handle = initRadioPlugin(); - plugin->freeHandleCB = freeRadio(); + plugin->freeCtxCB = freeRadio(); return (plugin); }; diff --git a/src/rest-api.c b/src/rest-api.c index 83bb2d22..62b782d5 100644 --- a/src/rest-api.c +++ b/src/rest-api.c @@ -37,22 +37,29 @@ static json_object *afbJsonType; // Sample Generic Ping Debug API -PUBLIC json_object* apiPingTest(AFB_request *request, void *pluginHandle) { +PUBLIC json_object* apiPingTest(AFB_request *request) { static pingcount = 0; json_object *response; - char query [512]; - int len; + char query [256]; + char session[256]; + int len; + AFB_clientCtx *client=request->client; // get client context from request + // request all query key/value len = getQueryAll (request, query, sizeof(query)); - if (len == 0) strcpy (query,"NoSearchQueryList"); + if (len == 0) strncpy (query, "NoSearchQueryList", sizeof(query)); // check if we have some post data - if (request->post == NULL) request->post="NoData"; + if (request->post == NULL) request->post="NoData"; + + // check is we have a session and a plugin handle + if (client == NULL) strcpy (session,"NoSession"); + else snprintf(session, sizeof(session),"uuid=%s token=%s ctx=0x%x handle=0x%x", client->uuid, client->token, client->ctx, client->ctx); // return response to caller - response = jsonNewMessage(AFB_SUCCESS, "Ping Binder Daemon count=%d CtxtId=%d Loa=%d query={%s} Handle=0x%x PostData: \'%s\' " - , pingcount++, request->client->cid, request->loa, query, request->post, pluginHandle); + response = jsonNewMessage(AFB_SUCCESS, "Ping Binder Daemon count=%d CtxtId=%d query={%s} session={%s} PostData: [%s] " + , pingcount++, request->client->cid, query, session, request->post); return (response); } @@ -151,7 +158,7 @@ STATIC AFB_error callPluginApi(AFB_plugin *plugin, AFB_request *request) { } // add client context to request - ctxClientGet(request); + ctxClientGet(request, plugin); // Effectively call the API with a subset of the context jresp = plugin->apis[idx].callback(request, plugin->handle); diff --git a/src/session.c b/src/session.c index 56620f35..45005ab4 100644 --- a/src/session.c +++ b/src/session.c @@ -332,14 +332,14 @@ STATIC int ctxUuidCompCB (const void *k1, const void *k2) { // Free context [XXXX Should be protected again memory abort XXXX] STATIC void ctxUuidFreeCB (struct lh_entry *entry) { - AFB_clientCtx *ctx = (AFB_clientCtx*) entry->v; + AFB_clientCtx *client = (AFB_clientCtx*) entry->v; // If application add a handle let's free it now - if (ctx->handle != NULL) { + if (client->ctx != NULL) { // Free client handle with a standard Free function, with app callback or ignore it - if (ctx->freeHandleCB == NULL) free (ctx->handle); - else if (ctx->freeHandleCB != (void*)-1) ctx->freeHandleCB(ctx->handle); + if (client->plugin->freeCtxCB == NULL) free (client->ctx); + else if (client->plugin->freeCtxCB != (void*)-1) client->plugin->freeCtxCB(client); } free ((void*)entry->v); } @@ -379,7 +379,7 @@ PUBLIC int ctxStoreGarbage (struct lh_table *lht, const int timeout) { } // This function will return exiting client context or newly created client context -PUBLIC AFB_error ctxClientGet (AFB_request *request) { +PUBLIC AFB_error ctxClientGet (AFB_request *request, AFB_plugin *plugin) { static int cid=0; AFB_clientCtx *clientCtx=NULL; const char *uuid; @@ -420,7 +420,8 @@ PUBLIC AFB_error ctxClientGet (AFB_request *request) { if (clientCtx == NULL) clientCtx = calloc(1, sizeof(AFB_clientCtx)); // init NULL clientContext uuid_generate(newuuid); // create a new UUID uuid_unparse_lower(newuuid, clientCtx->uuid); - clientCtx->cid=cid++; + clientCtx->cid=cid++; // simple application uniqueID + clientCtx->plugin = plugin; // provide plugin callbacks a hook to plugin // if table is full at 50% let's clean it up if(clientCtxs->count > (clientCtxs->size*0.5)) ctxStoreGarbage(clientCtxs, request->config->cntxTimeout); -- 2.16.6