Name: context-service
Summary: Context-Service
-Version: 0.5.3
+Version: 0.5.5
Release: 1
Group: System/Service
License: Apache-2.0
ctx::client_request::client_request(int type,
const char *client, int req_id, const char *subj, const char *desc,
- const char *sender, GDBusMethodInvocation *inv)
+ const char *sender, char *app_id, GDBusMethodInvocation *inv)
: request_info(type, client, req_id, subj, desc)
+ , __app_id(app_id)
, __sender(sender)
, __invocation(inv)
{
{
if (__invocation)
g_dbus_method_invocation_return_value(__invocation, g_variant_new("(iss)", ERR_OPERATION_FAILED, EMPTY_JSON_OBJECT, EMPTY_JSON_OBJECT));
+
+ g_free(__app_id);
+}
+
+const char* ctx::client_request::get_app_id()
+{
+ return __app_id;
}
bool ctx::client_request::reply(int error)
public:
client_request(int type,
const char *client, int req_id, const char *subj, const char *desc,
- const char *sender, GDBusMethodInvocation *inv);
+ const char *sender, char *app_id, GDBusMethodInvocation *inv);
~client_request();
+ const char *get_app_id();
bool reply(int error);
bool reply(int error, ctx::json &request_result);
bool reply(int error, ctx::json &request_result, ctx::json &data_read);
bool publish(int error, ctx::json &data);
private:
+ char *__app_id;
std::string __sender;
GDBusMethodInvocation *__invocation;
};
return NULL;
}
- if (!ctx::privilege_manager::is_allowed(request->get_client(), it->second.privilege)) {
+ if (!STR_EQ(TRIGGER_CLIENT_NAME, request->get_client()) &&
+ !ctx::privilege_manager::is_allowed(request->get_client(), it->second.privilege)) {
_W("Permission denied");
request->reply(ERR_PERMISSION_DENIED);
delete request;
void ctx::context_manager_impl::unsubscribe(ctx::request_info *request)
{
- _I(CYAN("'%s' unsubscribes RID-%d"), request->get_client(), request->get_id());
+ _I(CYAN("'%s' unsubscribes '%s' (RID-%d)"), request->get_client(), request->get_subject(), request->get_id());
// Search the subscribe request to be removed
request_list_t::iterator target = find_request(subscribe_request_list, request->get_client(), request->get_id());
read_req_cnt_map[req_id]--;
if (read_req_cnt_map[req_id] == 0) {
- reader->unsubscribe(req_id);
+ reader->unsubscribe(subject.c_str(), req_id);
read_req_cnt_map.erase(req_id);
}
int rid = find_sub(subject, option);
IF_FAIL_VOID_TAG(rid > 0, _W, "Unknown subscription for %s", subject);
- unsubscribe(rid);
+ unsubscribe(subject, rid);
}
-void ctx::fact_reader::unsubscribe(int subscription_id)
+void ctx::fact_reader::unsubscribe(const char *subject, int subscription_id)
{
- fact_request *req = new(std::nothrow) fact_request(REQ_UNSUBSCRIBE, CLIENT_NAME, subscription_id, "", NULL, NULL);
+ fact_request *req = new(std::nothrow) fact_request(REQ_UNSUBSCRIBE, CLIENT_NAME, subscription_id, subject, NULL, NULL);
IF_FAIL_VOID_TAG(req, _E, "Memory allocation failed");
g_idle_add(send_request, req);
int subscribe(const char *subject, json *option, bool wait_response = false);
void unsubscribe(const char *subject, json *option);
- void unsubscribe(int subscription_id);
+ void unsubscribe(const char *subject, int subscription_id);
bool read(const char *subject, json *option, context_fact& fact);
void reply_result(int req_id, int error, json *request_result = NULL, json *fact = NULL);
#include <context_trigger_types_internal.h>
#include <context_trigger.h>
#include <db_mgr.h>
+#include "../dbus_server_impl.h"
#include "rule_manager.h"
#include "script_generator.h"
#include "trigger.h"
}
}
+static void trigger_action_dbus_call(ctx::json& action)
+{
+ std::string bus_name, object, iface, method, user_data;
+
+ action.get(NULL, CT_RULE_ACTION_DBUS_NAME, &bus_name);
+ IF_FAIL_VOID_TAG(!bus_name.empty(), _E, "No target bus name");
+
+ action.get(NULL, CT_RULE_ACTION_DBUS_OBJECT, &object);
+ IF_FAIL_VOID_TAG(!object.empty(), _E, "No object path");
+
+ action.get(NULL, CT_RULE_ACTION_DBUS_INTERFACE, &iface);
+ IF_FAIL_VOID_TAG(!iface.empty(), _E, "No interface name");
+
+ action.get(NULL, CT_RULE_ACTION_DBUS_METHOD, &method);
+ IF_FAIL_VOID_TAG(!method.empty(), _E, "No method name");
+
+ if (!action.get(NULL, CT_RULE_ACTION_DBUS_USER_DATA, &user_data)) {
+ _E("No user data");
+ return;
+ }
+
+ ctx::dbus_server::call(bus_name.c_str(), object.c_str(), iface.c_str(), method.c_str(), user_data.c_str());
+}
+
void ctx::rule_manager::on_rule_triggered(int rule_id)
{
_D(YELLOW("Rule%d is triggered"), rule_id);
std::string creator;
record[0].get(NULL, "creator", &creator);
trigger_action_notification(action, creator);
+ } else if (type.compare(CT_RULE_ACTION_TYPE_DBUS_CALL) == 0) {
+ trigger_action_dbus_call(action);
}
}
}
std::ostringstream colstream;
std::ostringstream valstream;
-
for (std::list<std::string>::iterator it = keys.begin(); it != keys.end(); ++it) {
std::string s;
int64_t i;
if (record.get(NULL, (*it).c_str(), &s)) {
colstream << *it << ",";
- valstream << "'" << s << "',";
+
+ char* buf = sqlite3_mprintf("%Q", s.c_str());
+ IF_FAIL_RETURN_TAG(buf, false, _E, "Memory allocation failed");
+ valstream << buf << ",";
+ sqlite3_free(buf);
} else if (record.get(NULL, (*it).c_str(), &i)) {
colstream << *it << ",";
valstream << i << ",";
#include <signal.h>
#include <glib.h>
#include <gio/gio.h>
+#include <app_manager.h>
#include <types_internal.h>
#include <dbus_listener_iface.h>
return;
}
- ctx::client_request *request = new(std::nothrow) ctx::client_request(req_type, smack_label.c_str(), req_id, subject, input, sender, invocation);
+ char *app_id = NULL;
+ app_manager_get_app_id(pid, &app_id);
+ _D("AppId: %s", app_id);
+
+ ctx::client_request *request = new(std::nothrow) ctx::client_request(req_type, smack_label.c_str(), req_id, subject, input, sender, app_id, invocation);
if (!request) {
_E("Memory allocation failed");
g_dbus_method_invocation_return_value(invocation, g_variant_new("(iss)", ERR_OPERATION_FAILED, EMPTY_JSON_OBJECT, EMPTY_JSON_OBJECT));
GVariant *param = g_variant_new("(isis)", req_id, subject, error, data);
IF_FAIL_VOID_TAG(param, _E, "Memory allocation failed");
- GError *err = NULL;
g_dbus_connection_call(dbus_connection, dest, DBUS_PATH, DBUS_IFACE,
- METHOD_RESPOND, param, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, NULL, &err);
- HANDLE_GERROR(err);
+ METHOD_RESPOND, param, NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, NULL, NULL);
+}
+
+static void handle_call_result(GObject *source, GAsyncResult *res, gpointer user_data)
+{
+ _I("Call %u done", *static_cast<unsigned int*>(user_data));
+
+ GDBusConnection *conn = G_DBUS_CONNECTION(source);
+ GError *error = NULL;
+ g_dbus_connection_call_finish(conn, res, &error);
+ HANDLE_GERROR(error);
+}
+
+void ctx::dbus_server_impl::call(const char *dest, const char *obj, const char *iface, const char *method, const char *data)
+{
+ IF_FAIL_VOID_TAG(dest && obj && iface && method && data, _E, "Parameter null");
+
+ static unsigned int call_count = 0;
+ ++call_count;
+
+ _SI("Call %u: %s, %s, %s.%s, %s", call_count, dest, obj, iface, method, data);
+
+ GVariant *param = g_variant_new("(s)", data);
+ IF_FAIL_VOID_TAG(param, _E, "Memory allocation failed");
+
+ g_dbus_connection_call(dbus_connection, dest, obj, iface, method, param, NULL,
+ G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT, NULL, handle_call_result, &call_count);
}
static void handle_signal_received(GDBusConnection *conn, const gchar *sender,
{
_instance->publish(dest, req_id, subject, error, data);
}
+
+void ctx::dbus_server::call(const char *dest, const char *obj, const char *iface, const char *method, const char *data)
+{
+ _instance->call(dest, obj, iface, method, data);
+}
namespace ctx {
class dbus_server_impl : public dbus_server_iface {
- public:
- dbus_server_impl();
- ~dbus_server_impl();
+ public:
+ dbus_server_impl();
+ ~dbus_server_impl();
- bool init();
- void release();
+ bool init();
+ void release();
- void publish(const char* dest, int req_id, const char* subject, int error, const char* data);
- int64_t signal_subscribe(const char* sender, const char* path, const char* iface, const char* name, dbus_listener_iface* listener);
- void signal_unsubscribe(int64_t subscription_id);
+ void publish(const char *dest, int req_id, const char *subject, int error, const char *data);
+ void call(const char *dest, const char *obj, const char *iface, const char *method, const char *data);
+ int64_t signal_subscribe(const char *sender, const char *path, const char *iface, const char *name, dbus_listener_iface *listener);
+ void signal_unsubscribe(int64_t subscription_id);
}; /* class ctx::dbus_server */
namespace dbus_server {
- void publish(const char* dest, int req_id, const char* subject, int error, const char* data);
+ void publish(const char *dest, int req_id, const char *subject, int error, const char *data);
+ void call(const char *dest, const char *obj, const char *iface, const char *method, const char *data);
}
} /* namespace ctx */
{
return _description;
}
+
+const char* ctx::request_info::get_app_id()
+{
+ return NULL;
+}
const char *get_subject();
ctx::json& get_description();
+ virtual const char *get_app_id();
virtual bool reply(int error) = 0;
virtual bool reply(int error, ctx::json &request_result) = 0;
virtual bool reply(int error, ctx::json &request_result, ctx::json &data_read) = 0;