+// ********************************************************
+
+// FULUP integration proposal with client session context
+
+// ********************************************************
+
+
+#define MAX_RADIO 10
+
+// Structure holding existing radio with current usage status
+typedef struct {
+ int idx;
+ char *name;
+ int used;
+} radioDevT;
+
+// Radio plugin handle should store everething API may need
+typedef struct {
+ radioDevT *radios[MAX_RADIO]; // pointer to existing radio
+ int devCount;
+} pluginHandleT;
+
+// Client Context Structure Hold any specific to client [will be destroyed when client leave]
+typedef struct {
+ dev_ctx_T radio; // pointer to client radio
+ int idx; // index of radio within global array
+} ctxHandleT;
+
+
+// It his was not a demo only, it should be smarter to enable hot plug/unplug
+STATIC void updateRadioDevList(pluginHandleT *handle) {
+ int idx;
+
+ // loop on existing radio if any
+ for (idx = 0; idx < _radio_dev_count(); idx++) {
+ if (idx == MAX_RADIO) break;
+ handle->radios[idx] = calloc(1, sizeof(radioDevT)); // use calloc to set used to FALSE
+ handle->radios[idx]->name = (char *) _radio_dev_name(idx);
+ }
+ handle->devCount = _radio_dev_count();
+}
+
+
+// This is call at plugin load time [radio devices might still not be visible]
+STATIC pluginHandleT* initRadioPlugin() {
+
+ // Allocate Plugin handle
+ pluginHandleT *handle = calloc (1,sizeof (pluginHandleT)); // init handle with zero
+
+ // Some initialization steps
+ updateRadioDevList(handle);
+
+ return (handle);
+}
+
+// Stop a radio free related ressource and make it avaliable for other clients
+STATIC AFB_error releaseRadio (pluginHandleT* handle, ctxHandleT *ctx) {
+
+ // change radio status
+ (handle->radios[ctx->idx])->used = FALSE;
+
+ // stop related threads and free attached resources
+ radio_stop (&ctx->radio);
+
+ // May be some further cleanup ????
+
+ return (AFB_SUCCESS); // Could it fails ????
+}
+
+
+// Start a radio and reserve exclusive usage to requesting client
+STATIC ctxHandleT *reserveRadio (pluginHandleT* handle) {
+ ctxHandleT *client;
+ int idx;
+
+ // loop on existing radio if any
+ for (idx = 0; idx < _radio_dev_count(); idx++) {
+ if ((handle->radios[client->idx])->used = FALSE) break;
+ }
+
+ // No avaliable radio return now
+ if (idx == MAX_RADIO) return (NULL);
+
+ // Book radio
+ (handle->radios[client->idx])->used = TRUE;
+
+ // create client handle
+ client = calloc (1, sizeof (ctxHandleT));
+
+ // stop related threads and free attached resources
+ _radio_start_threads (&client->radio);
+
+ // May be some things to do ????
+
+
+ return (client);
+}
+
+// This is called when client session died [ex; client quit for more than 15mn]
+STATIC json_object* freeRadio () {
+
+ //releaseRadio (client->handle, client);
+ //free (client);
+}
+
+
+STATIC json_object* powerOnOff (AFB_request *request) {
+ json_object *jresp;
+ AFB_clientCtx *client = request->client; // get client context from request
+
+ // Make sure binder was started with client session
+ if (client == NULL) {
+ request->errcode=MHD_HTTP_FORBIDDEN;
+ return (jsonNewMessage(AFB_FAIL, "Radio binder need session [--token=xxxx]"));
+ }
+
+ // If we have a handle radio was on let power it down
+ if (client->ctx != NULL) {
+ dev_ctx_T *dev_ctx = (dev_ctx_T *)client->ctx;
+
+ releaseRadio (client->plugin->handle, client->ctx); // poweroff client related radio
+
+ jresp = json_object_new_object();
+ json_object_object_add(jresp, "power", json_object_new_string ("off"));
+ return (jresp);
+ }
+
+ // request a new client context token and check result
+ if (AFB_UNAUTH == ctxTokenCreate (request)) {
+ request->errcode=MHD_HTTP_UNAUTHORIZED;
+ jresp= jsonNewMessage(AFB_FAIL, "You're not authorized to request a radio [make sure you have the right authentication token");
+ return (jresp);
+ }
+
+ // Client is clean let's look it we have an avaliable radio to propose
+
+ // make sure we have last hot plug dongle visible
+ updateRadioDevList (client->plugin->handle);
+
+ // get try to get an unused radio
+ client->ctx = reserveRadio (client->plugin->handle);
+ if (client->ctx == NULL) {
+ return (jsonNewMessage(AFB_FAIL, "Sory No More Radio Avaliable"));
+ }
+
+ // At this point we should have something to retreive radio status before last poweroff [but this is only a demonstrator]
+}