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 ******************************************************************/
19 #include "descriptor.h"
21 #include "gatt_dbus.h"
26 #include "cagattservice.h"
32 static char const TAG[] = "BLE_DESCRIPTOR";
35 * Implementation of the @c org.bluez.GattDescriptor1.ReadValue()
38 * This function is implemented as a GDBus signal handler that returns
39 * a byte array containing the @c Value property of the GATT
42 * @param[in] object @c org.bluez.GattDescriptoror1 skeleton
43 * object associated with this method call.
44 * @param[in] invocation D-Bus method invocation related object used
45 * when sending results/errors asynchronously.
46 * @param[in] user_data Unused.
48 * @return @c TRUE to indicate that
49 * @c org.bluez.Descriptor.ReadValue()
50 * method is implemented.
52 static gboolean CAGattDescriptorReadValue(
53 GattDescriptor1 * object,
54 GDBusMethodInvocation * invocation,
59 * @todo The @c GattDescriptor1 object still owns the returned
60 * variant when using the below call. Should be we use
61 * @c gatt_descriptor1_dup_value() instead?
63 GVariant * const value = gatt_descriptor1_get_value(object);
65 gatt_descriptor1_complete_read_value(object, invocation, value);
71 * Initialize GATT descriptor fields.
73 * This function initializes the @c CAGattDescriptor object fields.
75 * @param[out] c Information about GATT characteristic
76 * to which the descriptor belongs.
77 * @param[in] connection D-Bus connection to the bus on which
78 * the descriptor will be exported.
79 * @param[in] s Information about GATT service
80 * information to which the descriptor
82 * @param[in] descriptor_path @c GattDescriptor1 object path for the
83 * user description descriptor.
84 * @param[in] value User description descriptor value,
85 * e.g. @c "OIC Node Request" or
86 * @c "OIC Node Response".
88 * @note This function does not allocate the @a descriptor object
89 * itself. The caller is responsible for allocating that
92 * @todo Too many parameters. Perhaps pass in a pointer to a struct
95 static bool CAGattDescriptorInitialize(CAGattCharacteristic * c,
96 GDBusConnection * connection,
98 char const * descriptor_path,
102 CAGattDescriptor * const d = &c->descriptor;
104 // Path of the form /org/iotivity/gatt/hci0/service0/char0/desc0.
106 g_strdup_printf("%s/%s", c->object_path, descriptor_path);
107 assert(g_variant_is_object_path(d->object_path));
109 d->descriptor = gatt_descriptor1_skeleton_new();
111 gatt_descriptor1_set_uuid(
113 CA_GATT_CHRC_USER_DESCRIPTION_DESC_UUID);
115 gatt_descriptor1_set_characteristic(d->descriptor,
118 gatt_descriptor1_set_value (d->descriptor,
119 g_variant_new_bytestring(value));
121 // Readable, no encryption, no authorization.
122 static char const * flags[] = { "read", NULL };
123 gatt_descriptor1_set_flags(d->descriptor, flags);
126 Connect the signal handler that implements the
127 orb.bluez.GattDescriptor1.ReadValue() method.
129 g_signal_connect(d->descriptor,
131 G_CALLBACK(CAGattDescriptorReadValue),
134 // Export the descriptor interface on the bus.
135 GError * error = NULL;
136 if (!g_dbus_interface_skeleton_export(
137 G_DBUS_INTERFACE_SKELETON(d->descriptor),
142 CAGattDescriptorDestroy(d);
146 "Unable to export D-Bus GATT descriptor "
158 bool CAGattRequestDescriptorInitialize(struct CAGattService * s,
159 GDBusConnection * connection)
161 CAGattCharacteristic * const c = &s->request_characteristic;
163 return CAGattDescriptorInitialize(c,
166 CA_GATT_REQUEST_USER_DESC_PATH,
167 CA_GATT_REQUEST_USER_DESCRIPTION);
170 bool CAGattResponseDescriptorInitialize(struct CAGattService * s,
171 GDBusConnection * connection)
173 CAGattCharacteristic * const c = &s->response_characteristic;
175 return CAGattDescriptorInitialize(c,
178 CA_GATT_RESPONSE_USER_DESC_PATH,
179 CA_GATT_RESPONSE_USER_DESCRIPTION);
182 void CAGattDescriptorDestroy(CAGattDescriptor * d)
184 assert(d != NULL); // As designed, d is always non-NULL.
186 g_clear_object(&d->descriptor);
188 g_free(d->object_path);
189 d->object_path = NULL;
192 GVariant * CAGattDescriptorGetProperties(GattDescriptor1 * descriptor)
195 * Create a variant containing the @c GattDescriptor1 properties,
196 * of the form @c a{sa{sv}}.
198 * @note We don't care about the "Value" property here since it is
199 * automatically made available by BlueZ on the client
204 Populate the property table, and create the variant to be
205 embedded in the results of the
206 org.freedesktop.Dbus.ObjectManager.GetManagedObjects() method
209 CADBusSkeletonProperty const properties[] = {
211 g_variant_new_string(
212 gatt_descriptor1_get_uuid(descriptor)) },
214 g_variant_new_object_path(
215 gatt_descriptor1_get_characteristic(descriptor)) },
218 gatt_descriptor1_get_flags(descriptor),
223 CAMakePropertyDictionary(
224 BLUEZ_GATT_DESCRIPTOR_INTERFACE,
226 sizeof(properties) / sizeof(properties[0]));