+/**
+ * Check whether the 'set' has the API of 'name'
+ * @param set the set of API
+ * @param name the name of the API to get
+ * @return 1 if the api exist or 0 otherwise
+ */
+int afb_apiset_has(struct afb_apiset *set, const char *name)
+{
+ return !!search(set, name);
+}
+
+/**
+ * Get from the 'set' the API of 'name' in 'api' with fallback to subset or default api
+ * @param set the set of API
+ * @param name the name of the API to get
+ * @param api the structure where to store data about the API of name
+ * @return 0 in case of success or -1 in case of error
+ */
+static struct api_desc *get_api(struct afb_apiset *set, const char *name)
+{
+ struct api_desc *i = search(set, name);
+ return i || !set->subset ? i : get_api(set->subset, name);
+}
+
+/**
+ * Get from the 'set' the API of 'name' in 'api' with fallback to subset or default api
+ * @param set the set of API
+ * @param name the name of the API to get
+ * @param api the structure where to store data about the API of name
+ * @return 0 in case of success or -1 in case of error
+ */
+int afb_apiset_get(struct afb_apiset *set, const char *name, struct afb_api *api)
+{
+ const struct api_desc *i;
+
+ i = get_api(set, name);
+ if (!i) {
+ errno = ENOENT;
+ return -1;
+ }
+ *api = i->api;
+ return 0;
+}
+
+/**
+ * Starts the service 'api'.
+ * @param api the api
+ * @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
+ */
+static int start_api(struct afb_apiset *set, struct api_desc *api, int share_session, int onneed)
+{
+ int rc;
+
+ if (api->status == 0)
+ return 0;
+ else if (api->status > 0) {
+ errno = api->status;
+ return -1;
+ }
+
+ INFO("API %s starting...", api->name);
+ if (api->api.itf->service_start) {
+ api->status = EBUSY;
+ rc = api->api.itf->service_start(api->api.closure, share_session, onneed, set);
+ if (rc < 0) {
+ api->status = errno ?: ECANCELED;
+ ERROR("The api %s failed to start (%d)", api->name, rc);
+ return -1;
+ }
+ } else if (!onneed) {
+ /* already started: it is an error */
+ ERROR("The api %s is not a startable service", api->name);
+ api->status = EINVAL;
+ return -1;
+ }
+ NOTICE("API %s started", api->name);
+ api->status = 0;
+ return 0;
+}
+
+/**
+ * Get from the 'set' the API of 'name' in 'api' with fallback to subset or default api
+ * @param set the set of API
+ * @param name the name of the API to get
+ * @param api the structure where to store data about the API of name
+ * @return 0 in case of success or -1 in case of error
+ */
+int afb_apiset_get_started(struct afb_apiset *set, const char *name, struct afb_api *api)
+{
+ struct api_desc *i;
+
+ i = get_api(set, name);
+ if (!i) {
+ errno = ENOENT;
+ return -1;
+ }
+ *api = i->api;
+ return i->status ? start_api(set, i, 1, 1) : 0;
+}
+