Initialize Tizen 2.3
[framework/api/bluetooth.git] / mobile / src / bluetooth-gatt.c
1 /*
2  * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdbool.h>
18 #include <dlog.h>
19 #include <bluetooth-api.h>
20
21 #include "bluetooth.h"
22 #include "bluetooth_private.h"
23
24 int bt_gatt_foreach_primary_services(const char *remote_address,
25                                 bt_gatt_primary_service_cb callback,
26                                 void *user_data)
27 {
28         int i;
29         int ret;
30         bool foreach_call = true;
31         bluetooth_device_address_t addr_hex = { {0,} };
32         bt_gatt_handle_info_t *prim_svc;
33
34         BT_CHECK_INIT_STATUS();
35         BT_CHECK_INPUT_PARAMETER(remote_address);
36         BT_CHECK_INPUT_PARAMETER(callback);
37
38         prim_svc = g_new0(bt_gatt_handle_info_t, 1);
39
40         _bt_convert_address_to_hex(&addr_hex, remote_address);
41
42         ret = _bt_get_error_code(bluetooth_gatt_get_primary_services(&addr_hex,
43                                                                 prim_svc));
44         if (ret != BT_ERROR_NONE) {
45                 BT_ERR("%s(0x%08x) : Failed to run function",
46                                         _bt_convert_error_to_string(ret), ret);
47                 g_free(prim_svc);
48                 return ret;
49         }
50
51         for (i = 0; i < prim_svc->count; i++) {
52                 if (prim_svc->handle[i] == NULL)
53                         continue;
54
55                 BT_DBG("handle: %s", prim_svc->handle[i]);
56
57                 if (foreach_call == true &&
58                     !callback((bt_gatt_attribute_h)prim_svc->handle[i], user_data)) {
59                         foreach_call = false;
60                 }
61
62                 /* Application should clone the handle using API in callback */
63                 /* bt_gatt_clone_attribute_handle */
64                 g_free(prim_svc->handle[i]);
65         }
66
67         g_free(prim_svc->handle);
68         g_free(prim_svc);
69
70         return ret;
71 }
72
73 int bt_gatt_discover_characteristics(bt_gatt_attribute_h service,
74                                 bt_gatt_characteristics_discovered_cb callback,
75                                 void *user_data)
76 {
77         int ret;
78
79         BT_CHECK_INIT_STATUS();
80         BT_CHECK_INPUT_PARAMETER(service);
81         BT_CHECK_INPUT_PARAMETER(callback);
82
83         ret = _bt_get_error_code(bluetooth_gatt_discover_service_characteristics((const char *)service));
84
85         if (ret != BT_ERROR_NONE) {
86                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
87         } else {
88                 _bt_set_cb(BT_EVENT_GATT_CHARACTERISTIC_DISCOVERED, callback, user_data);
89         }
90
91         return ret;
92 }
93
94 int bt_gatt_get_service_uuid(bt_gatt_attribute_h service, char **uuid)
95 {
96         int i;
97         int ret;
98         bt_gatt_service_property_t property;
99
100         BT_CHECK_INIT_STATUS();
101         BT_CHECK_INPUT_PARAMETER(service);
102
103         memset(&property, 0x00, sizeof(bt_gatt_service_property_t));
104
105         ret = _bt_get_error_code(bluetooth_gatt_get_service_property((const char *)service, &property));
106
107         if (ret != BT_ERROR_NONE) {
108                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
109         } else {
110                 *uuid = g_strdup(property.uuid);
111
112                 if (property.handle_info.count != 0 && property.handle_info.handle) {
113                         for (i = 0; i < property.handle_info.count; i++) {
114                                 g_free(property.handle_info.handle[i]);
115                         }
116                         g_free(property.handle_info.handle);
117                 }
118         }
119
120         return ret;
121 }
122
123 int bt_gatt_foreach_included_services(bt_gatt_attribute_h service,
124                                 bt_gatt_included_service_cb callback,
125                                 void *user_data)
126 {
127         int i;
128         int ret;
129         bool foreach_call = true;
130         bt_gatt_service_property_t property;
131
132         BT_CHECK_INIT_STATUS();
133         BT_CHECK_INPUT_PARAMETER(service);
134         BT_CHECK_INPUT_PARAMETER(callback);
135
136         memset(&property, 0x00, sizeof(bt_gatt_service_property_t));
137
138         ret = _bt_get_error_code(bluetooth_gatt_get_service_property((const char *)service, &property));
139
140         if (ret != BT_ERROR_NONE) {
141                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
142         } else {
143                 if (property.handle_info.count == 0 ||
144                      property.handle_info.handle == NULL) {
145                         return ret;
146                 }
147
148                 for (i = 0; i < property.handle_info.count; i++) {
149                         if (property.handle_info.handle[i] == NULL)
150                                 continue;
151
152                         if (foreach_call == true &&
153                             !callback((bt_gatt_attribute_h)property.handle_info.handle[i],
154                                         user_data)) {
155                                 foreach_call = false;
156                         }
157
158                         g_free(property.handle_info.handle[i]);
159                 }
160                 g_free(property.handle_info.handle);
161         }
162         return ret;
163 }
164
165 int bt_gatt_set_characteristic_changed_cb(bt_gatt_attribute_h service,
166                                 bt_gatt_characteristic_changed_cb callback,
167                                 void *user_data)
168 {
169         int ret;
170
171         BT_CHECK_INIT_STATUS();
172         BT_CHECK_INPUT_PARAMETER(service);
173         BT_CHECK_INPUT_PARAMETER(callback);
174
175         ret = _bt_get_error_code(bluetooth_gatt_watch_characteristics((const char *)service));
176
177         if (ret != BT_ERROR_NONE) {
178                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
179         } else {
180                 _bt_set_cb(BT_EVENT_GATT_VALUE_CHANGED, callback, user_data);
181         }
182
183         return ret;
184 }
185
186 int bt_gatt_unset_characteristic_changed_cb(bt_gatt_attribute_h service)
187 {
188         int ret;
189
190         BT_CHECK_INIT_STATUS();
191         BT_CHECK_INPUT_PARAMETER(service);
192
193         ret = _bt_get_error_code(bluetooth_gatt_unwatch_characteristics((const char *)service));
194
195         if (ret != BT_ERROR_NONE) {
196                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
197         } else {
198                 _bt_unset_cb(BT_EVENT_GATT_VALUE_CHANGED);
199         }
200
201         return ret;
202 }
203
204 int bt_gatt_get_characteristic_declaration(bt_gatt_attribute_h characteristic,
205                                 char **uuid, unsigned char **value,
206                                 int *value_length)
207 {
208         int ret;
209         bt_gatt_char_property_t property;
210
211         BT_CHECK_INIT_STATUS();
212         BT_CHECK_INPUT_PARAMETER(characteristic);
213
214         memset(&property, 0x00, sizeof(bt_gatt_char_property_t));
215
216         ret = _bt_get_error_code(bluetooth_gatt_get_characteristics_property((const char *)characteristic, &property));
217
218         if (ret != BT_ERROR_NONE) {
219                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
220         } else {
221                 if (property.uuid) {
222                         *uuid = g_strdup(property.uuid);
223                         g_free(property.uuid);
224                 }
225
226                 if (property.val && property.val_len != 0) {
227                         *value = g_memdup(property.val, property.val_len);
228                         *value_length = property.val_len;
229                         g_free(property.val);
230                 }
231
232                 g_free(property.name);
233
234         }
235
236         return ret;
237 }
238
239 int bt_gatt_set_characteristic_value(bt_gatt_attribute_h characteristic,
240                                 const unsigned char *value,
241                                 int value_length)
242 {
243         int ret;
244
245         BT_CHECK_INIT_STATUS();
246         BT_CHECK_INPUT_PARAMETER(characteristic);
247         BT_CHECK_INPUT_PARAMETER(value);
248
249         if (value_length <= 0)
250                 return BT_ERROR_INVALID_PARAMETER;
251
252         ret = _bt_get_error_code(bluetooth_gatt_set_characteristics_value((const char *)characteristic,
253                                                         (const guint8 *)value, value_length, 0));
254
255         if (ret != BT_ERROR_NONE) {
256                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
257         }
258
259         return ret;
260 }
261
262 int bt_gatt_set_characteristic_value_request(bt_gatt_attribute_h characteristic,
263                                 const unsigned char *value, int value_length,
264                                 unsigned char request, bt_gatt_characteristic_write_cb callback)
265 {
266         int ret;
267
268         BT_CHECK_INIT_STATUS();
269         BT_CHECK_INPUT_PARAMETER(characteristic);
270         BT_CHECK_INPUT_PARAMETER(value);
271
272         if (value_length <= 0)
273                 return BT_ERROR_INVALID_PARAMETER;
274
275         ret = _bt_get_error_code(bluetooth_gatt_set_characteristics_value((const char *)characteristic,
276                                                         (const guint8 *)value, value_length, request));
277
278         if (ret != BT_ERROR_NONE) {
279                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
280         } else {
281                 _bt_set_cb(BT_EVENT_GATT_WRITE_CHARACTERISTIC, callback, characteristic);
282         }
283
284         return ret;
285 }
286
287 int bt_gatt_clone_attribute_handle(bt_gatt_attribute_h *clone,
288                                 bt_gatt_attribute_h origin)
289 {
290         int error = BT_ERROR_NONE;
291
292         BT_CHECK_INIT_STATUS();
293         BT_CHECK_INPUT_PARAMETER(origin);
294
295         *clone = g_strdup((char *)origin);
296
297         return error;
298 }
299
300 int bt_gatt_destroy_attribute_handle(bt_gatt_attribute_h handle)
301 {
302         int error = BT_ERROR_NONE;
303
304         BT_CHECK_INIT_STATUS();
305         BT_CHECK_INPUT_PARAMETER(handle);
306
307         g_free(handle);
308
309         return error;
310 }
311
312 int bt_gatt_read_characteristic_value(bt_gatt_attribute_h characteristic,
313                 bt_gatt_characteristic_read_cb callback)
314 {
315         int ret;
316
317         BT_CHECK_INIT_STATUS();
318         BT_CHECK_INPUT_PARAMETER(characteristic);
319         BT_CHECK_INPUT_PARAMETER(callback);
320
321         ret = _bt_get_error_code(bluetooth_gatt_read_characteristic_value((const char *)characteristic));
322
323         if (ret != BT_ERROR_NONE) {
324                 BT_ERR("%s(0x%08x)", _bt_convert_error_to_string(ret), ret);
325         } else {
326                 _bt_set_cb(BT_EVENT_GATT_READ_CHARACTERISTIC, callback, NULL);
327         }
328
329         return ret;
330 }