2 * Copyright (c) 2012, Intel Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Intel Corporation nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 #include <murphy/common.h>
38 #include <murphy/common/debug.h>
39 #include <murphy/core/plugin.h>
40 #include <murphy/core/console.h>
41 #include <murphy/core/event.h>
42 #include <murphy/core/context.h>
43 #include <murphy/core/lua-bindings/murphy.h>
45 #include <murphy-db/mql.h>
46 #include <murphy-db/mqi.h>
48 #include <murphy/resource/config-api.h>
49 #include <murphy/resource/manager-api.h>
50 #include <murphy/resource/client-api.h>
51 #include <murphy/resource/protocol.h>
56 struct mrp_resmgr_data_s {
59 mrp_resmgr_screen_t *screen;
60 mrp_resmgr_audio_t *audio;
61 mrp_htbl_t *resources;
64 mrp_zone_mask_t zones;
67 static void print_resources_cb(mrp_console_t *, void *, int, char **);
69 MRP_CONSOLE_GROUP(manager_group, "ivi-resource-manager", NULL, NULL, {
70 MRP_TOKENIZED_CMD("resources", print_resources_cb, FALSE,
71 "resources", "prints managed resources",
72 "prints the resources managed by "
73 "ivi-resource-manager."),
76 static mrp_resmgr_data_t *resmgr_data;
78 void mrp_resmgr_register_dependency(mrp_resmgr_data_t *data,
79 const char *db_table_name)
86 MRP_ASSERT(data && db_table_name, "invalid argument");
89 size = (idx + 1) * sizeof(const char *);
91 if (!(depends = mrp_realloc(data->depends, size))) {
92 mrp_log_error("ivi-resource-manager: failed to allocate memory "
93 "for resource dependencies");
99 snprintf(dependency, sizeof(dependency), "$%s", db_table_name);
101 if (!(depends[idx] = mrp_strdup(dependency))) {
102 mrp_log_error("ivi-resource-manager: failed to strdup dependency");
103 data->depends = depends;
107 data->ndepend = idx + 1;
108 data->depends = depends;
111 void mrp_resmgr_insert_resource(mrp_resmgr_data_t *data,
118 MRP_ASSERT(data && zone && key && resource, "invalid argument");
119 MRP_ASSERT(data->resources, "uninitialised data structure");
121 zoneid = mrp_zone_get_id(zone);
123 data->zones |= ((mrp_zone_mask_t)1 << zoneid);
125 mrp_htbl_insert(data->resources, key, resource);
128 void *mrp_resmgr_remove_resource(mrp_resmgr_data_t *data,
132 MRP_ASSERT(data && zone && key, "invalid argument");
133 MRP_ASSERT(data->resources, "uninitialised data structure");
135 return mrp_htbl_remove(data->resources, key, FALSE);
138 void *mrp_resmgr_lookup_resource(mrp_resmgr_data_t *data, mrp_resource_t *key)
140 MRP_ASSERT(data && key, "invalid argument");
141 MRP_ASSERT(data->resources, "uninitialised data structure");
143 return mrp_htbl_lookup(data->resources, key);
146 static void print_resources_cb(mrp_console_t *c, void *user_data,
147 int argc, char **argv)
149 const char *zones[MRP_ZONE_MAX + 1];
154 MRP_UNUSED(user_data);
158 mrp_zone_get_all_names(MRP_ZONE_MAX+1, zones);
160 printf("Resources managed by ivi-resource-manager:\n");
162 for (zoneid = 0; zones[zoneid]; zoneid++) {
163 printf(" Zone '%s':\n", zones[zoneid]);
165 mrp_resmgr_screen_print(resmgr_data->screen, zoneid, buf, sizeof(buf));
168 mrp_resmgr_audio_print(resmgr_data->audio, zoneid, buf, sizeof(buf));
176 static int resource_update_cb(mrp_scriptlet_t *script, mrp_context_tbl_t *ctbl)
178 mrp_resmgr_data_t *data = (mrp_resmgr_data_t *)script->data;
179 mrp_zone_mask_t mask;
184 for (mask = data->zones, zoneid = 0; mask; mask >>= 1, zoneid++) {
186 mrp_resource_owner_recalc(zoneid);
192 static void add_depenedencies_to_resolver(mrp_resmgr_data_t *data)
194 static const char *target = "_ivi_resources";
195 static mrp_interpreter_t resource_updater = {
205 mrp_plugin_t *plugin;
207 mrp_resolver_t *resolver;
213 MRP_ASSERT(data, "invalid argument");
215 plugin = data->plugin;
217 if (!(ctx = plugin->ctx) || !(resolver = ctx->r))
220 if (!data->ndepend || !data->depends)
223 for (i = 0, e = (p = buf) + sizeof(buf); i < data->ndepend && p < e; i++)
224 p += snprintf(p, e-p, " %s", data->depends[i]);
226 printf("%s:%s\n\tresource_recalc()\n\n", target, buf);
228 success = mrp_resolver_add_prepared_target(resolver, target,
229 data->depends, data->ndepend,
230 &resource_updater, NULL, data);
232 mrp_log_error("ivi-resource-manager: failed to install "
233 "resolver target '%s'", target);
237 static void event_cb(mrp_event_watch_t *w, int id, mrp_msg_t *event_data,
240 mrp_plugin_t *plugin = (mrp_plugin_t *)user_data;
242 mrp_plugin_arg_t *args = plugin->args;
244 mrp_resmgr_data_t *data = (mrp_resmgr_data_t *)plugin->data;
245 const char *event = mrp_get_event_name(id);
246 uint16_t tag_inst = MRP_PLUGIN_TAG_INSTANCE;
247 uint16_t tag_name = MRP_PLUGIN_TAG_PLUGIN;
254 mrp_log_info("%s: got event 0x%x (%s):", plugin->instance, id, event);
257 if (!strcmp(event, MRP_PLUGIN_EVENT_STARTED)) {
258 success = mrp_msg_get(event_data,
259 MRP_MSG_TAG_STRING(tag_inst, &inst),
260 MRP_MSG_TAG_STRING(tag_name, &name),
263 if (!strcmp(inst, plugin->instance)) {
264 data->screen = mrp_resmgr_screen_create(data);
265 data->audio = mrp_resmgr_audio_create(data);
267 add_depenedencies_to_resolver(data);
270 } /* if PLUGIN_STARTED */
275 static int subscribe_events(mrp_plugin_t *plugin)
277 mrp_resmgr_data_t *data = (mrp_resmgr_data_t *)plugin->data;
278 mrp_event_mask_t events;
280 mrp_set_named_events(&events,
281 MRP_PLUGIN_EVENT_LOADED,
282 MRP_PLUGIN_EVENT_STARTED,
283 MRP_PLUGIN_EVENT_FAILED,
284 MRP_PLUGIN_EVENT_STOPPING,
285 MRP_PLUGIN_EVENT_STOPPED,
286 MRP_PLUGIN_EVENT_UNLOADED,
289 data->w = mrp_add_event_watch(&events, event_cb, plugin);
291 return (data->w != NULL);
295 static void unsubscribe_events(mrp_plugin_t *plugin)
297 mrp_resmgr_data_t *data = (mrp_resmgr_data_t *)plugin->data;
300 mrp_del_event_watch(data->w);
306 static int hash_compare(const void *key1, const void *key2)
315 static uint32_t hash_function(const void *key)
317 return (uint32_t)(((uint64_t)key >> 4) & 0xffffffff);
321 static int manager_init(mrp_plugin_t *plugin)
324 mrp_plugin_arg_t *args = plugin->args;
326 mrp_resmgr_data_t *data;
327 mrp_htbl_config_t cfg;
329 mrp_log_info("%s() called for IVI resource manager instance '%s'...",
330 __FUNCTION__, plugin->instance);
333 cfg.comp = hash_compare;
334 cfg.hash = hash_function;
336 cfg.nbucket = cfg.nentry / 4;
338 if (!(data = mrp_allocz(sizeof(*data)))) {
339 mrp_log_error("Failed to allocate private data for IVI resource "
340 "manager plugin instance %s.", plugin->instance);
344 data->plugin = plugin;
345 data->resources = mrp_htbl_create(&cfg);
350 subscribe_events(plugin);
356 static void manager_exit(mrp_plugin_t *plugin)
358 mrp_resmgr_data_t *data;
360 mrp_log_info("%s() called for IVI resource manager instance '%s'...",
361 __FUNCTION__, plugin->instance);
363 unsubscribe_events(plugin);
365 if ((data = plugin->data) && data == resmgr_data) {
366 mrp_resmgr_screen_destroy(data->screen);
371 #define MANAGER_DESCRIPTION "Plugin to implement IVI resources"
372 #define MANAGER_HELP "Maybe later ..."
373 #define MANAGER_VERSION MRP_VERSION_INT(0, 0, 1)
374 #define MANAGER_AUTHORS "Janos Kovacs <jankovac503@gmail.com>"
376 static mrp_plugin_arg_t args[] = {
380 MURPHY_REGISTER_PLUGIN("resource-manager",
388 args, MRP_ARRAY_SIZE(args),
396 * indent-tabs-mode: nil