+ /* check the mid of the slice */
+ i = (lo + up) >> 1;
+ a = &apis_array[i];
+ c = strcasecmp(a->name, api);
+ if (c == 0) {
+ /* found */
+ return a;
+ }
+ /* update the slice */
+ if (c < 0)
+ lo = i + 1;
+ else
+ up = i;
+ }
+}
+
+/**
+ * Dispatch the request 'req' with the 'context' to the
+ * method of 'api' and 'verb'.
+ * @param req the request to dispatch
+ * @param context the context of the request
+ * @param api the api of the verb
+ * @param verb the verb within the api
+ */
+void afb_apis_call(struct afb_req req, struct afb_context *context, const char *api, const char *verb)
+{
+ const struct api_desc *a;
+
+ /* init hooking the request */
+ req = afb_hook_req_call(req, context, api, verb);
+
+ /* search the api */
+ a = search(api);
+ if (!a)
+ afb_req_fail(req, "fail", "api not found");
+ else {
+ context->api_key = a->api.closure;
+ a->api.call(a->api.closure, req, context, verb);
+ }
+}
+
+/**
+ * Starts a service by its 'api' name.
+ * @param api name of the service to start
+ * @param share_session if true start the servic"e in a shared session
+ * if false start it in its own session
+ * @param onneed if true start the service if possible, if false the api
+ * must be a service
+ * @return a positive number on success
+ */
+int afb_apis_start_service(const char *api, int share_session, int onneed)
+{
+ int i;
+
+ for (i = 0 ; i < apis_count ; i++) {
+ if (!strcasecmp(apis_array[i].name, api))
+ return apis_array[i].api.service_start(apis_array[i].api.closure, share_session, onneed);
+ }
+ ERROR("can't find service %s", api);
+ errno = ENOENT;
+ return -1;
+}
+
+/**
+ * Starts all possible services but stops at first error.
+ * @param share_session if true start the servic"e in a shared session
+ * if false start it in its own session
+ * @return 0 on success or a negative number when an error is found
+ */
+int afb_apis_start_all_services(int share_session)
+{
+ int i, rc;
+
+ for (i = 0 ; i < apis_count ; i++) {
+ rc = apis_array[i].api.service_start(apis_array[i].api.closure, share_session, 1);
+ if (rc < 0)
+ return rc;
+ }
+ return 0;
+}
+
+/**
+ * Dispatch the request 'req' with the 'context' to the
+ * method of 'api' and 'verb'.
+ * @param req the request to dispatch
+ * @param context the context of the request
+ * @param api the api of the verb
+ * @param verb the verb within the api
+ */
+void afb_apis_xcall(struct afb_xreq *xreq)
+{
+ const struct api_desc *a;
+
+ /* init hooking the request */
+ // TODO req = afb_hook_req_call(req, context, api, verb);
+
+ /* search the api */
+ a = search(xreq->api);
+ if (!a)
+ afb_xreq_fail_f(xreq, "unknown-api", "api %s not found", xreq->api);
+ else {
+ xreq->context.api_key = a->api.closure;
+ a->api.xcall(a->api.closure, xreq);