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]
} 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
// 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);
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);
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"));
}
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();
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"},
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
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];
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);
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
// 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();
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
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 ????
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 ????
}
-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) {
plugin->apis = pluginApis;
plugin->handle = initRadioPlugin();
- plugin->freeHandleCB = freeRadio();
+ plugin->freeCtxCB = freeRadio();
return (plugin);
};
// 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);
}
}
// 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);
// 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);
}
}
// 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;
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);