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 ******************************************************************/
25 #include "cafragmentation.h"
27 #include "oic_malloc.h"
28 #include "oic_string.h"
37 static char const TAG[] = "BLE_CLIENT";
39 // ---------------------------------------------------------------------
41 // ---------------------------------------------------------------------
42 static bool CAGattClientServiceFilter(GDBusProxy * service)
45 On the client side, we only care about the GATT services on
46 remote devices. Ignore the locally created ones by checking for
47 the existence of the org.bluez.GattService1.Device property in
48 the service proxy. GATT services on remote devices will have
51 GVariant * const remote_device =
52 g_dbus_proxy_get_cached_property(service, "Device");
54 if (remote_device == NULL)
60 org.bluez.GattService1.Device property exists, meaning the
61 GATT service was advertised from a remote object.
63 g_object_unref(remote_device);
67 bool CAGattClientsInitialize(CALEContext * context)
70 Create a proxies to the org.bluez.GattService1 D-Bus objects that
71 will later be used to send requests and receive responses on the
74 GList * services = NULL;
76 CAGetBlueZManagedObjectProxies(&services,
77 BLUEZ_GATT_SERVICE_INTERFACE,
79 CAGattClientServiceFilter);
82 * @todo Is this really an error?
90 Map Bluetooth MAC address to OIC Transport Profile
93 GHashTable * const characteristic_map =
94 g_hash_table_new_full(g_str_hash,
99 char const * const address = NULL; // OICMalloc(...);
100 GDBusProxy * const client = NULL;
102 #if GLIB_CHECK_VERSION(2,40,0)
104 GLib hash table functions started returning a boolean result in
109 g_hash_table_insert(characteristic_map,
113 // An empty services list is NULL.
114 if (success && services != NULL)
116 ca_mutex_lock(context->lock);
117 context->characteristic_map = characteristic_map;
118 ca_mutex_unlock(context->lock);
124 bool CAGattClientsDestroy(CALEContext * context)
127 /* g_hash_table_destroy(...); */ // FIXME
131 // ---------------------------------------------------------------------
133 // ---------------------------------------------------------------------
135 * Send data to the GATT server through the given request
136 * @a characteristic proxy.
138 * @param[in] characteristic The D-Bus proxy of the request
139 * characteristic through which the
140 * @c WriteValue() method will be invoked.
141 * @param[in] data The byte array to be sent.
142 * @param[in] length The number of elements in the byte
145 static bool CAGattClientSendRequestData(GDBusProxy * characteristic,
146 CALEContext * context,
147 uint8_t const * data,
150 assert(context != NULL);
152 GVariant * const value =
153 g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE,
156 1); // sizeof(data[0]) == 1
158 GError * error = NULL;
160 GVariant * const ret =
161 g_dbus_proxy_call_sync(characteristic,
164 G_DBUS_CALL_FLAGS_NONE,
165 -1, // timeout (default == -1),
173 "[%p] WriteValue() call failed: %s",
179 ca_mutex_lock(context->lock);
181 if (context->on_client_error != NULL)
184 At this point endpoint and send data information is
187 context->on_client_error(NULL, // endpoint
193 ca_mutex_unlock(context->lock);
198 g_variant_unref(ret);
203 CAResult_t CAGattClientSendData(void const * method_info,
204 uint8_t const * data,
207 assert(method_info != NULL);
209 CAGattRequestInfo const * const info = method_info;
211 GDBusProxy * const characteristic =
212 G_DBUS_PROXY(info->characteristic_info);
214 return CAGattClientSendRequestData(characteristic,
220 CAResult_t CAGattClientSendDataToAll(void const * method_info,
221 uint8_t const * data,
224 assert(method_info != NULL);
226 CAResult_t result = CA_STATUS_OK;
228 CAGattRequestInfo const * const info = method_info;
230 for (GList const * l = info->characteristic_info;
231 l != NULL && result == CA_STATUS_OK;
234 GDBusProxy * const characteristic = G_DBUS_PROXY(l->data);
236 result = CAGattClientSendRequestData(characteristic,
245 // ---------------------------------------------------------------------
246 // GATT Response Receive
247 // ---------------------------------------------------------------------
248 void CAGattReceiveResponse(GDBusConnection * connection,
249 char const * sender_name,
250 char const * object_path,
251 char const * interface_name,
252 char const * signal_name,
253 GVariant * parameters,
259 (void)interface_name;
262 This handler is only trigged in a GATT client when receiving
263 data sent by a GATT server through a notification, e.g. such as
264 when a GATT server sent a response.
266 gsize fragment_len = 0;
267 gconstpointer const fragment =
268 g_variant_get_fixed_array(parameters,
270 1); // sizeof(guchar) == 1
272 CAGattRecvInfo * const info = user_data;
274 if (CAGattRecv(info, fragment, fragment_len))