summaryrefslogtreecommitdiffstats
path: root/src/sbus
diff options
context:
space:
mode:
Diffstat (limited to 'src/sbus')
-rwxr-xr-xsrc/sbus/sbus_codegen114
-rw-r--r--src/sbus/sssd_dbus_meta.h2
-rw-r--r--src/sbus/sssd_dbus_properties.c75
3 files changed, 151 insertions, 40 deletions
diff --git a/src/sbus/sbus_codegen b/src/sbus/sbus_codegen
index 96248a628..a8f91b784 100755
--- a/src/sbus/sbus_codegen
+++ b/src/sbus/sbus_codegen
@@ -187,6 +187,16 @@ class Property(Typed):
raise DBusXmlException('Invalid access type %s'%self.access)
def fq_c_name(self):
return "%s_%s" % (self.iface.c_name(), self.c_name())
+ def getter_name(self):
+ return "%s_get_%s" % (self.iface.c_name(), self.c_name())
+ def getter_invoker_name(self):
+ return "invoke_get_%s" % self.type
+ def getter_signature(self, name):
+ sig = "void (*%s)(struct sbus_request *, void *data, %s *" % (name, self.sssd_type)
+ if self.is_array:
+ sig += " *, int *"
+ sig += ")"
+ return sig
class Interface(Base):
def __init__(self, name):
@@ -237,6 +247,9 @@ def method_function_pointer(meth, name, with_names=False):
with_names and "data" or "",
method_arg_types(meth.in_args, with_names))
+def property_handlers(prop):
+ return prop.getter_signature(prop.getter_name())
+
def forward_method_invoker(signature, args):
out("")
out("/* invokes a handler with a '%s' DBus signature */", signature)
@@ -280,49 +293,36 @@ def source_method_invoker(signature, args):
def source_getter_invoker(prop):
out("")
- out("/* invokes a getter with a '%s' DBus type */", type)
- out("static int invoke_%s_getter(struct sbus_request *request, struct sbus_interface *intf, void *function_ptr)", prop.type)
+ if prop.is_array:
+ out("/* invokes a getter with an array of '%s' DBus type */", prop.dbus_type)
+ else:
+ out("/* invokes a getter with a '%s' DBus type */", prop.dbus_type)
+ out("static int %s(struct sbus_request *dbus_req, void *function_ptr)",
+ prop.getter_invoker_name())
out("{")
- out(" DBusError error = DBUS_ERROR_INIT;")
- out(" int ret;")
- for i in range(0, len(args)):
- arg = args[i]
- if arg.is_array:
- out(" %s *arg_%d;", arg.dbus_type, i)
- out(" int len_%d;", i)
- else:
- out(" %s arg_%d;", arg.dbus_type, i)
- out(" int (*handler)(struct sbus_request *, void *%s) = function_ptr;", method_arg_types(args))
+ if prop.is_array:
+ out(" %s *prop_val;", prop.sssd_type)
+ out(" int prop_len;")
+ out(" %s *out_val;", prop.dbus_type)
+ else:
+ out(" %s prop_val;", prop.sssd_type)
+ out(" %s out_val;", prop.dbus_type)
out("")
- out(" if (!dbus_message_get_args(request->message, &error,")
- for i in range(0, len(args)):
- arg = args[i]
- if arg.is_array:
- out(" DBUS_TYPE_ARRAY, %s, &arg_%d, &len_%d,",
- arg.dbus_constant, i, i)
- else:
- out(" %s, &arg_%d,", arg.dbus_constant, i)
- out(" DBUS_TYPE_INVALID)) {")
- out(" ret = sbus_request_fail_and_finish(request, error.name, error.message);")
- out(" dbus_error_free(&error);")
- out(" return ret;")
- out(" }")
+ out(" %s", prop.getter_signature("handler"), new_line=False)
+ out(" = function_ptr;")
out("")
- out(" ret = (handler)(request, intf", new_line=False)
- for i in range(0, len(args)):
- arg = args[i]
- out(",\n arg_%d", i, new_line=False)
- if arg.is_array:
- out(",\n len_%d", i, new_line=False)
+ out(" (handler)(dbus_req, dbus_req->intf->instance_data, &prop_val", new_line=False)
+ if prop.is_array:
+ out(", &prop_len", new_line=False)
out(");")
- out("")
- for i in range(0, len(args)):
- arg = args[i]
- if arg.type in ["as", "ao"]:
- out(" dbus_free_string_array((char **)arg_%d);", i)
- out(" return ret;")
+ out("")
+ out(" out_val = prop_val;")
+ if prop.is_array:
+ out(" return sbus_request_return_array_as_variant(dbus_req, %s, (uint8_t*)out_val, prop_len, sizeof(%s));", prop.dbus_constant, prop.sssd_type)
+ else:
+ out(" return sbus_request_return_as_variant(dbus_req, %s, &out_val);", prop.dbus_constant)
out("}")
def forward_method_invokers(ifaces):
@@ -342,6 +342,27 @@ def source_method_invokers(invokers):
for (signature, meth) in invokers.items():
source_method_invoker(signature, meth.in_args)
+def forward_prop_invoker(prop):
+ out("static int %s(struct sbus_request *dbus_req, void *function_ptr);",
+ prop.getter_invoker_name())
+
+def forward_prop_invokers(ifaces):
+ invokers = { }
+ for iface in ifaces:
+ for prop in iface.properties:
+ if not prop.is_basic:
+ continue
+ if prop.type in invokers:
+ continue
+ forward_prop_invoker(prop)
+ invokers[prop.type] = prop
+ return invokers
+
+def source_prop_invokers(invokers):
+ for (type, prop) in invokers.items():
+ if prop.readable:
+ source_getter_invoker(prop)
+
def source_finisher(meth):
out("")
out("int %s_finish(struct sbus_request *req%s)",
@@ -438,6 +459,7 @@ def source_signals(iface, signals):
def source_properties(iface, properties):
out("")
out("/* property info for %s */", iface.name)
+
out("const struct sbus_property_meta %s__properties[] = {", iface.c_name())
for prop in properties:
out(" {")
@@ -451,6 +473,14 @@ def source_properties(iface, properties):
out(" SBUS_PROPERTY_WRITABLE,")
else:
assert False, "should not be reached"
+ if prop.readable:
+ out(" offsetof(struct %s, %s),", iface.c_name(), prop.getter_name())
+ out(" %s,", prop.getter_invoker_name())
+ else:
+ out(" 0, /* not readable */")
+ out(" NULL, /* no invoker */")
+ out(" 0, /* not writable */")
+ out(" NULL, /* no invoker */")
out(" },")
out(" { NULL, }")
out("};")
@@ -491,7 +521,8 @@ def generate_source(ifaces, filename, include_header=None):
if include_header:
out("#include \"%s\"", os.path.basename(include_header))
- invokers = forward_method_invokers(ifaces)
+ meth_invokers = forward_method_invokers(ifaces)
+ prop_invokers = forward_prop_invokers(ifaces)
for iface in ifaces:
@@ -510,7 +541,8 @@ def generate_source(ifaces, filename, include_header=None):
# The sbus_interface structure
source_interface(iface)
- source_method_invokers(invokers)
+ source_method_invokers(meth_invokers)
+ source_prop_invokers(prop_invokers)
def header_finisher(iface, meth):
if meth.use_raw_handler():
@@ -529,6 +561,8 @@ def header_vtable(iface, methods):
# All methods
for meth in iface.methods:
out(" %s;", method_function_pointer(meth, meth.c_name(), with_names=True))
+ for prop in iface.properties:
+ out(" %s;", property_handlers(prop))
out("};")
@@ -584,7 +618,7 @@ def generate_header(ifaces, filename):
out(" */")
for iface in ifaces:
- if iface.methods:
+ if iface.methods or iface.properties:
header_vtable(iface, iface.methods)
for meth in iface.methods:
header_finisher(iface, meth)
diff --git a/src/sbus/sssd_dbus_meta.h b/src/sbus/sssd_dbus_meta.h
index 0ad21df97..4e170b7d6 100644
--- a/src/sbus/sssd_dbus_meta.h
+++ b/src/sbus/sssd_dbus_meta.h
@@ -60,6 +60,8 @@ struct sbus_property_meta {
const char *name;
const char *type;
int flags;
+ size_t vtable_offset_get;
+ sbus_method_invoker_fn invoker_get;
size_t vtable_offset_set;
sbus_method_invoker_fn invoker_set;
};
diff --git a/src/sbus/sssd_dbus_properties.c b/src/sbus/sssd_dbus_properties.c
index 835b3078b..bdd5b432f 100644
--- a/src/sbus/sssd_dbus_properties.c
+++ b/src/sbus/sssd_dbus_properties.c
@@ -105,6 +105,77 @@ dispatch_properties_set(struct sbus_connection *conn,
return EOK;
}
+static int
+dispatch_properties_get(struct sbus_connection *conn,
+ struct sbus_interface *intf,
+ DBusMessage *message)
+{
+ struct sbus_request *req;
+ const char *signature;
+ const struct sbus_interface_meta *meta;
+ DBusMessageIter iter;
+ sbus_msg_handler_fn handler_fn;
+ const struct sbus_property_meta *property;
+ const char *interface_name;
+ const char *property_name;
+
+ req = sbus_new_request(conn, intf, message);
+ if (req == NULL) {
+ return ENOMEM;
+ }
+
+ meta = intf->vtable->meta;
+
+ signature = dbus_message_get_signature(message);
+ /* Interface name, property name */
+ if (strcmp(signature, "ss") != 0) {
+ return sbus_request_fail_and_finish(req,
+ sbus_error_new(req,
+ DBUS_ERROR_INVALID_ARGS,
+ "Invalid argument types passed to Get method"));
+ }
+
+ dbus_message_iter_init(message, &iter);
+ dbus_message_iter_get_basic(&iter, &interface_name);
+ dbus_message_iter_next(&iter);
+ dbus_message_iter_get_basic(&iter, &property_name);
+
+ if (strcmp(interface_name, meta->name) != 0) {
+ return sbus_request_fail_and_finish(req,
+ sbus_error_new(req,
+ DBUS_ERROR_UNKNOWN_INTERFACE,
+ "No such interface"));
+ }
+
+ property = sbus_meta_find_property(intf->vtable->meta, property_name);
+ if (property == NULL) {
+ return sbus_request_fail_and_finish(req,
+ sbus_error_new(req,
+ DBUS_ERROR_UNKNOWN_PROPERTY,
+ "No such property"));
+ }
+
+ if (!(property->flags & SBUS_PROPERTY_READABLE)) {
+ return sbus_request_fail_and_finish(req,
+ sbus_error_new(req,
+ DBUS_ERROR_ACCESS_DENIED,
+ "Property is not readable"));
+ }
+
+ handler_fn = VTABLE_FUNC(intf->vtable, property->vtable_offset_get);
+ if (!handler_fn) {
+ return sbus_request_fail_and_finish(req,
+ sbus_error_new(req,
+ DBUS_ERROR_NOT_SUPPORTED,
+ "Not implemented"));
+ }
+
+ sbus_request_invoke_or_finish(req, handler_fn,
+ intf->instance_data,
+ property->invoker_get);
+ return EOK;
+}
+
int sbus_properties_dispatch(struct sbus_request *dbus_req)
{
const char *member;
@@ -116,6 +187,10 @@ int sbus_properties_dispatch(struct sbus_request *dbus_req)
return dispatch_properties_set(dbus_req->conn,
dbus_req->intf,
dbus_req->message);
+ } else if (strcmp (member, "Get") == 0) {
+ return dispatch_properties_get(dbus_req->conn,
+ dbus_req->intf,
+ dbus_req->message);
}
return ERR_SBUS_NOSUP;