summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJose Bollo <jose.bollo@iot.bzh>2019-09-27 18:29:22 +0200
committerJose Bollo <jose.bollo@iot.bzh>2019-09-30 11:52:27 +0200
commit6bf1b8c3a8af299c04d9be0d59b42c3a6d7c9127 (patch)
treea05094fef0e762eedef188f026aaabb4971d1e50
parente4d6dbdf10130b72fe4a898b105d3049a0cdf98a (diff)
Change agent interface
Instead of using callbacks, create the query to allow processing subqueries in response to agent queries. Signed-off-by: Jose Bollo <jose.bollo@iot.bzh>
-rw-r--r--src/agent-at.c31
-rw-r--r--src/cyn.c163
-rw-r--r--src/cyn.h27
3 files changed, 129 insertions, 92 deletions
diff --git a/src/agent-at.c b/src/agent-at.c
index 0ae8d13..e646ab7 100644
--- a/src/agent-at.c
+++ b/src/agent-at.c
@@ -45,6 +45,7 @@ parse(
) {
size_t iout, ikey, inf;
const char *val;
+ int sub;
iout = 0;
for (ikey = 0 ; ikey < KeyIdx_Count ; ikey++) {
@@ -66,29 +67,26 @@ parse(
switch(spec[1]) {
case 'c':
val = rkey->client;
+ sub = 1;
break;
case 's':
val = rkey->session;
+ sub = 1;
break;
case 'u':
val = rkey->user;
+ sub = 1;
break;
case 'p':
val = rkey->permission;
+ sub = 1;
break;
default:
/* none */
- val = 0;
+ sub = 0;
+ break;
}
- if (val) {
- /* substitution of the value */
- while (*val) {
- if (iout < szbuf)
- buffer[iout] = *val;
- iout++;
- val++;
- }
- } else {
+ if (!sub) {
/* no substitution */
if (spec[1] != ':' && spec[1] != '%') {
/* only escape % and : */
@@ -99,6 +97,14 @@ parse(
if (iout < szbuf)
buffer[iout] = spec[1];
iout++;
+ } else if (val) {
+ /* substitution of the value */
+ while (*val) {
+ if (iout < szbuf)
+ buffer[iout] = *val;
+ iout++;
+ val++;
+ }
}
spec += 2;
}
@@ -136,8 +142,7 @@ agent_at_cb(
void *agent_closure,
const data_key_t *key,
const char *value,
- on_result_cb_t *on_result_cb,
- void *on_result_closure
+ cyn_query_t *query
) {
data_key_t atkey;
char *block;
@@ -150,7 +155,7 @@ agent_at_cb(
/* initialize the derived key */
parse(value, key, &atkey, block, size);
/* ask for the derived key */
- return cyn_test_async(on_result_cb, on_result_closure, &atkey);
+ return cyn_subquery_async(query, (on_result_cb_t*)cyn_reply_query, query, &atkey);
}
/* see agent-at.h */
diff --git a/src/cyn.c b/src/cyn.c
index cedf3e2..6978251 100644
--- a/src/cyn.c
+++ b/src/cyn.c
@@ -75,7 +75,7 @@ struct agent
/**
* structure handling an asynchronous check
*/
-struct async_check
+struct cyn_query
{
/** callback for handling result of the check */
on_result_cb_t *on_result_cb;
@@ -380,58 +380,81 @@ required_agent(
return 0;
}
-
-static
-void
-async_reply(
- struct async_check *achk
-) {
- achk->on_result_cb(achk->closure, &achk->value);
- free(achk);
-}
-
-static
-void
-async_on_result(
- void *closure,
- const data_value_t *value
-);
-
static
void
async_call_agent(
struct agent *agent,
- struct async_check *achk
+ cyn_query_t *query,
+ const data_value_t *value
) {
int rc = agent->agent_cb(
agent->name,
agent->closure,
- &achk->key,
- &achk->value.value[agent->len + 1],
- async_on_result,
- achk);
+ &query->key,
+ &value->value[agent->len + 1],
+ query);
if (rc < 0)
- async_reply(achk);
+ cyn_reply_query(query, value);
}
static
-void
-async_on_result(
+cyn_query_t *
+alloc_query(
+ on_result_cb_t *on_result_cb,
void *closure,
- const data_value_t *value
+ const data_key_t *key,
+ int maxdepth
) {
- struct async_check *achk = closure;
- struct agent *agent;
+ size_t szcli, szses, szuse, szper;
+ cyn_query_t *query;
+ void *ptr;
- achk->value = *value;
- agent = required_agent(value->value);
- if (agent && achk->decount) {
- achk->decount--;
- async_call_agent(agent, achk);
- } else
- async_reply(achk);
+ /* allocate asynchronous query */
+ szcli = key->client ? 1 + strlen(key->client) : 0;
+ szses = key->session ? 1 + strlen(key->session) : 0;
+ szuse = key->user ? 1 + strlen(key->user) : 0;
+ szper = key->permission ? 1 + strlen(key->permission) : 0;
+ query = malloc(szcli + szses + szuse + szper + sizeof *query);
+ if (query) {
+ /* init the structure */
+ ptr = &query[1];
+ query->on_result_cb = on_result_cb;
+ query->closure = closure;
+ if (!key->client)
+ query->key.client = 0;
+ else {
+ query->key.client = ptr;
+ ptr = mempcpy(ptr, key->client, szcli);
+ }
+ if (!key->session)
+ query->key.session = 0;
+ else {
+ query->key.session = ptr;
+ ptr = mempcpy(ptr, key->session, szses);
+ }
+ if (!key->user)
+ query->key.user = 0;
+ else {
+ query->key.user = ptr;
+ ptr = mempcpy(ptr, key->user, szuse);
+ }
+ if (!key->permission)
+ query->key.permission = 0;
+ else {
+ query->key.permission = ptr;
+ ptr = mempcpy(ptr, key->permission, szper);
+ }
+ query->decount = maxdepth;
+ }
+ return query;
}
+
+
+
+
+
+
int
cyn_query_async(
on_result_cb_t *on_result_cb,
@@ -441,10 +464,8 @@ cyn_query_async(
) {
int rc;
data_value_t value;
- size_t szcli, szses, szuse, szper;
- struct async_check *achk;
+ cyn_query_t *query;
struct agent *agent;
- void *ptr;
/* get the direct value */
rc = db_test(key, &value);
@@ -464,49 +485,14 @@ cyn_query_async(
}
/* allocate asynchronous query */
- szcli = key->client ? 1 + strlen(key->client) : 0;
- szses = key->session ? 1 + strlen(key->session) : 0;
- szuse = key->user ? 1 + strlen(key->user) : 0;
- szper = key->permission ? 1 + strlen(key->permission) : 0;
- achk = malloc(szcli + szses + szuse + szper + sizeof *achk);
- if (!achk) {
+ query = alloc_query(on_result_cb, closure, key, maxdepth);
+ if (!query) {
on_result_cb(closure, &value);
return -ENOMEM;
}
- /* init the structure */
- ptr = &achk[1];
- achk->on_result_cb = on_result_cb;
- achk->closure = closure;
- if (!key->client)
- achk->key.client = 0;
- else {
- achk->key.client = ptr;
- ptr = mempcpy(ptr, key->client, szcli);
- }
- if (!key->session)
- achk->key.session = 0;
- else {
- achk->key.session = ptr;
- ptr = mempcpy(ptr, key->session, szses);
- }
- if (!key->user)
- achk->key.user = 0;
- else {
- achk->key.user = ptr;
- ptr = mempcpy(ptr, key->user, szuse);
- }
- if (!key->permission)
- achk->key.permission = 0;
- else {
- achk->key.permission = ptr;
- ptr = mempcpy(ptr, key->permission, szper);
- }
- achk->value = value;
- achk->decount = maxdepth;
-
/* call the agent */
- async_call_agent(agent, achk);
+ async_call_agent(agent, query, &value);
return 0;
}
@@ -530,6 +516,29 @@ cyn_check_async(
return cyn_query_async(on_result_cb, closure, key, CYN_SEARCH_DEEP_MAX);
}
+int
+cyn_subquery_async(
+ cyn_query_t *query,
+ on_result_cb_t *on_result_cb,
+ void *closure,
+ const data_key_t *key
+) {
+ return cyn_query_async(on_result_cb, closure, key, query->decount - 1);
+}
+
+void
+cyn_reply_query(
+ cyn_query_t *query,
+ const data_value_t *value
+) {
+ query->on_result_cb(query->closure, value);
+ free(query);
+}
+
+
+
+
+
/* see cyn.h */
int
cyn_agent_add(
diff --git a/src/cyn.h b/src/cyn.h
index 5b4c76f..5772608 100644
--- a/src/cyn.h
+++ b/src/cyn.h
@@ -18,6 +18,8 @@
#pragma once
+#define CYN_VERSION 99
+
/**
* Callback for entering asynchronousely the critical section
* When called it receives the 'magic' argument given when
@@ -50,6 +52,12 @@ typedef void (list_cb_t)(
const data_value_t *value);
/**
+ * Opaque structure for agent subqueries and responses.
+ */
+typedef struct cyn_query cyn_query_t;
+
+
+/**
* Callback for querying agents
*/
typedef int (agent_cb_t)(
@@ -57,8 +65,7 @@ typedef int (agent_cb_t)(
void *agent_closure,
const data_key_t *key,
const char *value,
- on_result_cb_t *on_result_cb,
- void *on_result_closure);
+ cyn_query_t *query);
/**
* Enter in the critical recoverable section if possible
@@ -226,6 +233,22 @@ cyn_check_async(
extern
int
+cyn_subquery_async(
+ cyn_query_t *query,
+ on_result_cb_t *on_result_cb,
+ void *closure,
+ const data_key_t *key
+);
+
+extern
+void
+cyn_reply_query(
+ cyn_query_t *query,
+ const data_value_t *value
+);
+
+extern
+int
cyn_agent_add(
const char *name,
agent_cb_t *agent_cb,