dbus: Remove duplication of object methods/signals/properties

There is no need to duplicate the method/signal/property arrays that
were registered for objects. The registration was using static arrays
on methods/signals/properties in all places and we can as well use
those throughout without having to allocate memory and copy all the
entries for every object. This reduces number of allocations and
amount of unnecessary code quite a bit.
This commit is contained in:
Jouni Malinen 2010-01-03 00:52:30 +02:00
parent 3e87bd5478
commit e90bd80cf5
4 changed files with 77 additions and 506 deletions

View file

@ -820,64 +820,22 @@ void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
} }
struct wpas_dbus_method {
const char *name;
const char *iface;
WPADBusMethodHandler handler;
struct wpa_dbus_argument args[3];
};
struct wpas_dbus_property {
const char *name;
const char *iface;
const char *type;
WPADBusPropertyAccessor getter;
WPADBusPropertyAccessor setter;
enum dbus_prop_access _access;
};
struct wpas_dbus_signal {
const char *name;
const char *iface;
struct wpa_dbus_argument args[3];
};
static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc, static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
void *priv, void *priv,
WPADBusArgumentFreeFunction priv_free, WPADBusArgumentFreeFunction priv_free,
const struct wpas_dbus_method *methods, const struct wpa_dbus_method_desc *methods,
const struct wpas_dbus_property *properties, const struct wpa_dbus_property_desc *properties,
const struct wpas_dbus_signal *signals) const struct wpa_dbus_signal_desc *signals)
{ {
int i;
obj_desc->user_data = priv; obj_desc->user_data = priv;
obj_desc->user_data_free_func = priv_free; obj_desc->user_data_free_func = priv_free;
obj_desc->methods = methods;
for (i = 0; methods && methods[i].name; i++) { obj_desc->properties = properties;
wpa_dbus_method_register(obj_desc, methods[i].iface, obj_desc->signals = signals;
methods[i].name, methods[i].handler,
methods[i].args);
}
for (i = 0; properties && properties[i].name; i++) {
wpa_dbus_property_register(obj_desc, properties[i].iface,
properties[i].name,
properties[i].type,
properties[i].getter,
properties[i].setter,
properties[i]._access);
}
for (i = 0; signals && signals[i].name; i++) {
wpa_dbus_signal_register(obj_desc, signals[i].iface,
signals[i].name, signals[i].args);
}
} }
static const struct wpas_dbus_method wpas_dbus_global_methods[] = { static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
{ "CreateInterface", WPAS_DBUS_NEW_INTERFACE, { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
(WPADBusMethodHandler) &wpas_dbus_handler_create_interface, (WPADBusMethodHandler) &wpas_dbus_handler_create_interface,
{ {
@ -904,7 +862,7 @@ static const struct wpas_dbus_method wpas_dbus_global_methods[] = {
{ NULL, NULL, NULL, { END_ARGS } } { NULL, NULL, NULL, { END_ARGS } }
}; };
static const struct wpas_dbus_property wpas_dbus_global_properties[] = { static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
{ "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "y", { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "y",
(WPADBusPropertyAccessor) wpas_dbus_getter_debug_level, (WPADBusPropertyAccessor) wpas_dbus_getter_debug_level,
(WPADBusPropertyAccessor) wpas_dbus_setter_debug_level, (WPADBusPropertyAccessor) wpas_dbus_setter_debug_level,
@ -933,7 +891,7 @@ static const struct wpas_dbus_property wpas_dbus_global_properties[] = {
{ NULL, NULL, NULL, NULL, NULL, 0 } { NULL, NULL, NULL, NULL, NULL, 0 }
}; };
static const struct wpas_dbus_signal wpas_dbus_global_signals[] = { static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
{ "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE, { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
{ {
{ "path", "o", ARG_OUT }, { "path", "o", ARG_OUT },
@ -1021,7 +979,7 @@ static void wpa_dbus_free(void *ptr)
} }
static const struct wpas_dbus_property wpas_dbus_network_properties[] = { static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
{ "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}", { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
(WPADBusPropertyAccessor) wpas_dbus_getter_network_properties, (WPADBusPropertyAccessor) wpas_dbus_getter_network_properties,
(WPADBusPropertyAccessor) wpas_dbus_setter_network_properties, (WPADBusPropertyAccessor) wpas_dbus_setter_network_properties,
@ -1036,7 +994,7 @@ static const struct wpas_dbus_property wpas_dbus_network_properties[] = {
}; };
static const struct wpas_dbus_signal wpas_dbus_network_signals[] = { static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK, { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
{ {
{ "properties", "a{sv}", ARG_OUT }, { "properties", "a{sv}", ARG_OUT },
@ -1149,7 +1107,7 @@ int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
} }
static const struct wpas_dbus_property wpas_dbus_bss_properties[] = { static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
{ "SSID", WPAS_DBUS_NEW_IFACE_BSSID, "ay", { "SSID", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
(WPADBusPropertyAccessor) wpas_dbus_getter_bss_ssid, (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ssid,
NULL, NULL,
@ -1204,7 +1162,7 @@ static const struct wpas_dbus_property wpas_dbus_bss_properties[] = {
}; };
static const struct wpas_dbus_signal wpas_dbus_bss_signals[] = { static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
{ "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSSID, { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSSID,
{ {
{ "properties", "a{sv}", ARG_OUT }, { "properties", "a{sv}", ARG_OUT },
@ -1324,7 +1282,7 @@ err:
} }
static const struct wpas_dbus_method wpas_dbus_interface_methods[] = { static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
{ "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE, { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
(WPADBusMethodHandler) &wpas_dbus_handler_scan, (WPADBusMethodHandler) &wpas_dbus_handler_scan,
{ {
@ -1396,7 +1354,7 @@ static const struct wpas_dbus_method wpas_dbus_interface_methods[] = {
{ NULL, NULL, NULL, { END_ARGS } } { NULL, NULL, NULL, { END_ARGS } }
}; };
static const struct wpas_dbus_property wpas_dbus_interface_properties[] = { static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
{ "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}", { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
(WPADBusPropertyAccessor) wpas_dbus_getter_capabilities, (WPADBusPropertyAccessor) wpas_dbus_getter_capabilities,
NULL, R NULL, R
@ -1456,7 +1414,7 @@ static const struct wpas_dbus_property wpas_dbus_interface_properties[] = {
{ NULL, NULL, NULL, NULL, NULL, 0 } { NULL, NULL, NULL, NULL, NULL, 0 }
}; };
static const struct wpas_dbus_signal wpas_dbus_interface_signals[] = { static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
{ "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE, { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
{ {
{ "success", "b", ARG_OUT }, { "success", "b", ARG_OUT },

View file

@ -84,20 +84,19 @@ static void recursive_iter_copy(DBusMessageIter *from, DBusMessageIter *to)
static unsigned int fill_dict_with_properties( static unsigned int fill_dict_with_properties(
DBusMessageIter *dict_iter, struct wpa_dbus_property_desc *props, DBusMessageIter *dict_iter, const struct wpa_dbus_property_desc *props,
const char *interface, const void *user_data) const char *interface, const void *user_data)
{ {
DBusMessage *reply; DBusMessage *reply;
DBusMessageIter entry_iter, ret_iter; DBusMessageIter entry_iter, ret_iter;
unsigned int counter = 0; unsigned int counter = 0;
struct wpa_dbus_property_desc *property_dsc; const struct wpa_dbus_property_desc *dsc;
for (property_dsc = props; property_dsc; for (dsc = props; dsc && dsc->dbus_property; dsc++) {
property_dsc = property_dsc->next) { if (!os_strncmp(dsc->dbus_interface, interface,
if (!os_strncmp(property_dsc->dbus_interface, interface,
WPAS_DBUS_INTERFACE_MAX) && WPAS_DBUS_INTERFACE_MAX) &&
property_dsc->access != W && property_dsc->getter) { dsc->access != W && dsc->getter) {
reply = property_dsc->getter(NULL, user_data); reply = dsc->getter(NULL, user_data);
if (!reply) if (!reply)
continue; continue;
@ -114,7 +113,7 @@ static unsigned int fill_dict_with_properties(
NULL, &entry_iter); NULL, &entry_iter);
dbus_message_iter_append_basic( dbus_message_iter_append_basic(
&entry_iter, DBUS_TYPE_STRING, &entry_iter, DBUS_TYPE_STRING,
&(property_dsc->dbus_property)); &dsc->dbus_property);
recursive_iter_copy(&ret_iter, &entry_iter); recursive_iter_copy(&ret_iter, &entry_iter);
@ -159,7 +158,7 @@ static DBusMessage * get_all_properties(
DBUS_DICT_ENTRY_END_CHAR_AS_STRING, DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
&dict_iter); &dict_iter);
props_num = fill_dict_with_properties(&dict_iter,obj_dsc->properties, props_num = fill_dict_with_properties(&dict_iter, obj_dsc->properties,
interface, obj_dsc->user_data); interface, obj_dsc->user_data);
dbus_message_iter_close_container(&iter, &dict_iter); dbus_message_iter_close_container(&iter, &dict_iter);
@ -177,22 +176,22 @@ static DBusMessage * get_all_properties(
static int is_signature_correct(DBusMessage *message, static int is_signature_correct(DBusMessage *message,
struct wpa_dbus_method_desc *method_dsc) const struct wpa_dbus_method_desc *method_dsc)
{ {
/* According to DBus documentation max length of signature is 255 */ /* According to DBus documentation max length of signature is 255 */
#define MAX_SIG_LEN 256 #define MAX_SIG_LEN 256
char registered_sig[MAX_SIG_LEN], *pos; char registered_sig[MAX_SIG_LEN], *pos;
const char *sig = dbus_message_get_signature(message); const char *sig = dbus_message_get_signature(message);
int i, ret; int ret;
const struct wpa_dbus_argument *arg;
pos = registered_sig; pos = registered_sig;
*pos = '\0'; *pos = '\0';
for (i = 0; i < method_dsc->args_num; i++) { for (arg = method_dsc->args; arg && arg->name; arg++) {
struct wpa_dbus_argument arg = method_dsc->args[i]; if (arg->dir == ARG_IN) {
if (arg.dir == ARG_IN) {
size_t blen = registered_sig + MAX_SIG_LEN - pos; size_t blen = registered_sig + MAX_SIG_LEN - pos;
ret = os_snprintf(pos, blen, "%s", arg.type); ret = os_snprintf(pos, blen, "%s", arg->type);
if (ret < 0 || (size_t) ret >= blen) if (ret < 0 || (size_t) ret >= blen)
return 0; return 0;
pos += ret; pos += ret;
@ -215,7 +214,7 @@ static DBusMessage * properties_get_all(DBusMessage *message, char *interface,
static DBusMessage * properties_get(DBusMessage *message, static DBusMessage * properties_get(DBusMessage *message,
struct wpa_dbus_property_desc *dsc, const struct wpa_dbus_property_desc *dsc,
void *user_data) void *user_data)
{ {
if (os_strcmp(dbus_message_get_signature(message), "ss")) if (os_strcmp(dbus_message_get_signature(message), "ss"))
@ -231,7 +230,7 @@ static DBusMessage * properties_get(DBusMessage *message,
static DBusMessage * properties_set(DBusMessage *message, static DBusMessage * properties_set(DBusMessage *message,
struct wpa_dbus_property_desc *dsc, const struct wpa_dbus_property_desc *dsc,
void *user_data) void *user_data)
{ {
if (os_strcmp(dbus_message_get_signature(message), "ssv")) if (os_strcmp(dbus_message_get_signature(message), "ssv"))
@ -251,7 +250,7 @@ properties_get_or_set(DBusMessage *message, DBusMessageIter *iter,
char *interface, char *interface,
struct wpa_dbus_object_desc *obj_dsc) struct wpa_dbus_object_desc *obj_dsc)
{ {
struct wpa_dbus_property_desc *property_dsc; const struct wpa_dbus_property_desc *property_dsc;
char *property; char *property;
const char *method; const char *method;
@ -266,7 +265,7 @@ properties_get_or_set(DBusMessage *message, DBusMessageIter *iter,
} }
dbus_message_iter_get_basic(iter, &property); dbus_message_iter_get_basic(iter, &property);
while (property_dsc) { while (property_dsc && property_dsc->dbus_property) {
/* compare property names and /* compare property names and
* interfaces */ * interfaces */
if (!os_strncmp(property_dsc->dbus_property, property, if (!os_strncmp(property_dsc->dbus_property, property,
@ -275,9 +274,9 @@ properties_get_or_set(DBusMessage *message, DBusMessageIter *iter,
WPAS_DBUS_INTERFACE_MAX)) WPAS_DBUS_INTERFACE_MAX))
break; break;
property_dsc = property_dsc->next; property_dsc++;
} }
if (property_dsc == NULL) { if (property_dsc == NULL || property_dsc->dbus_property == NULL) {
wpa_printf(MSG_DEBUG, "no property handler for %s.%s on %s", wpa_printf(MSG_DEBUG, "no property handler for %s.%s on %s",
interface, property, interface, property,
dbus_message_get_path(message)); dbus_message_get_path(message));
@ -337,7 +336,7 @@ static DBusMessage * properties_handler(DBusMessage *message,
static DBusMessage * msg_method_handler(DBusMessage *message, static DBusMessage * msg_method_handler(DBusMessage *message,
struct wpa_dbus_object_desc *obj_dsc) struct wpa_dbus_object_desc *obj_dsc)
{ {
struct wpa_dbus_method_desc *method_dsc = obj_dsc->methods; const struct wpa_dbus_method_desc *method_dsc = obj_dsc->methods;
const char *method; const char *method;
const char *msg_interface; const char *msg_interface;
@ -345,7 +344,7 @@ static DBusMessage * msg_method_handler(DBusMessage *message,
msg_interface = dbus_message_get_interface(message); msg_interface = dbus_message_get_interface(message);
/* try match call to any registered method */ /* try match call to any registered method */
while (method_dsc) { while (method_dsc && method_dsc->dbus_method) {
/* compare method names and interfaces */ /* compare method names and interfaces */
if (!os_strncmp(method_dsc->dbus_method, method, if (!os_strncmp(method_dsc->dbus_method, method,
WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) && WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) &&
@ -353,9 +352,9 @@ static DBusMessage * msg_method_handler(DBusMessage *message,
WPAS_DBUS_INTERFACE_MAX)) WPAS_DBUS_INTERFACE_MAX))
break; break;
method_dsc = method_dsc->next; method_dsc++;
} }
if (method_dsc == NULL) { if (method_dsc == NULL || method_dsc->dbus_method == NULL) {
wpa_printf(MSG_DEBUG, "no method handler for %s.%s on %s", wpa_printf(MSG_DEBUG, "no method handler for %s.%s on %s",
msg_interface, method, msg_interface, method,
dbus_message_get_path(message)); dbus_message_get_path(message));
@ -450,64 +449,9 @@ static DBusHandlerResult message_handler(DBusConnection *connection,
*/ */
void free_dbus_object_desc(struct wpa_dbus_object_desc *obj_dsc) void free_dbus_object_desc(struct wpa_dbus_object_desc *obj_dsc)
{ {
struct wpa_dbus_method_desc *method_dsc, *tmp_met_dsc;
struct wpa_dbus_signal_desc *signal_dsc, *tmp_sig_dsc;
struct wpa_dbus_property_desc *property_dsc, *tmp_prop_dsc;
int i;
if (!obj_dsc) if (!obj_dsc)
return; return;
/* free methods */
method_dsc = obj_dsc->methods;
while (method_dsc) {
tmp_met_dsc = method_dsc;
method_dsc = method_dsc->next;
os_free(tmp_met_dsc->dbus_interface);
os_free(tmp_met_dsc->dbus_method);
for (i = 0; i < tmp_met_dsc->args_num; i++) {
os_free(tmp_met_dsc->args[i].name);
os_free(tmp_met_dsc->args[i].type);
}
os_free(tmp_met_dsc);
}
/* free signals */
signal_dsc = obj_dsc->signals;
while (signal_dsc) {
tmp_sig_dsc = signal_dsc;
signal_dsc = signal_dsc->next;
os_free(tmp_sig_dsc->dbus_interface);
os_free(tmp_sig_dsc->dbus_signal);
for (i = 0; i < tmp_sig_dsc->args_num; i++) {
os_free(tmp_sig_dsc->args[i].name);
os_free(tmp_sig_dsc->args[i].type);
}
os_free(tmp_sig_dsc);
}
/* free properties */
property_dsc = obj_dsc->properties;
while (property_dsc) {
tmp_prop_dsc = property_dsc;
property_dsc = property_dsc->next;
os_free(tmp_prop_dsc->dbus_interface);
os_free(tmp_prop_dsc->dbus_property);
os_free(tmp_prop_dsc->type);
os_free(tmp_prop_dsc);
}
/* free handler's argument */ /* free handler's argument */
if (obj_dsc->user_data_free_func) if (obj_dsc->user_data_free_func)
obj_dsc->user_data_free_func(obj_dsc->user_data); obj_dsc->user_data_free_func(obj_dsc->user_data);
@ -644,300 +588,6 @@ int wpa_dbus_unregister_object_per_iface(
} }
/**
* wpa_dbus_method_register - Registers DBus method for given object
* @obj_dsc: Object description for which a method will be registered
* @dbus_interface: DBus interface under which method will be registered
* @dbus_method: a name the method will be registered with
* @method_handler: a function which will be called to handle this method call
* @args: method arguments list
* Returns: Zero on success and -1 on failure
*
* Registers DBus method under given name and interface for the object.
* Method calls will be handled with given handling function.
* Handler function is required to return a DBusMessage pointer which
* will be response to method call. Any method call before being handled
* must have registered appropriate handler by using this function.
*/
int wpa_dbus_method_register(struct wpa_dbus_object_desc *obj_dsc,
const char *dbus_interface,
const char *dbus_method,
WPADBusMethodHandler method_handler,
const struct wpa_dbus_argument args[])
{
struct wpa_dbus_method_desc *method_dsc = obj_dsc->methods;
struct wpa_dbus_method_desc *prev_desc;
int args_num = 0;
int i, error;
prev_desc = NULL;
while (method_dsc) {
prev_desc = method_dsc;
method_dsc = method_dsc->next;
}
/* count args */
if (args) {
while (args[args_num].name && args[args_num].type)
args_num++;
}
method_dsc = os_zalloc(sizeof(struct wpa_dbus_method_desc) +
args_num * sizeof(struct wpa_dbus_argument));
if (!method_dsc)
goto err;
if (prev_desc == NULL)
obj_dsc->methods = method_dsc;
else
prev_desc->next = method_dsc;
/* copy interface name */
method_dsc->dbus_interface = os_strdup(dbus_interface);
if (!method_dsc->dbus_interface)
goto err;
/* copy method name */
method_dsc->dbus_method = os_strdup(dbus_method);
if (!method_dsc->dbus_method)
goto err;
/* copy arguments */
error = 0;
method_dsc->args_num = args_num;
for (i = 0; i < args_num; i++) {
method_dsc->args[i].name = os_strdup(args[i].name);
if (!method_dsc->args[i].name) {
error = 1;
continue;
}
method_dsc->args[i].type = os_strdup(args[i].type);
if (!method_dsc->args[i].type) {
error = 1;
continue;
}
method_dsc->args[i].dir = args[i].dir;
}
if (error)
goto err;
method_dsc->method_handler = method_handler;
method_dsc->next = NULL;
return 0;
err:
wpa_printf(MSG_WARNING, "Failed to register dbus method %s in "
"interface %s", dbus_method, dbus_interface);
if (method_dsc) {
os_free(method_dsc->dbus_interface);
os_free(method_dsc->dbus_method);
for (i = 0; i < method_dsc->args_num; i++) {
os_free(method_dsc->args[i].name);
os_free(method_dsc->args[i].type);
}
if (prev_desc == NULL)
obj_dsc->methods = NULL;
else
prev_desc->next = NULL;
os_free(method_dsc);
}
return -1;
}
/**
* wpa_dbus_signal_register - Registers DBus signal for given object
* @obj_dsc: Object description for which a signal will be registered
* @dbus_interface: DBus interface under which signal will be registered
* @dbus_signal: a name the signal will be registered with
* @args: signal arguments list
* Returns: Zero on success and -1 on failure
*
* Registers DBus signal under given name and interface for the object.
* Signal registration is NOT required in order to send signals, but not
* registered signals will not be respected in introspection data
* therefore it is highly recommended to register every signal before
* using it.
*/
int wpa_dbus_signal_register(struct wpa_dbus_object_desc *obj_dsc,
const char *dbus_interface,
const char *dbus_signal,
const struct wpa_dbus_argument args[])
{
struct wpa_dbus_signal_desc *signal_dsc = obj_dsc->signals;
struct wpa_dbus_signal_desc *prev_desc;
int args_num = 0;
int i, error = 0;
prev_desc = NULL;
while (signal_dsc) {
prev_desc = signal_dsc;
signal_dsc = signal_dsc->next;
}
/* count args */
if (args) {
while (args[args_num].name && args[args_num].type)
args_num++;
}
signal_dsc = os_zalloc(sizeof(struct wpa_dbus_signal_desc) +
args_num * sizeof(struct wpa_dbus_argument));
if (!signal_dsc)
goto err;
if (prev_desc == NULL)
obj_dsc->signals = signal_dsc;
else
prev_desc->next = signal_dsc;
/* copy interface name */
signal_dsc->dbus_interface = os_strdup(dbus_interface);
if (!signal_dsc->dbus_interface)
goto err;
/* copy signal name */
signal_dsc->dbus_signal = os_strdup(dbus_signal);
if (!signal_dsc->dbus_signal)
goto err;
/* copy arguments */
signal_dsc->args_num = args_num;
for (i = 0; i < args_num; i++) {
signal_dsc->args[i].name = os_strdup(args[i].name);
if (!signal_dsc->args[i].name) {
error = 1;
continue;
}
signal_dsc->args[i].type = os_strdup(args[i].type);
if (!signal_dsc->args[i].type) {
error = 1;
continue;
}
}
if (error)
goto err;
signal_dsc->next = NULL;
return 0;
err:
wpa_printf(MSG_WARNING, "Failed to register dbus signal %s in "
"interface %s", dbus_signal, dbus_interface);
if (signal_dsc) {
os_free(signal_dsc->dbus_interface);
os_free(signal_dsc->dbus_signal);
for (i = 0; i < signal_dsc->args_num; i++) {
os_free(signal_dsc->args[i].name);
os_free(signal_dsc->args[i].type);
}
if (prev_desc == NULL)
obj_dsc->signals = NULL;
else
prev_desc->next = NULL;
os_free(signal_dsc);
}
return -1;
}
/**
* wpa_dbus_property_register - Registers DBus property for given object
* @obj_dsc: Object description for which a property will be registered
* @dbus_interface: DBus interface under which method will be registered
* @dbus_property: a name the property will be registered with
* @type: a property type signature in form of DBus type description
* @getter: a function called in order to get property value
* @setter: a function called in order to set property value
* @access: property access permissions specifier (R, W or RW)
* Returns: Zero on success and -1 on failure
*
* Registers DBus property under given name and interface for the object.
* Properties are set with giver setter function and get with getter.Getter
* or setter are required to return DBusMessage which is response to Set/Get
* method calls. Every property must be registered by this function before
* being used.
*/
int wpa_dbus_property_register(struct wpa_dbus_object_desc *obj_dsc,
const char *dbus_interface,
const char *dbus_property,
const char *type,
WPADBusPropertyAccessor getter,
WPADBusPropertyAccessor setter,
enum dbus_prop_access _access)
{
struct wpa_dbus_property_desc *property_dsc = obj_dsc->properties;
struct wpa_dbus_property_desc *prev_desc;
prev_desc = NULL;
while (property_dsc) {
prev_desc = property_dsc;
property_dsc = property_dsc->next;
}
property_dsc = os_zalloc(sizeof(struct wpa_dbus_property_desc));
if (!property_dsc)
goto err;
if (prev_desc == NULL)
obj_dsc->properties = property_dsc;
else
prev_desc->next = property_dsc;
/* copy interface name */
property_dsc->dbus_interface = os_strdup(dbus_interface);
if (!property_dsc->dbus_interface)
goto err;
/* copy property name */
property_dsc->dbus_property = os_strdup(dbus_property);
if (!property_dsc->dbus_property)
goto err;
/* copy property type */
property_dsc->type = os_strdup(type);
if (!property_dsc->type)
goto err;
property_dsc->getter = getter;
property_dsc->setter = setter;
property_dsc->access = _access;
property_dsc->next = NULL;
return 0;
err:
wpa_printf(MSG_WARNING, "Failed to register dbus property %s in "
"interface %s", dbus_property, dbus_interface);
if (property_dsc) {
os_free(property_dsc->dbus_interface);
os_free(property_dsc->dbus_property);
os_free(property_dsc->type);
if (prev_desc == NULL)
obj_dsc->properties = NULL;
else
prev_desc->next = NULL;
os_free(property_dsc);
}
return -1;
}
/** /**
* wpas_dbus_signal_network_added - Send a property changed signal * wpas_dbus_signal_network_added - Send a property changed signal
* @iface: dbus priv struct * @iface: dbus priv struct

View file

@ -29,9 +29,9 @@ struct wpa_dbus_object_desc {
DBusConnection *connection; DBusConnection *connection;
/* list of methods, properties and signals registered with object */ /* list of methods, properties and signals registered with object */
struct wpa_dbus_method_desc *methods; const struct wpa_dbus_method_desc *methods;
struct wpa_dbus_signal_desc *signals; const struct wpa_dbus_signal_desc *signals;
struct wpa_dbus_property_desc *properties; const struct wpa_dbus_property_desc *properties;
/* argument for method handlers and properties /* argument for method handlers and properties
* getter and setter functions */ * getter and setter functions */
@ -56,62 +56,44 @@ struct wpa_dbus_argument {
* struct wpa_dbus_method_desc - DBus method description * struct wpa_dbus_method_desc - DBus method description
*/ */
struct wpa_dbus_method_desc { struct wpa_dbus_method_desc {
/* pointer to next description in list */
struct wpa_dbus_method_desc *next;
/* method interface */
char *dbus_interface;
/* method name */ /* method name */
char *dbus_method; const char *dbus_method;
/* method interface */
const char *dbus_interface;
/* method handling function */ /* method handling function */
WPADBusMethodHandler method_handler; WPADBusMethodHandler method_handler;
/* number of method arguments */
int args_num;
/* array of arguments */ /* array of arguments */
struct wpa_dbus_argument args[]; struct wpa_dbus_argument args[3];
}; };
/** /**
* struct wpa_dbus_signal_desc - DBus signal description * struct wpa_dbus_signal_desc - DBus signal description
*/ */
struct wpa_dbus_signal_desc { struct wpa_dbus_signal_desc {
/* pointer to next description in list */
struct wpa_dbus_signal_desc *next;
/* signal interface */
char *dbus_interface;
/* signal name */ /* signal name */
char *dbus_signal; const char *dbus_signal;
/* signal interface */
/* number of signal arguments */ const char *dbus_interface;
int args_num;
/* array of arguments */ /* array of arguments */
struct wpa_dbus_argument args[0]; struct wpa_dbus_argument args[3];
}; };
/** /**
* struct wpa_dbus_property_desc - DBus property description * struct wpa_dbus_property_desc - DBus property description
*/ */
struct wpa_dbus_property_desc { struct wpa_dbus_property_desc {
/* pointer to next description in list */
struct wpa_dbus_property_desc *next;
/* property interface */
char *dbus_interface;
/* property name */ /* property name */
char *dbus_property; const char *dbus_property;
/* property interface */
const char *dbus_interface;
/* property type signature in DBus type notation */ /* property type signature in DBus type notation */
char *type; const char *type;
/* property access permissions */
enum dbus_prop_access access;
/* property getter function */ /* property getter function */
WPADBusPropertyAccessor getter; WPADBusPropertyAccessor getter;
/* property setter function */ /* property setter function */
WPADBusPropertyAccessor setter; WPADBusPropertyAccessor setter;
/* property access permissions */
enum dbus_prop_access access;
}; };
@ -141,25 +123,6 @@ int wpa_dbus_unregister_object_per_iface(
struct wpas_dbus_priv *ctrl_iface, struct wpas_dbus_priv *ctrl_iface,
const char *path); const char *path);
int wpa_dbus_method_register(struct wpa_dbus_object_desc *obj_dsc,
const char *dbus_interface,
const char *dbus_method,
WPADBusMethodHandler method_handler,
const struct wpa_dbus_argument args[]);
int wpa_dbus_signal_register(struct wpa_dbus_object_desc *obj_dsc,
const char *dbus_interface,
const char *dbus_signal,
const struct wpa_dbus_argument args[]);
int wpa_dbus_property_register(
struct wpa_dbus_object_desc *obj_dsc,
const char *dbus_interface, const char *dbus_property,
const char *type,
WPADBusPropertyAccessor getter,
WPADBusPropertyAccessor setter,
enum dbus_prop_access _access);
void wpa_dbus_signal_property_changed(struct wpas_dbus_priv *iface, void wpa_dbus_signal_property_changed(struct wpas_dbus_priv *iface,
WPADBusPropertyAccessor property_getter, WPADBusPropertyAccessor property_getter,
void *getter_arg, void *getter_arg,

View file

@ -67,17 +67,17 @@ static void add_arg(struct wpabuf *xml, const char *name, const char *type,
} }
static void add_entry(struct wpabuf *xml, char *type, char *name, int args_num, static void add_entry(struct wpabuf *xml, const char *type, const char *name,
struct wpa_dbus_argument *args, int include_dir) const struct wpa_dbus_argument *args, int include_dir)
{ {
int i; const struct wpa_dbus_argument *arg;
if (args_num == 0) {
if (args == NULL || args->name == NULL) {
wpabuf_printf(xml, "<%s name=\"%s\"/>", type, name); wpabuf_printf(xml, "<%s name=\"%s\"/>", type, name);
return; return;
} }
wpabuf_printf(xml, "<%s name=\"%s\">", type, name); wpabuf_printf(xml, "<%s name=\"%s\">", type, name);
for (i = 0; i < args_num; i++) { for (arg = args; arg && arg->name; arg++) {
struct wpa_dbus_argument *arg = &args[i];
add_arg(xml, arg->name, arg->type, add_arg(xml, arg->name, arg->type,
include_dir ? (arg->dir == ARG_IN ? "in" : "out") : include_dir ? (arg->dir == ARG_IN ? "in" : "out") :
NULL); NULL);
@ -87,7 +87,7 @@ static void add_entry(struct wpabuf *xml, char *type, char *name, int args_num,
static void add_property(struct wpabuf *xml, static void add_property(struct wpabuf *xml,
struct wpa_dbus_property_desc *dsc) const struct wpa_dbus_property_desc *dsc)
{ {
wpabuf_printf(xml, "<property name=\"%s\" type=\"%s\" access=\"%s\"/>", wpabuf_printf(xml, "<property name=\"%s\" type=\"%s\" access=\"%s\"/>",
dsc->dbus_property, dsc->type, dsc->dbus_property, dsc->type,
@ -96,40 +96,40 @@ static void add_property(struct wpabuf *xml,
} }
static void extract_interfaces_methods(struct dl_list *list, static void extract_interfaces_methods(
struct wpa_dbus_method_desc *methods) struct dl_list *list, const struct wpa_dbus_method_desc *methods)
{ {
struct wpa_dbus_method_desc *dsc; const struct wpa_dbus_method_desc *dsc;
struct interfaces *iface; struct interfaces *iface;
for (dsc = methods; dsc; dsc = dsc->next) { for (dsc = methods; dsc && dsc->dbus_method; dsc++) {
iface = add_interface(list, dsc->dbus_interface); iface = add_interface(list, dsc->dbus_interface);
if (iface) if (iface)
add_entry(iface->xml, "method", dsc->dbus_method, add_entry(iface->xml, "method", dsc->dbus_method,
dsc->args_num, dsc->args, 1); dsc->args, 1);
} }
} }
static void extract_interfaces_signals(struct dl_list *list, static void extract_interfaces_signals(
struct wpa_dbus_signal_desc *signals) struct dl_list *list, const struct wpa_dbus_signal_desc *signals)
{ {
struct wpa_dbus_signal_desc *dsc; const struct wpa_dbus_signal_desc *dsc;
struct interfaces *iface; struct interfaces *iface;
for (dsc = signals; dsc; dsc = dsc->next) { for (dsc = signals; dsc && dsc->dbus_signal; dsc++) {
iface = add_interface(list, dsc->dbus_interface); iface = add_interface(list, dsc->dbus_interface);
if (iface) if (iface)
add_entry(iface->xml, "signal", dsc->dbus_signal, add_entry(iface->xml, "signal", dsc->dbus_signal,
dsc->args_num, dsc->args, 0); dsc->args, 0);
} }
} }
static void extract_interfaces_properties( static void extract_interfaces_properties(
struct dl_list *list, struct wpa_dbus_property_desc *properties) struct dl_list *list, const struct wpa_dbus_property_desc *properties)
{ {
struct wpa_dbus_property_desc *dsc; const struct wpa_dbus_property_desc *dsc;
struct interfaces *iface; struct interfaces *iface;
for (dsc = properties; dsc; dsc = dsc->next) { for (dsc = properties; dsc && dsc->dbus_property; dsc++) {
iface = add_interface(list, dsc->dbus_interface); iface = add_interface(list, dsc->dbus_interface);
if (iface) if (iface)
add_property(iface->xml, dsc); add_property(iface->xml, dsc);