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