summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ahl-binding/CMakeLists.txt58
-rw-r--r--ahl-binding/ahl-binding.cpp528
-rw-r--r--ahl-binding/ahl-binding.hpp52
-rw-r--r--ahl-binding/config_entry.cpp24
-rw-r--r--ahl-binding/config_entry.hpp17
-rw-r--r--ahl-binding/interrupt.cpp220
-rw-r--r--ahl-binding/interrupt.hpp34
-rw-r--r--ahl-binding/jsonc_utils.hpp48
-rw-r--r--ahl-binding/role.cpp410
-rw-r--r--ahl-binding/role.hpp102
10 files changed, 746 insertions, 747 deletions
diff --git a/ahl-binding/CMakeLists.txt b/ahl-binding/CMakeLists.txt
index bd2be0c..042903c 100644
--- a/ahl-binding/CMakeLists.txt
+++ b/ahl-binding/CMakeLists.txt
@@ -19,38 +19,38 @@
# Add target to project dependency list
PROJECT_TARGET_ADD(audiohighlevel)
- # Define project Targets
- ADD_LIBRARY(${TARGET_NAME} MODULE
- config_entry.cpp
- role.cpp
- interrupt.cpp
- ahl-binding.cpp
- )
+ # Define project Targets
+ ADD_LIBRARY(${TARGET_NAME} MODULE
+ config_entry.cpp
+ role.cpp
+ interrupt.cpp
+ ahl-binding.cpp
+ )
- # Binder exposes a unique public entry point
- SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
- PREFIX "afb-"
- LABELS "BINDING"
- LINK_FLAGS ${BINDINGS_LINK_FLAG}
- OUTPUT_NAME ${TARGET_NAME}
- )
+ # Binder exposes a unique public entry point
+ SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES
+ PREFIX "afb-"
+ LABELS "BINDING"
+ LINK_FLAGS ${BINDINGS_LINK_FLAG}
+ OUTPUT_NAME ${TARGET_NAME}
+ )
- # Define target includes
- TARGET_INCLUDE_DIRECTORIES(${TARGET_NAME}
- PUBLIC ${GLIB_PKG_INCLUDE_DIRS}
- ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/../controller/ctl-lib
- ${CMAKE_CURRENT_SOURCE_DIR}/../afb-utilities
- )
+ # Define target includes
+ TARGET_INCLUDE_DIRECTORIES(${TARGET_NAME}
+ PUBLIC ${GLIB_PKG_INCLUDE_DIRS}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../controller/ctl-lib
+ ${CMAKE_CURRENT_SOURCE_DIR}/../afb-utilities
+ )
- # Library dependencies (include updates automatically)
- # Find package for GLIB does not seem to export
- TARGET_LINK_LIBRARIES(${TARGET_NAME}
- #ahl-policy
+ # Library dependencies (include updates automatically)
+ # Find package for GLIB does not seem to export
+ TARGET_LINK_LIBRARIES(${TARGET_NAME}
+ #ahl-policy
afb-helpers
- ctl-utilities
- ${GLIB_PKG_LIBRARIES}
- ${link_libraries}
- )
+ ctl-utilities
+ ${GLIB_PKG_LIBRARIES}
+ ${link_libraries}
+ )
diff --git a/ahl-binding/ahl-binding.cpp b/ahl-binding/ahl-binding.cpp
index 98d36b6..3a16197 100644
--- a/ahl-binding/ahl-binding.cpp
+++ b/ahl-binding/ahl-binding.cpp
@@ -25,7 +25,7 @@
*/
int ahl_api_create(void*, afb_api_t handle)
{
- return ahl_binding_t::instance().preinit(handle);
+ return ahl_binding_t::instance().preinit(handle);
}
/**
@@ -35,19 +35,19 @@ int ahl_api_create(void*, afb_api_t handle)
*/
int afbBindingEntry(afb_api_t handle)
{
- using namespace std::placeholders;
- assert(handle != nullptr);
-
- afb_api_new_api(
- handle,
- HL_API_NAME,
- HL_API_INFO,
- 1,
- ahl_api_create,
- nullptr
- );
-
- return 0;
+ using namespace std::placeholders;
+ assert(handle != nullptr);
+
+ afb_api_new_api(
+ handle,
+ HL_API_NAME,
+ HL_API_INFO,
+ 1,
+ ahl_api_create,
+ nullptr
+ );
+
+ return 0;
}
/**
@@ -56,7 +56,7 @@ int afbBindingEntry(afb_api_t handle)
*/
int ahl_api_init(afb_api_t)
{
- return ahl_binding_t::instance().init();
+ return ahl_binding_t::instance().init();
}
/**
@@ -66,7 +66,7 @@ int ahl_api_init(afb_api_t)
*/
void ahl_api_on_event(afb_api_t, const char* e, struct json_object* o)
{
- ahl_binding_t::instance().event(e, o);
+ ahl_binding_t::instance().event(e, o);
}
/**
@@ -76,7 +76,7 @@ void ahl_api_on_event(afb_api_t, const char* e, struct json_object* o)
*/
int ahl_api_config_roles(afb_api_t, CtlSectionT*, json_object* o)
{
- return ahl_binding_t::instance().parse_roles_config(o);
+ return ahl_binding_t::instance().parse_roles_config(o);
}
/**
@@ -85,7 +85,7 @@ int ahl_api_config_roles(afb_api_t, CtlSectionT*, json_object* o)
*/
void ahl_api_get_roles(afb_req_t req)
{
- ahl_binding_t::instance().get_roles(req);
+ ahl_binding_t::instance().get_roles(req);
}
/**
@@ -94,7 +94,7 @@ void ahl_api_get_roles(afb_req_t req)
*/
void ahl_api_subscribe(afb_req_t req)
{
- ahl_binding_t::instance().subscribe(req);
+ ahl_binding_t::instance().subscribe(req);
}
/**
@@ -103,7 +103,7 @@ void ahl_api_subscribe(afb_req_t req)
*/
void ahl_api_unsubscribe(afb_req_t req)
{
- ahl_binding_t::instance().unsubscribe(req);
+ ahl_binding_t::instance().unsubscribe(req);
}
/**
@@ -114,17 +114,17 @@ void ahl_api_unsubscribe(afb_req_t req)
*/
void ahl_api_role(afb_req_t req)
{
- role_t* role = (role_t*)req->vcbdata;
- assert(role != nullptr);
+ role_t* role = (role_t*)req->vcbdata;
+ assert(role != nullptr);
- role->invoke(req);
+ role->invoke(req);
}
/**
* @brief Default constructor.
*/
ahl_binding_t::ahl_binding_t()
- : handle_{nullptr}
+ : handle_{nullptr}
{
}
@@ -134,8 +134,8 @@ ahl_binding_t::ahl_binding_t()
*/
ahl_binding_t& ahl_binding_t::instance()
{
- static ahl_binding_t s;
- return s;
+ static ahl_binding_t s;
+ return s;
}
/**
@@ -145,26 +145,26 @@ ahl_binding_t& ahl_binding_t::instance()
*/
int ahl_binding_t::preinit(afb_api_t handle)
{
- handle_ = handle;
-
- try
- {
- load_static_verbs();
- load_controller_configs();
-
- if (afb_api_on_event(handle_, ahl_api_on_event))
- throw std::runtime_error("Failed to register event handler callback.");
-
- if (afb_api_on_init(handle_, ahl_api_init))
- throw std::runtime_error("Failed to register init handler callback.");
- }
- catch(std::exception& e)
- {
- AFB_API_ERROR(handle, "%s", e.what());
- return -1;
- }
-
- return 0;
+ handle_ = handle;
+
+ try
+ {
+ load_static_verbs();
+ load_controller_configs();
+
+ if (afb_api_on_event(handle_, ahl_api_on_event))
+ throw std::runtime_error("Failed to register event handler callback.");
+
+ if (afb_api_on_init(handle_, ahl_api_init))
+ throw std::runtime_error("Failed to register init handler callback.");
+ }
+ catch(std::exception& e)
+ {
+ AFB_API_ERROR(handle, "%s", e.what());
+ return -1;
+ }
+
+ return 0;
}
/**
@@ -172,17 +172,17 @@ int ahl_binding_t::preinit(afb_api_t handle)
*/
int ahl_binding_t::init()
{
- using namespace std::placeholders;
+ using namespace std::placeholders;
- if (afb_api_require_api(handle_, HAL_MGR_API, 1))
- {
- AFB_API_ERROR(handle_, "Failed to require '%s' API!", HAL_MGR_API);
- return -1;
- }
- AFB_API_NOTICE(handle_, "Required '%s' API found!", HAL_MGR_API);
+ if (afb_api_require_api(handle_, HAL_MGR_API, 1))
+ {
+ AFB_API_ERROR(handle_, "Failed to require '%s' API!", HAL_MGR_API);
+ return -1;
+ }
+ AFB_API_NOTICE(handle_, "Required '%s' API found!", HAL_MGR_API);
- afb_api_seal(handle_);
- AFB_API_NOTICE(handle_, "API is now sealed!");
+ afb_api_seal(handle_);
+ AFB_API_NOTICE(handle_, "API is now sealed!");
volume_changed_ = afb_api_make_event(handle_, "volume_changed");
if(!afb_event_is_valid(volume_changed_))
@@ -191,8 +191,8 @@ int ahl_binding_t::init()
return -2;
}
- if (update_streams()) return -1;
- return 0;
+ if (update_streams()) return -1;
+ return 0;
}
/**
@@ -201,70 +201,70 @@ int ahl_binding_t::init()
*/
int ahl_binding_t::update_streams()
{
- json_object* loaded = nullptr;
- size_t hals_count = 0, streams_count = 0;
-
- if (afb_api_call_sync(handle_, "4a-hal-manager", "loaded", json_object_new_object(), &loaded, nullptr, nullptr))
- {
- 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;
- }
-
- if (!json_object_is_type(loaded, json_type_array))
- {
- 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(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(loaded, i));
- AFB_API_DEBUG(handle_, "Found an active HAL: %s", halname);
-
- if (afb_api_call_sync(handle_, halname, "info", json_object_new_object(), &info, nullptr, nullptr))
- {
- 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* streamsJ = nullptr;
- json_object_object_get_ex(info, "streams", &streamsJ);
- streams_count = json_object_array_length(streamsJ);
- for(int j = 0; j < streams_count; ++j)
- {
- json_object * nameJ = nullptr, * cardIdJ = nullptr;
- json_object * streamJ = json_object_array_get_idx(streamsJ, j);
-
- json_object_object_get_ex(streamJ, "name", &nameJ);
- json_object_object_get_ex(streamJ, "cardId", &cardIdJ);
-
- update_stream(
- halname,
- json_object_get_string(nameJ),
- json_object_get_string(cardIdJ)
- );
- }
-
- json_object_put(info);
- }
- json_object_put(loaded);
-
- return 0;
+ json_object* loaded = nullptr;
+ size_t hals_count = 0, streams_count = 0;
+
+ if (afb_api_call_sync(handle_, "4a-hal-manager", "loaded", json_object_new_object(), &loaded, nullptr, nullptr))
+ {
+ 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;
+ }
+
+ if (!json_object_is_type(loaded, json_type_array))
+ {
+ 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(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(loaded, i));
+ AFB_API_DEBUG(handle_, "Found an active HAL: %s", halname);
+
+ if (afb_api_call_sync(handle_, halname, "info", json_object_new_object(), &info, nullptr, nullptr))
+ {
+ 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* streamsJ = nullptr;
+ json_object_object_get_ex(info, "streams", &streamsJ);
+ streams_count = json_object_array_length(streamsJ);
+ for(int j = 0; j < streams_count; ++j)
+ {
+ json_object * nameJ = nullptr, * cardIdJ = nullptr;
+ json_object * streamJ = json_object_array_get_idx(streamsJ, j);
+
+ json_object_object_get_ex(streamJ, "name", &nameJ);
+ json_object_object_get_ex(streamJ, "cardId", &cardIdJ);
+
+ update_stream(
+ halname,
+ json_object_get_string(nameJ),
+ json_object_get_string(cardIdJ)
+ );
+ }
+
+ json_object_put(info);
+ }
+ json_object_put(loaded);
+
+ return 0;
}
/**
@@ -275,179 +275,179 @@ int ahl_binding_t::update_streams()
*/
void ahl_binding_t::update_stream(std::string halname, std::string stream, std::string deviceid)
{
- for(auto& r : roles_)
- {
- if(r.stream() == stream)
- {
- if (r.device_uri().size())
- AFB_API_WARNING(handle_, "Multiple stream with same name: '%s'.", stream.c_str());
- else
- {
- r.device_uri(deviceid);
- r.hal(halname);
- }
- }
- }
+ for(auto& r : roles_)
+ {
+ if(r.stream() == stream)
+ {
+ if (r.device_uri().size())
+ AFB_API_WARNING(handle_, "Multiple stream with same name: '%s'.", stream.c_str());
+ else
+ {
+ r.device_uri(deviceid);
+ r.hal(halname);
+ }
+ }
+ }
}
void ahl_binding_t::event(std::string name, json_object* arg)
{
- AFB_API_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_api_add_verb(
- handle_,
- "get_roles",
- "Retrieve array of available audio roles",
- ahl_api_get_roles,
- nullptr,
- nullptr,
- AFB_SESSION_NONE_X2, 0))
- {
- throw std::runtime_error("Failed to add 'get_role' verb to the API.");
- }
-
- if (afb_api_add_verb(
- handle_,
- "subscribe",
- "Subscribe to \"volume_changed\" event",
- ahl_api_subscribe,
- nullptr,
- nullptr,
- AFB_SESSION_NONE_X2, 0))
- {
- throw std::runtime_error("Failed to add 'subscribe' verb to the API.");
- }
-
- if (afb_api_add_verb(
- handle_,
- "unsubscribe",
- "Unsubscribe to \"volume_changed\" event",
- ahl_api_unsubscribe,
- nullptr,
- nullptr,
- AFB_SESSION_NONE_X2, 0))
- {
- throw std::runtime_error("Failed to add 'unsubscribe' verb to the API.");
- }
+ if (afb_api_add_verb(
+ handle_,
+ "get_roles",
+ "Retrieve array of available audio roles",
+ ahl_api_get_roles,
+ nullptr,
+ nullptr,
+ AFB_SESSION_NONE_X2, 0))
+ {
+ throw std::runtime_error("Failed to add 'get_role' verb to the API.");
+ }
+
+ if (afb_api_add_verb(
+ handle_,
+ "subscribe",
+ "Subscribe to \"volume_changed\" event",
+ ahl_api_subscribe,
+ nullptr,
+ nullptr,
+ AFB_SESSION_NONE_X2, 0))
+ {
+ throw std::runtime_error("Failed to add 'subscribe' verb to the API.");
+ }
+
+ if (afb_api_add_verb(
+ handle_,
+ "unsubscribe",
+ "Unsubscribe to \"volume_changed\" event",
+ ahl_api_unsubscribe,
+ nullptr,
+ nullptr,
+ AFB_SESSION_NONE_X2, 0))
+ {
+ throw std::runtime_error("Failed to add 'unsubscribe' verb to the API.");
+ }
}
void ahl_binding_t::load_controller_configs()
{
- char* dir_list = getenv("CONTROL_CONFIG_PATH");
- if (!dir_list) dir_list = strdup(CONTROL_CONFIG_PATH);
- struct json_object* config_files = CtlConfigScan(dir_list, "policy");
- if (!config_files) throw std::runtime_error("No config files found!");
-
- // Only one file should be found this way, but read all just in case
- size_t config_files_count = json_object_array_length(config_files);
- for(int i = 0; i < config_files_count; ++i)
- {
- config_entry_t file {json_object_array_get_idx(config_files, i)};
-
- if(load_controller_config(file.filepath()) < 0)
- {
- std::stringstream ss;
- ss << "Failed to load config file '"
- << file.filename()
- << "' from '"
- << file.fullpath()
- << "'!";
- throw std::runtime_error(ss.str());
- }
- }
+ char* dir_list = getenv("CONTROL_CONFIG_PATH");
+ if (!dir_list) dir_list = strdup(CONTROL_CONFIG_PATH);
+ struct json_object* config_files = CtlConfigScan(dir_list, "policy");
+ if (!config_files) throw std::runtime_error("No config files found!");
+
+ // Only one file should be found this way, but read all just in case
+ size_t config_files_count = json_object_array_length(config_files);
+ for(int i = 0; i < config_files_count; ++i)
+ {
+ config_entry_t file {json_object_array_get_idx(config_files, i)};
+
+ if(load_controller_config(file.filepath()) < 0)
+ {
+ std::stringstream ss;
+ ss << "Failed to load config file '"
+ << file.filename()
+ << "' from '"
+ << file.fullpath()
+ << "'!";
+ throw std::runtime_error(ss.str());
+ }
+ }
}
int ahl_binding_t::load_controller_config(const std::string& path)
{
- CtlConfigT* controller_config;
-
- controller_config = CtlLoadMetaData(handle_, path.c_str());
- if (!controller_config)
- {
- AFB_API_ERROR(handle_, "Failed to load controller from config file!");
- return -1;
- }
-
- static CtlSectionT controller_sections[] =
- {
- {.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);
-
- return 0;
+ CtlConfigT* controller_config;
+
+ controller_config = CtlLoadMetaData(handle_, path.c_str());
+ if (!controller_config)
+ {
+ AFB_API_ERROR(handle_, "Failed to load controller from config file!");
+ return -1;
+ }
+
+ static CtlSectionT controller_sections[] =
+ {
+ {.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);
+
+ return 0;
}
int ahl_binding_t::parse_roles_config(json_object* o)
{
- assert(o != nullptr);
- assert(json_object_is_type(o, json_type_array));
+ assert(o != nullptr);
+ assert(json_object_is_type(o, json_type_array));
- if (roles_.size()) return 0; // Roles already added, ignore.
+ if (roles_.size()) return 0; // Roles already added, ignore.
- size_t count = json_object_array_length(o);
- roles_.reserve(count);
- for(int i = 0; i < count; ++i)
- {
- json_object* jr = json_object_array_get_idx(o, i);
- assert(jr != nullptr);
+ size_t count = json_object_array_length(o);
+ roles_.reserve(count);
+ for(int i = 0; i < count; ++i)
+ {
+ json_object* jr = json_object_array_get_idx(o, i);
+ assert(jr != nullptr);
- roles_.push_back(role_t(jr));
- role_t& r = roles_[roles_.size() - 1];
- if(create_api_verb(&r))
- return -1;
- }
+ roles_.push_back(role_t(jr));
+ role_t& r = roles_[roles_.size() - 1];
+ if(create_api_verb(&r))
+ return -1;
+ }
- return 0;
+ return 0;
}
int ahl_binding_t::create_api_verb(role_t* r)
{
- AFB_API_NOTICE(handle_, "New audio role: %s", r->uid().c_str());
-
- if (afb_api_add_verb(
- handle_,
- r->uid().c_str(),
- r->description().c_str(),
- ahl_api_role,
- r,
- nullptr,
- AFB_SESSION_NONE_X2, 0))
- {
- AFB_API_ERROR(handle_, "Failed to add '%s' verb to the API.",
- r->uid().c_str());
- return -1;
- }
-
- return 0;
+ AFB_API_NOTICE(handle_, "New audio role: %s", r->uid().c_str());
+
+ if (afb_api_add_verb(
+ handle_,
+ r->uid().c_str(),
+ r->description().c_str(),
+ ahl_api_role,
+ r,
+ nullptr,
+ AFB_SESSION_NONE_X2, 0))
+ {
+ AFB_API_ERROR(handle_, "Failed to add '%s' verb to the API.",
+ r->uid().c_str());
+ return -1;
+ }
+
+ return 0;
}
void ahl_binding_t::get_roles(afb_req_t req) const
{
- json_bool verbose = FALSE;
- json_object* arg = afb_req_json(req);
- json_object* jverbose;
- if (arg != nullptr)
- {
- json_bool ret = json_object_object_get_ex(arg, "verbose", &jverbose);
- if (ret) verbose = json_object_get_boolean(jverbose);
- }
-
- json_object* result = json_object_new_array();
- for(const auto& r : roles_)
- {
- if (verbose == TRUE || r.device_uri().size())
- json_object_array_add(result, json_object_new_string(r.uid().c_str()));
- }
- afb_req_success(req, result, nullptr);
+ json_bool verbose = FALSE;
+ json_object* arg = afb_req_json(req);
+ json_object* jverbose;
+ if (arg != nullptr)
+ {
+ json_bool ret = json_object_object_get_ex(arg, "verbose", &jverbose);
+ if (ret) verbose = json_object_get_boolean(jverbose);
+ }
+
+ json_object* result = json_object_new_array();
+ for(const auto& r : roles_)
+ {
+ if (verbose == TRUE || r.device_uri().size())
+ json_object_array_add(result, json_object_new_string(r.uid().c_str()));
+ }
+ afb_req_success(req, result, nullptr);
}
void ahl_binding_t::subscribe(afb_req_t req) const
@@ -477,10 +477,10 @@ int ahl_binding_t::emit_volume_changed(const std::string& role, int volume) cons
const std::vector<role_t> ahl_binding_t::roles() const
{
- return roles_;
+ return roles_;
}
afb_api_t ahl_binding_t::handle() const
{
- return handle_;
+ return handle_;
}
diff --git a/ahl-binding/ahl-binding.hpp b/ahl-binding/ahl-binding.hpp
index 24f4acb..9e670bb 100644
--- a/ahl-binding/ahl-binding.hpp
+++ b/ahl-binding/ahl-binding.hpp
@@ -36,41 +36,41 @@
class ahl_binding_t
{
- using role_action = std::function<void(afb_req_t, std::string, std::string, json_object*)>;
+ using role_action = std::function<void(afb_req_t, std::string, std::string, json_object*)>;
private:
- afb_api_t handle_;
- afb_event_t volume_changed_;
- std::vector<role_t> roles_;
+ afb_api_t handle_;
+ afb_event_t volume_changed_;
+ std::vector<role_t> roles_;
- explicit ahl_binding_t();
+ explicit ahl_binding_t();
- void load_static_verbs();
+ void load_static_verbs();
- void load_controller_configs();
- int load_controller_config(const std::string& path);
- int update_streams();
- void update_stream(std::string hal, std::string stream, std::string deviceuri);
- int create_api_verb(role_t* r);
+ void load_controller_configs();
+ int load_controller_config(const std::string& path);
+ int update_streams();
+ void update_stream(std::string hal, std::string stream, std::string deviceuri);
+ int create_api_verb(role_t* r);
- void policy_open(afb_req_t req, const role_t& role);
+ void policy_open(afb_req_t req, const role_t& role);
public:
- static ahl_binding_t& instance();
- int preinit(afb_api_t handle);
- int init();
- void event(std::string name, json_object* arg);
- void get_roles(afb_req_t req) const;
- void subscribe(afb_req_t req) const;
- void unsubscribe(afb_req_t req) const;
- int emit_volume_changed(const std::string& role, int volume) const;
-
- const std::vector<role_t> roles() const;
- afb_api_t handle() const;
-
- void audiorole(afb_req_t req);
- int parse_roles_config(json_object* o);
+ static ahl_binding_t& instance();
+ int preinit(afb_api_t handle);
+ int init();
+ void event(std::string name, json_object* arg);
+ void get_roles(afb_req_t req) const;
+ void subscribe(afb_req_t req) const;
+ void unsubscribe(afb_req_t req) const;
+ int emit_volume_changed(const std::string& role, int volume) const;
+
+ const std::vector<role_t> roles() const;
+ afb_api_t handle() const;
+
+ void audiorole(afb_req_t req);
+ int parse_roles_config(json_object* o);
};
diff --git a/ahl-binding/config_entry.cpp b/ahl-binding/config_entry.cpp
index 65d7a40..8685d34 100644
--- a/ahl-binding/config_entry.cpp
+++ b/ahl-binding/config_entry.cpp
@@ -18,45 +18,45 @@
#include "config_entry.hpp"
config_entry_t::config_entry_t(std::string fp, std::string fn)
- : fullpath_{fp}
- , filename_{fn}
+ : fullpath_{fp}
+ , filename_{fn}
{
}
config_entry_t::config_entry_t(struct json_object* j)
{
- jcast(fullpath_, j, "fullpath");
- jcast(filename_, j, "filename");
+ jcast(fullpath_, j, "fullpath");
+ jcast(filename_, j, "filename");
}
config_entry_t& config_entry_t::operator<<(struct json_object* j)
{
- jcast(fullpath_, j, "fullpath");
- jcast(filename_, j, "filename");
- return *this;
+ jcast(fullpath_, j, "fullpath");
+ jcast(filename_, j, "filename");
+ return *this;
}
std::string config_entry_t::fullpath() const
{
- return fullpath_;
+ return fullpath_;
}
std::string config_entry_t::filename() const
{
- return filename_;
+ return filename_;
}
std::string config_entry_t::filepath() const
{
- return fullpath_ + '/' + filename_;
+ return fullpath_ + '/' + filename_;
}
void config_entry_t::fullpath(std::string fp)
{
- fullpath_ = fp;
+ fullpath_ = fp;
}
void config_entry_t::finename(std::string fn)
{
- filename_ = fn;
+ filename_ = fn;
}
diff --git a/ahl-binding/config_entry.hpp b/ahl-binding/config_entry.hpp
index 492eed2..58b0b06 100644
--- a/ahl-binding/config_entry.hpp
+++ b/ahl-binding/config_entry.hpp
@@ -24,26 +24,25 @@ class config_entry_t
private:
std::string fullpath_;
std::string filename_;
-
+
public:
explicit config_entry_t() = default;
explicit config_entry_t(const config_entry_t&) = default;
- explicit config_entry_t(config_entry_t&&) = default;
-
+ explicit config_entry_t(config_entry_t&&) = default;
+
~config_entry_t() = default;
-
+
config_entry_t& operator=(const config_entry_t&) = default;
- config_entry_t& operator=(config_entry_t&&) = default;
-
+ config_entry_t& operator=(config_entry_t&&) = default;
+
explicit config_entry_t(std::string fp, std::string fn);
explicit config_entry_t(struct json_object* j);
config_entry_t& operator<<(struct json_object* j);
-
+
std::string fullpath() const;
std::string filename() const;
std::string filepath() const;
-
+
void fullpath(std::string fp);
void finename(std::string fn);
-
};
diff --git a/ahl-binding/interrupt.cpp b/ahl-binding/interrupt.cpp
index 5bf0b79..a0fa563 100644
--- a/ahl-binding/interrupt.cpp
+++ b/ahl-binding/interrupt.cpp
@@ -5,147 +5,147 @@
interrupt_t::interrupt_t(json_object* o)
{
- jcast(type_, o, "type");
- json_object * value = NULL;
- json_object_object_get_ex(o, "args", &value);
- args_ = value;
+ jcast(type_, o, "type");
+ json_object * value = NULL;
+ json_object_object_get_ex(o, "args", &value);
+ args_ = value;
}
interrupt_t& interrupt_t::operator<<(json_object* o)
{
- jcast(type_, o, "type");
- json_object * value = NULL;
- json_object_object_get_ex(o, "args", &value);
- args_ = value;
- return *this;
+ jcast(type_, o, "type");
+ json_object * value = NULL;
+ json_object_object_get_ex(o, "args", &value);
+ args_ = value;
+ return *this;
}
std::string interrupt_t::type() const
{
- return type_;
+ return type_;
}
json_object* interrupt_t::args() const
{
- return args_;
+ return args_;
}
void interrupt_t::type(std::string v)
{
- type_ = v;
+ type_ = v;
}
void interrupt_t::args(json_object* v)
{
- args_ = v;
+ args_ = v;
}
int interrupt_t::apply(afb_req_t req, const role_t& role)
{
- /*if (type_ == "mute")
- {
- }
- else if (type_ == "continue")
- {
- }
- else if (type_ == "cancel")
- {
- }
- else */if (type_ == "ramp")
- {
- for(const auto& r: ahl_binding_t::instance().roles())
- {
- if (r.opened() && role.priority() > r.priority())
- {
- // { "ramp" : { "uid" : "ramp-slow", "volume" : 30 } }
- json_object* arg = json_object_new_object();
- json_object_object_add(arg, "ramp", args_);
- json_object_get(args_);
- json_object* result = nullptr;
+ /*if (type_ == "mute")
+ {
+ }
+ else if (type_ == "continue")
+ {
+ }
+ else if (type_ == "cancel")
+ {
+ }
+ else */if (type_ == "ramp")
+ {
+ for(const auto& r: ahl_binding_t::instance().roles())
+ {
+ if (r.opened() && role.priority() > r.priority())
+ {
+ // { "ramp" : { "uid" : "ramp-slow", "volume" : 30 } }
+ json_object* arg = json_object_new_object();
+ json_object_object_add(arg, "ramp", args_);
+ json_object_get(args_);
+ json_object* result = nullptr;
- AFB_API_DEBUG(ahl_binding_t::instance().handle(),
- "Call '%s'/'%s' '%s'",
- r.hal().c_str(), r.stream().c_str(), json_object_to_json_string(arg));
+ AFB_API_DEBUG(ahl_binding_t::instance().handle(),
+ "Call '%s'/'%s' '%s'",
+ r.hal().c_str(), r.stream().c_str(), json_object_to_json_string(arg));
- if(afb_api_call_sync(ahl_binding_t::instance().handle(), r.hal().c_str(), r.stream().c_str(), arg, &result, nullptr, nullptr))
- {
- afb_req_fail(req, "Failed to call 'ramp' action on stream", nullptr);
- return -1;
- }
- json_object* jvolold = nullptr;
- if (json_object_object_get_ex(result, "volold", &jvolold))
- {
- applied_on_.push_back(std::make_tuple<std::string, int>(r.uid(), json_object_get_int(jvolold)));
- AFB_API_DEBUG(ahl_binding_t::instance().handle(),
- "POLICY: Applying a ramp to '%s' stream because '%s' is opened and have higher priority!",
- r.stream().c_str(), role.stream().c_str());
- }
- }
- }
- return 0;
- }
- else
- {
- afb_req_fail(req, "Unkown interrupt uid!", nullptr);
- return -1;
- }
+ if(afb_api_call_sync(ahl_binding_t::instance().handle(), r.hal().c_str(), r.stream().c_str(), arg, &result, nullptr, nullptr))
+ {
+ afb_req_fail(req, "Failed to call 'ramp' action on stream", nullptr);
+ return -1;
+ }
+ json_object* jvolold = nullptr;
+ if (json_object_object_get_ex(result, "volold", &jvolold))
+ {
+ applied_on_.push_back(std::make_tuple<std::string, int>(r.uid(), json_object_get_int(jvolold)));
+ AFB_API_DEBUG(ahl_binding_t::instance().handle(),
+ "POLICY: Applying a ramp to '%s' stream because '%s' is opened and have higher priority!",
+ r.stream().c_str(), role.stream().c_str());
+ }
+ }
+ }
+ return 0;
+ }
+ else
+ {
+ afb_req_fail(req, "Unkown interrupt uid!", nullptr);
+ return -1;
+ }
}
void interrupt_t::clear()
{
- for (const std::tuple<std::string, int>& state : applied_on_)
- {
- std::string role;
- int vol;
- std::tie(role, vol) = state;
- /*if (type_ == "mute")
- {
- }
- else if (type_ == "continue")
- {
- }
- else if (type_ == "cancel")
- {
- }
- else */if (type_ == "ramp")
- {
- for(const auto& r: ahl_binding_t::instance().roles())
- {
- if (r.uid() == role)
- {
- // { "ramp" : { "uid" : "ramp-slow", "volume" : 30 } }
- // Create an fake-interrupt, with the old volume
- json_object* interrupt = json_tokener_parse(json_object_to_json_string(args_));
- json_object_object_add(interrupt, "volume", json_object_new_int(vol)); // Replace the volume
- /*
- json_object* volume = nullptr;
- if (json_object_object_get_ex(interrupt, "volume", &volume))
- {
- json_object_set_int(volume, vol);
- }
- */
+ for (const std::tuple<std::string, int>& state : applied_on_)
+ {
+ std::string role;
+ int vol;
+ std::tie(role, vol) = state;
+ /*if (type_ == "mute")
+ {
+ }
+ else if (type_ == "continue")
+ {
+ }
+ else if (type_ == "cancel")
+ {
+ }
+ else */if (type_ == "ramp")
+ {
+ for(const auto& r: ahl_binding_t::instance().roles())
+ {
+ if (r.uid() == role)
+ {
+ // { "ramp" : { "uid" : "ramp-slow", "volume" : 30 } }
+ // Create an fake-interrupt, with the old volume
+ json_object* interrupt = json_tokener_parse(json_object_to_json_string(args_));
+ json_object_object_add(interrupt, "volume", json_object_new_int(vol)); // Replace the volume
+ /*
+ json_object* volume = nullptr;
+ if (json_object_object_get_ex(interrupt, "volume", &volume))
+ {
+ json_object_set_int(volume, vol);
+ }
+ */
- json_object* arg = json_object_new_object();
- json_object_object_add(arg, "ramp", interrupt);
- json_object* result = nullptr;
+ json_object* arg = json_object_new_object();
+ json_object_object_add(arg, "ramp", interrupt);
+ json_object* result = nullptr;
- AFB_API_DEBUG(ahl_binding_t::instance().handle(),
- "Call '%s'/'%s' '%s",
- r.hal().c_str(), r.stream().c_str(), json_object_to_json_string(arg));
+ AFB_API_DEBUG(ahl_binding_t::instance().handle(),
+ "Call '%s'/'%s' '%s",
+ r.hal().c_str(), r.stream().c_str(), json_object_to_json_string(arg));
- if(afb_api_call_sync(ahl_binding_t::instance().handle(), r.hal().c_str(), r.stream().c_str(), arg, &result, nullptr, nullptr))
- {
- AFB_API_ERROR(ahl_binding_t::instance().handle(),
- "Failed to call 'ramp' action on '%s'", role.c_str());
- }
- else
- {
- AFB_API_DEBUG(ahl_binding_t::instance().handle(),
- "Called 'ramp' action on '%s'", role.c_str());
- }
- }
- }
- }
- }
- applied_on_.clear();
+ if(afb_api_call_sync(ahl_binding_t::instance().handle(), r.hal().c_str(), r.stream().c_str(), arg, &result, nullptr, nullptr))
+ {
+ AFB_API_ERROR(ahl_binding_t::instance().handle(),
+ "Failed to call 'ramp' action on '%s'", role.c_str());
+ }
+ else
+ {
+ AFB_API_DEBUG(ahl_binding_t::instance().handle(),
+ "Called 'ramp' action on '%s'", role.c_str());
+ }
+ }
+ }
+ }
+ }
+ applied_on_.clear();
}
diff --git a/ahl-binding/interrupt.hpp b/ahl-binding/interrupt.hpp
index c123699..d0caf79 100644
--- a/ahl-binding/interrupt.hpp
+++ b/ahl-binding/interrupt.hpp
@@ -11,27 +11,27 @@ class role_t;
class interrupt_t
{
private:
- std::string type_;
- json_object* args_;
- std::vector<std::tuple<std::string, uint32_t>> applied_on_;
+ std::string type_;
+ json_object* args_;
+ std::vector<std::tuple<std::string, uint32_t>> applied_on_;
public:
- explicit interrupt_t() = default;
- explicit interrupt_t(const interrupt_t&) = default;
- explicit interrupt_t(interrupt_t&&) = default;
- ~interrupt_t() = default;
+ explicit interrupt_t() = default;
+ explicit interrupt_t(const interrupt_t&) = default;
+ explicit interrupt_t(interrupt_t&&) = default;
+ ~interrupt_t() = default;
- interrupt_t& operator=(const interrupt_t&) = default;
- interrupt_t& operator=(interrupt_t&&) = default;
+ interrupt_t& operator=(const interrupt_t&) = default;
+ interrupt_t& operator=(interrupt_t&&) = default;
- explicit interrupt_t(json_object* o);
- interrupt_t& operator<<(json_object* o);
+ explicit interrupt_t(json_object* o);
+ interrupt_t& operator<<(json_object* o);
- std::string type() const;
- json_object* args() const;
+ std::string type() const;
+ json_object* args() const;
- void type(std::string v);
- void args(json_object* v);
- int apply(afb_req_t req, const role_t& role);
- void clear();
+ void type(std::string v);
+ void args(json_object* v);
+ int apply(afb_req_t req, const role_t& role);
+ void clear();
};
diff --git a/ahl-binding/jsonc_utils.hpp b/ahl-binding/jsonc_utils.hpp
index 097eda4..4657611 100644
--- a/ahl-binding/jsonc_utils.hpp
+++ b/ahl-binding/jsonc_utils.hpp
@@ -24,58 +24,58 @@
template<class T>
inline T& jcast(T& v, json_object* o)
{
- v << o;
- return v;
+ v << o;
+ return v;
}
template<class T>
inline T& jcast_array(T& v, json_object* o)
{
- if (o == nullptr) return v;
- auto sz = json_object_array_length(o);
- for(auto i = 0; i < sz ; ++i)
- {
- typename T::value_type item;
- jcast(item, json_object_array_get_idx(o, i));
- v.push_back(item);
- }
- return v;
+ if (o == nullptr) return v;
+ auto sz = json_object_array_length(o);
+ for(auto i = 0; i < sz ; ++i)
+ {
+ typename T::value_type item;
+ jcast(item, json_object_array_get_idx(o, i));
+ v.push_back(item);
+ }
+ return v;
}
template<>
inline bool& jcast<bool>(bool& v, json_object* o)
{
- v = (json_object_get_boolean(o) == TRUE);
- return v;
+ v = (json_object_get_boolean(o) == TRUE);
+ return v;
}
template<>
inline double& jcast<double>(double& v, json_object* o)
{
- v = json_object_get_double(o);
- return v;
+ v = json_object_get_double(o);
+ return v;
}
template<>
inline int32_t& jcast<int32_t>(int32_t& v, json_object* o)
{
- v = json_object_get_int(o);
- return v;
+ v = json_object_get_int(o);
+ return v;
}
template<>
inline int64_t& jcast<int64_t>(int64_t& v, json_object* o)
{
- v = json_object_get_int(o);
- return v;
+ v = json_object_get_int(o);
+ return v;
}
template<>
inline std::string& jcast<std::string>(std::string& v, json_object* o)
{
- const char* tmp = json_object_get_string(o);
- v = tmp ? tmp : "";
- return v;
+ const char* tmp = json_object_get_string(o);
+ v = tmp ? tmp : "";
+ return v;
}
template<class T>
@@ -83,7 +83,7 @@ inline T& jcast(T& v, json_object* o, std::string field)
{
json_object * value;
json_object_object_get_ex(o, field.c_str(), &value);
- return jcast<T>(v, value);
+ return jcast<T>(v, value);
}
template<class T>
@@ -91,5 +91,5 @@ inline T& jcast_array(T& v, json_object* o, std::string field)
{
json_object * value;
json_object_object_get_ex(o, field.c_str(), &value);
- return jcast_array<T>(v, value);
+ return jcast_array<T>(v, value);
}
diff --git a/ahl-binding/role.cpp b/ahl-binding/role.cpp
index 3a4dd0e..635e585 100644
--- a/ahl-binding/role.cpp
+++ b/ahl-binding/role.cpp
@@ -24,208 +24,208 @@ using session_t = std::vector<role_t*>;
role_t::role_t(json_object* j)
{
- jcast(uid_, j, "uid");
- jcast(description_, j, "description");
- jcast(priority_, j, "priority");
- jcast(stream_, j, "stream");
- jcast_array(interrupts_, j, "interrupts");
- opened_ = false;
+ jcast(uid_, j, "uid");
+ jcast(description_, j, "description");
+ jcast(priority_, j, "priority");
+ jcast(stream_, j, "stream");
+ jcast_array(interrupts_, j, "interrupts");
+ opened_ = false;
}
role_t& role_t::operator<<(json_object* j)
{
- jcast(uid_, j, "uid");
- jcast(description_, j, "description");
- jcast(priority_, j, "priority");
- jcast(stream_, j, "stream");
- jcast_array(interrupts_, j, "interrupts");
- return *this;
+ jcast(uid_, j, "uid");
+ jcast(description_, j, "description");
+ jcast(priority_, j, "priority");
+ jcast(stream_, j, "stream");
+ jcast_array(interrupts_, j, "interrupts");
+ return *this;
}
std::string role_t::uid() const
{
- return uid_;
+ return uid_;
}
std::string role_t::description() const
{
- return description_;
+ return description_;
}
std::string role_t::hal() const
{
- return hal_;
+ return hal_;
}
std::string role_t::stream() const
{
- return stream_;
+ return stream_;
}
int role_t::priority() const
{
- return priority_;
+ return priority_;
}
std::string role_t::device_uri() const
{
- return device_uri_;
+ return device_uri_;
}
bool role_t::opened() const
{
- return opened_;
+ return opened_;
}
void role_t::uid(std::string v)
{
- uid_ = v;
+ uid_ = v;
}
void role_t::description(std::string v)
{
- description_ = v;
+ description_ = v;
}
void role_t::hal(std::string v)
{
- hal_ = v;
+ hal_ = v;
}
void role_t::stream(std::string v)
{
- stream_ = v;
+ stream_ = v;
}
void role_t::priority(int v)
{
- priority_ = v;
+ priority_ = v;
}
void role_t::device_uri(std::string v)
{
- device_uri_ = v;
+ device_uri_ = v;
}
const std::vector<interrupt_t>& role_t::interrupts() const
{
- return interrupts_;
+ return interrupts_;
}
int role_t::apply_policy(afb_req_t req)
{
- return interrupts_.size() ? interrupts_[0].apply(req, *this) : 0;
+ return interrupts_.size() ? interrupts_[0].apply(req, *this) : 0;
}
void role_t::invoke(afb_req_t req)
{
- json_object* arg = afb_req_json(req);
- if (arg == nullptr)
- {
- afb_req_fail(req, "No valid argument!", nullptr);
- return;
- }
-
- json_object* jaction;
- json_bool ret = json_object_object_get_ex(arg, "action", &jaction);
- if (!ret)
- {
- afb_req_fail(req, "No valid action!", nullptr);
- return;
- }
-
- std::string action = json_object_get_string(jaction);
- if (action.size() == 0)
- {
- afb_req_fail(req, "No valid action!", nullptr);
- return;
- }
-
- if (action == "open") open(req, arg);
- else if (action == "close") close(req, arg);
- else if (action == "volume") volume(req, arg);
- else if (action == "interrupt") interrupt(req, arg);
- else if (action == "mute") mute(req, arg);
- else if (action == "unmute") unmute(req, arg);
- else afb_req_fail(req, "Unknown action!", nullptr);
+ json_object* arg = afb_req_json(req);
+ if (arg == nullptr)
+ {
+ afb_req_fail(req, "No valid argument!", nullptr);
+ return;
+ }
+
+ json_object* jaction;
+ json_bool ret = json_object_object_get_ex(arg, "action", &jaction);
+ if (!ret)
+ {
+ afb_req_fail(req, "No valid action!", nullptr);
+ return;
+ }
+
+ std::string action = json_object_get_string(jaction);
+ if (action.size() == 0)
+ {
+ afb_req_fail(req, "No valid action!", nullptr);
+ return;
+ }
+
+ if (action == "open") open(req, arg);
+ else if (action == "close") close(req, arg);
+ else if (action == "volume") volume(req, arg);
+ else if (action == "interrupt") interrupt(req, arg);
+ else if (action == "mute") mute(req, arg);
+ else if (action == "unmute") unmute(req, arg);
+ else afb_req_fail(req, "Unknown action!", nullptr);
}
void role_t::open(afb_req_t r, json_object* o)
{
- if (opened_)
- {
- afb_req_fail(r, "Already opened!", nullptr);
- return;
- }
-
- if (!apply_policy(r))
- {
- afb_req_context(r,
- 0, // Do not replace previous context if any
- [](void* arg) -> void* { return new session_t(); },
- [](void* arg) {
- afb_api_t api = ahl_binding_t::instance().handle();
- session_t* opened_roles = reinterpret_cast<session_t*>(arg);
- for(role_t* role : *opened_roles)
- {
- AFB_API_DEBUG(api, "Released role %s\n", role->uid_.c_str());
- role->opened_ = false;
- if(role->interrupts_.size()) role->interrupts_[0].clear();
-
- // send a mute command to the HAL. We cannot reuse the do_mute function,
- // because in the context here, the afb_request is no longer valid.
- json_object* a = json_object_new_object();
- json_object_object_add(a, "mute", json_object_new_boolean(true));
-
- afb_api_call(
- api,
- role->hal_.c_str(),
- role->stream_.c_str(),
- a,
- NULL,
- NULL);
- }
- delete opened_roles;
- },
- nullptr
- );
-
- opened_ = true;
-
- // Add the current role to the session
- session_t* context = reinterpret_cast<session_t*>(afb_req_context_get(r));
- if(context) context->push_back(this);
-
- json_object* result = json_object_new_object();
- json_object_object_add(result, "device_uri", json_object_new_string(device_uri_.c_str()));
-
- afb_req_success(r, result, nullptr);
- }
+ if (opened_)
+ {
+ afb_req_fail(r, "Already opened!", nullptr);
+ return;
+ }
+
+ if (!apply_policy(r))
+ {
+ afb_req_context(r,
+ 0, // Do not replace previous context if any
+ [](void* arg) -> void* { return new session_t(); },
+ [](void* arg) {
+ afb_api_t api = ahl_binding_t::instance().handle();
+ session_t* opened_roles = reinterpret_cast<session_t*>(arg);
+ for(role_t* role : *opened_roles)
+ {
+ AFB_API_DEBUG(api, "Released role %s\n", role->uid_.c_str());
+ role->opened_ = false;
+ if(role->interrupts_.size()) role->interrupts_[0].clear();
+
+ // send a mute command to the HAL. We cannot reuse the do_mute function,
+ // because in the context here, the afb_request is no longer valid.
+ json_object* a = json_object_new_object();
+ json_object_object_add(a, "mute", json_object_new_boolean(true));
+
+ afb_api_call(
+ api,
+ role->hal_.c_str(),
+ role->stream_.c_str(),
+ a,
+ NULL,
+ NULL);
+ }
+ delete opened_roles;
+ },
+ nullptr
+ );
+
+ opened_ = true;
+
+ // Add the current role to the session
+ session_t* context = reinterpret_cast<session_t*>(afb_req_context_get(r));
+ if(context) context->push_back(this);
+
+ json_object* result = json_object_new_object();
+ json_object_object_add(result, "device_uri", json_object_new_string(device_uri_.c_str()));
+
+ afb_req_success(r, result, nullptr);
+ }
}
void role_t::close(afb_req_t r, json_object* o)
{
- if (!opened_)
- {
- afb_req_success(r, nullptr, "Already closed!");
- return;
- }
-
- session_t* context = reinterpret_cast<session_t*>(afb_req_context_get(r));
- if(!context)
- {
- afb_req_fail(r, "Stream is opened by another client!", nullptr);
- return;
- }
-
- // Remove the current role from the session.
- std::string uid = uid_;
- std::remove_if(context->begin(), context->end(), [uid](role_t* r) { return r->uid_ == uid; });
- context->push_back(this);
-
- opened_ = false;
- if(interrupts_.size()) interrupts_[0].clear();
- afb_req_success(r, nullptr, "Stream closed!");
+ if (!opened_)
+ {
+ afb_req_success(r, nullptr, "Already closed!");
+ return;
+ }
+
+ session_t* context = reinterpret_cast<session_t*>(afb_req_context_get(r));
+ if(!context)
+ {
+ afb_req_fail(r, "Stream is opened by another client!", nullptr);
+ return;
+ }
+
+ // Remove the current role from the session.
+ std::string uid = uid_;
+ std::remove_if(context->begin(), context->end(), [uid](role_t* r) { return r->uid_ == uid; });
+ context->push_back(this);
+
+ opened_ = false;
+ if(interrupts_.size()) interrupts_[0].clear();
+ afb_req_success(r, nullptr, "Stream closed!");
}
void role_t::mute(afb_req_t r, json_object* o) {
@@ -238,100 +238,100 @@ void role_t::unmute(afb_req_t r, json_object *o) {
void role_t::do_mute(afb_req_t r, bool v) {
- json_object* a = json_object_new_object();
- json_object_object_add(a, "mute", json_object_new_boolean(v));
- afb_api_t api = ahl_binding_t::instance().handle();
-
- afb_api_call(
- api,
- hal_.c_str(),
- stream_.c_str(),
- a,
- [](void* closure, json_object* result, const char* error, const char* info, afb_api_t handle)
- {
- AFB_API_DEBUG(handle, "Got the following answer: %s", json_object_to_json_string(result));
- afb_req_t r = (afb_req_t)closure;
-
- json_object_get(result);
- if (error) afb_req_fail(r, json_object_to_json_string(result), nullptr);
- else afb_req_success(r, result, nullptr);
- afb_req_unref(r);
- },
- afb_req_addref(r));
+ json_object* a = json_object_new_object();
+ json_object_object_add(a, "mute", json_object_new_boolean(v));
+ afb_api_t api = ahl_binding_t::instance().handle();
+
+ afb_api_call(
+ api,
+ hal_.c_str(),
+ stream_.c_str(),
+ a,
+ [](void* closure, json_object* result, const char* error, const char* info, afb_api_t handle)
+ {
+ AFB_API_DEBUG(handle, "Got the following answer: %s", json_object_to_json_string(result));
+ afb_req_t r = (afb_req_t)closure;
+
+ json_object_get(result);
+ if (error) afb_req_fail(r, json_object_to_json_string(result), nullptr);
+ else afb_req_success(r, result, nullptr);
+ afb_req_unref(r);
+ },
+ afb_req_addref(r));
}
struct volumeclosure
{
- std::string role;
- afb_req_t req;
+ std::string role;
+ afb_req_t req;
};
void role_t::volume(afb_req_t r, json_object* o)
{
afb_api_t api = ahl_binding_t::instance().handle();
- if(!afb_req_has_permission(r, "urn:AGL:permission::public:4a-audio-mixer"))
- {
- if (!opened_)
- {
- afb_req_fail(r, "You have to open the stream first!", nullptr);
- return;
- }
-
- if(!afb_req_context_get(r))
- {
- afb_req_fail(r, "Stream is opened by another client!", nullptr);
- return;
- }
- }
- else
- {
- AFB_API_DEBUG(api, "Granted special audio-mixer permission to change volume");
- }
-
- json_object* value;
- json_bool ret = json_object_object_get_ex(o, "value", &value);
- if (!ret)
- {
- afb_req_fail(r, "No value given!", nullptr);
- return;
- }
-
- json_object_get(value);
-
- json_object* a = json_object_new_object();
- json_object_object_add(a, "volume", value);
+ if(!afb_req_has_permission(r, "urn:AGL:permission::public:4a-audio-mixer"))
+ {
+ if (!opened_)
+ {
+ afb_req_fail(r, "You have to open the stream first!", nullptr);
+ return;
+ }
+
+ if(!afb_req_context_get(r))
+ {
+ afb_req_fail(r, "Stream is opened by another client!", nullptr);
+ return;
+ }
+ }
+ else
+ {
+ AFB_API_DEBUG(api, "Granted special audio-mixer permission to change volume");
+ }
+
+ json_object* value;
+ json_bool ret = json_object_object_get_ex(o, "value", &value);
+ if (!ret)
+ {
+ afb_req_fail(r, "No value given!", nullptr);
+ return;
+ }
+
+ json_object_get(value);
+
+ json_object* a = json_object_new_object();
+ json_object_object_add(a, "volume", value);
volumeclosure* userdata = new volumeclosure();
userdata->role = uid_;
userdata->req = afb_req_addref(r);
- afb_api_call(
- api,
- hal_.c_str(),
- stream_.c_str(),
- a,
- [](void* closure, json_object* result, const char* error, const char* info, afb_api_t handle)
- {
- AFB_API_DEBUG(handle, "Got the following answer: %s", json_object_to_json_string(result));
- volumeclosure* r = reinterpret_cast<volumeclosure*>(closure);
-
- json_object_get(result);
- if (error) afb_req_fail(r->req, json_object_to_json_string(result), nullptr);
- else
- {
- json_object* volnew;
- if (json_object_object_get_ex(result, "volnew", &volnew))
- {
- ahl_binding_t::instance().emit_volume_changed(r->role, json_object_get_int(volnew));
- }
- afb_req_success(r->req, result, nullptr);
- }
- afb_req_unref(r->req);
- delete r;
- },
- userdata
- );
+ afb_api_call(
+ api,
+ hal_.c_str(),
+ stream_.c_str(),
+ a,
+ [](void* closure, json_object* result, const char* error, const char* info, afb_api_t handle)
+ {
+ AFB_API_DEBUG(handle, "Got the following answer: %s", json_object_to_json_string(result));
+ volumeclosure* r = reinterpret_cast<volumeclosure*>(closure);
+
+ json_object_get(result);
+ if (error) afb_req_fail(r->req, json_object_to_json_string(result), nullptr);
+ else
+ {
+ json_object* volnew;
+ if (json_object_object_get_ex(result, "volnew", &volnew))
+ {
+ ahl_binding_t::instance().emit_volume_changed(r->role, json_object_get_int(volnew));
+ }
+ afb_req_success(r->req, result, nullptr);
+ }
+ afb_req_unref(r->req);
+ delete r;
+ },
+ userdata
+ );
}
void role_t::interrupt(afb_req_t r, json_object* o)
diff --git a/ahl-binding/role.hpp b/ahl-binding/role.hpp
index 7cf0f7e..e0c979a 100644
--- a/ahl-binding/role.hpp
+++ b/ahl-binding/role.hpp
@@ -24,59 +24,59 @@
class role_t
{
private:
- // Members filled by config
- std::string uid_;
- std::string description_;
- std::string hal_;
- std::string stream_;
- int priority_;
- std::vector<interrupt_t> interrupts_;
+ // Members filled by config
+ std::string uid_;
+ std::string description_;
+ std::string hal_;
+ std::string stream_;
+ int priority_;
+ std::vector<interrupt_t> interrupts_;
- std::string device_uri_;
- bool opened_ = false;
-
- int apply_policy(afb_req_t req);
+ std::string device_uri_;
+ bool opened_ = false;
- void do_mute(afb_req_t, bool);
+ int apply_policy(afb_req_t req);
+
+ void do_mute(afb_req_t, bool);
public:
- explicit role_t() = default;
- explicit role_t(const role_t&) = default;
- explicit role_t(role_t&&) = default;
-
- ~role_t() = default;
-
- role_t& operator=(const role_t&) = default;
- role_t& operator=(role_t&&) = default;
-
- static role_t from_json(json_object* o);
-
- explicit role_t(json_object* j);
-
- role_t& operator<<(json_object* j);
-
- std::string uid() const;
- std::string description() const;
- std::string hal() const;
- std::string stream() const;
- int priority() const;
- const std::vector<interrupt_t>& interrupts() const;
- std::string device_uri() const;
- bool opened() const;
-
- void uid(std::string v);
- void description(std::string v);
- void hal(std::string v);
- void stream(std::string v);
- void device_uri(std::string v);
- void priority(int v);
-
- void invoke(afb_req_t r);
-
- void open(afb_req_t r, json_object* o);
- void close(afb_req_t r, json_object* o);
- void volume(afb_req_t r, json_object* o);
- void interrupt(afb_req_t r, json_object* o);
- void mute(afb_req_t r, json_object* o);
- void unmute(afb_req_t r, json_object* o);
+ explicit role_t() = default;
+ explicit role_t(const role_t&) = default;
+ explicit role_t(role_t&&) = default;
+
+ ~role_t() = default;
+
+ role_t& operator=(const role_t&) = default;
+ role_t& operator=(role_t&&) = default;
+
+ static role_t from_json(json_object* o);
+
+ explicit role_t(json_object* j);
+
+ role_t& operator<<(json_object* j);
+
+ std::string uid() const;
+ std::string description() const;
+ std::string hal() const;
+ std::string stream() const;
+ int priority() const;
+ const std::vector<interrupt_t>& interrupts() const;
+ std::string device_uri() const;
+ bool opened() const;
+
+ void uid(std::string v);
+ void description(std::string v);
+ void hal(std::string v);
+ void stream(std::string v);
+ void device_uri(std::string v);
+ void priority(int v);
+
+ void invoke(afb_req_t r);
+
+ void open(afb_req_t r, json_object* o);
+ void close(afb_req_t r, json_object* o);
+ void volume(afb_req_t r, json_object* o);
+ void interrupt(afb_req_t r, json_object* o);
+ void mute(afb_req_t r, json_object* o);
+ void unmute(afb_req_t r, json_object* o);
};