00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "utils/includes.h"
00017
00018 #include "utils/common.h"
00019 #include "utils/eloop.h"
00020 #include "dbus_common.h"
00021 #include "dbus_common_i.h"
00022 #include "dbus_new.h"
00023 #include "dbus_new_helpers.h"
00024
00025
00035 static void recursive_iter_copy(DBusMessageIter *from, DBusMessageIter *to)
00036 {
00037
00038 char *subtype = NULL;
00039 int type;
00040
00041
00042 while ((type = dbus_message_iter_get_arg_type(from)) !=
00043 DBUS_TYPE_INVALID) {
00044
00045
00046 if (dbus_type_is_basic(type)) {
00047 if (dbus_type_is_fixed(type)) {
00048
00049
00050
00051
00052
00053 dbus_uint64_t v;
00054 dbus_message_iter_get_basic(from, &v);
00055 dbus_message_iter_append_basic(to, type, &v);
00056 } else {
00057 char *v;
00058 dbus_message_iter_get_basic(from, &v);
00059 dbus_message_iter_append_basic(to, type, &v);
00060 }
00061 } else {
00062
00063 DBusMessageIter write_subiter, read_subiter;
00064
00065 dbus_message_iter_recurse(from, &read_subiter);
00066
00067 if (type == DBUS_TYPE_VARIANT ||
00068 type == DBUS_TYPE_ARRAY) {
00069 subtype = dbus_message_iter_get_signature(
00070 &read_subiter);
00071 }
00072
00073 dbus_message_iter_open_container(to, type, subtype,
00074 &write_subiter);
00075
00076 recursive_iter_copy(&read_subiter, &write_subiter);
00077
00078 dbus_message_iter_close_container(to, &write_subiter);
00079 if (subtype)
00080 dbus_free(subtype);
00081 }
00082
00083 dbus_message_iter_next(from);
00084 }
00085 }
00086
00087
00088 static unsigned int fill_dict_with_properties(
00089 DBusMessageIter *dict_iter, const struct wpa_dbus_property_desc *props,
00090 const char *interface, const void *user_data)
00091 {
00092 DBusMessage *reply;
00093 DBusMessageIter entry_iter, ret_iter;
00094 unsigned int counter = 0;
00095 const struct wpa_dbus_property_desc *dsc;
00096
00097 for (dsc = props; dsc && dsc->dbus_property; dsc++) {
00098 if (!os_strncmp(dsc->dbus_interface, interface,
00099 WPAS_DBUS_INTERFACE_MAX) &&
00100 dsc->access != W && dsc->getter) {
00101 reply = dsc->getter(NULL, user_data);
00102 if (!reply)
00103 continue;
00104
00105 if (dbus_message_get_type(reply) ==
00106 DBUS_MESSAGE_TYPE_ERROR) {
00107 dbus_message_unref(reply);
00108 continue;
00109 }
00110
00111 dbus_message_iter_init(reply, &ret_iter);
00112
00113 dbus_message_iter_open_container(dict_iter,
00114 DBUS_TYPE_DICT_ENTRY,
00115 NULL, &entry_iter);
00116 dbus_message_iter_append_basic(
00117 &entry_iter, DBUS_TYPE_STRING,
00118 &dsc->dbus_property);
00119
00120 recursive_iter_copy(&ret_iter, &entry_iter);
00121
00122 dbus_message_iter_close_container(dict_iter,
00123 &entry_iter);
00124 dbus_message_unref(reply);
00125 counter++;
00126 }
00127 }
00128
00129 return counter;
00130 }
00131
00132
00145 static DBusMessage * get_all_properties(
00146 DBusMessage *message, char *interface,
00147 struct wpa_dbus_object_desc *obj_dsc)
00148 {
00149
00150 DBusMessage *reply = dbus_message_new_method_return(message);
00151 DBusMessageIter iter, dict_iter;
00152 int props_num;
00153
00154 dbus_message_iter_init_append(reply, &iter);
00155
00156 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
00157 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
00158 DBUS_TYPE_STRING_AS_STRING
00159 DBUS_TYPE_VARIANT_AS_STRING
00160 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
00161 &dict_iter);
00162
00163 props_num = fill_dict_with_properties(&dict_iter, obj_dsc->properties,
00164 interface, obj_dsc->user_data);
00165
00166 dbus_message_iter_close_container(&iter, &dict_iter);
00167
00168 if (props_num == 0) {
00169 dbus_message_unref(reply);
00170 reply = dbus_message_new_error(message,
00171 DBUS_ERROR_INVALID_ARGS,
00172 "No readable properties in "
00173 "this interface");
00174 }
00175
00176 return reply;
00177 }
00178
00179
00180 static int is_signature_correct(DBusMessage *message,
00181 const struct wpa_dbus_method_desc *method_dsc)
00182 {
00183
00184 #define MAX_SIG_LEN 256
00185 char registered_sig[MAX_SIG_LEN], *pos;
00186 const char *sig = dbus_message_get_signature(message);
00187 int ret;
00188 const struct wpa_dbus_argument *arg;
00189
00190 pos = registered_sig;
00191 *pos = '\0';
00192
00193 for (arg = method_dsc->args; arg && arg->name; arg++) {
00194 if (arg->dir == ARG_IN) {
00195 size_t blen = registered_sig + MAX_SIG_LEN - pos;
00196 ret = os_snprintf(pos, blen, "%s", arg->type);
00197 if (ret < 0 || (size_t) ret >= blen)
00198 return 0;
00199 pos += ret;
00200 }
00201 }
00202
00203 return !os_strncmp(registered_sig, sig, MAX_SIG_LEN);
00204 }
00205
00206
00207 static DBusMessage * properties_get_all(DBusMessage *message, char *interface,
00208 struct wpa_dbus_object_desc *obj_dsc)
00209 {
00210 if (os_strcmp(dbus_message_get_signature(message), "s") != 0)
00211 return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
00212 NULL);
00213
00214 return get_all_properties(message, interface, obj_dsc);
00215 }
00216
00217
00218 static DBusMessage * properties_get(DBusMessage *message,
00219 const struct wpa_dbus_property_desc *dsc,
00220 void *user_data)
00221 {
00222 if (os_strcmp(dbus_message_get_signature(message), "ss"))
00223 return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
00224 NULL);
00225
00226 if (dsc->access != W && dsc->getter)
00227 return dsc->getter(message, user_data);
00228
00229 return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
00230 "Property is write-only");
00231 }
00232
00233
00234 static DBusMessage * properties_set(DBusMessage *message,
00235 const struct wpa_dbus_property_desc *dsc,
00236 void *user_data)
00237 {
00238 if (os_strcmp(dbus_message_get_signature(message), "ssv"))
00239 return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
00240 NULL);
00241
00242 if (dsc->access != R && dsc->setter)
00243 return dsc->setter(message, user_data);
00244
00245 return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
00246 "Property is read-only");
00247 }
00248
00249
00250 static DBusMessage *
00251 properties_get_or_set(DBusMessage *message, DBusMessageIter *iter,
00252 char *interface,
00253 struct wpa_dbus_object_desc *obj_dsc)
00254 {
00255 const struct wpa_dbus_property_desc *property_dsc;
00256 char *property;
00257 const char *method;
00258
00259 method = dbus_message_get_member(message);
00260 property_dsc = obj_dsc->properties;
00261
00262
00263 if (!dbus_message_iter_next(iter) ||
00264 dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING) {
00265 return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
00266 NULL);
00267 }
00268 dbus_message_iter_get_basic(iter, &property);
00269
00270 while (property_dsc && property_dsc->dbus_property) {
00271
00272
00273 if (!os_strncmp(property_dsc->dbus_property, property,
00274 WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) &&
00275 !os_strncmp(property_dsc->dbus_interface, interface,
00276 WPAS_DBUS_INTERFACE_MAX))
00277 break;
00278
00279 property_dsc++;
00280 }
00281 if (property_dsc == NULL || property_dsc->dbus_property == NULL) {
00282 wpa_printf(MSG_DEBUG, "no property handler for %s.%s on %s",
00283 interface, property,
00284 dbus_message_get_path(message));
00285 return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
00286 "No such property");
00287 }
00288
00289 if (os_strncmp(WPA_DBUS_PROPERTIES_GET, method,
00290 WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) == 0)
00291 return properties_get(message, property_dsc,
00292 obj_dsc->user_data);
00293
00294 return properties_set(message, property_dsc, obj_dsc->user_data);
00295 }
00296
00297
00298 static DBusMessage * properties_handler(DBusMessage *message,
00299 struct wpa_dbus_object_desc *obj_dsc)
00300 {
00301 DBusMessageIter iter;
00302 char *interface;
00303 const char *method;
00304
00305 method = dbus_message_get_member(message);
00306 dbus_message_iter_init(message, &iter);
00307
00308 if (!os_strncmp(WPA_DBUS_PROPERTIES_GET, method,
00309 WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) ||
00310 !os_strncmp(WPA_DBUS_PROPERTIES_SET, method,
00311 WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) ||
00312 !os_strncmp(WPA_DBUS_PROPERTIES_GETALL, method,
00313 WPAS_DBUS_METHOD_SIGNAL_PROP_MAX)) {
00314
00315 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
00316 {
00317 return dbus_message_new_error(message,
00318 DBUS_ERROR_INVALID_ARGS,
00319 NULL);
00320 }
00321
00322 dbus_message_iter_get_basic(&iter, &interface);
00323
00324 if (!os_strncmp(WPA_DBUS_PROPERTIES_GETALL, method,
00325 WPAS_DBUS_METHOD_SIGNAL_PROP_MAX)) {
00326
00327 return properties_get_all(message, interface, obj_dsc);
00328 }
00329
00330 return properties_get_or_set(message, &iter, interface,
00331 obj_dsc);
00332 }
00333 return dbus_message_new_error(message, DBUS_ERROR_UNKNOWN_METHOD,
00334 NULL);
00335 }
00336
00337
00338 static DBusMessage * msg_method_handler(DBusMessage *message,
00339 struct wpa_dbus_object_desc *obj_dsc)
00340 {
00341 const struct wpa_dbus_method_desc *method_dsc = obj_dsc->methods;
00342 const char *method;
00343 const char *msg_interface;
00344
00345 method = dbus_message_get_member(message);
00346 msg_interface = dbus_message_get_interface(message);
00347
00348
00349 while (method_dsc && method_dsc->dbus_method) {
00350
00351 if (!os_strncmp(method_dsc->dbus_method, method,
00352 WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) &&
00353 !os_strncmp(method_dsc->dbus_interface, msg_interface,
00354 WPAS_DBUS_INTERFACE_MAX))
00355 break;
00356
00357 method_dsc++;
00358 }
00359 if (method_dsc == NULL || method_dsc->dbus_method == NULL) {
00360 wpa_printf(MSG_DEBUG, "no method handler for %s.%s on %s",
00361 msg_interface, method,
00362 dbus_message_get_path(message));
00363 return dbus_message_new_error(message,
00364 DBUS_ERROR_UNKNOWN_METHOD, NULL);
00365 }
00366
00367 if (!is_signature_correct(message, method_dsc)) {
00368 return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS,
00369 NULL);
00370 }
00371
00372 return method_dsc->method_handler(message,
00373 obj_dsc->user_data);
00374 }
00375
00376
00392 static DBusHandlerResult message_handler(DBusConnection *connection,
00393 DBusMessage *message, void *user_data)
00394 {
00395 struct wpa_dbus_object_desc *obj_dsc = user_data;
00396 const char *method;
00397 const char *path;
00398 const char *msg_interface;
00399 DBusMessage *reply;
00400
00401
00402 method = dbus_message_get_member(message);
00403 path = dbus_message_get_path(message);
00404 msg_interface = dbus_message_get_interface(message);
00405 if (!method || !path || !msg_interface)
00406 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00407
00408 wpa_printf(MSG_MSGDUMP, "dbus: %s.%s (%s)",
00409 msg_interface, method, path);
00410
00411
00412 if (!os_strncmp(WPA_DBUS_INTROSPECTION_METHOD, method,
00413 WPAS_DBUS_METHOD_SIGNAL_PROP_MAX) &&
00414 !os_strncmp(WPA_DBUS_INTROSPECTION_INTERFACE, msg_interface,
00415 WPAS_DBUS_INTERFACE_MAX)) {
00416 #ifdef CONFIG_CTRL_IFACE_DBUS_INTRO
00417 reply = wpa_dbus_introspect(message, obj_dsc);
00418 #else
00419 reply = dbus_message_new_error(
00420 message, DBUS_ERROR_UNKNOWN_METHOD,
00421 "wpa_supplicant was compiled without "
00422 "introspection support.");
00423 #endif
00424 } else if (!os_strncmp(WPA_DBUS_PROPERTIES_INTERFACE, msg_interface,
00425 WPAS_DBUS_INTERFACE_MAX)) {
00426
00427 reply = properties_handler(message, obj_dsc);
00428 } else {
00429 reply = msg_method_handler(message, obj_dsc);
00430 }
00431
00432
00433 if (!reply)
00434 reply = dbus_message_new_method_return(message);
00435 if (reply) {
00436 if (!dbus_message_get_no_reply(message))
00437 dbus_connection_send(connection, reply, NULL);
00438 dbus_message_unref(reply);
00439 }
00440
00441 wpa_dbus_flush_all_changed_properties(connection);
00442
00443 return DBUS_HANDLER_RESULT_HANDLED;
00444 }
00445
00446
00455 void free_dbus_object_desc(struct wpa_dbus_object_desc *obj_dsc)
00456 {
00457 if (!obj_dsc)
00458 return;
00459
00460
00461 if (obj_dsc->user_data_free_func)
00462 obj_dsc->user_data_free_func(obj_dsc->user_data);
00463
00464 os_free(obj_dsc->path);
00465 os_free(obj_dsc->prop_changed_flags);
00466 os_free(obj_dsc);
00467 }
00468
00469
00470 static void free_dbus_object_desc_cb(DBusConnection *connection, void *obj_dsc)
00471 {
00472 free_dbus_object_desc(obj_dsc);
00473 }
00474
00487 int wpa_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface,
00488 char *dbus_path, char *dbus_service,
00489 struct wpa_dbus_object_desc *obj_desc)
00490 {
00491 DBusError error;
00492 int ret = -1;
00493 DBusObjectPathVTable wpa_vtable = {
00494 &free_dbus_object_desc_cb, &message_handler,
00495 NULL, NULL, NULL, NULL
00496 };
00497
00498 obj_desc->connection = iface->con;
00499 obj_desc->path = os_strdup(dbus_path);
00500
00501
00502 if (!dbus_connection_register_object_path(iface->con,
00503 dbus_path, &wpa_vtable,
00504 obj_desc)) {
00505 wpa_printf(MSG_ERROR, "dbus: Could not set up message "
00506 "handler");
00507 return -1;
00508 }
00509
00510
00511 dbus_error_init(&error);
00512 switch (dbus_bus_request_name(iface->con, dbus_service,
00513 0, &error)) {
00514 case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
00515 ret = 0;
00516 break;
00517 case DBUS_REQUEST_NAME_REPLY_EXISTS:
00518 case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
00519 case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
00520 wpa_printf(MSG_ERROR, "dbus: Could not request service name: "
00521 "already registered");
00522 break;
00523 default:
00524 wpa_printf(MSG_ERROR, "dbus: Could not request service name: "
00525 "%s %s", error.name, error.message);
00526 break;
00527 }
00528 dbus_error_free(&error);
00529
00530 if (ret != 0)
00531 return -1;
00532
00533 wpa_printf(MSG_DEBUG, "Providing DBus service '%s'.", dbus_service);
00534
00535 return 0;
00536 }
00537
00538
00549 int wpa_dbus_register_object_per_iface(
00550 struct wpas_dbus_priv *ctrl_iface,
00551 const char *path, const char *ifname,
00552 struct wpa_dbus_object_desc *obj_desc)
00553 {
00554 DBusConnection *con;
00555
00556 DBusObjectPathVTable vtable = {
00557 &free_dbus_object_desc_cb, &message_handler,
00558 NULL, NULL, NULL, NULL
00559 };
00560
00561
00562 if (ctrl_iface == NULL)
00563 return 0;
00564
00565 con = ctrl_iface->con;
00566 obj_desc->connection = con;
00567 obj_desc->path = os_strdup(path);
00568
00569
00570 if (!dbus_connection_register_object_path(con, path, &vtable,
00571 obj_desc)) {
00572 wpa_printf(MSG_ERROR, "dbus: Could not set up message "
00573 "handler for interface %s object %s", ifname, path);
00574 return -1;
00575 }
00576
00577 return 0;
00578 }
00579
00580
00581 static void flush_object_timeout_handler(void *eloop_ctx, void *timeout_ctx);
00582
00583
00592 int wpa_dbus_unregister_object_per_iface(
00593 struct wpas_dbus_priv *ctrl_iface, const char *path)
00594 {
00595 DBusConnection *con = ctrl_iface->con;
00596 struct wpa_dbus_object_desc *obj_desc = NULL;
00597
00598 dbus_connection_get_object_path_data(con, path, (void **) &obj_desc);
00599 if (!obj_desc) {
00600 wpa_printf(MSG_ERROR, "dbus: %s: Could not obtain object's "
00601 "private data: %s", __func__, path);
00602 } else {
00603 eloop_cancel_timeout(flush_object_timeout_handler, con,
00604 obj_desc);
00605 }
00606
00607 if (!dbus_connection_unregister_object_path(con, path))
00608 return -1;
00609
00610 return 0;
00611 }
00612
00613
00614 static void put_changed_properties(const struct wpa_dbus_object_desc *obj_dsc,
00615 const char *interface,
00616 DBusMessageIter *dict_iter)
00617 {
00618 DBusMessage *getter_reply;
00619 DBusMessageIter prop_iter, entry_iter;
00620 const struct wpa_dbus_property_desc *dsc;
00621 int i;
00622
00623 for (dsc = obj_dsc->properties, i = 0; dsc && dsc->dbus_property;
00624 dsc++, i++) {
00625 if (obj_dsc->prop_changed_flags == NULL ||
00626 !obj_dsc->prop_changed_flags[i])
00627 continue;
00628 if (os_strcmp(dsc->dbus_interface, interface) != 0)
00629 continue;
00630 obj_dsc->prop_changed_flags[i] = 0;
00631
00632 getter_reply = dsc->getter(NULL, obj_dsc->user_data);
00633 if (!getter_reply ||
00634 dbus_message_get_type(getter_reply) ==
00635 DBUS_MESSAGE_TYPE_ERROR) {
00636 wpa_printf(MSG_ERROR, "dbus: %s: Cannot get new value "
00637 "of property %s", __func__,
00638 dsc->dbus_property);
00639 continue;
00640 }
00641
00642 if (!dbus_message_iter_init(getter_reply, &prop_iter) ||
00643 !dbus_message_iter_open_container(dict_iter,
00644 DBUS_TYPE_DICT_ENTRY,
00645 NULL, &entry_iter) ||
00646 !dbus_message_iter_append_basic(&entry_iter,
00647 DBUS_TYPE_STRING,
00648 &dsc->dbus_property))
00649 goto err;
00650
00651 recursive_iter_copy(&prop_iter, &entry_iter);
00652
00653 if (!dbus_message_iter_close_container(dict_iter, &entry_iter))
00654 goto err;
00655
00656 dbus_message_unref(getter_reply);
00657 }
00658
00659 return;
00660
00661 err:
00662 wpa_printf(MSG_ERROR, "dbus: %s: Cannot construct signal", __func__);
00663 }
00664
00665
00666 static void send_prop_changed_signal(
00667 DBusConnection *con, const char *path, const char *interface,
00668 const struct wpa_dbus_object_desc *obj_dsc)
00669 {
00670 DBusMessage *msg;
00671 DBusMessageIter signal_iter, dict_iter;
00672
00673 msg = dbus_message_new_signal(path, interface, "PropertiesChanged");
00674 if (msg == NULL)
00675 return;
00676
00677 dbus_message_iter_init_append(msg, &signal_iter);
00678
00679 if (!dbus_message_iter_open_container(&signal_iter, DBUS_TYPE_ARRAY,
00680 "{sv}", &dict_iter))
00681 goto err;
00682
00683 put_changed_properties(obj_dsc, interface, &dict_iter);
00684
00685 if (!dbus_message_iter_close_container(&signal_iter, &dict_iter))
00686 goto err;
00687
00688 dbus_connection_send(con, msg, NULL);
00689
00690 out:
00691 dbus_message_unref(msg);
00692 return;
00693
00694 err:
00695 wpa_printf(MSG_DEBUG, "dbus: %s: Failed to construct signal",
00696 __func__);
00697 goto out;
00698 }
00699
00700
00701 static void flush_object_timeout_handler(void *eloop_ctx, void *timeout_ctx)
00702 {
00703 DBusConnection *con = eloop_ctx;
00704 struct wpa_dbus_object_desc *obj_desc = timeout_ctx;
00705
00706 wpa_printf(MSG_DEBUG, "dbus: %s: Timeout - sending changed properties "
00707 "of object %s", __func__, obj_desc->path);
00708 wpa_dbus_flush_object_changed_properties(con, obj_desc->path);
00709 }
00710
00711
00712 static void recursive_flush_changed_properties(DBusConnection *con,
00713 const char *path)
00714 {
00715 char **objects = NULL;
00716 char subobj_path[WPAS_DBUS_OBJECT_PATH_MAX];
00717 int i;
00718
00719 wpa_dbus_flush_object_changed_properties(con, path);
00720
00721 if (!dbus_connection_list_registered(con, path, &objects))
00722 goto out;
00723
00724 for (i = 0; objects[i]; i++) {
00725 os_snprintf(subobj_path, WPAS_DBUS_OBJECT_PATH_MAX,
00726 "%s/%s", path, objects[i]);
00727 recursive_flush_changed_properties(con, subobj_path);
00728 }
00729
00730 out:
00731 dbus_free_string_array(objects);
00732 }
00733
00734
00742 void wpa_dbus_flush_all_changed_properties(DBusConnection *con)
00743 {
00744 recursive_flush_changed_properties(con, WPAS_DBUS_NEW_PATH);
00745 }
00746
00747
00765 void wpa_dbus_flush_object_changed_properties(DBusConnection *con,
00766 const char *path)
00767 {
00768 struct wpa_dbus_object_desc *obj_desc = NULL;
00769 const struct wpa_dbus_property_desc *dsc;
00770 int i;
00771
00772 dbus_connection_get_object_path_data(con, path, (void **) &obj_desc);
00773 if (!obj_desc)
00774 return;
00775 eloop_cancel_timeout(flush_object_timeout_handler, con, obj_desc);
00776
00777 dsc = obj_desc->properties;
00778 for (dsc = obj_desc->properties, i = 0; dsc && dsc->dbus_property;
00779 dsc++, i++) {
00780 if (obj_desc->prop_changed_flags == NULL ||
00781 !obj_desc->prop_changed_flags[i])
00782 continue;
00783 send_prop_changed_signal(con, path, dsc->dbus_interface,
00784 obj_desc);
00785 }
00786 }
00787
00788
00789 #define WPA_DBUS_SEND_PROP_CHANGED_TIMEOUT 5000
00790
00791
00805 void wpa_dbus_mark_property_changed(struct wpas_dbus_priv *iface,
00806 const char *path, const char *interface,
00807 const char *property)
00808 {
00809 struct wpa_dbus_object_desc *obj_desc = NULL;
00810 const struct wpa_dbus_property_desc *dsc;
00811 int i = 0;
00812
00813 if (iface == NULL)
00814 return;
00815
00816 dbus_connection_get_object_path_data(iface->con, path,
00817 (void **) &obj_desc);
00818 if (!obj_desc) {
00819 wpa_printf(MSG_ERROR, "dbus: wpa_dbus_property_changed: "
00820 "could not obtain object's private data: %s", path);
00821 return;
00822 }
00823
00824 for (dsc = obj_desc->properties; dsc && dsc->dbus_property; dsc++, i++)
00825 if (os_strcmp(property, dsc->dbus_property) == 0 &&
00826 os_strcmp(interface, dsc->dbus_interface) == 0) {
00827 if (obj_desc->prop_changed_flags)
00828 obj_desc->prop_changed_flags[i] = 1;
00829 break;
00830 }
00831
00832 if (!dsc || !dsc->dbus_property) {
00833 wpa_printf(MSG_ERROR, "dbus: wpa_dbus_property_changed: "
00834 "no property %s in object %s", property, path);
00835 return;
00836 }
00837
00838 if (!eloop_is_timeout_registered(flush_object_timeout_handler,
00839 iface->con, obj_desc->path)) {
00840 eloop_register_timeout(0, WPA_DBUS_SEND_PROP_CHANGED_TIMEOUT,
00841 flush_object_timeout_handler,
00842 iface->con, obj_desc);
00843 }
00844 }
00845
00846
00859 void wpa_dbus_get_object_properties(struct wpas_dbus_priv *iface,
00860 const char *path, const char *interface,
00861 DBusMessageIter *dict_iter)
00862 {
00863 struct wpa_dbus_object_desc *obj_desc = NULL;
00864
00865 dbus_connection_get_object_path_data(iface->con, path,
00866 (void **) &obj_desc);
00867 if (!obj_desc) {
00868 wpa_printf(MSG_ERROR, "dbus: wpa_dbus_get_object_properties: "
00869 "could not obtain object's private data: %s", path);
00870 return;
00871 }
00872
00873 fill_dict_with_properties(dict_iter, obj_desc->properties,
00874 interface, obj_desc->user_data);
00875 }