1a4d4d16a5125501cf73305d781ee5f7ce785034
[profile/ivi/neard.git] / src / bluetooth.c
1 /*
2  *
3  *  neard - Near Field Communication manager
4  *
5  *  Copyright (C) 2011  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <gdbus.h>
31
32 #include "near.h"
33
34 #define BLUEZ_SERVICE                   "org.bluez"
35 #define MANAGER_INTF                    BLUEZ_SERVICE ".Manager"
36 #define ADAPTER_INTF                    BLUEZ_SERVICE ".Adapter"
37 #define OOB_INTF                        BLUEZ_SERVICE ".OutOfBand"
38 #define DEFAULT_ADAPTER                 "DefaultAdapter"
39 #define ADAPTER_REMOVED                 "AdapterRemoved"
40 #define DEFAULT_ADAPTER_CHANGED         "DefaultAdapterChanged"
41 #define MANAGER_PATH                    "/"
42 #define OOB_AGENT                       "/org/neard/agent/neard_oob"
43
44 #define BT_NOINPUTOUTPUT                "NoInputNoOutput"
45 #define BT_DISPLAY_YESNO                "DisplayYesNo"
46
47 /* BT EIR list */
48 #define EIR_UUID128_ALL         0x07 /* 128-bit UUID, all listed */
49 #define EIR_NAME_SHORT          0x08 /* shortened local name */
50 #define EIR_NAME_COMPLETE       0x09 /* complete local name */
51
52 /* Specific OOB EIRs */
53 #define EIR_CLASS_OF_DEVICE     0x0D  /* class of device */
54 #define EIR_SP_HASH             0x0E  /* simple pairing hash C */
55 #define EIR_SP_RANDOMIZER       0x0F  /* simple pairing randomizer R */
56 /* Optional EIRs */
57 #define EIR_DEVICE_ID           0x10  /* device ID */
58 #define EIR_SECURITY_MGR_FLAGS  0x11  /* security manager flags */
59
60 #define EIR_SIZE_LEN            1
61 #define EIR_HEADER_LEN          (EIR_SIZE_LEN + 1)
62 #define BT_ADDRESS_SIZE         6
63 #define COD_SIZE                3
64 #define OOB_SP_SIZE             16
65
66 struct near_oob_data {
67         char *def_adapter;
68
69         char *bd_addr;          /* oob mandatory */
70
71         /* optional */
72         char *bt_name;                  /* short or long name */
73         uint8_t bt_name_len;
74         int class_of_device;            /* Class of device */
75         near_bool_t powered;
76         near_bool_t pairable;
77         near_bool_t discoverable;
78         uint8_t *uuids;
79         int uuids_len;
80
81         uint8_t *spair_hash;                    /* OOB hash Key */
82         uint8_t *spair_randomizer;              /* OOB randomizer key */
83         uint8_t authentication[OOB_SP_SIZE];    /* On BT 2.0 */
84         uint8_t security_manager_oob_flags;     /* see BT Core 4.0 */
85 };
86
87 static DBusConnection *bt_conn;
88 static struct near_oob_data bt_def_oob_data;
89
90 static int bt_do_pairing(struct near_oob_data *oob);
91
92 static void __bt_eir_free(struct near_oob_data *oob)
93 {
94         DBG("");
95
96         if (oob->def_adapter != NULL) {
97                 g_free(oob->def_adapter);
98                 oob->def_adapter = NULL;
99         }
100
101         if (oob->bd_addr != NULL) {
102                 g_free(oob->bd_addr);
103                 oob->bd_addr = NULL;
104         }
105
106         if (oob->bt_name != NULL) {
107                 g_free(oob->bt_name);
108                 oob->bt_name = NULL;
109         }
110
111         if (oob->spair_hash != NULL) {
112                 g_free(oob->spair_hash);
113                 oob->spair_hash = NULL;
114         }
115
116         if (oob->spair_randomizer != NULL) {
117                 g_free(oob->spair_randomizer);
118                 oob->spair_randomizer = NULL;
119         }
120
121
122 }
123
124 static void bt_eir_free(struct near_oob_data *oob)
125 {
126         __bt_eir_free(oob);
127
128         g_free(oob);
129 }
130
131 /* D-Bus helper functions */
132 static int bt_generic_call(DBusConnection *conn,
133                 struct near_oob_data *oob,              /* user data */
134                 const char *dest,                       /* method call */
135                 const char *path,
136                 const char *interface,
137                 const char *method,
138                 DBusPendingCallNotifyFunction bt_cb,    /* callback */
139                 int type, ...)                          /* params */
140 {
141         DBusMessage *msg;
142         DBusPendingCall *pending;
143         va_list args;
144         int err;
145
146         DBG("%s", method);
147
148         msg = dbus_message_new_method_call(dest, path, interface, method);
149
150         if (msg == NULL) {
151                 near_error("Unable to allocate new D-Bus %s message", method);
152                 err = -ENOMEM;
153         }
154
155         va_start(args, type);
156
157         if (!dbus_message_append_args_valist(msg, type, args)) {
158                 va_end(args);
159                 err = -EIO;
160                 goto error_done;
161         }
162         va_end(args);
163
164         if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) {
165                 near_error("Sending %s failed", method);
166                 err = -EIO;
167                 goto error_done;
168         }
169
170         if (pending == NULL) {
171                 near_error("D-Bus connection not available");
172                 err = -EIO;
173                 goto error_done;
174         }
175
176         /* Prepare for notification */
177         dbus_pending_call_set_notify(pending, bt_cb, oob, NULL);
178         err = 0 ;
179
180 error_done:
181         dbus_message_unref(msg);
182         return err;
183 }
184
185 static void bt_create_paired_device_cb(DBusPendingCall *pending,
186                                         void *user_data)
187 {
188         DBusMessage *reply;
189         DBusError   error;
190         struct near_oob_data *oob = user_data;
191
192         DBG("");
193
194         reply = dbus_pending_call_steal_reply(pending);
195         if (reply == NULL)
196                 return;
197
198         dbus_error_init(&error);
199
200         if (dbus_set_error_from_message(&error, reply)) {
201                 near_error("%s", error.message);
202                 dbus_error_free(&error);
203                 goto cb_done;
204         }
205
206         near_info("Pairing done successfully !");
207
208 cb_done:
209         /* task completed - clean memory*/
210         bt_eir_free(oob);
211
212         dbus_message_unref(reply);
213         dbus_pending_call_unref(pending);
214
215         return;
216 }
217
218 static int bt_create_paired_device(DBusConnection *conn,
219                                 struct near_oob_data *oob,
220                                 const char *capabilities)
221 {
222         const char *agent_path = OOB_AGENT;
223
224         return bt_generic_call(bt_conn, oob, BLUEZ_SERVICE,
225                         oob->def_adapter, ADAPTER_INTF, "CreatePairedDevice",
226                         bt_create_paired_device_cb,
227                         /* params */
228                         DBUS_TYPE_STRING, &oob->bd_addr,
229                         DBUS_TYPE_OBJECT_PATH, &agent_path,
230                         DBUS_TYPE_STRING, &capabilities,
231                         DBUS_TYPE_INVALID);
232
233 }
234
235 static void bt_oob_add_remote_data_cb(DBusPendingCall *pending, void *user_data)
236 {
237         DBusMessage *reply;
238         DBusError   error;
239         struct near_oob_data *oob = user_data;
240
241         DBG("");
242
243         reply = dbus_pending_call_steal_reply(pending);
244         if (reply == NULL)
245                 return;
246
247         dbus_error_init(&error);
248
249         if (dbus_set_error_from_message(&error, reply))
250                 goto cb_fail;
251
252         near_info("OOB data added");
253
254         dbus_message_unref(reply);
255         dbus_pending_call_unref(pending);
256
257         /* Jump to the next: Pairing !!!*/
258         DBG("Try to pair devices...");
259         bt_create_paired_device(bt_conn, oob, BT_DISPLAY_YESNO);
260         return;
261
262 cb_fail:
263         near_error("%s", error.message);
264         dbus_error_free(&error);
265
266         bt_eir_free(oob);
267
268         dbus_message_unref(reply);
269         dbus_pending_call_unref(pending);
270
271         return;
272 }
273
274 static int bt_oob_add_remote_data(DBusConnection *conn,
275                                 struct near_oob_data *oob)
276 {
277         int16_t hash_len = 16;
278         int16_t rdm_len = 16;
279
280         return bt_generic_call(bt_conn, oob, BLUEZ_SERVICE,
281                         oob->def_adapter, OOB_INTF, "AddRemoteData",
282                         bt_oob_add_remote_data_cb,
283                         /* params */
284                         DBUS_TYPE_STRING, &oob->bd_addr,
285                         DBUS_TYPE_ARRAY,
286                                 DBUS_TYPE_BYTE, &oob->spair_hash, hash_len,
287                         DBUS_TYPE_ARRAY,
288                                 DBUS_TYPE_BYTE, &oob->spair_randomizer, rdm_len,
289                         DBUS_TYPE_INVALID);
290 }
291
292 /* Pairing: JustWorks or OOB  */
293 static int bt_do_pairing(struct near_oob_data *oob)
294 {
295         int err = 0;
296
297         DBG("%s", oob->bd_addr);
298
299         /* Is this a *real* oob pairing or a "JustWork" */
300         if ((oob->spair_hash) && (oob->spair_randomizer))
301                 err = bt_oob_add_remote_data(bt_conn, oob);
302         else
303                 err = bt_create_paired_device(bt_conn, oob,
304                                 BT_NOINPUTOUTPUT);
305
306         if (err < 0)
307                 near_error("Pairing failed. Err[%d]", err);
308
309         return err;
310 }
311
312 /*
313  */
314 static int extract_properties(DBusMessage *reply,
315                 struct near_oob_data *oob)
316 {
317         char *data = NULL;
318         int idata;
319         int i, j;
320
321         DBusMessageIter array, dict;
322
323         if (dbus_message_iter_init(reply, &array) == FALSE)
324                 return -1;
325
326         if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY)
327                 return -1;
328
329         dbus_message_iter_recurse(&array, &dict);
330
331         while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
332                 DBusMessageIter entry, value;
333                 const char *key;
334
335                 dbus_message_iter_recurse(&dict, &entry);
336                 dbus_message_iter_get_basic(&entry, &key);
337
338                 dbus_message_iter_next(&entry);
339                 dbus_message_iter_recurse(&entry, &value);
340
341                 if (g_str_equal(key, "Address") == TRUE) {
342                         dbus_message_iter_get_basic(&value, &data);
343
344                         /* Now, fill the local struct */
345                         oob->bd_addr = g_try_malloc0(BT_ADDRESS_SIZE);
346                         if (oob->bd_addr == NULL)
347                                 return -ENOMEM;
348
349                         /* Address is like: "ff:ee:dd:cc:bb:aa" */
350                         for (i = 5, j = 0 ; i >= 0; i--, j += 3)
351                                 oob->bd_addr[i] = strtol(data + j, NULL, 16);
352                         DBG("local address: %s", data);
353
354                 } else if (g_str_equal(key, "Name") == TRUE) {
355                         dbus_message_iter_get_basic(&value, &data);
356                         oob->bt_name = g_strdup(data);
357                         if (oob->bt_name != NULL) {
358                                 oob->bt_name_len = strlen(oob->bt_name);
359                                 DBG("local name: %s", oob->bt_name);
360                         }
361
362                 } else if (g_str_equal(key, "Class") == TRUE) {
363                         dbus_message_iter_get_basic(&value, &idata);
364                         oob->class_of_device = idata;
365
366                 } else if (g_str_equal(key, "Powered") == TRUE) {
367                         dbus_message_iter_get_basic(&value, &idata);
368                         oob->powered = idata;
369
370                 } else if (g_str_equal(key, "Discoverable") == TRUE) {
371                         dbus_message_iter_get_basic(&value, &idata);
372                         oob->discoverable = idata;
373
374                 } else if (g_str_equal(key, "Pairable") == TRUE) {
375                         dbus_message_iter_get_basic(&value, &idata);
376                         oob->pairable = idata;
377
378                 } else if (g_str_equal(key, "UUIDs") == TRUE) {
379                         oob->uuids_len = sizeof(value);
380                         oob->uuids = g_try_malloc0(oob->uuids_len);
381                         if (oob->uuids == NULL)
382                                 return -ENOMEM;
383                         memcpy(oob->uuids, &value, oob->uuids_len);
384                 }
385
386                 dbus_message_iter_next(&dict);
387         }
388
389         return 0;
390 }
391
392 static int bt_parse_properties(DBusMessage *reply, void *user_data)
393 {
394         struct near_oob_data *bt_props = user_data;
395
396         DBG("");
397
398         /* Free datas */
399         g_free(bt_props->bd_addr);
400         g_free(bt_props->bt_name);
401
402         /* Grab properties from dbus */
403         if (extract_properties(reply, bt_props) < 0)
404                 goto fail;
405
406         return 0;
407
408 fail:
409         g_free(bt_props->bd_addr);
410         bt_props->bd_addr = NULL;
411
412         g_free(bt_props->bt_name);
413         bt_props->bt_name = NULL;
414
415         return -ENOMEM;
416 }
417
418
419 /* Get default local adapter properties */
420 static void bt_get_properties_cb(DBusPendingCall *pending, void *user_data)
421 {
422         struct near_oob_data *bt_props = user_data;
423         DBusMessage *reply;
424         DBusError   error;
425         int err;
426
427         DBG("");
428
429         reply = dbus_pending_call_steal_reply(pending);
430         if (reply == NULL)
431                 return;
432
433         dbus_error_init(&error);
434
435         if (dbus_set_error_from_message(&error, reply))
436                 goto cb_fail;
437
438         err = bt_parse_properties(reply, bt_props);
439         if (err < 0)
440                 near_error("Problem parsing local properties %d", err);
441         else
442                 DBG("Get Properties complete: %s", bt_props->def_adapter);
443
444         /* clean */
445         dbus_message_unref(reply);
446         dbus_pending_call_unref(pending);
447         return;
448
449 cb_fail:
450         near_error("%s", error.message);
451         dbus_error_free(&error);
452
453         dbus_message_unref(reply);
454         dbus_pending_call_unref(pending);
455
456         return;
457 }
458
459 static void bt_get_default_adapter_cb(DBusPendingCall *pending, void *user_data)
460 {
461         struct near_oob_data *bt_props = user_data;
462         DBusMessage *reply;
463         DBusError   error;
464         gchar *path;
465
466         DBG("");
467
468         reply = dbus_pending_call_steal_reply(pending);
469         if (reply == NULL)
470                 return;
471
472         dbus_error_init(&error);
473
474         if (dbus_set_error_from_message(&error, reply))
475                 goto cb_fail;
476
477         if (dbus_message_get_args(reply, NULL, DBUS_TYPE_OBJECT_PATH,
478                                         &path, DBUS_TYPE_INVALID) == FALSE)
479                 goto cb_fail;
480
481         /* Save the default adapter */
482         bt_props->def_adapter = g_strdup(path);
483         DBG("Using default adapter %s", bt_props->def_adapter);
484
485         /* clean */
486         dbus_message_unref(reply);
487         dbus_pending_call_unref(pending);
488
489         /* Jump on getAdapterProperties */
490         bt_generic_call(bt_conn, bt_props,
491                         BLUEZ_SERVICE,
492                         bt_props->def_adapter,
493                         ADAPTER_INTF, "GetProperties",
494                         bt_get_properties_cb,
495                         DBUS_TYPE_INVALID);
496         return;
497
498 cb_fail:
499         near_error("%s", error.message);
500         dbus_error_free(&error);
501
502         dbus_message_unref(reply);
503         dbus_pending_call_unref(pending);
504
505         return;
506 }
507
508 static int bt_refresh_adapter_props(DBusConnection *conn, void *user_data)
509 {
510         DBG("%p %p", conn, user_data);
511
512         return bt_generic_call(conn, user_data,
513                         BLUEZ_SERVICE,
514                         MANAGER_PATH, MANAGER_INTF,
515                         DEFAULT_ADAPTER,
516                         bt_get_default_adapter_cb,
517                         DBUS_TYPE_INVALID);
518 }
519
520 /* Parse and fill the bluetooth oob information block */
521 static void bt_parse_eir(uint8_t *eir_data, uint16_t eir_data_len,
522                                                 struct near_oob_data *oob)
523 {
524         char *tmp;
525         uint16_t len = 0;
526
527         DBG("total len: %u", eir_data_len);
528
529         while (len < eir_data_len - 1) {
530                 uint8_t eir_len = eir_data[0];  /* EIR field length */
531                 uint8_t eir_code;               /* EIR field type*/
532                 uint8_t data_len;               /* EIR data length */
533                 uint8_t *data;
534
535                 /* check for early termination */
536                 if (eir_len == 0)
537                         break;
538
539                 len += eir_len + 1;
540
541                 /* Do not continue EIR Data parsing if got incorrect length */
542                 if (len > eir_data_len)
543                         break;
544
545                 data_len = eir_len - 1;
546
547                 eir_code = eir_data[1]; /* EIR code */
548                 data = &eir_data[2];
549
550                 DBG("type 0x%.2X data_len %u", eir_code, data_len);
551
552                 switch (eir_code) {
553                 case EIR_NAME_SHORT:
554                 case EIR_NAME_COMPLETE:
555                         oob->bt_name = g_try_malloc0(data_len + 1); /* eos */
556                         if (oob->bt_name) {
557                                 oob->bt_name_len = data_len;
558                                 memcpy(oob->bt_name, data, oob->bt_name_len);
559                                 oob->bt_name[data_len] = 0;     /* end str*/
560                         }
561                         break;
562
563                 case EIR_CLASS_OF_DEVICE:
564                         tmp = g_strdup_printf("%02X%02X%02X",
565                                         *data, *(data + 1), *(data + 2));
566                         if (tmp != NULL)
567                                 oob->class_of_device = strtol(tmp, NULL, 16);
568                         g_free(tmp);
569                         break;
570
571                 case EIR_SP_HASH:
572                         oob->spair_hash = g_try_malloc0(OOB_SP_SIZE);
573                         if (oob->spair_hash)
574                                 memcpy(oob->spair_hash, data, OOB_SP_SIZE);
575                         break;
576
577                 case EIR_SP_RANDOMIZER:
578                         oob->spair_randomizer = g_try_malloc0(OOB_SP_SIZE);
579                         if (oob->spair_randomizer)
580                                 memcpy(oob->spair_randomizer,
581                                                 data, OOB_SP_SIZE);
582                         break;
583
584                 case EIR_SECURITY_MGR_FLAGS:
585                         oob->security_manager_oob_flags = *data;
586                         break;
587
588                 case EIR_UUID128_ALL:
589                         /* TODO: Process uuids128
590                          * */
591                         break;
592
593                 default:        /* ignore and skip */
594                         near_error("Unknown EIR x%02x (len: %d)", eir_code,
595                                                                 eir_len);
596                         break;
597                 }
598                 /* Next eir */
599                 eir_data += eir_len + 1;
600         }
601 }
602
603 /*
604  * Because of some "old" implementation, "version" will help
605  * to determine the record data structure.
606  * Some specifications are proprietary (eg. "short mode")
607  * and are not fully documented.
608  */
609 int __near_bluetooth_parse_oob_record(uint8_t version, uint8_t *bt_data,
610                 near_bool_t pair)
611 {
612         struct near_oob_data *oob;
613         uint16_t bt_oob_data_size;
614         uint8_t *ptr = bt_data;
615         uint8_t marker;
616         char *tmp;
617
618         DBG("");
619
620         oob = g_try_malloc0(sizeof(struct near_oob_data));
621
622         if (version == BT_MIME_V2_1) {
623                 /* Total OOB data size (including size bytes)*/
624                 bt_oob_data_size = *((uint16_t *)(bt_data));
625                 bt_oob_data_size -= 2 ; /* remove oob datas size len */
626
627                 /* First item: BD_ADDR (mandatory) */
628                 ptr = &bt_data[2];
629                 oob->bd_addr = g_strdup_printf("%02X:%02X:%02X:%02X:%02X:%02X",
630                                 ptr[5], ptr[4], ptr[3], ptr[2], ptr[1], ptr[0]);
631
632                 /* Skip to the next element (optional) */
633                 ptr += BT_ADDRESS_SIZE;
634                 bt_oob_data_size -= BT_ADDRESS_SIZE ;
635
636                 if (bt_oob_data_size)
637                         bt_parse_eir(ptr, bt_oob_data_size, oob);
638         } else if (version == BT_MIME_V2_0) {
639                 marker = *ptr++;        /* could be '$' */
640
641                 oob->bd_addr = g_strdup_printf(
642                                 "%02X:%02X:%02X:%02X:%02X:%02X",
643                                 ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
644                 ptr = ptr + BT_ADDRESS_SIZE;
645
646                 /* Class of device */
647                 tmp = g_strdup_printf("%02X%02X%02X",
648                                 *ptr, *(ptr + 1), *(ptr + 2));
649                 if (tmp != NULL)
650                         oob->class_of_device = strtol(tmp, NULL, 16);
651                 g_free(tmp);
652
653                 ptr = ptr + 3;
654
655                 /* "Short mode" seems to use a 4 bytes code
656                  * instead of 16 bytes...
657                  */
658                 if (marker == '$') {   /* Short NFC */
659                         memcpy(oob->authentication, ptr, 4);
660                         ptr = ptr + 4;
661                 } else {
662                         memcpy(oob->authentication, ptr, 16);
663                         ptr = ptr + 16;
664                 }
665
666                 /* get the device name */
667                 oob->bt_name_len = *ptr++;
668                 oob->bt_name = g_try_malloc0(oob->bt_name_len+1);
669                 if (oob->bt_name) {
670                         memcpy(oob->bt_name, ptr, oob->bt_name_len);
671                         oob->bt_name[oob->bt_name_len+1] = 0;
672                 }
673                 ptr = ptr + oob->bt_name_len;
674         } else {
675                 return -EINVAL;
676         }
677
678         if (pair == FALSE)
679                 return 0;
680
681         /* check and get the default adapter */
682         oob->def_adapter = g_strdup(bt_def_oob_data.def_adapter);
683         if (oob->bt_name == NULL) {
684                 near_error("bt_get_default_adapter failed");
685                 bt_eir_free(oob);
686                 return -EIO;
687         }
688
689         return  bt_do_pairing(oob);
690 }
691
692 int __near_bluetooth_pair(void *data)
693 {
694         struct near_oob_data *oob = data;
695
696         /* check and get the default adapter */
697         oob->def_adapter = g_strdup(bt_def_oob_data.def_adapter);
698         if (oob->bt_name == NULL) {
699                 near_error("bt_get_default_adapter failed: %d", -EIO);
700                 bt_eir_free(oob);
701                 return -EIO;
702         }
703
704         return bt_do_pairing(oob);
705 }
706
707 /* This function is synchronous as oob datas change on each session */
708 static int bt_sync_oob_readlocaldata(DBusConnection *conn, char *adapter_path,
709                 char *spair_hash,
710                 char *spair_randomizer)
711 {
712         DBusMessage *message, *reply;
713         DBusError error;
714         int hash_len, rndm_len;
715
716         message = dbus_message_new_method_call(BLUEZ_SERVICE, adapter_path,
717                         OOB_INTF, "ReadLocalData");
718         if (!message)
719                 return 0;
720
721         dbus_error_init(&error);
722
723         reply = dbus_connection_send_with_reply_and_block(conn,
724                         message, -1, &error);
725
726         dbus_message_unref(message);
727
728         if (!reply) {
729                 if (dbus_error_is_set(&error) == TRUE) {
730                         near_error("%s", error.message);
731                         dbus_error_free(&error);
732                 } else {
733                         near_error("Failed to set property");
734                 }
735                 return 0;
736         }
737
738         if (dbus_message_get_args(reply, NULL,
739                         DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, spair_hash, &hash_len,
740                         DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
741                                                 spair_randomizer, &rndm_len,
742                         DBUS_TYPE_INVALID) == FALSE)
743                 goto done;
744
745         if ((hash_len != OOB_SP_SIZE) || (rndm_len != OOB_SP_SIZE)) {
746                 DBG("no OOB data found !");
747                 goto done;
748         }
749
750         dbus_message_unref(reply);
751         DBG("OOB data found");
752         return hash_len;
753
754 done:
755         dbus_message_unref(reply);
756         return 0;
757 }
758
759 /*
760  * External API to get bt properties
761  * Prepare a "real" oob datas block
762  * */
763 uint8_t *__near_bluetooth_local_get_properties(int *bt_data_len)
764 {
765         uint8_t *bt_oob_block = NULL;
766         uint16_t bt_oob_block_size = 0;
767         int max_block_size;
768         uint8_t offset;
769
770         char hash[OOB_SP_SIZE];
771         char random[OOB_SP_SIZE];
772
773         /* Check adapter datas */
774         if (bt_def_oob_data.def_adapter == NULL) {
775                 near_error("No bt adapter info");
776                 goto fail;
777         }
778
779         /* Prepare the BT block */
780         max_block_size = sizeof(uint16_t) +             /* stored oob size */
781                         BT_ADDRESS_SIZE +
782                         EIR_HEADER_LEN + bt_def_oob_data.bt_name_len +
783                         EIR_HEADER_LEN + COD_SIZE +     /* class */
784                         EIR_HEADER_LEN + OOB_SP_SIZE +  /* oob hash */
785                         EIR_HEADER_LEN + OOB_SP_SIZE;   /* oob random */
786
787
788         bt_oob_block_size = sizeof(uint16_t)    /* stored oob size */
789                         + BT_ADDRESS_SIZE;      /* device address */
790
791         bt_oob_block = g_try_malloc0(max_block_size);
792         if (bt_oob_block == NULL)
793                 goto fail;
794         offset = sizeof(uint16_t); /* Skip size...will be filled later */
795
796         /* Now prepare data frame */
797         memcpy(bt_oob_block + offset, bt_def_oob_data.bd_addr, BT_ADDRESS_SIZE);
798         offset += BT_ADDRESS_SIZE;
799
800         /* bt name */
801         if (bt_def_oob_data.bt_name != NULL) {
802                 bt_oob_block_size += (bt_def_oob_data.bt_name_len +
803                                                                 EIR_HEADER_LEN);
804
805                 bt_oob_block[offset++] = bt_def_oob_data.bt_name_len +
806                                                                 EIR_SIZE_LEN;
807                 bt_oob_block[offset++] = EIR_NAME_COMPLETE; /* EIR data type */
808                 memcpy(bt_oob_block + offset, bt_def_oob_data.bt_name,
809                                         bt_def_oob_data.bt_name_len);
810                 offset += bt_def_oob_data.bt_name_len;
811         }
812
813         /* CoD */
814         bt_oob_block_size += COD_SIZE +  EIR_HEADER_LEN;
815
816         bt_oob_block[offset++] = COD_SIZE + EIR_SIZE_LEN;
817         bt_oob_block[offset++] = EIR_CLASS_OF_DEVICE;
818
819         memcpy(bt_oob_block + offset,
820                         (uint8_t *)&bt_def_oob_data.class_of_device, COD_SIZE);
821         offset += COD_SIZE;
822
823         /* The following data are generated dynamically
824          * so we have to read the local oob data
825          * */
826         if (bt_sync_oob_readlocaldata(bt_conn, bt_def_oob_data.def_adapter,
827                                         hash, random) == OOB_SP_SIZE) {
828                 bt_oob_block_size += 2 * (OOB_SP_SIZE + EIR_HEADER_LEN);
829
830                 /* OOB datas */
831                 if (hash != NULL) {
832                         bt_oob_block[offset++] = OOB_SP_SIZE + EIR_SIZE_LEN;
833                         bt_oob_block[offset++] = EIR_SP_HASH;
834                         memcpy(bt_oob_block + offset, hash, OOB_SP_SIZE);
835                         offset += OOB_SP_SIZE;
836                 }
837
838                 if (random != NULL) {
839                         bt_oob_block[offset++] = OOB_SP_SIZE + EIR_SIZE_LEN;
840                         bt_oob_block[offset++] = EIR_SP_RANDOMIZER;
841                         memcpy(bt_oob_block + offset, random, OOB_SP_SIZE);
842                         offset += OOB_SP_SIZE;
843                 }
844         }
845
846         *(uint16_t *)bt_oob_block = bt_oob_block_size ;
847         *bt_data_len = bt_oob_block_size;
848
849         return bt_oob_block;
850
851 fail:
852         g_free(bt_oob_block);
853         return NULL;
854 }
855
856 static void bt_connect(DBusConnection *conn, void *user_data)
857 {
858
859         DBG("connection %p with %p", conn, user_data);
860         if (bt_refresh_adapter_props(conn, user_data) < 0)
861                 near_error("bt_get_default_adapter failed");
862
863         return;
864 }
865
866 static void bt_disconnect(DBusConnection *conn, void *user_data)
867 {
868         DBG("%p", conn);
869
870         __bt_eir_free(user_data);
871 }
872
873 /* BT adapter removed handler */
874 static gboolean bt_adapter_removed(DBusConnection *conn,
875                                         DBusMessage *message,
876                                         void *user_data)
877 {
878         DBusMessageIter iter;
879         struct near_oob_data *bt_props = user_data;
880         const char *adapter_path;
881
882         DBG("");
883
884         if (bt_props->def_adapter == NULL)
885                 return TRUE;
886
887         if (dbus_message_iter_init(message, &iter) == FALSE)
888                 return TRUE;
889
890         dbus_message_iter_get_basic(&iter, &adapter_path);
891
892         if (g_strcmp0(adapter_path, bt_props->def_adapter) == 0) {
893                 near_info("Remove the default adapter [%s]", adapter_path);
894
895                 __bt_eir_free(bt_props);
896                 bt_props->def_adapter = NULL;
897         }
898
899         return TRUE;
900 }
901
902 /* BT default adapter changed handler */
903 static gboolean bt_default_adapter_changed(DBusConnection *conn,
904                                         DBusMessage *message,
905                                         void *user_data)
906 {
907         struct near_oob_data *bt_props = user_data;
908         DBusMessageIter iter;
909         const char *adapter_path;
910
911         DBG("");
912
913         if (dbus_message_iter_init(message, &iter) == FALSE)
914                 return TRUE;
915
916         dbus_message_iter_get_basic(&iter, &adapter_path);
917         DBG("New default adapter [%s]", adapter_path);
918
919         /* Disable the old one */
920         __bt_eir_free(bt_props);
921         bt_props->def_adapter = NULL;
922
923         /* Refresh */
924         bt_refresh_adapter_props(conn, user_data);
925
926         return TRUE;
927 }
928
929 static void bt_dbus_disconnect_cb(DBusConnection *conn, void *user_data)
930 {
931         near_error("D-Bus disconnect (BT)");
932         bt_conn = NULL;
933 }
934
935 static guint watch;
936 static guint removed_watch;
937 static guint adapter_watch;
938
939 static int bt_prepare_handlers(DBusConnection *conn)
940 {
941         DBG("%p", conn);
942
943         if (conn == NULL)
944                 return -EIO;
945
946         watch = g_dbus_add_service_watch(conn, BLUEZ_SERVICE,
947                                                 bt_connect,
948                                                 bt_disconnect,
949                                                 &bt_def_oob_data, NULL);
950
951         removed_watch = g_dbus_add_signal_watch(conn, NULL, NULL, MANAGER_INTF,
952                                                 ADAPTER_REMOVED,
953                                                 bt_adapter_removed,
954                                                 &bt_def_oob_data, NULL);
955
956
957         adapter_watch = g_dbus_add_signal_watch(conn, NULL, NULL, MANAGER_INTF,
958                                                 DEFAULT_ADAPTER_CHANGED,
959                                                 bt_default_adapter_changed,
960                                                 &bt_def_oob_data, NULL);
961
962         if (watch == 0 ||  removed_watch == 0 || adapter_watch == 0) {
963                 near_error("Bluez event handlers failed to register.");
964                 g_dbus_remove_watch(conn, watch);
965                 g_dbus_remove_watch(conn, removed_watch);
966                 g_dbus_remove_watch(conn, adapter_watch);
967
968                 return -EIO;
969         }
970
971         return 0;
972 }
973
974 /* Bluetooth exiting function */
975 void __near_bluetooth_cleanup(void)
976 {
977         DBG("");
978
979         if (bt_conn == NULL)
980                 return;
981
982         g_dbus_remove_watch(bt_conn, watch);
983         g_dbus_remove_watch(bt_conn, removed_watch);
984         g_dbus_remove_watch(bt_conn, adapter_watch);
985
986         dbus_connection_unref(bt_conn);
987
988         __bt_eir_free(&bt_def_oob_data);
989
990         return;
991 }
992
993 /*
994  * Bluetooth initialization function.
995  *      Allocate bt local settings storage
996  *      and setup event handlers
997  */
998 int __near_bluetooth_init(void)
999 {
1000         DBusError err;
1001
1002         DBG("");
1003
1004         dbus_error_init(&err);
1005
1006         /* save the dbus connection */
1007         bt_conn = near_dbus_get_connection();
1008         if (bt_conn == NULL) {
1009                 if (dbus_error_is_set(&err) == TRUE) {
1010                         near_error("%s", err.message);
1011                         dbus_error_free(&err);
1012                 } else
1013                         near_error("Can't register with system bus\n");
1014                 return -EIO;
1015         }
1016
1017         /* dbus disconnect callback */
1018         g_dbus_set_disconnect_function(bt_conn, bt_dbus_disconnect_cb,
1019                                                 NULL, NULL);
1020
1021         /* Set bluez event handlers */
1022         return bt_prepare_handlers(bt_conn);
1023 }