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>
57 struct mrp_resmgr_data_s {
60 mrp_resmgr_screen_t *screen;
61 mrp_resmgr_audio_t *audio;
62 mrp_resmgr_appid_t *appid;
63 mrp_htbl_t *resources;
66 mrp_zone_mask_t zones;
69 static void print_resources_cb(mrp_console_t *, void *, int, char **);
71 MRP_CONSOLE_GROUP(manager_group, "ivi-resource-manager", NULL, NULL, {
72 MRP_TOKENIZED_CMD("resources", print_resources_cb, FALSE,
73 "resources", "prints managed resources",
74 "prints the resources managed by "
75 "ivi-resource-manager."),
78 static mrp_resmgr_data_t *resmgr_data;
80 void mrp_resmgr_register_dependency(mrp_resmgr_data_t *data,
81 const char *db_table_name)
88 MRP_ASSERT(data && db_table_name, "invalid argument");
91 size = (idx + 1) * sizeof(const char *);
93 if (!(depends = mrp_realloc(data->depends, size))) {
94 mrp_log_error("ivi-resource-manager: failed to allocate memory "
95 "for resource dependencies");
101 snprintf(dependency, sizeof(dependency), "$%s", db_table_name);
103 if (!(depends[idx] = mrp_strdup(dependency))) {
104 mrp_log_error("ivi-resource-manager: failed to strdup dependency");
105 data->depends = depends;
109 data->ndepend = idx + 1;
110 data->depends = depends;
113 void mrp_resmgr_insert_resource(mrp_resmgr_data_t *data,
120 MRP_ASSERT(data && zone && key && resource, "invalid argument");
121 MRP_ASSERT(data->resources, "uninitialised data structure");
123 zoneid = mrp_zone_get_id(zone);
125 data->zones |= ((mrp_zone_mask_t)1 << zoneid);
127 mrp_htbl_insert(data->resources, key, resource);
130 void *mrp_resmgr_remove_resource(mrp_resmgr_data_t *data,
134 MRP_ASSERT(data && zone && key, "invalid argument");
135 MRP_ASSERT(data->resources, "uninitialised data structure");
137 return mrp_htbl_remove(data->resources, key, FALSE);
140 void *mrp_resmgr_lookup_resource(mrp_resmgr_data_t *data, mrp_resource_t *key)
142 MRP_ASSERT(data && key, "invalid argument");
143 MRP_ASSERT(data->resources, "uninitialised data structure");
145 return mrp_htbl_lookup(data->resources, key);
148 mrp_resmgr_screen_t *mrp_resmgr_get_screen(mrp_resmgr_data_t *data)
150 MRP_ASSERT(data, "invalid argument");
151 MRP_ASSERT(data->screen, "confused with data structures");
156 mrp_resmgr_audio_t *mrp_resmgr_get_audio(mrp_resmgr_data_t *data)
158 MRP_ASSERT(data, "invalid argument");
159 MRP_ASSERT(data->audio, "confused with data structures");
164 mrp_resmgr_appid_t *mrp_resmgr_get_appid(mrp_resmgr_data_t *data)
166 MRP_ASSERT(data, "invalid argument");
167 MRP_ASSERT(data->appid, "confused with data structures");
172 static void print_resources_cb(mrp_console_t *c, void *user_data,
173 int argc, char **argv)
175 const char *zones[MRP_ZONE_MAX + 1];
180 MRP_UNUSED(user_data);
184 mrp_zone_get_all_names(MRP_ZONE_MAX+1, zones);
186 printf("Resources managed by ivi-resource-manager:\n");
188 for (zoneid = 0; zones[zoneid]; zoneid++) {
189 printf(" Zone '%s':\n", zones[zoneid]);
191 mrp_resmgr_screen_print(resmgr_data->screen, zoneid, buf, sizeof(buf));
194 mrp_resmgr_audio_print(resmgr_data->audio, zoneid, buf, sizeof(buf));
202 static int resource_update_cb(mrp_scriptlet_t *script, mrp_context_tbl_t *ctbl)
204 mrp_resmgr_data_t *data = (mrp_resmgr_data_t *)script->data;
205 mrp_zone_mask_t mask;
210 for (mask = data->zones, zoneid = 0; mask; mask >>= 1, zoneid++) {
212 mrp_resource_owner_recalc(zoneid);
218 static void add_depenedencies_to_resolver(mrp_resmgr_data_t *data)
220 static const char *target = "_ivi_resources";
221 static mrp_interpreter_t resource_updater = {
231 mrp_plugin_t *plugin;
233 mrp_resolver_t *resolver;
239 MRP_ASSERT(data, "invalid argument");
241 plugin = data->plugin;
243 if (!(ctx = plugin->ctx) || !(resolver = ctx->r))
246 if (!data->ndepend || !data->depends)
249 for (i = 0, e = (p = buf) + sizeof(buf); i < data->ndepend && p < e; i++)
250 p += snprintf(p, e-p, " %s", data->depends[i]);
252 printf("%s:%s\n\tresource_recalc()\n\n", target, buf);
254 success = mrp_resolver_add_prepared_target(resolver, target,
255 data->depends, data->ndepend,
256 &resource_updater, NULL, data);
258 mrp_log_error("ivi-resource-manager: failed to install "
259 "resolver target '%s'", target);
263 static void event_cb(mrp_event_watch_t *w, int id, mrp_msg_t *event_data,
266 mrp_plugin_t *plugin = (mrp_plugin_t *)user_data;
268 mrp_plugin_arg_t *args = plugin->args;
270 mrp_resmgr_data_t *data = (mrp_resmgr_data_t *)plugin->data;
271 const char *event = mrp_get_event_name(id);
272 uint16_t tag_inst = MRP_PLUGIN_TAG_INSTANCE;
273 uint16_t tag_name = MRP_PLUGIN_TAG_PLUGIN;
280 mrp_log_info("%s: got event 0x%x (%s):", plugin->instance, id, event);
283 if (!strcmp(event, MRP_PLUGIN_EVENT_STARTED)) {
284 success = mrp_msg_get(event_data,
285 MRP_MSG_TAG_STRING(tag_inst, &inst),
286 MRP_MSG_TAG_STRING(tag_name, &name),
289 if (!strcmp(inst, plugin->instance)) {
290 data->screen = mrp_resmgr_screen_create(data);
291 data->audio = mrp_resmgr_audio_create(data);
292 data->appid = mrp_resmgr_appid_create(data);
294 add_depenedencies_to_resolver(data);
297 } /* if PLUGIN_STARTED */
302 static int subscribe_events(mrp_plugin_t *plugin)
304 mrp_resmgr_data_t *data = (mrp_resmgr_data_t *)plugin->data;
305 mrp_event_mask_t events;
307 mrp_set_named_events(&events,
308 MRP_PLUGIN_EVENT_LOADED,
309 MRP_PLUGIN_EVENT_STARTED,
310 MRP_PLUGIN_EVENT_FAILED,
311 MRP_PLUGIN_EVENT_STOPPING,
312 MRP_PLUGIN_EVENT_STOPPED,
313 MRP_PLUGIN_EVENT_UNLOADED,
316 data->w = mrp_add_event_watch(&events, event_cb, plugin);
318 return (data->w != NULL);
322 static void unsubscribe_events(mrp_plugin_t *plugin)
324 mrp_resmgr_data_t *data = (mrp_resmgr_data_t *)plugin->data;
327 mrp_del_event_watch(data->w);
333 static int hash_compare(const void *key1, const void *key2)
342 static uint32_t hash_function(const void *key)
344 return (uint32_t)(((uint64_t)key >> 4) & 0xffffffff);
348 static int manager_init(mrp_plugin_t *plugin)
351 mrp_plugin_arg_t *args = plugin->args;
353 mrp_resmgr_data_t *data;
354 mrp_htbl_config_t cfg;
356 mrp_log_info("%s() called for IVI resource manager instance '%s'...",
357 __FUNCTION__, plugin->instance);
360 cfg.comp = hash_compare;
361 cfg.hash = hash_function;
363 cfg.nbucket = cfg.nentry / 4;
365 if (!(data = mrp_allocz(sizeof(*data)))) {
366 mrp_log_error("Failed to allocate private data for IVI resource "
367 "manager plugin instance %s.", plugin->instance);
371 data->plugin = plugin;
372 data->resources = mrp_htbl_create(&cfg);
377 subscribe_events(plugin);
383 static void manager_exit(mrp_plugin_t *plugin)
385 mrp_resmgr_data_t *data;
387 mrp_log_info("%s() called for IVI resource manager instance '%s'...",
388 __FUNCTION__, plugin->instance);
390 unsubscribe_events(plugin);
392 if ((data = plugin->data) && data == resmgr_data) {
393 mrp_resmgr_screen_destroy(data->screen);
394 mrp_resmgr_audio_destroy(data->audio);
395 mrp_resmgr_appid_destroy(data->appid);
400 #define MANAGER_DESCRIPTION "Plugin to implement IVI resources"
401 #define MANAGER_HELP "Maybe later ..."
402 #define MANAGER_VERSION MRP_VERSION_INT(0, 0, 1)
403 #define MANAGER_AUTHORS "Janos Kovacs <jankovac503@gmail.com>"
405 static mrp_plugin_arg_t args[] = {
409 MURPHY_REGISTER_PLUGIN("resource-manager",
417 args, MRP_ARRAY_SIZE(args),
425 * indent-tabs-mode: nil