1 /******************************************************************
3 * Copyright 2015 Intel Corporation All Rights Reserved.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 ******************************************************************/
28 static char const TAG[] = "BLE_UTILS";
30 bool CAGetBlueZManagedObjectProxies(GList ** proxies,
31 char const * interface,
32 CALEContext * context,
33 CALEProxyFilter filter)
35 assert(interface != NULL);
36 assert(proxies != NULL);
37 assert(context != NULL);
40 Failure is only reported if an error occurred. An empty
41 returned list, for example, is not an error since it could
42 be updated at a later time when handling D-Bus signals related
43 to the given interface.
47 oc_mutex_lock(context->lock);
49 if (context->objects == NULL)
51 oc_mutex_unlock(context->lock);
56 Iterate over the objects to find those that implement the given
57 BlueZ interface and them to the given list.
59 for (GList * l = context->objects; l != NULL; l = l->next)
61 GDBusProxy * const proxy =
62 G_DBUS_PROXY(g_dbus_object_get_interface(
63 G_DBUS_OBJECT(l->data),
68 if (filter == NULL || filter(proxy))
71 Add the object information to the list.
73 Note that we prepend instead of append in this case
74 since it is more efficient to do so for linked lists
75 like the one used here.
77 *proxies = g_list_prepend(*proxies, proxy);
81 // Rejected by filter.
82 g_object_unref(proxy);
87 oc_mutex_unlock(context->lock);
92 GDBusProxy * CAGetBlueZInterfaceProxy(GVariant * tuple,
93 char const * interface,
94 GDBusObjectManager * object_manager)
97 The tuple is of the form "(oa{sv})".
99 The object path is first tuple element, and the properties the
100 second. Check if the given interface exists in the properties.
101 Return the object path (the dictionary item key) of the found
102 property (the dictionary item value).
104 GVariant * const props = g_variant_get_child_value(tuple, 1);
106 GVariant * const value =
107 g_variant_lookup_value(props, interface, NULL);
109 GDBusProxy * proxy = NULL;
114 A set of properties corresponding to the given D-Bus
115 interface was found. Create a proxy to the object that
116 implements that interface. Store that proxy, the D-Bus
117 object path and properties in the given list.
120 gchar const * path = NULL;
122 // The object path is the first tuple element.
123 g_variant_get_child(tuple, 0, "&o", &path);
126 Create a proxy to the object that implements the given
131 g_dbus_object_manager_get_interface(object_manager,
135 g_variant_unref(value);
138 g_variant_unref(props);
143 bool CASetBlueZObjectProperty(GDBusProxy * proxy,
144 char const * interface,
145 char const * property,
149 Only make the D-Bus call to set the property if we need to
152 GVariant * const cached_value =
153 g_dbus_proxy_get_cached_property(proxy, property);
155 if (cached_value != NULL)
157 bool const already_set = g_variant_equal(cached_value, value);
159 g_variant_unref(cached_value);
164 Ownership of the value GVariant was transferred when
165 this function was called. It won't be used since the
166 property with the same value is already set, so release
169 g_variant_unref(value);
176 Either the property wasn't previously set or it is being
177 changed. Set property on the given interface.
179 GError * error = NULL;
181 GVariant * const ret =
182 g_dbus_proxy_call_sync(proxy,
183 "org.freedesktop.DBus.Properties.Set",
184 g_variant_new("(ssv)",
188 G_DBUS_CALL_FLAGS_NONE,
189 -1, // timeout (default == -1),
197 "Attempt to set \"%s\" property for "
198 "\"%s\" interface failed.: %s",
199 property, interface, error->message);
206 g_variant_unref(ret);
211 GVariant * CAMakePropertyDictionary(
212 char const * interface_name,
213 CADBusSkeletonProperty const * properties,
217 Create a variant containing the proxy properties, of the form
221 GVariantBuilder builder;
223 // Create the inner (property) dictionary.
224 g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
226 CADBusSkeletonProperty const * const end =
229 for (CADBusSkeletonProperty const * prop = properties;
233 g_variant_builder_add(&builder, "{sv}", prop->name, prop->value);
236 GVariant * const props = g_variant_builder_end(&builder);
238 // Now create the dictionary with the above property dictionary
240 g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sa{sv}}"));
242 g_variant_builder_add(&builder, "{s@a{sv}}", interface_name, props);
244 return g_variant_builder_end(&builder);