summaryrefslogtreecommitdiffstats
path: root/ahl-binding/ahl-binding.cpp
diff options
context:
space:
mode:
authorLoïc Collignon <loic.collignon@iot.bzh>2018-10-19 13:50:35 +0200
committerLoïc Collignon <loic.collignon@iot.bzh>2018-10-22 10:04:42 +0200
commit29f1daa03ca6a664b64ba600e50e4ec949b6cc11 (patch)
tree74da011abe57deb322aa6d07f3d86f23a789217b /ahl-binding/ahl-binding.cpp
parent9b62cff70a07bebe28e8cd5fb496c7bf5fef04f8 (diff)
Migration to Afb API v3
Migrate the API to get rid of dynapi by using API v3 instead. Also fix possible bugs and memory leaks when startup fails. Bug: SPEC-1546 Change-Id: I7cf8e9454d6910b1258dfe671dedde3b84855fc4 Signed-off-by: Loïc Collignon <loic.collignon@iot.bzh>
Diffstat (limited to 'ahl-binding/ahl-binding.cpp')
-rw-r--r--ahl-binding/ahl-binding.cpp126
1 files changed, 65 insertions, 61 deletions
diff --git a/ahl-binding/ahl-binding.cpp b/ahl-binding/ahl-binding.cpp
index ce31499..a7cf7d4 100644
--- a/ahl-binding/ahl-binding.cpp
+++ b/ahl-binding/ahl-binding.cpp
@@ -18,31 +18,27 @@
#include <algorithm>
#include "ahl-binding.hpp"
-afb_dynapi* AFB_default; // BUG: Is it possible to get rid of this ?
-
/**
* @brief Callback invoked on new api creation.
* @param[in] handle Handle to the new api.
* @return Status code, zero if success.
*/
-int ahl_api_create(void*, struct afb_dynapi* handle)
+int ahl_api_create(void*, afb_api_t handle)
{
return ahl_binding_t::instance().preinit(handle);
}
/**
- * @brief Entry point for dynamic API.
+ * @brief Entry point for API.
* @param[in] handle Handle to start with for API creation.
* @return Status code, zero if success.
*/
-int afbBindingEntry(afb_dynapi* handle)
+int afbBindingEntry(afb_api_t handle)
{
using namespace std::placeholders;
assert(handle != nullptr);
- AFB_default = handle;
-
- return afb_dynapi_new_api(
+ afb_api_new_api(
handle,
HL_API_NAME,
HL_API_INFO,
@@ -50,13 +46,15 @@ int afbBindingEntry(afb_dynapi* handle)
ahl_api_create,
nullptr
);
+
+ return 0;
}
/**
* @brief Callback invoked when API enter the init phase.
* @return Status code, zero if success.
*/
-int ahl_api_init(afb_dynapi*)
+int ahl_api_init(afb_api_t)
{
return ahl_binding_t::instance().init();
}
@@ -66,7 +64,7 @@ int ahl_api_init(afb_dynapi*)
* @param[in] e Event's name.
* @param[in] o Event's args.
*/
-void ahl_api_on_event(afb_dynapi*, const char* e, struct json_object* o)
+void ahl_api_on_event(afb_api_t, const char* e, struct json_object* o)
{
ahl_binding_t::instance().event(e, o);
}
@@ -76,7 +74,7 @@ void ahl_api_on_event(afb_dynapi*, const char* e, struct json_object* o)
* @param[in] o Config section to handle.
* @return Status code, zero if success.
*/
-int ahl_api_config_roles(afb_dynapi*, CtlSectionT*, json_object* o)
+int ahl_api_config_roles(afb_api_t, CtlSectionT*, json_object* o)
{
return ahl_binding_t::instance().parse_roles_config(o);
}
@@ -85,7 +83,7 @@ int ahl_api_config_roles(afb_dynapi*, CtlSectionT*, json_object* o)
* @brief Callback invoked when clients call the verb 'get_roles'.
* @param[in] req Request to handle.
*/
-void ahl_api_get_roles(afb_request* req)
+void ahl_api_get_roles(afb_req_t req)
{
ahl_binding_t::instance().get_roles(req);
}
@@ -96,7 +94,7 @@ void ahl_api_get_roles(afb_request* req)
*
* Handle dynamic verbs based on role name ('multimedia', 'navigation', ...)
*/
-void ahl_api_role(afb_request* req)
+void ahl_api_role(afb_req_t req)
{
role_t* role = (role_t*)req->vcbdata;
assert(role != nullptr);
@@ -127,7 +125,7 @@ ahl_binding_t& ahl_binding_t::instance()
* @param[in] handle Handle to the api.
* @return Status code, zero if success.
*/
-int ahl_binding_t::preinit(afb_dynapi* handle)
+int ahl_binding_t::preinit(afb_api_t handle)
{
handle_ = handle;
@@ -136,15 +134,15 @@ int ahl_binding_t::preinit(afb_dynapi* handle)
load_static_verbs();
load_controller_configs();
- if (afb_dynapi_on_event(handle_, ahl_api_on_event))
+ if (afb_api_on_event(handle_, ahl_api_on_event))
throw std::runtime_error("Failed to register event handler callback.");
- if (afb_dynapi_on_init(handle_, ahl_api_init))
+ if (afb_api_on_init(handle_, ahl_api_init))
throw std::runtime_error("Failed to register init handler callback.");
}
catch(std::exception& e)
{
- AFB_DYNAPI_ERROR(handle, "%s", e.what());
+ AFB_API_ERROR(handle, "%s", e.what());
return -1;
}
@@ -158,22 +156,22 @@ int ahl_binding_t::init()
{
using namespace std::placeholders;
- if (afb_dynapi_require_api(handle_, HAL_MGR_API, 1))
+ if (afb_api_require_api(handle_, HAL_MGR_API, 1))
{
- AFB_DYNAPI_ERROR(handle_, "Failed to require '%s' API!", HAL_MGR_API);
+ AFB_API_ERROR(handle_, "Failed to require '%s' API!", HAL_MGR_API);
return -1;
}
- AFB_DYNAPI_NOTICE(handle_, "Required '%s' API found!", HAL_MGR_API);
+ AFB_API_NOTICE(handle_, "Required '%s' API found!", HAL_MGR_API);
- if (afb_dynapi_require_api(handle_, "smixer", 1))
+ if (afb_api_require_api(handle_, "smixer", 1))
{
- AFB_DYNAPI_ERROR(handle_, "Failed to require 'smixer' API!");
+ AFB_API_ERROR(handle_, "Failed to require 'smixer' API!");
return -1;
}
- AFB_DYNAPI_NOTICE(handle_, "Required 'smixer' API found!");
+ AFB_API_NOTICE(handle_, "Required 'smixer' API found!");
- afb_dynapi_seal(handle_);
- AFB_DYNAPI_NOTICE(handle_, "API is now sealed!");
+ afb_api_seal(handle_);
+ AFB_API_NOTICE(handle_, "API is now sealed!");
if (update_streams()) return -1;
return 0;
@@ -186,42 +184,48 @@ int ahl_binding_t::init()
int ahl_binding_t::update_streams()
{
json_object* loaded = nullptr;
- json_object* response = nullptr;
size_t hals_count = 0, streams_count = 0;
- if (afb_dynapi_call_sync(handle_, "4a-hal-manager", "loaded", json_object_new_object(), &loaded))
+ if (afb_api_call_sync(handle_, "4a-hal-manager", "loaded", json_object_new_object(), &loaded, nullptr, nullptr))
{
- AFB_DYNAPI_ERROR(handle_, "Failed to call 'loaded' verb on '4a-hal-manager' API!");
- if (loaded) AFB_DYNAPI_ERROR(handle_, "%s", json_object_to_json_string(loaded));
+ AFB_API_ERROR(handle_, "Failed to call 'loaded' verb on '4a-hal-manager' API!");
+ if (loaded)
+ {
+ AFB_API_ERROR(handle_, "%s", json_object_to_json_string(loaded));
+ json_object_put(loaded);
+ }
return -1;
}
- json_bool ret = json_object_object_get_ex(loaded, "response", &response);
- if (!ret)
+
+ if (!json_object_is_type(loaded, json_type_array))
{
- AFB_DYNAPI_ERROR(handle_, "Maformed response; missing 'response' field");
+ AFB_API_ERROR(handle_, "Expected an array from '4a-hal-manager/loaded', but got something else!");
+ json_object_put(loaded);
return -1;
}
- hals_count = json_object_array_length(response);
+ hals_count = json_object_array_length(loaded);
for(int i = 0; i < hals_count; ++i)
{
json_object* info = nullptr;
- const char* halname = json_object_get_string(json_object_array_get_idx(response, i));
- AFB_DYNAPI_DEBUG(handle_, "Found an active HAL: %s", halname);
+ const char* halname = json_object_get_string(json_object_array_get_idx(loaded, i));
+ AFB_API_DEBUG(handle_, "Found an active HAL: %s", halname);
- if (afb_dynapi_call_sync(handle_, halname, "info", json_object_new_object(), &info))
+ if (afb_api_call_sync(handle_, halname, "info", json_object_new_object(), &info, nullptr, nullptr))
{
- AFB_DYNAPI_ERROR(handle_, "Failed to call 'info' verb on '%s' API!", halname);
- if (info) AFB_DYNAPI_ERROR(handle_, "%s", json_object_to_json_string(info));
+ AFB_API_ERROR(handle_, "Failed to call 'info' verb on '%s' API!", halname);
+ if (info)
+ {
+ AFB_API_ERROR(handle_, "%s", json_object_to_json_string(info));
+ json_object_put(info);
+ }
+ json_object_put(loaded);
return -1;
}
- json_object * responseJ = nullptr;
- json_object_object_get_ex(info, "response", &responseJ);
-
json_object* streamsJ = nullptr;
- json_object_object_get_ex(responseJ, "streams", &streamsJ);
+ json_object_object_get_ex(info, "streams", &streamsJ);
streams_count = json_object_array_length(streamsJ);
for(int j = 0; j < streams_count; ++j)
{
@@ -258,7 +262,7 @@ void ahl_binding_t::update_stream(std::string halname, std::string stream, std::
if(r.stream() == stream)
{
if (r.device_uri().size())
- AFB_DYNAPI_WARNING(handle_, "Multiple stream with same name: '%s'.", stream.c_str());
+ AFB_API_WARNING(handle_, "Multiple stream with same name: '%s'.", stream.c_str());
else
{
r.device_uri(deviceid);
@@ -270,19 +274,19 @@ void ahl_binding_t::update_stream(std::string halname, std::string stream, std::
void ahl_binding_t::event(std::string name, json_object* arg)
{
- AFB_DYNAPI_DEBUG(handle_, "Event '%s' received with the following arg: %s", name.c_str(), json_object_to_json_string(arg));
+ AFB_API_DEBUG(handle_, "Event '%s' received with the following arg: %s", name.c_str(), json_object_to_json_string(arg));
}
void ahl_binding_t::load_static_verbs()
{
- if (afb_dynapi_add_verb(
+ if (afb_api_add_verb(
handle_,
"get_roles",
"Retrieve array of available audio roles",
ahl_api_get_roles,
nullptr,
nullptr,
- AFB_SESSION_NONE_X2))
+ AFB_SESSION_NONE_X2, 0))
{
throw std::runtime_error("Failed to add 'get_role' verb to the API.");
}
@@ -321,18 +325,18 @@ int ahl_binding_t::load_controller_config(const std::string& path)
controller_config = CtlLoadMetaData(handle_, path.c_str());
if (!controller_config)
{
- AFB_DYNAPI_ERROR(handle_, "Failed to load controller from config file!");
+ AFB_API_ERROR(handle_, "Failed to load controller from config file!");
return -1;
}
static CtlSectionT controller_sections[] =
{
- {.key = "plugins", .uid = nullptr, .info = nullptr, .loadCB = PluginConfig, .handle = nullptr, .actions = nullptr},
- {.key = "onload", .uid = nullptr, .info = nullptr, .loadCB = OnloadConfig, .handle = nullptr, .actions = nullptr},
- {.key = "controls", .uid = nullptr, .info = nullptr, .loadCB = ControlConfig, .handle = nullptr, .actions = nullptr},
- {.key = "events", .uid = nullptr, .info = nullptr, .loadCB = EventConfig, .handle = nullptr, .actions = nullptr},
- {.key = "roles", .uid = nullptr, .info = nullptr, .loadCB = ahl_api_config_roles, .handle = nullptr, .actions = nullptr },
- {.key = nullptr, .uid = nullptr, .info = nullptr, .loadCB = nullptr, .handle = nullptr, .actions = nullptr}
+ {.key = "plugins", .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = PluginConfig, .handle = nullptr, .actions = nullptr},
+ {.key = "onload", .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = OnloadConfig, .handle = nullptr, .actions = nullptr},
+ {.key = "controls", .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = ControlConfig, .handle = nullptr, .actions = nullptr},
+ {.key = "events", .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = EventConfig, .handle = nullptr, .actions = nullptr},
+ {.key = "roles", .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = ahl_api_config_roles, .handle = nullptr, .actions = nullptr },
+ {.key = nullptr, .uid = nullptr, .info = nullptr, .prefix = nullptr, .loadCB = nullptr, .handle = nullptr, .actions = nullptr}
};
CtlLoadSections(handle_, controller_config, controller_sections);
@@ -365,18 +369,18 @@ int ahl_binding_t::parse_roles_config(json_object* o)
int ahl_binding_t::create_api_verb(role_t* r)
{
- AFB_DYNAPI_NOTICE(handle_, "New audio role: %s", r->uid().c_str());
+ AFB_API_NOTICE(handle_, "New audio role: %s", r->uid().c_str());
- if (afb_dynapi_add_verb(
+ if (afb_api_add_verb(
handle_,
r->uid().c_str(),
r->description().c_str(),
ahl_api_role,
r,
nullptr,
- AFB_SESSION_NONE_X2))
+ AFB_SESSION_NONE_X2, 0))
{
- AFB_DYNAPI_ERROR(handle_, "Failed to add '%s' verb to the API.",
+ AFB_API_ERROR(handle_, "Failed to add '%s' verb to the API.",
r->uid().c_str());
return -1;
}
@@ -384,10 +388,10 @@ int ahl_binding_t::create_api_verb(role_t* r)
return 0;
}
-void ahl_binding_t::get_roles(afb_request* req)
+void ahl_binding_t::get_roles(afb_req_t req)
{
json_bool verbose = FALSE;
- json_object* arg = afb_request_json(req);
+ json_object* arg = afb_req_json(req);
json_object* jverbose;
if (arg != nullptr)
{
@@ -401,7 +405,7 @@ void ahl_binding_t::get_roles(afb_request* req)
if (verbose == TRUE || r.device_uri().size())
json_object_array_add(result, json_object_new_string(r.uid().c_str()));
}
- afb_request_success(req, result, nullptr);
+ afb_req_success(req, result, nullptr);
}
const std::vector<role_t> ahl_binding_t::roles() const
@@ -409,7 +413,7 @@ const std::vector<role_t> ahl_binding_t::roles() const
return roles_;
}
-afb_dynapi* ahl_binding_t::handle() const
+afb_api_t ahl_binding_t::handle() const
{
return handle_;
}