diff -Nru bluez-4.91/acinclude.m4 bluez-4.96/acinclude.m4 --- bluez-4.91/acinclude.m4 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/acinclude.m4 2011-07-31 06:52:19.000000000 +0000 @@ -84,13 +84,11 @@ AC_SUBST(CONFIGDIR, "${configdir}") AC_SUBST(STORAGEDIR, "${storagedir}") - UDEV_DATADIR="`$PKG_CONFIG --variable=udevdir udev`" - if (test -z "${UDEV_DATADIR}"); then - UDEV_DATADIR="${sysconfdir}/udev/rules.d" - else - UDEV_DATADIR="${UDEV_DATADIR}/rules.d" + UDEV_DIR="`$PKG_CONFIG --variable=udevdir udev`" + if (test -z "${UDEV_DIR}"); then + UDEV_DIR="/lib/udev" fi - AC_SUBST(UDEV_DATADIR) + AC_SUBST(UDEV_DIR) ]) AC_DEFUN([AC_PATH_DBUS], [ @@ -110,6 +108,9 @@ AC_DEFUN([AC_PATH_GLIB], [ PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes, AC_MSG_ERROR(GLib library version 2.16 or later is required)) + AC_CHECK_LIB(glib-2.0, g_slist_free_full, dummy=yes, + AC_DEFINE(NEED_G_SLIST_FREE_FULL, 1, + [Define to 1 if you need g_slist_free_full() function.])) AC_SUBST(GLIB_CFLAGS) AC_SUBST(GLIB_LIBS) ]) @@ -148,6 +149,12 @@ [Define to 1 if you need the usb_interrupt_read() function.])) ]) +AC_DEFUN([AC_PATH_UDEV], [ + PKG_CHECK_MODULES(UDEV, libudev, udev_found=yes, udev_found=no) + AC_SUBST(UDEV_CFLAGS) + AC_SUBST(UDEV_LIBS) +]) + AC_DEFUN([AC_PATH_SNDFILE], [ PKG_CHECK_MODULES(SNDFILE, sndfile, sndfile_found=yes, sndfile_found=no) AC_SUBST(SNDFILE_CFLAGS) @@ -186,10 +193,11 @@ serial_enable=yes network_enable=yes sap_enable=no + proximity_enable=no service_enable=yes health_enable=no pnat_enable=no - attrib_enable=no + gatt_example_enable=no tracer_enable=no tools_enable=yes hidd_enable=no @@ -201,12 +209,13 @@ pcmcia_enable=no hid2hci_enable=no dfutool_enable=no - udevrules_enable=yes - configfiles_enable=yes + datafiles_enable=yes telephony_driver=dummy maemo6_enable=no sap_driver=dummy dbusoob_enable=no + wiimote_enable=no + thermometer_enable=no AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization], [disable code optimization]), [ optimization_enable=${enableval} @@ -233,6 +242,10 @@ ]) AC_SUBST([SAP_DRIVER], [sap-${sap_driver}.c]) + AC_ARG_ENABLE(proximity, AC_HELP_STRING([--enable-proximity], [enable proximity plugin]), [ + proximity_enable=${enableval} + ]) + AC_ARG_ENABLE(serial, AC_HELP_STRING([--disable-serial], [disable serial plugin]), [ serial_enable=${enableval} ]) @@ -257,8 +270,8 @@ pnat_enable=${enableval} ]) - AC_ARG_ENABLE(attrib, AC_HELP_STRING([--enable-attrib], [enable attrib plugin]), [ - attrib_enable=${enableval} + AC_ARG_ENABLE(gatt-example, AC_HELP_STRING([--enable-gatt-example], [enable GATT example plugin]), [ + gatt_example_enable=${enableval} ]) AC_ARG_ENABLE(gstreamer, AC_HELP_STRING([--enable-gstreamer], [enable GStreamer support]), [ @@ -317,12 +330,8 @@ test_enable=${enableval} ]) - AC_ARG_ENABLE(udevrules, AC_HELP_STRING([--enable-udevrules], [install Bluetooth udev rules]), [ - udevrules_enable=${enableval} - ]) - - AC_ARG_ENABLE(configfiles, AC_HELP_STRING([--enable-configfiles], [install Bluetooth configuration files]), [ - configfiles_enable=${enableval} + AC_ARG_ENABLE(datafiles, AC_HELP_STRING([--enable-datafiles], [install Bluetooth configuration and data files]), [ + datafiles_enable=${enableval} ]) AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [enable compiling with debugging information]), [ @@ -343,10 +352,18 @@ dbusoob_enable=${enableval} ]) + AC_ARG_ENABLE(wiimote, AC_HELP_STRING([--enable-wiimote], [compile with Wii Remote plugin]), [ + wiimote_enable=${enableval} + ]) + AC_ARG_ENABLE(hal, AC_HELP_STRING([--enable-hal], [Use HAL to determine adapter class]), [ hal_enable=${enableval} ]) + AC_ARG_ENABLE(thermometer, AC_HELP_STRING([--enable-thermometer], [enable thermometer plugin]), [ + thermometer_enable=${enableval} + ]) + if (test "${fortify_enable}" = "yes"); then CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2" fi @@ -379,12 +396,13 @@ AM_CONDITIONAL(SERIALPLUGIN, test "${serial_enable}" = "yes") AM_CONDITIONAL(NETWORKPLUGIN, test "${network_enable}" = "yes") AM_CONDITIONAL(SAPPLUGIN, test "${sap_enable}" = "yes") + AM_CONDITIONAL(PROXIMITYPLUGIN, test "${proximity_enable}" = "yes") AM_CONDITIONAL(SERVICEPLUGIN, test "${service_enable}" = "yes") AM_CONDITIONAL(HEALTHPLUGIN, test "${health_enable}" = "yes") AM_CONDITIONAL(MCAP, test "${health_enable}" = "yes") AM_CONDITIONAL(HAL, test "${hal_enable}" = "yes") AM_CONDITIONAL(READLINE, test "${readline_found}" = "yes") - AM_CONDITIONAL(ATTRIBPLUGIN, test "${attrib_enable}" = "yes") + AM_CONDITIONAL(GATT_EXAMPLE_PLUGIN, test "${gatt_example_enable}" = "yes") AM_CONDITIONAL(ECHOPLUGIN, test "no" = "yes") AM_CONDITIONAL(PNATPLUGIN, test "${pnat_enable}" = "yes") AM_CONDITIONAL(TRACER, test "${tracer_enable}" = "yes") @@ -396,10 +414,11 @@ AM_CONDITIONAL(TOOLS, test "${tools_enable}" = "yes") AM_CONDITIONAL(BCCMD, test "${bccmd_enable}" = "yes") AM_CONDITIONAL(PCMCIA, test "${pcmcia_enable}" = "yes") - AM_CONDITIONAL(HID2HCI, test "${hid2hci_enable}" = "yes" && test "${usb_found}" = "yes") + AM_CONDITIONAL(HID2HCI, test "${hid2hci_enable}" = "yes" && test "${usb_found}" = "yes" && test "${udev_found}" = "yes") AM_CONDITIONAL(DFUTOOL, test "${dfutool_enable}" = "yes" && test "${usb_found}" = "yes") - AM_CONDITIONAL(UDEVRULES, test "${udevrules_enable}" = "yes") - AM_CONDITIONAL(CONFIGFILES, test "${configfiles_enable}" = "yes") + AM_CONDITIONAL(DATAFILES, test "${datafiles_enable}" = "yes") AM_CONDITIONAL(MAEMO6PLUGIN, test "${maemo6_enable}" = "yes") AM_CONDITIONAL(DBUSOOBPLUGIN, test "${dbusoob_enable}" = "yes") + AM_CONDITIONAL(WIIMOTEPLUGIN, test "${wiimote_enable}" = "yes") + AM_CONDITIONAL(THERMOMETERPLUGIN, test "${thermometer_enable}" = "yes") ]) diff -Nru bluez-4.91/attrib/att.c bluez-4.96/attrib/att.c --- bluez-4.91/attrib/att.c 2011-03-16 00:34:27.000000000 +0000 +++ bluez-4.96/attrib/att.c 2011-07-04 04:59:05.000000000 +0000 @@ -39,18 +39,18 @@ case ATT_ECODE_INVALID_HANDLE: return "Invalid handle"; case ATT_ECODE_READ_NOT_PERM: - return "Atribute can't be read"; + return "Attribute can't be read"; case ATT_ECODE_WRITE_NOT_PERM: return "Attribute can't be written"; case ATT_ECODE_INVALID_PDU: return "Attribute PDU was invalid"; - case ATT_ECODE_INSUFF_AUTHEN: + case ATT_ECODE_AUTHENTICATION: return "Attribute requires authentication before read/write"; case ATT_ECODE_REQ_NOT_SUPP: return "Server doesn't support the request received"; case ATT_ECODE_INVALID_OFFSET: return "Offset past the end of the attribute"; - case ATT_ECODE_INSUFF_AUTHO: + case ATT_ECODE_AUTHORIZATION: return "Attribute requires authorization before read/write"; case ATT_ECODE_PREP_QUEUE_FULL: return "Too many prepare writes have been queued"; diff -Nru bluez-4.91/attrib/att.h bluez-4.96/attrib/att.h --- bluez-4.91/attrib/att.h 2011-03-16 00:34:27.000000000 +0000 +++ bluez-4.96/attrib/att.h 2011-05-03 08:20:36.000000000 +0000 @@ -79,10 +79,10 @@ #define ATT_ECODE_READ_NOT_PERM 0x02 #define ATT_ECODE_WRITE_NOT_PERM 0x03 #define ATT_ECODE_INVALID_PDU 0x04 -#define ATT_ECODE_INSUFF_AUTHEN 0x05 +#define ATT_ECODE_AUTHENTICATION 0x05 #define ATT_ECODE_REQ_NOT_SUPP 0x06 #define ATT_ECODE_INVALID_OFFSET 0x07 -#define ATT_ECODE_INSUFF_AUTHO 0x08 +#define ATT_ECODE_AUTHORIZATION 0x08 #define ATT_ECODE_PREP_QUEUE_FULL 0x09 #define ATT_ECODE_ATTR_NOT_FOUND 0x0A #define ATT_ECODE_ATTR_NOT_LONG 0x0B @@ -110,6 +110,9 @@ #define ATT_DEFAULT_L2CAP_MTU 48 #define ATT_DEFAULT_LE_MTU 23 +#define ATT_CID 4 +#define ATT_PSM 31 + /* Requirements for read/write operations */ enum { ATT_NONE, /* No restrictions */ diff -Nru bluez-4.91/attrib/client.c bluez-4.96/attrib/client.c --- bluez-4.91/attrib/client.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/attrib/client.c 2011-07-31 06:52:19.000000000 +0000 @@ -32,8 +32,11 @@ #include #include +#include +#include #include +#include "glib-helper.h" #include "adapter.h" #include "device.h" #include "log.h" @@ -45,23 +48,12 @@ #include "att.h" #include "gattrib.h" +#include "attio.h" #include "gatt.h" #include "client.h" #define CHAR_INTERFACE "org.bluez.Characteristic" -struct gatt_service { - struct btd_device *dev; - bdaddr_t sba; - bdaddr_t dba; - char *path; - GSList *primary; - GAttrib *attrib; - DBusMessage *msg; - int psm; - gboolean listen; -}; - struct format { guint8 format; guint8 exponent; @@ -70,16 +62,28 @@ guint16 desc; } __attribute__ ((packed)); -struct primary { - struct gatt_service *gatt; - struct att_primary *att; +struct query { + DBusMessage *msg; + guint attioid; + GSList *list; +}; + +struct gatt_service { + struct btd_device *dev; + struct att_primary *prim; + DBusConnection *conn; + GAttrib *attrib; + guint attioid; + int psm; char *path; GSList *chars; + GSList *offline_chars; GSList *watchers; + struct query *query; }; struct characteristic { - struct primary *prim; + struct gatt_service *gatt; char *path; uint16_t handle; uint16_t end; @@ -93,9 +97,8 @@ }; struct query_data { - struct primary *prim; + struct gatt_service *gatt; struct characteristic *chr; - DBusMessage *msg; uint16_t handle; }; @@ -103,13 +106,11 @@ guint id; char *name; char *path; - struct primary *prim; + struct gatt_service *gatt; }; static GSList *gatt_services = NULL; -static DBusConnection *connection; - static void characteristic_free(void *user_data) { struct characteristic *chr = user_data; @@ -131,40 +132,26 @@ g_free(watcher); } -static void primary_free(void *user_data) -{ - struct primary *prim = user_data; - GSList *l; - - for (l = prim->watchers; l; l = l->next) { - struct watcher *watcher = l->data; - g_dbus_remove_watch(connection, watcher->id); - } - - g_slist_foreach(prim->chars, (GFunc) characteristic_free, NULL); - g_slist_free(prim->chars); - g_free(prim->path); - g_free(prim); -} - -static void gatt_service_free(void *user_data) +static void gatt_service_free(struct gatt_service *gatt) { - struct gatt_service *gatt = user_data; - - g_slist_foreach(gatt->primary, (GFunc) primary_free, NULL); - g_slist_free(gatt->primary); - g_attrib_unref(gatt->attrib); + g_slist_free_full(gatt->watchers, watcher_free); + g_slist_free_full(gatt->chars, characteristic_free); + g_slist_free(gatt->offline_chars); g_free(gatt->path); btd_device_unref(gatt->dev); + dbus_connection_unref(gatt->conn); g_free(gatt); } -static int gatt_dev_cmp(gconstpointer a, gconstpointer b) +static void gatt_get_address(struct gatt_service *gatt, + bdaddr_t *sba, bdaddr_t *dba) { - const struct gatt_service *gatt = a; - const struct btd_device *dev = b; + struct btd_device *device = gatt->dev; + struct btd_adapter *adapter; - return gatt->dev != dev; + adapter = device_get_adapter(device); + adapter_get_address(adapter, sba); + device_get_address(device, dba); } static int characteristic_handle_cmp(gconstpointer a, gconstpointer b) @@ -222,14 +209,11 @@ static void watcher_exit(DBusConnection *conn, void *user_data) { struct watcher *watcher = user_data; - struct primary *prim = watcher->prim; - struct gatt_service *gatt = prim->gatt; - - DBG("%s watcher %s exited", prim->path, watcher->name); + struct gatt_service *gatt = watcher->gatt; - prim->watchers = g_slist_remove(prim->watchers, watcher); + DBG("%s watcher %s exited", gatt->path, watcher->name); - g_attrib_unref(gatt->attrib); + gatt->watchers = g_slist_remove(gatt->watchers, watcher); } static int characteristic_set_value(struct characteristic *chr, @@ -249,6 +233,7 @@ { struct watcher *w = data; struct characteristic *chr = user_data; + DBusConnection *conn = w->gatt->conn; DBusMessage *msg; msg = dbus_message_new_method_call(w->name, w->path, @@ -261,7 +246,7 @@ &chr->value, chr->vlen, DBUS_TYPE_INVALID); dbus_message_set_no_reply(msg, TRUE); - g_dbus_send_message(connection, msg); + g_dbus_send_message(conn, msg); } static void events_handler(const uint8_t *pdu, uint16_t len, @@ -269,8 +254,7 @@ { struct gatt_service *gatt = user_data; struct characteristic *chr; - struct primary *prim; - GSList *lprim, *lchr; + GSList *l; uint8_t opdu[ATT_MAX_MTU]; guint handle; uint16_t olen; @@ -283,17 +267,12 @@ handle = att_get_u16(&pdu[1]); - for (lprim = gatt->primary, prim = NULL, chr = NULL; lprim; - lprim = lprim->next) { - prim = lprim->data; + l = g_slist_find_custom(gatt->chars, GUINT_TO_POINTER(handle), + characteristic_handle_cmp); + if (!l) + return; - lchr = g_slist_find_custom(prim->chars, - GUINT_TO_POINTER(handle), characteristic_handle_cmp); - if (lchr) { - chr = lchr->data; - break; - } - } + chr = l->data; if (chr == NULL) { DBG("Attribute handle 0x%02x not found", handle); @@ -309,131 +288,81 @@ if (characteristic_set_value(chr, &pdu[3], len - 3) < 0) DBG("Can't change Characteristic 0x%02x", handle); - g_slist_foreach(prim->watchers, update_watchers, chr); + g_slist_foreach(gatt->watchers, update_watchers, chr); break; } } -static void attrib_destroy(gpointer user_data) +static void offline_char_written(gpointer user_data) { - struct gatt_service *gatt = user_data; + struct characteristic *chr = user_data; + struct gatt_service *gatt = chr->gatt; - gatt->attrib = NULL; + gatt->offline_chars = g_slist_remove(gatt->offline_chars, chr); + + if (gatt->offline_chars || gatt->watchers) + return; + + btd_device_remove_attio_callback(gatt->dev, gatt->attioid); + gatt->attioid = 0; } -static void attrib_disconnect(gpointer user_data) +static void offline_char_write(gpointer data, gpointer user_data) { - struct gatt_service *gatt = user_data; + struct characteristic *chr = data; + GAttrib *attrib = user_data; - /* Remote initiated disconnection only */ - g_attrib_unref(gatt->attrib); + gatt_write_cmd(attrib, chr->handle, chr->value, chr->vlen, + offline_char_written, chr); } -static void connect_cb(GIOChannel *chan, GError *gerr, gpointer user_data) +static void attio_connected(GAttrib *attrib, gpointer user_data) { struct gatt_service *gatt = user_data; - if (gerr) { - if (gatt->msg) { - DBusMessage *reply = btd_error_failed(gatt->msg, - gerr->message); - g_dbus_send_message(connection, reply); - } + gatt->attrib = attrib; - error("%s", gerr->message); - goto fail; - } - - if (gatt->attrib == NULL) - return; - - /* Listen mode: used for notification and indication */ - if (gatt->listen == TRUE) { - g_attrib_register(gatt->attrib, - ATT_OP_HANDLE_NOTIFY, + g_attrib_register(gatt->attrib, ATT_OP_HANDLE_NOTIFY, events_handler, gatt, NULL); - g_attrib_register(gatt->attrib, - ATT_OP_HANDLE_IND, + g_attrib_register(gatt->attrib, ATT_OP_HANDLE_IND, events_handler, gatt, NULL); - return; - } - return; -fail: - g_attrib_unref(gatt->attrib); + g_slist_foreach(gatt->offline_chars, offline_char_write, attrib); } -static int l2cap_connect(struct gatt_service *gatt, GError **gerr, - gboolean listen) +static void attio_disconnected(gpointer user_data) { - GIOChannel *io; - - if (gatt->attrib != NULL) { - gatt->attrib = g_attrib_ref(gatt->attrib); - gatt->listen = listen; - return 0; - } - - /* - * FIXME: If the service doesn't support Client Characteristic - * Configuration it is necessary to poll the server from time - * to time checking for modifications. - */ - if (gatt->psm < 0) - io = bt_io_connect(BT_IO_L2CAP, connect_cb, gatt, NULL, gerr, - BT_IO_OPT_SOURCE_BDADDR, &gatt->sba, - BT_IO_OPT_DEST_BDADDR, &gatt->dba, - BT_IO_OPT_CID, GATT_CID, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, - BT_IO_OPT_INVALID); - else - io = bt_io_connect(BT_IO_L2CAP, connect_cb, gatt, NULL, gerr, - BT_IO_OPT_SOURCE_BDADDR, &gatt->sba, - BT_IO_OPT_DEST_BDADDR, &gatt->dba, - BT_IO_OPT_PSM, gatt->psm, - BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, - BT_IO_OPT_INVALID); - if (!io) - return -1; - - gatt->attrib = g_attrib_new(io); - g_io_channel_unref(io); - gatt->listen = listen; - - g_attrib_set_destroy_function(gatt->attrib, attrib_destroy, gatt); - g_attrib_set_disconnect_function(gatt->attrib, attrib_disconnect, - gatt); + struct gatt_service *gatt = user_data; - return 0; + gatt->attrib = NULL; } static DBusMessage *register_watcher(DBusConnection *conn, DBusMessage *msg, void *data) { const char *sender = dbus_message_get_sender(msg); - struct primary *prim = data; + struct gatt_service *gatt = data; struct watcher *watcher; - GError *gerr = NULL; char *path; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) return btd_error_invalid_args(msg); - if (l2cap_connect(prim->gatt, &gerr, TRUE) < 0) { - DBusMessage *reply = btd_error_failed(msg, gerr->message); - g_error_free(gerr); - return reply; - } - watcher = g_new0(struct watcher, 1); watcher->name = g_strdup(sender); - watcher->prim = prim; + watcher->gatt = gatt; watcher->path = g_strdup(path); watcher->id = g_dbus_add_disconnect_watch(conn, sender, watcher_exit, watcher, watcher_free); - prim->watchers = g_slist_append(prim->watchers, watcher); + if (gatt->attioid == 0) + gatt->attioid = btd_device_add_attio_callback(gatt->dev, + attio_connected, + attio_disconnected, + gatt); + + gatt->watchers = g_slist_append(gatt->watchers, watcher); return dbus_message_new_method_return(msg); } @@ -442,7 +371,7 @@ DBusMessage *msg, void *data) { const char *sender = dbus_message_get_sender(msg); - struct primary *prim = data; + struct gatt_service *gatt = data; struct watcher *watcher, *match; GSList *l; char *path; @@ -454,25 +383,29 @@ match = g_new0(struct watcher, 1); match->name = g_strdup(sender); match->path = g_strdup(path); - l = g_slist_find_custom(prim->watchers, match, watcher_cmp); + l = g_slist_find_custom(gatt->watchers, match, watcher_cmp); watcher_free(match); if (!l) return btd_error_not_authorized(msg); watcher = l->data; g_dbus_remove_watch(conn, watcher->id); - prim->watchers = g_slist_remove(prim->watchers, watcher); + gatt->watchers = g_slist_remove(gatt->watchers, watcher); watcher_free(watcher); + if (gatt->watchers == NULL && gatt->attioid) { + btd_device_remove_attio_callback(gatt->dev, gatt->attioid); + gatt->attioid = 0; + } + return dbus_message_new_method_return(msg); } static DBusMessage *set_value(DBusConnection *conn, DBusMessage *msg, DBusMessageIter *iter, struct characteristic *chr) { - struct gatt_service *gatt = chr->prim->gatt; + struct gatt_service *gatt = chr->gatt; DBusMessageIter sub; - GError *gerr = NULL; uint8_t *value; int len; @@ -484,16 +417,18 @@ dbus_message_iter_get_fixed_array(&sub, &value, &len); - if (l2cap_connect(gatt, &gerr, FALSE) < 0) { - DBusMessage *reply = btd_error_failed(msg, gerr->message); - g_error_free(gerr); - return reply; - } - - gatt_write_cmd(gatt->attrib, chr->handle, value, len, NULL, NULL); - characteristic_set_value(chr, value, len); + if (gatt->attioid == 0) { + gatt->attioid = btd_device_add_attio_callback(gatt->dev, + attio_connected, + attio_disconnected, + gatt); + gatt->offline_chars = g_slist_append(gatt->offline_chars, chr); + } else + gatt_write_cmd(gatt->attrib, chr->handle, value, len, + NULL, NULL); + return dbus_message_new_method_return(msg); } @@ -572,34 +507,34 @@ return g_string_free(characteristics, FALSE); } -static void store_characteristics(struct gatt_service *gatt, - struct primary *prim) +static void store_characteristics(const bdaddr_t *sba, const bdaddr_t *dba, + uint16_t start, GSList *chars) { char *characteristics; - struct att_primary *att = prim->att; - characteristics = characteristic_list_to_string(prim->chars); + characteristics = characteristic_list_to_string(chars); - write_device_characteristics(&gatt->sba, &gatt->dba, att->start, - characteristics); + write_device_characteristics(sba, dba, start, characteristics); g_free(characteristics); } -static void register_characteristics(struct primary *prim) +static void register_characteristic(gpointer data, gpointer user_data) { - GSList *lc; + struct characteristic *chr = data; + DBusConnection *conn = chr->gatt->conn; + const char *gatt_path = user_data; - for (lc = prim->chars; lc; lc = lc->next) { - struct characteristic *chr = lc->data; - g_dbus_register_interface(connection, chr->path, - CHAR_INTERFACE, char_methods, - NULL, NULL, chr, NULL); - DBG("Registered: %s", chr->path); - } + chr->path = g_strdup_printf("%s/characteristic%04x", gatt_path, + chr->handle); + + g_dbus_register_interface(conn, chr->path, CHAR_INTERFACE, + char_methods, NULL, NULL, chr, NULL); + + DBG("Registered: %s", chr->path); } -static GSList *string_to_characteristic_list(struct primary *prim, +static GSList *string_to_characteristic_list(struct gatt_service *gatt, const char *str) { GSList *l = NULL; @@ -626,10 +561,7 @@ continue; } - chr->prim = prim; - chr->path = g_strdup_printf("%s/characteristic%04x", - prim->path, chr->handle); - + chr->gatt = gatt; l = g_slist_append(l, chr); } @@ -638,39 +570,29 @@ return l; } -static void load_characteristics(gpointer data, gpointer user_data) +static GSList *load_characteristics(struct gatt_service *gatt, uint16_t start) { - struct primary *prim = data; - struct att_primary *att = prim->att; - struct gatt_service *gatt = user_data; GSList *chrs_list; + bdaddr_t sba, dba; char *str; - if (prim->chars) { - DBG("Characteristics already loaded"); - return; - } + gatt_get_address(gatt, &sba, &dba); - str = read_device_characteristics(&gatt->sba, &gatt->dba, att->start); + str = read_device_characteristics(&sba, &dba, start); if (str == NULL) - return; + return NULL; - chrs_list = string_to_characteristic_list(prim, str); + chrs_list = string_to_characteristic_list(gatt, str); free(str); - if (chrs_list == NULL) - return; - - prim->chars = chrs_list; - register_characteristics(prim); - - return; + return chrs_list; } static void store_attribute(struct gatt_service *gatt, uint16_t handle, uint16_t type, uint8_t *value, gsize len) { + bdaddr_t sba, dba; bt_uuid_t uuid; char *str, *tmp; guint i; @@ -685,15 +607,39 @@ for (i = 0, tmp = str + MAX_LEN_UUID_STR; i < len; i++, tmp += 2) sprintf(tmp, "%02X", value[i]); - write_device_attribute(&gatt->sba, &gatt->dba, handle, str); + gatt_get_address(gatt, &sba, &dba); + + write_device_attribute(&sba, &dba, handle, str); + g_free(str); } +static void query_list_append(struct gatt_service *gatt, struct query_data *data) +{ + struct query *query = gatt->query; + + query->list = g_slist_append(query->list, data); +} + +static void query_list_remove(struct gatt_service *gatt, struct query_data *data) +{ + struct query *query = gatt->query; + + query->list = g_slist_remove(query->list, data); + if (query->list != NULL) + return; + + btd_device_remove_attio_callback(gatt->dev, query->attioid); + g_free(query); + + gatt->query = NULL; +} + static void update_char_desc(guint8 status, const guint8 *pdu, guint16 len, gpointer user_data) { struct query_data *current = user_data; - struct gatt_service *gatt = current->prim->gatt; + struct gatt_service *gatt = current->gatt; struct characteristic *chr = current->chr; if (status == 0) { @@ -719,7 +665,7 @@ } } - g_attrib_unref(gatt->attrib); + query_list_remove(gatt, current); g_free(current); } @@ -727,7 +673,7 @@ gpointer user_data) { struct query_data *current = user_data; - struct gatt_service *gatt = current->prim->gatt; + struct gatt_service *gatt = current->gatt; struct characteristic *chr = current->chr; if (status != 0) @@ -745,7 +691,7 @@ (void *) chr->format, sizeof(*chr->format)); done: - g_attrib_unref(gatt->attrib); + query_list_remove(gatt, current); g_free(current); } @@ -753,7 +699,7 @@ guint16 len, gpointer user_data) { struct query_data *current = user_data; - struct gatt_service *gatt = current->prim->gatt; + struct gatt_service *gatt = current->gatt; struct characteristic *chr = current->chr; if (status == 0) @@ -770,7 +716,7 @@ } } - g_attrib_unref(gatt->attrib); + query_list_remove(gatt, current); g_free(current); } @@ -787,7 +733,7 @@ gpointer user_data) { struct query_data *current = user_data; - struct gatt_service *gatt = current->prim->gatt; + struct gatt_service *gatt = current->gatt; struct att_data_list *list; guint8 format; int i; @@ -819,16 +765,16 @@ continue; } qfmt = g_new0(struct query_data, 1); - qfmt->prim = current->prim; + qfmt->gatt = current->gatt; qfmt->chr = current->chr; qfmt->handle = handle; if (uuid_desc16_cmp(&uuid, GATT_CHARAC_USER_DESC_UUID) == 0) { - gatt->attrib = g_attrib_ref(gatt->attrib); + query_list_append(gatt, qfmt); gatt_read_char(gatt->attrib, handle, 0, update_char_desc, qfmt); } else if (uuid_desc16_cmp(&uuid, GATT_CHARAC_FMT_UUID) == 0) { - gatt->attrib = g_attrib_ref(gatt->attrib); + query_list_append(gatt, qfmt); gatt_read_char(gatt->attrib, handle, 0, update_char_format, qfmt); } else @@ -837,7 +783,7 @@ att_data_list_free(list); done: - g_attrib_unref(gatt->attrib); + query_list_remove(gatt, current); g_free(current); } @@ -845,22 +791,23 @@ { struct query_data *qdesc, *qvalue; struct characteristic *chr = data; - struct primary *prim = user_data; - struct gatt_service *gatt = prim->gatt; + struct gatt_service *gatt = user_data; qdesc = g_new0(struct query_data, 1); - qdesc->prim = prim; + qdesc->gatt = gatt; qdesc->chr = chr; - gatt->attrib = g_attrib_ref(gatt->attrib); + query_list_append(gatt, qdesc); + gatt_find_info(gatt->attrib, chr->handle + 1, chr->end, descriptor_cb, qdesc); qvalue = g_new0(struct query_data, 1); - qvalue->prim = prim; + qvalue->gatt = gatt; qvalue->chr = chr; - gatt->attrib = g_attrib_ref(gatt->attrib); + query_list_append(gatt, qvalue); + gatt_read_char(gatt->attrib, chr->handle, 0, update_char_value, qvalue); } @@ -870,17 +817,17 @@ DBusMessage *reply; DBusMessageIter iter, array_iter; struct query_data *current = user_data; - struct primary *prim = current->prim; - struct att_primary *att = prim->att; - struct gatt_service *gatt = prim->gatt; + struct gatt_service *gatt = current->gatt; + struct att_primary *prim = gatt->prim; uint16_t *previous_end = NULL; GSList *l; + bdaddr_t sba, dba; if (status != 0) { const char *str = att_ecode2str(status); DBG("Discover all characteristics failed: %s", str); - reply = btd_error_failed(current->msg, str); + reply = btd_error_failed(gatt->query->msg, str); goto fail; } @@ -890,17 +837,15 @@ guint handle = current_chr->value_handle; GSList *lchr; - lchr = g_slist_find_custom(prim->chars, + lchr = g_slist_find_custom(gatt->chars, GUINT_TO_POINTER(handle), characteristic_handle_cmp); if (lchr) continue; chr = g_new0(struct characteristic, 1); - chr->prim = prim; + chr->gatt = gatt; chr->perm = current_chr->properties; chr->handle = current_chr->value_handle; - chr->path = g_strdup_printf("%s/characteristic%04x", - prim->path, chr->handle); strncpy(chr->type, current_chr->uuid, sizeof(chr->type)); if (previous_end) @@ -908,23 +853,25 @@ previous_end = &chr->end; - prim->chars = g_slist_append(prim->chars, chr); + gatt->chars = g_slist_append(gatt->chars, chr); } if (previous_end) - *previous_end = att->end; + *previous_end = prim->end; + + gatt_get_address(gatt, &sba, &dba); + store_characteristics(&sba, &dba, prim->start, gatt->chars); - store_characteristics(gatt, prim); - register_characteristics(prim); + g_slist_foreach(gatt->chars, register_characteristic, gatt->path); - reply = dbus_message_new_method_return(current->msg); + reply = dbus_message_new_method_return(gatt->query->msg); dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH_AS_STRING, &array_iter); - for (l = prim->chars; l; l = l->next) { + for (l = gatt->chars; l; l = l->next) { struct characteristic *chr = l->data; dbus_message_iter_append_basic(&array_iter, @@ -933,35 +880,58 @@ dbus_message_iter_close_container(&iter, &array_iter); - g_slist_foreach(prim->chars, update_all_chars, prim); + g_slist_foreach(gatt->chars, update_all_chars, gatt); fail: - g_dbus_send_message(connection, reply); - g_attrib_unref(gatt->attrib); + g_dbus_send_message(gatt->conn, reply); + query_list_remove(gatt, current); g_free(current); } +static void send_discover(GAttrib *attrib, gpointer user_data) +{ + struct query_data *qchr = user_data; + struct gatt_service *gatt = qchr->gatt; + struct att_primary *prim = gatt->prim; + + gatt->attrib = attrib; + + gatt_discover_char(gatt->attrib, prim->start, prim->end, NULL, + char_discovered_cb, qchr); +} + +static void cancel_discover(gpointer user_data) +{ + struct query_data *qchr = user_data; + struct gatt_service *gatt = qchr->gatt; + + gatt->attrib = NULL; +} + static DBusMessage *discover_char(DBusConnection *conn, DBusMessage *msg, void *data) { - struct primary *prim = data; - struct att_primary *att = prim->att; - struct gatt_service *gatt = prim->gatt; + struct gatt_service *gatt = data; + struct query *query; struct query_data *qchr; - GError *gerr = NULL; - if (l2cap_connect(prim->gatt, &gerr, FALSE) < 0) { - DBusMessage *reply = btd_error_failed(msg, gerr->message); - g_error_free(gerr); - return reply; - } + if (gatt->query) + return btd_error_busy(msg); + + query = g_new0(struct query, 1); qchr = g_new0(struct query_data, 1); - qchr->prim = prim; - qchr->msg = dbus_message_ref(msg); + qchr->gatt = gatt; - gatt_discover_char(gatt->attrib, att->start, att->end, NULL, - char_discovered_cb, qchr); + query->msg = dbus_message_ref(msg); + query->attioid = btd_device_add_attio_callback(gatt->dev, + send_discover, + cancel_discover, + qchr); + + gatt->query = query; + + query_list_append(gatt, qchr); return NULL; } @@ -969,7 +939,7 @@ static DBusMessage *prim_get_properties(DBusConnection *conn, DBusMessage *msg, void *data) { - struct primary *prim = data; + struct gatt_service *gatt = data; DBusMessage *reply; DBusMessageIter iter; DBusMessageIter dict; @@ -989,16 +959,16 @@ DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); - chars = g_new0(char *, g_slist_length(prim->chars) + 1); + chars = g_new0(char *, g_slist_length(gatt->chars) + 1); - for (i = 0, l = prim->chars; l; l = l->next, i++) { + for (i = 0, l = gatt->chars; l; l = l->next, i++) { struct characteristic *chr = l->data; chars[i] = chr->path; } dict_append_array(&dict, "Characteristics", DBUS_TYPE_OBJECT_PATH, &chars, i); - uuid = prim->att->uuid; + uuid = gatt->prim->uuid; dict_append_entry(&dict, "UUID", DBUS_TYPE_STRING, &uuid); g_free(chars); @@ -1019,98 +989,95 @@ { } }; -static void register_primaries(struct gatt_service *gatt, GSList *primaries) +static struct gatt_service *primary_register(DBusConnection *conn, + struct btd_device *device, + struct att_primary *prim, + int psm) { - GSList *l; - - for (l = primaries; l; l = l->next) { - struct att_primary *att = l->data; - struct primary *prim; - - prim = g_new0(struct primary, 1); - prim->att = att; - prim->gatt = gatt; - prim->path = g_strdup_printf("%s/service%04x", gatt->path, - att->start); - - g_dbus_register_interface(connection, prim->path, - CHAR_INTERFACE, prim_methods, - NULL, NULL, prim, NULL); - DBG("Registered: %s", prim->path); - - gatt->primary = g_slist_append(gatt->primary, prim); - btd_device_add_service(gatt->dev, prim->path); - load_characteristics(prim, gatt); - } -} - -int attrib_client_register(struct btd_device *device, int psm) -{ - struct btd_adapter *adapter = device_get_adapter(device); - const char *path = device_get_path(device); struct gatt_service *gatt; - GSList *primaries = btd_device_get_primaries(device); - bdaddr_t sba, dba; + const char *device_path; - adapter_get_address(adapter, &sba); - device_get_address(device, &dba); + device_path = device_get_path(device); gatt = g_new0(struct gatt_service, 1); gatt->dev = btd_device_ref(device); - gatt->listen = FALSE; - gatt->path = g_strdup(path); - bacpy(&gatt->sba, &sba); - bacpy(&gatt->dba, &dba); + gatt->prim = prim; gatt->psm = psm; + gatt->conn = dbus_connection_ref(conn); + gatt->path = g_strdup_printf("%s/service%04x", device_path, + prim->start); - register_primaries(gatt, primaries); - - gatt_services = g_slist_append(gatt_services, gatt); + g_dbus_register_interface(gatt->conn, gatt->path, + CHAR_INTERFACE, prim_methods, + NULL, NULL, gatt, NULL); + gatt->chars = load_characteristics(gatt, prim->start); + g_slist_foreach(gatt->chars, register_characteristic, gatt->path); - return 0; + return gatt; } -void attrib_client_unregister(struct btd_device *device) +GSList *attrib_client_register(DBusConnection *connection, + struct btd_device *device, int psm, + GAttrib *attrib, GSList *primaries) { - struct gatt_service *gatt; - GSList *l, *lp, *lc; + GSList *l, *services; - l = g_slist_find_custom(gatt_services, device, gatt_dev_cmp); - if (!l) - return; + for (l = primaries, services = NULL; l; l = l->next) { + struct att_primary *prim = l->data; + struct gatt_service *gatt; - gatt = l->data; - gatt_services = g_slist_remove(gatt_services, gatt); + gatt = primary_register(connection, device, prim, psm); + + DBG("Registered: %s", gatt->path); + + services = g_slist_append(services, g_strdup(gatt->path)); + gatt_services = g_slist_append(gatt_services, gatt); - for (lp = gatt->primary; lp; lp = lp->next) { - struct primary *prim = lp->data; - for (lc = prim->chars; lc; lc = lc->next) { - struct characteristic *chr = lc->data; - g_dbus_unregister_interface(connection, chr->path, - CHAR_INTERFACE); - } - g_dbus_unregister_interface(connection, prim->path, - CHAR_INTERFACE); } - gatt_service_free(gatt); + return services; } -int attrib_client_init(DBusConnection *conn) +static void primary_unregister(struct gatt_service *gatt) { + GSList *l; - connection = dbus_connection_ref(conn); + if (gatt->attioid) + btd_device_remove_attio_callback(gatt->dev, gatt->attioid); - /* - * FIXME: if the adapter supports BLE start scanning. Temporary - * solution, this approach doesn't allow to control scanning based - * on the discoverable property. - */ + for (l = gatt->chars; l; l = l->next) { + struct characteristic *chr = l->data; + g_dbus_unregister_interface(gatt->conn, chr->path, + CHAR_INTERFACE); + } - return 0; + g_dbus_unregister_interface(gatt->conn, gatt->path, CHAR_INTERFACE); +} + +static int path_cmp(gconstpointer data, gconstpointer user_data) +{ + const char *path = data; + const char *gatt_path = user_data; + + return g_strcmp0(path, gatt_path); } -void attrib_client_exit(void) +void attrib_client_unregister(GSList *services) { - dbus_connection_unref(connection); + GSList *l, *left; + + for (l = gatt_services, left = NULL; l; l = l->next) { + struct gatt_service *gatt = l->data; + + if (!g_slist_find_custom(services, gatt->path, path_cmp)) { + left = g_slist_append(left, gatt); + continue; + } + + primary_unregister(gatt); + gatt_service_free(gatt); + } + + g_slist_free(gatt_services); + gatt_services = left; } diff -Nru bluez-4.91/attrib/client.h bluez-4.96/attrib/client.h --- bluez-4.91/attrib/client.h 2010-10-02 23:25:27.000000000 +0000 +++ bluez-4.96/attrib/client.h 2011-07-31 06:52:19.000000000 +0000 @@ -22,7 +22,7 @@ * */ -int attrib_client_init(DBusConnection *conn); -void attrib_client_exit(void); -int attrib_client_register(struct btd_device *device, int psm); -void attrib_client_unregister(struct btd_device *device); +GSList *attrib_client_register(DBusConnection *connection, + struct btd_device *device, int psm, + GAttrib *attrib, GSList *primaries); +void attrib_client_unregister(GSList *services); diff -Nru bluez-4.91/attrib/example.c bluez-4.96/attrib/example.c --- bluez-4.91/attrib/example.c 2011-03-16 00:34:27.000000000 +0000 +++ bluez-4.96/attrib/example.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,341 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2010 Nokia Corporation - * Copyright (C) 2010 Marcel Holtmann - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include - -#include - -#include "log.h" -#include "attrib-server.h" - -#include "att.h" -#include "example.h" - -/* FIXME: Not defined by SIG? UUID128? */ -#define OPCODES_SUPPORTED_UUID 0xA001 -#define BATTERY_STATE_SVC_UUID 0xA002 -#define BATTERY_STATE_UUID 0xA003 -#define THERM_HUMIDITY_SVC_UUID 0xA004 -#define MANUFACTURER_SVC_UUID 0xA005 -#define TEMPERATURE_UUID 0xA006 -#define FMT_CELSIUS_UUID 0xA007 -#define FMT_OUTSIDE_UUID 0xA008 -#define RELATIVE_HUMIDITY_UUID 0xA009 -#define FMT_PERCENT_UUID 0xA00A -#define BLUETOOTH_SIG_UUID 0xA00B -#define MANUFACTURER_NAME_UUID 0xA00C -#define MANUFACTURER_SERIAL_UUID 0xA00D -#define VENDOR_SPECIFIC_SVC_UUID 0xA00E -#define VENDOR_SPECIFIC_TYPE_UUID 0xA00F -#define FMT_KILOGRAM_UUID 0xA010 -#define FMT_HANGING_UUID 0xA011 - -static GSList *sdp_handles = NULL; - -static int register_attributes(void) -{ - const char *desc_out_temp = "Outside Temperature"; - const char *desc_out_hum = "Outside Relative Humidity"; - const char *desc_weight = "Rucksack Weight"; - const char *manufacturer_name1 = "ACME Temperature Sensor"; - const char *manufacturer_name2 = "ACME Weighing Scales"; - const char *serial1 = "237495-3282-A"; - const char *serial2 = "11267-2327A00239"; - - const uint128_t char_weight_uuid_btorder = { - .data = { 0x80, 0x88, 0xF2, 0x18, 0x90, 0x2C, 0x45, 0x0B, - 0xB6, 0xC4, 0x62, 0x89, 0x1E, 0x8C, 0x25, 0xE9 } }; - const uint128_t prim_weight_uuid_btorder = { - .data = { 0x4F, 0x0A, 0xC0, 0x96, 0x35, 0xD4, 0x49, 0x11, - 0x96, 0x31, 0xDE, 0xA8, 0xDC, 0x74, 0xEE, 0xFE } }; - - uint128_t char_weight_uuid; - uint8_t atval[256]; - uint32_t handle; - bt_uuid_t uuid; - int len; - - btoh128(&char_weight_uuid_btorder, &char_weight_uuid); - - /* Battery state service: primary service definition */ - bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID); - att_put_u16(BATTERY_STATE_SVC_UUID, &atval[0]); - attrib_db_add(0x0100, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2); - - /* Battery: battery state characteristic */ - bt_uuid16_create(&uuid, GATT_CHARAC_UUID); - atval[0] = ATT_CHAR_PROPER_READ; - att_put_u16(0x0110, &atval[1]); - att_put_u16(BATTERY_STATE_UUID, &atval[3]); - attrib_db_add(0x0106, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); - - /* Battery: battery state attribute */ - bt_uuid16_create(&uuid, BATTERY_STATE_UUID); - atval[0] = 0x04; - attrib_db_add(0x0110, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 1); - - /* Battery: Client Characteristic Configuration */ - bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID); - atval[0] = 0x00; - atval[1] = 0x00; - attrib_db_add(0x0111, &uuid, ATT_NONE, ATT_AUTHENTICATION, atval, 2); - - /* Add an SDP record for the above service */ - handle = attrib_create_sdp(0x0100, "Battery State Service"); - if (handle) - sdp_handles = g_slist_prepend(sdp_handles, GUINT_TO_POINTER(handle)); - - /* Thermometer: primary service definition */ - bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID); - att_put_u16(THERM_HUMIDITY_SVC_UUID, &atval[0]); - attrib_db_add(0x0200, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2); - - /* Thermometer: Include */ - bt_uuid16_create(&uuid, GATT_INCLUDE_UUID); - att_put_u16(0x0500, &atval[0]); - att_put_u16(0x0504, &atval[2]); - att_put_u16(MANUFACTURER_SVC_UUID, &atval[4]); - attrib_db_add(0x0201, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 6); - - /* Thermometer: Include */ - att_put_u16(0x0550, &atval[0]); - att_put_u16(0x0568, &atval[2]); - att_put_u16(VENDOR_SPECIFIC_SVC_UUID, &atval[4]); - attrib_db_add(0x0202, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 6); - - /* Thermometer: temperature characteristic */ - bt_uuid16_create(&uuid, GATT_CHARAC_UUID); - atval[0] = ATT_CHAR_PROPER_READ; - att_put_u16(0x0204, &atval[1]); - att_put_u16(TEMPERATURE_UUID, &atval[3]); - attrib_db_add(0x0203, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); - - /* Thermometer: temperature characteristic value */ - bt_uuid16_create(&uuid, TEMPERATURE_UUID); - atval[0] = 0x8A; - atval[1] = 0x02; - attrib_db_add(0x0204, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2); - - /* Thermometer: temperature characteristic format */ - bt_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID); - atval[0] = 0x0E; - atval[1] = 0xFE; - att_put_u16(FMT_CELSIUS_UUID, &atval[2]); - atval[4] = 0x01; - att_put_u16(FMT_OUTSIDE_UUID, &atval[5]); - attrib_db_add(0x0205, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 7); - - /* Thermometer: characteristic user description */ - bt_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID); - len = strlen(desc_out_temp); - strncpy((char *) atval, desc_out_temp, len); - attrib_db_add(0x0206, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len); - - /* Thermometer: relative humidity characteristic */ - bt_uuid16_create(&uuid, GATT_CHARAC_UUID); - atval[0] = ATT_CHAR_PROPER_READ; - att_put_u16(0x0212, &atval[1]); - att_put_u16(RELATIVE_HUMIDITY_UUID, &atval[3]); - attrib_db_add(0x0210, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); - - /* Thermometer: relative humidity value */ - bt_uuid16_create(&uuid, RELATIVE_HUMIDITY_UUID); - atval[0] = 0x27; - attrib_db_add(0x0212, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 1); - - /* Thermometer: relative humidity characteristic format */ - bt_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID); - atval[0] = 0x04; - atval[1] = 0x00; - att_put_u16(FMT_PERCENT_UUID, &atval[2]); - att_put_u16(BLUETOOTH_SIG_UUID, &atval[4]); - att_put_u16(FMT_OUTSIDE_UUID, &atval[6]); - attrib_db_add(0x0213, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 8); - - /* Thermometer: characteristic user description */ - bt_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID); - len = strlen(desc_out_hum); - strncpy((char *) atval, desc_out_hum, len); - attrib_db_add(0x0214, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len); - - /* Add an SDP record for the above service */ - handle = attrib_create_sdp(0x0200, "Thermometer"); - if (handle) - sdp_handles = g_slist_prepend(sdp_handles, GUINT_TO_POINTER(handle)); - - /* Secondary Service: Manufacturer Service */ - bt_uuid16_create(&uuid, GATT_SND_SVC_UUID); - att_put_u16(MANUFACTURER_SVC_UUID, &atval[0]); - attrib_db_add(0x0500, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2); - - /* Manufacturer name characteristic definition */ - bt_uuid16_create(&uuid, GATT_CHARAC_UUID); - atval[0] = ATT_CHAR_PROPER_READ; - att_put_u16(0x0502, &atval[1]); - att_put_u16(MANUFACTURER_NAME_UUID, &atval[3]); - attrib_db_add(0x0501, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); - - /* Manufacturer name characteristic value */ - bt_uuid16_create(&uuid, MANUFACTURER_NAME_UUID); - len = strlen(manufacturer_name1); - strncpy((char *) atval, manufacturer_name1, len); - attrib_db_add(0x0502, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len); - - /* Manufacturer serial number characteristic */ - bt_uuid16_create(&uuid, GATT_CHARAC_UUID); - atval[0] = ATT_CHAR_PROPER_READ; - att_put_u16(0x0504, &atval[1]); - att_put_u16(MANUFACTURER_SERIAL_UUID, &atval[3]); - attrib_db_add(0x0503, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); - - /* Manufacturer serial number characteristic value */ - bt_uuid16_create(&uuid, MANUFACTURER_SERIAL_UUID); - len = strlen(serial1); - strncpy((char *) atval, serial1, len); - attrib_db_add(0x0504, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len); - - /* Secondary Service: Manufacturer Service */ - bt_uuid16_create(&uuid, GATT_SND_SVC_UUID); - att_put_u16(MANUFACTURER_SVC_UUID, &atval[0]); - attrib_db_add(0x0505, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2); - - /* Manufacturer name characteristic definition */ - bt_uuid16_create(&uuid, GATT_CHARAC_UUID); - atval[0] = ATT_CHAR_PROPER_READ; - att_put_u16(0x0507, &atval[1]); - att_put_u16(MANUFACTURER_NAME_UUID, &atval[3]); - attrib_db_add(0x0506, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); - - /* Secondary Service: Vendor Specific Service */ - bt_uuid16_create(&uuid, GATT_SND_SVC_UUID); - att_put_u16(VENDOR_SPECIFIC_SVC_UUID, &atval[0]); - attrib_db_add(0x0550, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2); - - /* Vendor Specific Type characteristic definition */ - bt_uuid16_create(&uuid, GATT_CHARAC_UUID); - atval[0] = ATT_CHAR_PROPER_READ; - att_put_u16(0x0568, &atval[1]); - att_put_u16(VENDOR_SPECIFIC_TYPE_UUID, &atval[3]); - attrib_db_add(0x0560, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); - - /* Vendor Specific Type characteristic value */ - bt_uuid16_create(&uuid, VENDOR_SPECIFIC_TYPE_UUID); - atval[0] = 0x56; - atval[1] = 0x65; - atval[2] = 0x6E; - atval[3] = 0x64; - atval[4] = 0x6F; - atval[5] = 0x72; - attrib_db_add(0x0568, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 6); - - /* Manufacturer name attribute */ - bt_uuid16_create(&uuid, MANUFACTURER_NAME_UUID); - len = strlen(manufacturer_name2); - strncpy((char *) atval, manufacturer_name2, len); - attrib_db_add(0x0507, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len); - - /* Characteristic: serial number */ - bt_uuid16_create(&uuid, GATT_CHARAC_UUID); - atval[0] = ATT_CHAR_PROPER_READ; - att_put_u16(0x0509, &atval[1]); - att_put_u16(MANUFACTURER_SERIAL_UUID, &atval[3]); - attrib_db_add(0x0508, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); - - /* Serial number characteristic value */ - bt_uuid16_create(&uuid, MANUFACTURER_SERIAL_UUID); - len = strlen(serial2); - strncpy((char *) atval, serial2, len); - attrib_db_add(0x0509, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len); - - /* Weight service: primary service definition */ - bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID); - memcpy(atval, &prim_weight_uuid_btorder, 16); - attrib_db_add(0x0680, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 16); - - /* Weight: include */ - bt_uuid16_create(&uuid, GATT_INCLUDE_UUID); - att_put_u16(0x0505, &atval[0]); - att_put_u16(0x0509, &atval[2]); - att_put_u16(MANUFACTURER_SVC_UUID, &atval[4]); - attrib_db_add(0x0681, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 6); - - /* Weight: characteristic */ - bt_uuid16_create(&uuid, GATT_CHARAC_UUID); - atval[0] = ATT_CHAR_PROPER_READ; - att_put_u16(0x0683, &atval[1]); - memcpy(&atval[3], &char_weight_uuid_btorder, 16); - attrib_db_add(0x0682, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 19); - - /* Weight: characteristic value */ - bt_uuid128_create(&uuid, char_weight_uuid); - atval[0] = 0x82; - atval[1] = 0x55; - atval[2] = 0x00; - atval[3] = 0x00; - attrib_db_add(0x0683, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 4); - - /* Weight: characteristic format */ - bt_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID); - atval[0] = 0x08; - atval[1] = 0xFD; - att_put_u16(FMT_KILOGRAM_UUID, &atval[2]); - att_put_u16(BLUETOOTH_SIG_UUID, &atval[4]); - att_put_u16(FMT_HANGING_UUID, &atval[6]); - attrib_db_add(0x0684, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 8); - - /* Weight: characteristic user description */ - bt_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID); - len = strlen(desc_weight); - strncpy((char *) atval, desc_weight, len); - attrib_db_add(0x0685, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len); - - /* Add an SDP record for the above service */ - handle = attrib_create_sdp(0x0680, "Weight Service"); - if (handle) - sdp_handles = g_slist_prepend(sdp_handles, GUINT_TO_POINTER(handle)); - - return 0; -} - -int server_example_init(void) -{ - return register_attributes(); -} - -void server_example_exit(void) -{ - while (sdp_handles) { - uint32_t handle = GPOINTER_TO_UINT(sdp_handles->data); - - attrib_free_sdp(handle); - sdp_handles = g_slist_remove(sdp_handles, sdp_handles->data); - } -} diff -Nru bluez-4.91/attrib/example.h bluez-4.96/attrib/example.h --- bluez-4.91/attrib/example.h 2010-10-02 23:25:27.000000000 +0000 +++ bluez-4.96/attrib/example.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2010 Nokia Corporation - * Copyright (C) 2010 Marcel Holtmann - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -int server_example_init(void); -void server_example_exit(void); diff -Nru bluez-4.91/attrib/gatt.c bluez-4.96/attrib/gatt.c --- bluez-4.91/attrib/gatt.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/attrib/gatt.c 2011-07-04 04:59:05.000000000 +0000 @@ -22,9 +22,18 @@ * */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include +#include #include #include +#include +#include + +#include "glib-helper.h" #include "att.h" #include "gattrib.h" @@ -56,8 +65,7 @@ static void discover_char_free(struct discover_char *dc) { - g_slist_foreach(dc->characteristics, (GFunc) g_free, NULL); - g_slist_free(dc->characteristics); + g_slist_free_full(dc->characteristics, g_free); g_attrib_unref(dc->attrib); g_free(dc->uuid); g_free(dc); @@ -68,13 +76,11 @@ { bt_uuid_t prim; guint16 plen; - uint8_t op; bt_uuid16_create(&prim, GATT_PRIM_SVC_UUID); if (uuid == NULL) { /* Discover all primary services */ - op = ATT_OP_READ_BY_GROUP_REQ; plen = enc_read_by_grp_req(start, end, &prim, pdu, len); } else { uint16_t u16; @@ -83,7 +89,6 @@ int vlen; /* Discover primary service by service UUID */ - op = ATT_OP_FIND_BY_TYPE_REQ; if (uuid->type == BT_UUID16) { u16 = htobs(uuid->value.u16); @@ -575,3 +580,78 @@ return g_attrib_send(attrib, 0, ATT_OP_WRITE_CMD, buf, plen, NULL, user_data, notify); } + +static sdp_data_t *proto_seq_find(sdp_list_t *proto_list) +{ + sdp_list_t *list; + uuid_t proto; + + sdp_uuid16_create(&proto, ATT_UUID); + + for (list = proto_list; list; list = list->next) { + sdp_list_t *p; + for (p = list->data; p; p = p->next) { + sdp_data_t *seq = p->data; + if (seq && seq->dtd == SDP_UUID16 && + sdp_uuid16_cmp(&proto, &seq->val.uuid) == 0) + return seq->next; + } + } + + return NULL; +} + +static gboolean parse_proto_params(sdp_list_t *proto_list, uint16_t *psm, + uint16_t *start, uint16_t *end) +{ + sdp_data_t *seq1, *seq2; + + if (psm) + *psm = sdp_get_proto_port(proto_list, L2CAP_UUID); + + /* Getting start and end handle */ + seq1 = proto_seq_find(proto_list); + if (!seq1 || seq1->dtd != SDP_UINT16) + return FALSE; + + seq2 = seq1->next; + if (!seq2 || seq2->dtd != SDP_UINT16) + return FALSE; + + if (start) + *start = seq1->val.uint16; + + if (end) + *end = seq2->val.uint16; + + return TRUE; +} + +gboolean gatt_parse_record(const sdp_record_t *rec, + uuid_t *prim_uuid, uint16_t *psm, + uint16_t *start, uint16_t *end) +{ + sdp_list_t *list; + uuid_t uuid; + gboolean ret; + + if (sdp_get_service_classes(rec, &list) < 0) + return FALSE; + + memcpy(&uuid, list->data, sizeof(uuid)); + sdp_list_free(list, free); + + if (sdp_get_access_protos(rec, &list) < 0) + return FALSE; + + ret = parse_proto_params(list, psm, start, end); + + sdp_list_foreach(list, (sdp_list_func_t) sdp_list_free, NULL); + sdp_list_free(list, NULL); + + /* FIXME: replace by bt_uuid_t after uuid_t/sdp code cleanup */ + if (ret && prim_uuid) + memcpy(prim_uuid, &uuid, sizeof(uuid_t)); + + return ret; +} diff -Nru bluez-4.91/attrib/gatt.h bluez-4.96/attrib/gatt.h --- bluez-4.91/attrib/gatt.h 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/attrib/gatt.h 2011-05-03 08:20:36.000000000 +0000 @@ -21,8 +21,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ - -#define GATT_CID 4 +#include typedef void (*gatt_cb_t) (GSList *l, guint8 status, gpointer user_data); @@ -51,3 +50,7 @@ guint gatt_exchange_mtu(GAttrib *attrib, uint16_t mtu, GAttribResultFunc func, gpointer user_data); + +gboolean gatt_parse_record(const sdp_record_t *rec, + uuid_t *prim_uuid, uint16_t *psm, + uint16_t *start, uint16_t *end); diff -Nru bluez-4.91/attrib/gattrib.c bluez-4.96/attrib/gattrib.c --- bluez-4.91/attrib/gattrib.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/attrib/gattrib.c 2011-04-25 09:44:21.000000000 +0000 @@ -409,7 +409,7 @@ if (bt_io_get(attrib->io, BT_IO_L2CAP, NULL, BT_IO_OPT_OMTU, &omtu, BT_IO_OPT_INVALID)) { - if (omtu > ATT_MAX_MTU) + if (omtu == 0 || omtu > ATT_MAX_MTU) omtu = ATT_MAX_MTU; } else omtu = ATT_DEFAULT_LE_MTU; diff -Nru bluez-4.91/attrib/gatttool.c bluez-4.96/attrib/gatttool.c --- bluez-4.91/attrib/gatttool.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/attrib/gatttool.c 2011-07-04 04:59:05.000000000 +0000 @@ -63,6 +63,7 @@ static gboolean opt_interactive = FALSE; static GMainLoop *event_loop; static gboolean got_error = FALSE; +static GSourceFunc operation; struct characteristic_data { GAttrib *attrib; @@ -70,13 +71,68 @@ uint16_t end; }; +static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data) +{ + GAttrib *attrib = user_data; + uint8_t opdu[ATT_MAX_MTU]; + uint16_t handle, i, olen = 0; + + handle = att_get_u16(&pdu[1]); + + switch (pdu[0]) { + case ATT_OP_HANDLE_NOTIFY: + g_print("Notification handle = 0x%04x value: ", handle); + break; + case ATT_OP_HANDLE_IND: + g_print("Indication handle = 0x%04x value: ", handle); + break; + default: + g_print("Invalid opcode\n"); + return; + } + + for (i = 3; i < len; i++) + g_print("%02x ", pdu[i]); + + g_print("\n"); + + if (pdu[0] == ATT_OP_HANDLE_NOTIFY) + return; + + olen = enc_confirmation(opdu, sizeof(opdu)); + + if (olen > 0) + g_attrib_send(attrib, 0, opdu[0], opdu, olen, NULL, NULL, NULL); +} + +static gboolean listen_start(gpointer user_data) +{ + GAttrib *attrib = user_data; + + g_attrib_register(attrib, ATT_OP_HANDLE_NOTIFY, events_handler, + attrib, NULL); + g_attrib_register(attrib, ATT_OP_HANDLE_IND, events_handler, + attrib, NULL); + + return FALSE; +} + static void connect_cb(GIOChannel *io, GError *err, gpointer user_data) { + GAttrib *attrib; + if (err) { g_printerr("%s\n", err->message); got_error = TRUE; g_main_loop_quit(event_loop); } + + attrib = g_attrib_new(io); + + if (opt_listen) + g_idle_add(listen_start, attrib); + + operation(attrib); } static void primary_all_cb(GSList *services, guint8 status, gpointer user_data) @@ -120,52 +176,6 @@ g_main_loop_quit(event_loop); } -static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data) -{ - GAttrib *attrib = user_data; - uint8_t opdu[ATT_MAX_MTU]; - uint16_t handle, i, olen = 0; - - handle = att_get_u16(&pdu[1]); - - switch (pdu[0]) { - case ATT_OP_HANDLE_NOTIFY: - g_print("Notification handle = 0x%04x value: ", handle); - break; - case ATT_OP_HANDLE_IND: - g_print("Indication handle = 0x%04x value: ", handle); - break; - default: - g_print("Invalid opcode\n"); - return; - } - - for (i = 3; i < len; i++) - g_print("%02x ", pdu[i]); - - g_print("\n"); - - if (pdu[0] == ATT_OP_HANDLE_NOTIFY) - return; - - olen = enc_confirmation(opdu, sizeof(opdu)); - - if (olen > 0) - g_attrib_send(attrib, 0, opdu[0], opdu, olen, NULL, NULL, NULL); -} - -static gboolean listen_start(gpointer user_data) -{ - GAttrib *attrib = user_data; - - g_attrib_register(attrib, ATT_OP_HANDLE_NOTIFY, events_handler, - attrib, NULL); - g_attrib_register(attrib, ATT_OP_HANDLE_IND, events_handler, - attrib, NULL); - - return FALSE; -} - static gboolean primary(gpointer user_data) { GAttrib *attrib = user_data; @@ -273,12 +283,6 @@ att_data_list_free(list); - gatt_read_char_by_uuid(char_data->attrib, char_data->start, - char_data->end, opt_uuid, - char_read_by_uuid_cb, - char_data); - - return; done: g_free(char_data); g_main_loop_quit(event_loop); @@ -366,7 +370,7 @@ goto done; } - g_print("Characteristic value was written sucessfully\n"); + g_print("Characteristic value was written successfully\n"); done: if (opt_listen == FALSE) @@ -533,9 +537,7 @@ GOptionContext *context; GOptionGroup *gatt_group, *params_group, *char_rw_group; GError *gerr = NULL; - GAttrib *attrib; GIOChannel *chan; - GSourceFunc callback; opt_sec_level = g_strdup("low"); @@ -576,17 +578,17 @@ } if (opt_primary) - callback = primary; + operation = primary; else if (opt_characteristics) - callback = characteristics; + operation = characteristics; else if (opt_char_read) - callback = characteristics_read; + operation = characteristics_read; else if (opt_char_write) - callback = characteristics_write; + operation = characteristics_write; else if (opt_char_write_req) - callback = characteristics_write_req; + operation = characteristics_write_req; else if (opt_char_desc) - callback = characteristics_desc; + operation = characteristics_desc; else { gchar *help = g_option_context_get_help(context, TRUE, NULL); g_print("%s\n", help); @@ -602,24 +604,12 @@ goto done; } - attrib = g_attrib_new(chan); - g_io_channel_unref(chan); - event_loop = g_main_loop_new(NULL, FALSE); - if (opt_listen) - g_idle_add(listen_start, attrib); - - g_idle_add(callback, attrib); - g_main_loop_run(event_loop); - g_attrib_unregister_all(attrib); - g_main_loop_unref(event_loop); - g_attrib_unref(attrib); - done: g_option_context_free(context); g_free(opt_src); diff -Nru bluez-4.91/attrib/interactive.c bluez-4.96/attrib/interactive.c --- bluez-4.91/attrib/interactive.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/attrib/interactive.c 2011-07-04 04:59:05.000000000 +0000 @@ -315,14 +315,8 @@ att_data_list_free(list); - gatt_read_char_by_uuid(attrib, char_data->start, char_data->end, - &char_data->uuid, char_read_by_uuid_cb, - char_data); - rl_forced_update_display(); - return; - done: g_free(char_data); } @@ -724,6 +718,8 @@ "Show this help"}, { "exit", cmd_exit, "", "Exit interactive mode" }, + { "quit", cmd_exit, "", + "Exit interactive mode" }, { "connect", cmd_connect, "[address]", "Connect to a remote device" }, { "disconnect", cmd_disconnect, "", diff -Nru bluez-4.91/attrib/main.c bluez-4.96/attrib/main.c --- bluez-4.91/attrib/main.c 2010-08-25 05:10:02.000000000 +0000 +++ bluez-4.96/attrib/main.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,60 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2010 Nokia Corporation - * Copyright (C) 2010 Marcel Holtmann - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include - -#include "plugin.h" -#include "manager.h" - -static DBusConnection *connection; - -static int attrib_init(void) -{ - connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); - if (connection == NULL) - return -EIO; - - if (attrib_manager_init(connection) < 0) { - dbus_connection_unref(connection); - return -EIO; - } - - return 0; -} - -static void attrib_exit(void) -{ - attrib_manager_exit(); - - dbus_connection_unref(connection); -} - -BLUETOOTH_PLUGIN_DEFINE(attrib, VERSION, - BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, attrib_init, attrib_exit) diff -Nru bluez-4.91/attrib/manager.c bluez-4.96/attrib/manager.c --- bluez-4.91/attrib/manager.c 2011-03-16 00:34:27.000000000 +0000 +++ bluez-4.96/attrib/manager.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2010 Nokia Corporation - * Copyright (C) 2010 Marcel Holtmann - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include - -#include "../src/adapter.h" -#include "../src/device.h" -#include "hcid.h" - -#include "manager.h" -#include "client.h" -#include "example.h" - -#define GATT_UUID "00001801-0000-1000-8000-00805f9b34fb" - -static DBusConnection *connection; - -static int client_probe(struct btd_device *device, GSList *uuids) -{ - const sdp_record_t *rec; - int psm = -1; - - rec = btd_device_get_record(device, GATT_UUID); - if (rec) { - sdp_list_t *list; - if (sdp_get_access_protos(rec, &list) < 0) - return -1; - - psm = sdp_get_proto_port(list, L2CAP_UUID); - - sdp_list_foreach(list, (sdp_list_func_t) sdp_list_free, NULL); - sdp_list_free(list, NULL); - - if (psm < 0) - return -1; - } - - return attrib_client_register(device, psm); -} - -static void client_remove(struct btd_device *device) -{ - attrib_client_unregister(device); -} - -static struct btd_device_driver client_driver = { - .name = "gatt-client", - .uuids = BTD_UUIDS(GATT_UUID), - .probe = client_probe, - .remove = client_remove, -}; - -int attrib_manager_init(DBusConnection *conn) -{ - connection = dbus_connection_ref(conn); - - attrib_client_init(connection); - - btd_register_device_driver(&client_driver); - - - if (main_opts.attrib_server) - return server_example_init(); - - return 0; -} - -void attrib_manager_exit(void) -{ - btd_unregister_device_driver(&client_driver); - - if (main_opts.attrib_server) - server_example_exit(); - - attrib_client_exit(); - - dbus_connection_unref(connection); -} diff -Nru bluez-4.91/attrib/manager.h bluez-4.96/attrib/manager.h --- bluez-4.91/attrib/manager.h 2010-08-25 05:10:02.000000000 +0000 +++ bluez-4.96/attrib/manager.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2010 Nokia Corporation - * Copyright (C) 2010 Marcel Holtmann - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -int attrib_manager_init(DBusConnection *conn); -void attrib_manager_exit(void); diff -Nru bluez-4.91/attrib/utils.c bluez-4.96/attrib/utils.c --- bluez-4.91/attrib/utils.c 2011-03-16 00:34:27.000000000 +0000 +++ bluez-4.96/attrib/utils.c 2011-05-03 08:20:36.000000000 +0000 @@ -30,6 +30,7 @@ #include #include +#include "att.h" #include "gattrib.h" #include "gatt.h" #include "btio.h" @@ -84,7 +85,7 @@ chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err, BT_IO_OPT_SOURCE_BDADDR, &sba, BT_IO_OPT_DEST_BDADDR, &dba, - BT_IO_OPT_CID, GATT_CID, + BT_IO_OPT_CID, ATT_CID, BT_IO_OPT_OMTU, mtu, BT_IO_OPT_SEC_LEVEL, sec, BT_IO_OPT_INVALID); diff -Nru bluez-4.91/audio/a2dp.c bluez-4.96/audio/a2dp.c --- bluez-4.91/audio/a2dp.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/audio/a2dp.c 2011-07-31 06:52:19.000000000 +0000 @@ -36,6 +36,7 @@ #include #include +#include "glib-helper.h" #include "log.h" #include "device.h" #include "manager.h" @@ -82,6 +83,7 @@ a2dp_config_cb_t config_cb; a2dp_stream_cb_t resume_cb; a2dp_stream_cb_t suspend_cb; + guint source_id; void *user_data; unsigned int id; }; @@ -162,10 +164,8 @@ setups = g_slist_remove(setups, s); if (s->session) avdtp_unref(s->session); - g_slist_foreach(s->cb, (GFunc) g_free, NULL); - g_slist_free(s->cb); - g_slist_foreach(s->caps, (GFunc) g_free, NULL); - g_slist_free(s->caps); + g_slist_free_full(s->cb, g_free); + g_slist_free_full(s->caps, g_free); g_free(s); } @@ -197,13 +197,40 @@ { struct a2dp_setup *setup = cb->setup; + if (cb->source_id) + g_source_remove(cb->source_id); + setup->cb = g_slist_remove(setup->cb, cb); setup_unref(cb->setup); g_free(cb); } -static gboolean finalize_config(struct a2dp_setup *s) +static void finalize_setup_errno(struct a2dp_setup *s, int err, + GSourceFunc cb1, ...) +{ + GSourceFunc finalize; + va_list args; + struct avdtp_error avdtp_err; + + if (err < 0) { + avdtp_error_init(&avdtp_err, AVDTP_ERRNO, -err); + s->err = &avdtp_err; + } + + va_start(args, cb1); + finalize = cb1; + setup_ref(s); + while (finalize != NULL) { + finalize(s); + finalize = va_arg(args, GSourceFunc); + } + setup_unref(s); + va_end(args); +} + +static gboolean finalize_config(gpointer data) { + struct a2dp_setup *s = data; GSList *l; struct avdtp_stream *stream = s->err ? NULL : s->stream; @@ -223,18 +250,9 @@ return FALSE; } -static gboolean finalize_config_errno(struct a2dp_setup *s, int err) -{ - struct avdtp_error avdtp_err; - - avdtp_error_init(&avdtp_err, AVDTP_ERRNO, -err); - s->err = err ? &avdtp_err : NULL; - - return finalize_config(s); -} - -static gboolean finalize_resume(struct a2dp_setup *s) +static gboolean finalize_resume(gpointer data) { + struct a2dp_setup *s = data; GSList *l; for (l = s->cb; l != NULL; ) { @@ -252,18 +270,9 @@ return FALSE; } -static gboolean finalize_resume_errno(struct a2dp_setup *s, int err) -{ - struct avdtp_error avdtp_err; - - avdtp_error_init(&avdtp_err, AVDTP_ERRNO, -err); - s->err = err ? &avdtp_err : NULL; - - return finalize_resume(s); -} - -static gboolean finalize_suspend(struct a2dp_setup *s) +static gboolean finalize_suspend(gpointer data) { + struct a2dp_setup *s = data; GSList *l; for (l = s->cb; l != NULL; ) { @@ -281,17 +290,7 @@ return FALSE; } -static gboolean finalize_suspend_errno(struct a2dp_setup *s, int err) -{ - struct avdtp_error avdtp_err; - - avdtp_error_init(&avdtp_err, AVDTP_ERRNO, -err); - s->err = err ? &avdtp_err : NULL; - - return finalize_suspend(s); -} - -static gboolean finalize_select(struct a2dp_setup *s) +static void finalize_select(struct a2dp_setup *s) { GSList *l; @@ -306,8 +305,6 @@ cb->select_cb(s->session, s->sep, s->caps, cb->user_data); setup_cb_free(cb); } - - return FALSE; } static struct a2dp_setup *find_setup_by_session(struct avdtp *session) @@ -373,11 +370,10 @@ sep->session = NULL; } - if (sep->endpoint) - media_endpoint_clear_configuration(sep->endpoint); - sep->stream = NULL; + if (sep->endpoint) + media_endpoint_clear_configuration(sep->endpoint); } static gboolean auto_config(gpointer data) @@ -777,7 +773,7 @@ if (ret == NULL) { setup->stream = NULL; - finalize_config_errno(setup, -EPERM); + finalize_setup_errno(setup, -EPERM, finalize_config, NULL); return; } @@ -787,7 +783,7 @@ error("Error on avdtp_open %s (%d)", strerror(-err), -err); setup->stream = NULL; - finalize_config_errno(setup, err); + finalize_setup_errno(setup, err, finalize_config, NULL); } static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep, @@ -844,7 +840,7 @@ return; setup->stream = NULL; - finalize_config_errno(setup, -EPERM); + finalize_setup_errno(setup, -EPERM, finalize_config, NULL); return; } @@ -852,7 +848,7 @@ if (ret < 0) { error("Error on avdtp_open %s (%d)", strerror(-ret), -ret); setup->stream = NULL; - finalize_config_errno(setup, ret); + finalize_setup_errno(setup, ret, finalize_config, NULL); } } @@ -1011,6 +1007,7 @@ struct a2dp_sep *a2dp_sep = user_data; struct a2dp_setup *setup; gboolean start; + int perr; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) DBG("Sink %p: Suspend_Cfm", sep); @@ -1029,23 +1026,22 @@ if (err) { setup->stream = NULL; setup->err = err; - finalize_suspend(setup); } - else - finalize_suspend_errno(setup, 0); + + finalize_suspend(setup); if (!start) return; if (err) { - setup->err = err; - finalize_suspend(setup); - } else if (avdtp_start(session, a2dp_sep->stream) < 0) { - struct avdtp_error start_err; - error("avdtp_start failed"); - avdtp_error_init(&start_err, AVDTP_ERRNO, EIO); - setup->err = err; - finalize_suspend(setup); + finalize_resume(setup); + return; + } + + perr = avdtp_start(session, a2dp_sep->stream); + if (perr < 0) { + error("Error on avdtp_start %s (%d)", strerror(-perr), -perr); + finalize_setup_errno(setup, -EIO, finalize_suspend, NULL); } } @@ -1065,8 +1061,8 @@ if (!setup) return TRUE; - finalize_suspend_errno(setup, -ECONNRESET); - finalize_resume_errno(setup, -ECONNRESET); + finalize_setup_errno(setup, -ECONNRESET, finalize_suspend, + finalize_resume, NULL); return TRUE; } @@ -1099,7 +1095,7 @@ return FALSE; failed: - finalize_config_errno(setup, posix_err); + finalize_setup_errno(setup, posix_err, finalize_config, NULL); return FALSE; } @@ -1377,10 +1373,9 @@ static struct a2dp_server *find_server(GSList *list, const bdaddr_t *src) { - GSList *l; - for (l = list; l; l = l->next) { - struct a2dp_server *server = l->data; + for (; list; list = list->next) { + struct a2dp_server *server = list->data; if (bacmp(&server->src, src) == 0) return server; @@ -1552,15 +1547,20 @@ if (!server) return; - g_slist_foreach(server->sinks, (GFunc) a2dp_remove_sep, NULL); - g_slist_free(server->sinks); - - g_slist_foreach(server->sources, (GFunc) a2dp_remove_sep, NULL); - g_slist_free(server->sources); + g_slist_free_full(server->sinks, (GDestroyNotify) a2dp_unregister_sep); + g_slist_free_full(server->sources, + (GDestroyNotify) a2dp_unregister_sep); avdtp_exit(src); servers = g_slist_remove(servers, server); + + if (server->source_record_id) + remove_record_from_server(server->source_record_id); + + if (server->sink_record_id) + remove_record_from_server(server->sink_record_id); + g_free(server); if (servers) @@ -1688,6 +1688,9 @@ } } + if (sep->locked) + return; + a2dp_unregister_sep(sep); } @@ -2037,7 +2040,6 @@ struct avdtp_media_codec_capability *codec_cap = NULL; int posix_err; bdaddr_t src; - uint8_t remote_type; avdtp_get_peers(session, &src, NULL); server = find_server(servers, &src); @@ -2075,20 +2077,16 @@ /* Copy given caps if they are different than current caps */ if (setup->caps != caps) { - g_slist_foreach(setup->caps, (GFunc) g_free, NULL); - g_slist_free(setup->caps); + g_slist_free_full(setup->caps, g_free); setup->caps = g_slist_copy(caps); } switch (avdtp_sep_get_state(sep->lsep)) { case AVDTP_STATE_IDLE: - if (sep->type == AVDTP_SEP_TYPE_SOURCE) { + if (sep->type == AVDTP_SEP_TYPE_SOURCE) l = server->sources; - remote_type = AVDTP_SEP_TYPE_SINK; - } else { - remote_type = AVDTP_SEP_TYPE_SOURCE; + else l = server->sinks; - } for (; l != NULL; l = l->next) { tmp = l->data; @@ -2126,7 +2124,8 @@ case AVDTP_STATE_STREAMING: if (avdtp_stream_has_capabilities(setup->stream, caps)) { DBG("Configuration match: resuming"); - g_idle_add((GSourceFunc) finalize_config, setup); + cb_data->source_id = g_idle_add(finalize_config, + setup); } else if (!setup->reconfigure) { setup->reconfigure = TRUE; if (avdtp_close(session, sep->stream, FALSE) < 0) { @@ -2184,7 +2183,8 @@ if (sep->suspending) setup->start = TRUE; else - g_idle_add((GSourceFunc) finalize_resume, setup); + cb_data->source_id = g_idle_add(finalize_resume, + setup); break; default: error("SEP in bad state for resume"); @@ -2221,7 +2221,7 @@ goto failed; break; case AVDTP_STATE_OPEN: - g_idle_add((GSourceFunc) finalize_suspend, setup); + cb_data->source_id = g_idle_add(finalize_suspend, setup); break; case AVDTP_STATE_STREAMING: if (avdtp_suspend(session, sep->stream) < 0) { @@ -2286,7 +2286,9 @@ gboolean a2dp_sep_unlock(struct a2dp_sep *sep, struct avdtp *session) { + struct a2dp_server *server = sep->server; avdtp_state_t state; + GSList *l; state = avdtp_sep_get_state(sep->lsep); @@ -2294,6 +2296,17 @@ DBG("SEP %p unlocked", sep->lsep); + if (sep->type == AVDTP_SEP_TYPE_SOURCE) + l = server->sources; + else + l = server->sinks; + + /* Unregister sep if it was removed */ + if (g_slist_find(l, sep) == NULL) { + a2dp_unregister_sep(sep); + return TRUE; + } + if (!sep->stream || state == AVDTP_STATE_IDLE) return TRUE; diff -Nru bluez-4.91/audio/avdtp.c bluez-4.96/audio/avdtp.c --- bluez-4.91/audio/avdtp.c 2011-03-16 00:34:27.000000000 +0000 +++ bluez-4.96/audio/avdtp.c 2011-07-31 06:52:19.000000000 +0000 @@ -61,6 +61,10 @@ #define MAX_SEID 0x3E +#ifndef MAX +# define MAX(x, y) ((x) > (y) ? (x) : (y)) +#endif + #define AVDTP_DISCOVER 0x01 #define AVDTP_GET_CAPABILITIES 0x02 #define AVDTP_SET_CONFIGURATION 0x03 @@ -374,6 +378,7 @@ guint idle_timer; gboolean delay_reporting; uint16_t delay; /* AVDTP 1.3 Delay Reporting feature */ + gboolean starting; /* only valid while sep state == OPEN */ }; /* Structure describing an AVDTP connection between two devices */ @@ -453,10 +458,8 @@ static struct avdtp_server *find_server(GSList *list, const bdaddr_t *src) { - GSList *l; - - for (l = list; l; l = l->next) { - struct avdtp_server *server = l->data; + for (; list; list = list->next) { + struct avdtp_server *server = list->data; if (bacmp(&server->src, src) == 0) return server; @@ -795,11 +798,8 @@ if (stream->io_id) g_source_remove(stream->io_id); - g_slist_foreach(stream->callbacks, (GFunc) g_free, NULL); - g_slist_free(stream->callbacks); - - g_slist_foreach(stream->caps, (GFunc) g_free, NULL); - g_slist_free(stream->caps); + g_slist_free_full(stream->callbacks, g_free); + g_slist_free_full(stream->caps, g_free); g_free(stream); } @@ -877,6 +877,8 @@ { struct avdtp_stream *stream = session->pending_open; struct avdtp_local_sep *sep = stream->lsep; + int sk, buf_size, min_buf_size; + GError *err = NULL; session->pending_open = NULL; @@ -901,22 +903,30 @@ stream->omtu = omtu; stream->imtu = imtu; - /* only if local SEP is of type SRC */ - if (sep->info.type == AVDTP_SEP_TYPE_SOURCE) { - int sk, buf_size, min_buf_size; - - sk = g_io_channel_unix_get_fd(stream->io); - buf_size = get_send_buffer_size(sk); - if (buf_size < 0) - goto proceed; - - DBG("sk %d, omtu %d, send buffer size %d", sk, omtu, buf_size); - min_buf_size = omtu * 2; - if (buf_size < min_buf_size) { - DBG("send buffer size to be increassed to %d", - min_buf_size); - set_send_buffer_size(sk, min_buf_size); - } + /* Apply special settings only if local SEP is of type SRC */ + if (sep->info.type != AVDTP_SEP_TYPE_SOURCE) + goto proceed; + + bt_io_set(stream->io, BT_IO_L2CAP, &err, + BT_IO_OPT_FLUSHABLE, TRUE, + BT_IO_OPT_INVALID); + if (err != NULL) { + error("Enabling flushable packets failed: %s", err->message); + g_error_free(err); + } else + DBG("Flushable packets enabled"); + + sk = g_io_channel_unix_get_fd(stream->io); + buf_size = get_send_buffer_size(sk); + if (buf_size < 0) + goto proceed; + + DBG("sk %d, omtu %d, send buffer size %d", sk, omtu, buf_size); + min_buf_size = omtu * 2; + if (buf_size < min_buf_size) { + DBG("send buffer size to be increassed to %d", + min_buf_size); + set_send_buffer_size(sk, min_buf_size); } proceed: @@ -1050,17 +1060,13 @@ old_state = sep->state; sep->state = state; - for (l = stream->callbacks; l != NULL; l = g_slist_next(l)) { - struct stream_callback *cb = l->data; - cb->cb(stream, old_state, state, err_ptr, cb->user_data); - } - switch (state) { case AVDTP_STATE_CONFIGURED: if (sep->info.type == AVDTP_SEP_TYPE_SINK) avdtp_delay_report(session, stream, stream->delay); break; case AVDTP_STATE_OPEN: + stream->starting = FALSE; if (old_state > AVDTP_STATE_OPEN && session->auto_dc) stream->idle_timer = g_timeout_add_seconds(STREAM_TIMEOUT, stream_timeout, @@ -1079,18 +1085,29 @@ g_source_remove(stream->idle_timer); stream->idle_timer = 0; } - session->streams = g_slist_remove(session->streams, stream); if (session->pending_open == stream) handle_transport_connect(session, NULL, 0, 0); if (session->req && session->req->stream == stream) handle_unanswered_req(session, stream); /* Remove pending commands for this stream from the queue */ cleanup_queue(session, stream); - stream_free(stream); break; default: break; } + + l = stream->callbacks; + while (l != NULL) { + struct stream_callback *cb = l->data; + l = g_slist_next(l); + cb->cb(stream, old_state, state, err_ptr, cb->user_data); + } + + if (state == AVDTP_STATE_IDLE && + g_slist_find(session->streams, stream)) { + session->streams = g_slist_remove(session->streams, stream); + stream_free(stream); + } } static void finalize_discovery(struct avdtp *session, int err) @@ -1217,8 +1234,7 @@ if (session->req) pending_req_free(session->req); - g_slist_foreach(session->seps, (GFunc) g_free, NULL); - g_slist_free(session->seps); + g_slist_free_full(session->seps, g_free); g_free(session->buf); @@ -1694,10 +1710,13 @@ stream = sep->stream; - if (sep->state != AVDTP_STATE_OPEN) { + /* Also reject start cmd if we already initiated start */ + if (sep->state != AVDTP_STATE_OPEN || + stream->starting == TRUE) { err = AVDTP_BAD_STATE; goto failed; } + stream->starting = TRUE; if (sep->ind && sep->ind->start) { if (!sep->ind->start(session, sep, stream, &err, @@ -1712,6 +1731,7 @@ AVDTP_START, NULL, 0); failed: + DBG("Rejecting (%d)", err); memset(&rej, 0, sizeof(rej)); rej.acp_seid = failed_seid; rej.error = err; @@ -2154,7 +2174,7 @@ } if (session->in.signal_id != session->req->signal_id) { - error("Reponse signal doesn't match"); + error("Response signal doesn't match"); return TRUE; } @@ -2205,10 +2225,8 @@ static struct avdtp *find_session(GSList *list, const bdaddr_t *dst) { - GSList *l; - - for (l = list; l != NULL; l = g_slist_next(l)) { - struct avdtp *s = l->data; + for (; list != NULL; list = g_slist_next(list)) { + struct avdtp *s = list->data; if (bacmp(dst, &s->dst)) continue; @@ -2231,22 +2249,22 @@ adapter = manager_find_adapter(&session->server->src); if (!adapter) - goto done; + return ver; ba2str(&session->dst, addr); device = adapter_find_device(adapter, addr); if (!device) - goto done; + return ver; rec = btd_device_get_record(device, A2DP_SINK_UUID); if (!rec) rec = btd_device_get_record(device, A2DP_SOURCE_UUID); if (!rec) - goto done; + return ver; if (sdp_get_access_protos(rec, &protos) < 0) - goto done; + return ver; proto_desc = sdp_get_proto_desc(protos, AVDTP_UUID); if (proto_desc && proto_desc->dtd == SDP_UINT16) @@ -2255,7 +2273,6 @@ sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL); sdp_list_free(protos, NULL); -done: return ver; } @@ -2340,7 +2357,7 @@ if (session->state == AVDTP_SESSION_STATE_CONNECTING) { DBG("AVDTP imtu=%u, omtu=%u", session->imtu, session->omtu); - session->buf = g_malloc0(session->imtu); + session->buf = g_malloc0(MAX(session->imtu, session->omtu)); avdtp_set_state(session, AVDTP_SESSION_STATE_CONNECTED); if (session->io_id) @@ -2569,9 +2586,12 @@ break; case AVDTP_START: error("Start: %s (%d)", strerror(err), err); - if (lsep && lsep->cfm && lsep->cfm->start) + if (lsep && lsep->cfm && lsep->cfm->start) { lsep->cfm->start(session, lsep, stream, &averr, lsep->user_data); + if (stream) + stream->starting = FALSE; + } break; case AVDTP_SUSPEND: error("Suspend: %s (%d)", strerror(err), err); @@ -2644,8 +2664,10 @@ if (session->state == AVDTP_SESSION_STATE_DISCONNECTED) { session->io = l2cap_connect(session); - if (!session->io) + if (!session->io) { + err = -EIO; goto failed; + } avdtp_set_state(session, AVDTP_SESSION_STATE_CONNECTING); } @@ -2706,6 +2728,8 @@ { int sep_count, i; uint8_t getcap_cmd; + int ret = 0; + gboolean getcap_pending = FALSE; if (session->version >= 0x0103 && session->server->version >= 0x0103) getcap_cmd = AVDTP_GET_ALL_CAPABILITIES; @@ -2718,7 +2742,6 @@ struct avdtp_remote_sep *sep; struct avdtp_stream *stream; struct seid_req req; - int ret; DBG("seid %d type %d media %d in use %d", resp->seps[i].seid, resp->seps[i].type, @@ -2744,12 +2767,14 @@ ret = send_request(session, TRUE, NULL, getcap_cmd, &req, sizeof(req)); - if (ret < 0) { - finalize_discovery(session, -ret); + if (ret < 0) break; - } + getcap_pending = TRUE; } + if (!getcap_pending) + finalize_discovery(session, -ret); + return TRUE; } @@ -2780,8 +2805,7 @@ sep->type, sep->media_type); if (sep->caps) { - g_slist_foreach(sep->caps, (GFunc) g_free, NULL); - g_slist_free(sep->caps); + g_slist_free_full(sep->caps, g_free); sep->caps = NULL; sep->codec = NULL; sep->delay_reporting = FALSE; @@ -3072,9 +3096,11 @@ return FALSE; error("START request rejected: %s (%d)", avdtp_strerror(&err), err.err.error_code); - if (sep && sep->cfm && sep->cfm->start) + if (sep && sep->cfm && sep->cfm->start) { sep->cfm->start(session, sep, stream, &err, sep->user_data); + stream->starting = FALSE; + } return TRUE; case AVDTP_SUSPEND: if (!stream_rej_to_err(buf, size, &err, &acp_seid)) @@ -3177,10 +3203,8 @@ gboolean avdtp_stream_has_capabilities(struct avdtp_stream *stream, GSList *caps) { - GSList *l; - - for (l = caps; l; l = g_slist_next(l)) { - struct avdtp_service_capability *cap = l->data; + for (; caps; caps = g_slist_next(caps)) { + struct avdtp_service_capability *cap = caps->data; if (!avdtp_stream_has_capability(stream, cap)) return FALSE; @@ -3534,6 +3558,7 @@ int avdtp_start(struct avdtp *session, struct avdtp_stream *stream) { struct start_req req; + int ret; if (!g_slist_find(session->streams, stream)) return -EINVAL; @@ -3546,11 +3571,20 @@ return -EINVAL; } + if (stream->starting == TRUE) { + DBG("stream already started"); + return -EINVAL; + } + memset(&req, 0, sizeof(req)); req.first_seid.seid = stream->rseid; - return send_request(session, FALSE, stream, AVDTP_START, + ret = send_request(session, FALSE, stream, AVDTP_START, &req, sizeof(req)); + if (ret == 0) + stream->starting = TRUE; + + return ret; } int avdtp_close(struct avdtp *session, struct avdtp_stream *stream, @@ -3740,7 +3774,7 @@ case AVDTP_BAD_HEADER_FORMAT: return "Bad Header Format"; case AVDTP_BAD_LENGTH: - return "Bad Packet Lenght"; + return "Bad Packet Length"; case AVDTP_BAD_ACP_SEID: return "Bad Acceptor SEID"; case AVDTP_SEP_IN_USE: @@ -3849,9 +3883,15 @@ if (!server) return; - for (l = server->sessions; l; l = l->next) { + l = server->sessions; + while (l) { struct avdtp *session = l->data; + l = l->next; + /* value of l pointer should be updated before invoking + * connection_lost since it internally uses avdtp_unref + * which operates on server->session list as well + */ connection_lost(session, -ECONNABORTED); } diff -Nru bluez-4.91/audio/control.c bluez-4.96/audio/control.c --- bluez-4.91/audio/control.c 2010-12-18 19:12:16.000000000 +0000 +++ bluez-4.96/audio/control.c 2011-07-31 06:52:19.000000000 +0000 @@ -80,6 +80,7 @@ #define CTYPE_STABLE 0xC /* opcodes */ +#define OP_VENDORDEP 0x00 #define OP_UNITINFO 0x30 #define OP_SUBUNITINFO 0x31 #define OP_PASSTHROUGH 0x7c @@ -127,6 +128,16 @@ } __attribute__ ((packed)); #define AVRCP_HEADER_LENGTH 3 +struct avrcp_spec_avc_pdu { + uint8_t company_id[3]; + uint8_t pdu_id; + uint8_t packet_type:2; + uint8_t rsvd:6; + uint16_t params_len; + uint8_t params[0]; +} __attribute__ ((packed)); +#define AVRCP_SPECAVCPDU_HEADER_LENGTH 7 + #elif __BYTE_ORDER == __BIG_ENDIAN struct avctp_header { @@ -147,6 +158,16 @@ } __attribute__ ((packed)); #define AVRCP_HEADER_LENGTH 3 +struct avrcp_spec_avc_pdu { + uint8_t company_id[3]; + uint8_t pdu_id; + uint8_t rsvd:6; + uint8_t packet_type:2; + uint16_t params_len; + uint8_t params[0]; +} __attribute__ ((packed)); +#define AVRCP_SPECAVCPDU_HEADER_LENGTH 7 + #else #error "Unknown byte order" #endif @@ -200,7 +221,7 @@ static void auth_cb(DBusError *derr, void *user_data); -static sdp_record_t *avrcp_ct_record() +static sdp_record_t *avrcp_ct_record(void) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; uuid_t root_uuid, l2cap, avctp, avrct; @@ -264,7 +285,7 @@ return record; } -static sdp_record_t *avrcp_tg_record() +static sdp_record_t *avrcp_tg_record(void) { sdp_list_t *svclass_id, *pfseq, *apseq, *root; uuid_t root_uuid, l2cap, avctp, avrtg; @@ -398,6 +419,15 @@ operands[0] & 0x7F, status); } +/* handle vendordep pdu inside an avctp packet */ +static int handle_vendordep_pdu(struct control *control, + struct avrcp_header *avrcp, + int operand_count) +{ + avrcp->code = CTYPE_NOT_IMPLEMENTED; + return AVRCP_HEADER_LENGTH; +} + static void avctp_disconnected(struct audio_device *dev) { struct control *control = dev->control; @@ -545,7 +575,7 @@ } else if (avctp->pid != htons(AV_REMOTE_SVCLASS_ID)) { avctp->ipid = 1; avctp->cr = AVCTP_RESPONSE; - avrcp->code = CTYPE_REJECTED; + packet_size = sizeof(*avctp); } else if (avctp->cr == AVCTP_COMMAND && avrcp->code == CTYPE_CONTROL && avrcp->subunit_type == SUBUNIT_PANEL && @@ -569,11 +599,20 @@ operands[1] = SUBUNIT_PANEL << 3; DBG("reply to %s", avrcp->opcode == OP_UNITINFO ? "OP_UNITINFO" : "OP_SUBUNITINFO"); + } else if (avctp->cr == AVCTP_COMMAND && + avrcp->opcode == OP_VENDORDEP) { + int r_size; + operand_count -= 3; + avctp->cr = AVCTP_RESPONSE; + r_size = handle_vendordep_pdu(control, avrcp, operand_count); + packet_size = AVCTP_HEADER_LENGTH + r_size; } else { avctp->cr = AVCTP_RESPONSE; avrcp->code = CTYPE_REJECTED; } ret = write(sock, buf, packet_size); + if (ret != packet_size) + goto failed; return TRUE; @@ -910,10 +949,8 @@ static struct avctp_server *find_server(GSList *list, const bdaddr_t *src) { - GSList *l; - - for (l = list; l; l = l->next) { - struct avctp_server *server = l->data; + for (; list; list = list->next) { + struct avctp_server *server = list->data; if (bacmp(&server->src, src) == 0) return server; @@ -1008,13 +1045,8 @@ { struct audio_device *device = data; struct control *control = device->control; - DBusMessage *reply; int err; - reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - if (control->state != AVCTP_STATE_CONNECTED) return btd_error_not_connected(msg); @@ -1033,13 +1065,8 @@ { struct audio_device *device = data; struct control *control = device->control; - DBusMessage *reply; int err; - reply = dbus_message_new_method_return(msg); - if (!reply) - return NULL; - if (control->state != AVCTP_STATE_CONNECTED) return btd_error_not_connected(msg); diff -Nru bluez-4.91/audio/ctl_bluetooth.c bluez-4.96/audio/ctl_bluetooth.c --- bluez-4.91/audio/ctl_bluetooth.c 2010-01-09 20:52:17.000000000 +0000 +++ bluez-4.96/audio/ctl_bluetooth.c 2011-07-04 04:59:05.000000000 +0000 @@ -213,11 +213,9 @@ *value = 0; ret = bluetooth_send_ctl(data, key, 0, rsp); - if (ret < 0) - goto done; + if (ret == 0) + *value = rsp->key; - *value = rsp->key; -done: return ret; } diff -Nru bluez-4.91/audio/gstavdtpsink.c bluez-4.96/audio/gstavdtpsink.c --- bluez-4.91/audio/gstavdtpsink.c 2011-01-20 07:49:26.000000000 +0000 +++ bluez-4.96/audio/gstavdtpsink.c 2011-07-04 04:59:05.000000000 +0000 @@ -1491,7 +1491,7 @@ err = gst_avdtp_sink_audioservice_send(self, &req->h); if (err < 0) { - GST_ERROR_OBJECT(self, "Error ocurred while sending " + GST_ERROR_OBJECT(self, "Error occurred while sending " "start packet"); return FALSE; } @@ -1643,7 +1643,7 @@ err = gst_avdtp_sink_audioservice_send(self, &open_req->h); if (err < 0) { - GST_ERROR_OBJECT(self, "Error ocurred while sending " + GST_ERROR_OBJECT(self, "Error occurred while sending " "open packet"); return FALSE; } @@ -1679,7 +1679,7 @@ req->h.length += req->codec.length - sizeof(req->codec); err = gst_avdtp_sink_audioservice_send(self, &req->h); if (err < 0) { - GST_ERROR_OBJECT(self, "Error ocurred while sending " + GST_ERROR_OBJECT(self, "Error occurred while sending " "configurarion packet"); return FALSE; } @@ -1868,7 +1868,7 @@ ssize_t bytes_read; const char *type, *name; uint16_t length; - int fd, err; + int fd, err = 0; length = inmsg->length ? inmsg->length : BT_SUGGESTED_BUFFER_SIZE; diff -Nru bluez-4.91/audio/gstpragma.h bluez-4.96/audio/gstpragma.h --- bluez-4.91/audio/gstpragma.h 2011-02-13 20:40:34.000000000 +0000 +++ bluez-4.96/audio/gstpragma.h 2011-05-31 02:39:53.000000000 +0000 @@ -21,4 +21,4 @@ * */ -//#pragma GCC diagnostic warning "-Wmissing-declarations" +/* #pragma GCC diagnostic warning "-Wmissing-declarations" */ diff -Nru bluez-4.91/audio/gstsbcutil.c bluez-4.96/audio/gstsbcutil.c --- bluez-4.91/audio/gstsbcutil.c 2010-01-09 20:52:17.000000000 +0000 +++ bluez-4.96/audio/gstsbcutil.c 2011-07-04 04:59:05.000000000 +0000 @@ -311,7 +311,7 @@ } /* - * Given a GstCaps, this will return a fixed GstCaps on sucessfull conversion. + * Given a GstCaps, this will return a fixed GstCaps on successful conversion. * If an error occurs, it will return NULL and error_message will contain the * error message. * diff -Nru bluez-4.91/audio/headset.c bluez-4.96/audio/headset.c --- bluez-4.91/audio/headset.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/audio/headset.c 2011-07-04 04:59:05.000000000 +0000 @@ -318,7 +318,8 @@ return 0; } -static int headset_send(struct headset *hs, char *format, ...) +static int __attribute__((format(printf, 2, 3))) + headset_send(struct headset *hs, char *format, ...) { va_list ap; int ret; @@ -411,7 +412,7 @@ else str = indicator_values(ag.indicators); - err = headset_send(hs, str); + err = headset_send(hs, "%s", str); g_free(str); @@ -444,8 +445,7 @@ g_slist_foreach(p->callbacks, (GFunc) pending_connect_complete, dev); - g_slist_foreach(p->callbacks, (GFunc) g_free, NULL); - g_slist_free(p->callbacks); + g_slist_free_full(p->callbacks, g_free); if (p->io) { g_io_channel_shutdown(p->io, TRUE, NULL); @@ -483,7 +483,7 @@ void *user_data) { struct connect_cb *cb; - unsigned int free_cb_id = 1; + static unsigned int free_cb_id = 1; pending_connect_init(hs, target_state); @@ -502,7 +502,8 @@ return cb->id; } -static void send_foreach_headset(GSList *devices, +static void __attribute__((format(printf, 3, 4))) + send_foreach_headset(GSList *devices, int (*cmp) (struct headset *hs), char *format, ...) { @@ -687,14 +688,17 @@ struct headset *hs = device->headset; struct headset_slc *slc = hs->slc; - if (err != CME_ERROR_NONE) { - if (slc->cme_enabled) - return headset_send(hs, "\r\n+CME ERROR: %d\r\n", err); - else - return headset_send(hs, "\r\nERROR\r\n"); - } + if ((err != CME_ERROR_NONE) && slc->cme_enabled) + return headset_send(hs, "\r\n+CME ERROR: %d\r\n", err); - return headset_send(hs, "\r\nOK\r\n"); + switch (err) { + case CME_ERROR_NONE: + return headset_send(hs, "\r\nOK\r\n"); + case CME_ERROR_NO_NETWORK_SERVICE: + return headset_send(hs, "\r\nNO CARRIER\r\n"); + default: + return headset_send(hs, "\r\nERROR\r\n"); + } } int telephony_event_reporting_rsp(void *telephony_device, cme_error_t err) @@ -901,7 +905,7 @@ if (ag.rh >= 0) headset_send(hs, "\r\n+BTRH: %d\r\n", ag.rh); - return headset_send(hs, "\r\nOK\r\n", ag.rh); + return headset_send(hs, "\r\nOK\r\n"); } int telephony_last_dialed_number_rsp(void *telephony_device, cme_error_t err) @@ -1195,6 +1199,13 @@ return 0; } +static int apple_command(struct audio_device *device, const char *buf) +{ + DBG("Got Apple command: %s", buf); + + return telephony_generic_rsp(device, CME_ERROR_NONE); +} + static struct event event_callbacks[] = { { "ATA", answer_call }, { "ATD", dial_number }, @@ -1216,6 +1227,8 @@ { "AT+COPS", operator_selection }, { "AT+NREC", nr_and_ec }, { "AT+BVRA", voice_dial }, + { "AT+XAPL", apple_command }, + { "AT+IPHONEACCEV", apple_command }, { 0 } }; @@ -1317,6 +1330,8 @@ error("Badly formated or unrecognized command: %s", &slc->buf[slc->data_start]); err = headset_send(hs, "\r\nERROR\r\n"); + if (err < 0) + goto failed; } else if (err < 0) error("Error handling command %s: %s (%d)", &slc->buf[slc->data_start], @@ -1755,7 +1770,7 @@ if (ag.ring_timer) { DBG("IndicateCall received when already indicating"); - goto done; + return reply; } err = headset_send(hs, "\r\nRING\r\n"); @@ -1768,7 +1783,6 @@ ag.ring_timer = g_timeout_add_seconds(RING_INTERVAL, ring_timer_cb, NULL); -done: return reply; } @@ -2036,6 +2050,7 @@ return btd_error_invalid_args(msg); } + static GDBusMethodTable headset_methods[] = { { "Connect", "", "", hs_connect, G_DBUS_METHOD_FLAG_ASYNC }, @@ -2044,7 +2059,8 @@ { "IndicateCall", "", "", hs_ring }, { "CancelCall", "", "", hs_cancel_call }, { "Play", "", "", hs_play, - G_DBUS_METHOD_FLAG_ASYNC }, + G_DBUS_METHOD_FLAG_ASYNC | + G_DBUS_METHOD_FLAG_DEPRECATED }, { "Stop", "", "", hs_stop }, { "IsPlaying", "", "b", hs_is_playing, G_DBUS_METHOD_FLAG_DEPRECATED }, @@ -2147,8 +2163,7 @@ headset_close_rfcomm(dev); - g_slist_foreach(hs->nrec_cbs, (GFunc) g_free, NULL); - g_slist_free(hs->nrec_cbs); + g_slist_free_full(hs->nrec_cbs, g_free); g_free(hs); dev->headset = NULL; @@ -2397,10 +2412,16 @@ hs->dc_timer = 0; } - sock = g_io_channel_unix_get_fd(hs->sco); + if (hs->sco) { + sock = g_io_channel_unix_get_fd(hs->sco); + + /* shutdown but leave the socket open and wait for hup */ + shutdown(sock, SHUT_RDWR); + } else { + headset_set_state(dev, HEADSET_STATE_CONNECTED); - /* shutdown but leave the socket open and wait for hup */ - shutdown(sock, SHUT_RDWR); + g_idle_add((GSourceFunc) dummy_connect_complete, dev); + } id = connect_cb_new(hs, HEADSET_STATE_CONNECTED, cb, user_data); @@ -2541,8 +2562,11 @@ emit_property_changed(dev->conn, dev->path, AUDIO_HEADSET_INTERFACE, "State", DBUS_TYPE_STRING, &state_str); + + /* Do not watch HUP since we need to know when the link is + really disconnected */ hs->sco_id = g_io_add_watch(hs->sco, - G_IO_ERR | G_IO_HUP | G_IO_NVAL, + G_IO_ERR | G_IO_NVAL, (GIOFunc) sco_cb, dev); g_dbus_emit_signal(dev->conn, dev->path, diff -Nru bluez-4.91/audio/ipc.h bluez-4.96/audio/ipc.h --- bluez-4.91/audio/ipc.h 2010-01-09 20:52:17.000000000 +0000 +++ bluez-4.96/audio/ipc.h 2011-07-04 04:59:05.000000000 +0000 @@ -264,7 +264,7 @@ } __attribute__ ((packed)); /* This message is followed by one byte of data containing the stream data fd - as ancilliary data */ + as ancillary data */ struct bt_new_stream_ind { bt_audio_msg_header_t h; } __attribute__ ((packed)); diff -Nru bluez-4.91/audio/manager.c bluez-4.96/audio/manager.c --- bluez-4.91/audio/manager.c 2010-12-26 17:20:48.000000000 +0000 +++ bluez-4.96/audio/manager.c 2011-07-04 04:59:05.000000000 +0000 @@ -124,10 +124,8 @@ static struct audio_adapter *find_adapter(GSList *list, struct btd_adapter *btd_adapter) { - GSList *l; - - for (l = list; l; l = l->next) { - struct audio_adapter *adapter = l->data; + for (; list; list = list->next) { + struct audio_adapter *adapter = list->data; if (adapter->btd_adapter == btd_adapter) return adapter; @@ -562,7 +560,6 @@ GError *err = NULL; uint8_t ch; const char *server_uuid, *remote_uuid; - uint16_t svclass; struct audio_device *device; int perr; @@ -580,7 +577,6 @@ server_uuid = HFP_AG_UUID; remote_uuid = HFP_HS_UUID; - svclass = HANDSFREE_AGW_SVCLASS_ID; device = manager_get_device(&src, &dst, TRUE); if (!device) @@ -697,8 +693,11 @@ return 0; failed: - error("%s", err->message); - g_error_free(err); + if (err) { + error("%s", err->message); + g_error_free(err); + } + if (adapter->hsp_ag_server) { g_io_channel_shutdown(adapter->hsp_ag_server, TRUE, NULL); g_io_channel_unref(adapter->hsp_ag_server); @@ -910,15 +909,15 @@ if (!adp) return -EINVAL; + btd_adapter_register_powered_callback(adapter, state_changed); + state_changed(adapter, TRUE); + err = headset_server_init(adp); if (err < 0) { audio_adapter_unref(adp); return err; } - btd_adapter_register_powered_callback(adapter, state_changed); - state_changed(adapter, TRUE); - return 0; } diff -Nru bluez-4.91/audio/media.c bluez-4.96/audio/media.c --- bluez-4.91/audio/media.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/audio/media.c 2011-07-31 06:52:19.000000000 +0000 @@ -34,6 +34,7 @@ #include "../src/adapter.h" #include "../src/dbus-common.h" +#include "glib-helper.h" #include "log.h" #include "error.h" #include "device.h" @@ -166,7 +167,12 @@ switch (new_state) { case HEADSET_STATE_DISCONNECTED: - media_endpoint_clear_configuration(endpoint); + if (endpoint->transport && + media_transport_get_dev(endpoint->transport) == dev) { + + DBG("Clear endpoint %p", endpoint); + media_endpoint_clear_configuration(endpoint); + } break; case HEADSET_STATE_CONNECTING: media_endpoint_set_configuration(endpoint, dev, NULL, 0, @@ -365,7 +371,7 @@ return btd_error_invalid_args(msg); if (media_endpoint_create(adapter, sender, path, uuid, delay_reporting, - codec, capabilities, size, &err) == FALSE) { + codec, capabilities, size, &err) == NULL) { if (err == -EPROTONOSUPPORT) return btd_error_not_supported(msg); else @@ -408,9 +414,8 @@ { struct media_adapter *adapter = data; - g_slist_foreach(adapter->endpoints, (GFunc) media_endpoint_release, - NULL); - g_slist_free(adapter->endpoints); + g_slist_free_full(adapter->endpoints, + (GDestroyNotify) media_endpoint_release); dbus_connection_unref(adapter->conn); @@ -643,6 +648,7 @@ DBusConnection *conn; DBusMessage *msg; const char *path; + struct media_transport *transport = endpoint->transport; if (endpoint->transport == NULL) return; @@ -665,8 +671,8 @@ DBUS_TYPE_INVALID); g_dbus_send_message(conn, msg); done: - media_transport_destroy(endpoint->transport); endpoint->transport = NULL; + media_transport_destroy(transport); } void media_endpoint_release(struct media_endpoint *endpoint) diff -Nru bluez-4.91/audio/pcm_bluetooth.c bluez-4.96/audio/pcm_bluetooth.c --- bluez-4.91/audio/pcm_bluetooth.c 2010-08-25 05:10:02.000000000 +0000 +++ bluez-4.96/audio/pcm_bluetooth.c 2011-05-31 02:39:53.000000000 +0000 @@ -44,7 +44,7 @@ #include "sbc.h" #include "rtp.h" -//#define ENABLE_DEBUG +/* #define ENABLE_DEBUG */ #define UINT_SECS_MAX (UINT_MAX / 1000000 - 1) @@ -820,7 +820,6 @@ unsigned short *revents) { static char buf[1]; - int ret; DBG(""); @@ -831,7 +830,8 @@ assert(pfds[1].fd >= 0); if (io->state != SND_PCM_STATE_PREPARED) - ret = read(pfds[0].fd, buf, 1); + if (read(pfds[0].fd, buf, 1) < 0) + SYSERR("read error: %s (%d)", strerror(errno), errno); if (pfds[1].revents & (POLLERR | POLLHUP | POLLNVAL)) io->state = SND_PCM_STATE_DISCONNECTED; diff -Nru bluez-4.91/audio/telephony-maemo6.c bluez-4.96/audio/telephony-maemo6.c --- bluez-4.91/audio/telephony-maemo6.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/audio/telephony-maemo6.c 2011-07-31 06:52:19.000000000 +0000 @@ -36,6 +36,9 @@ #include #include +#include + +#include "glib-helper.h" #include "log.h" #include "telephony.h" #include "error.h" @@ -448,8 +451,10 @@ } } -static void pending_req_finalize(struct pending_req *req) +static void pending_req_finalize(void *data) { + struct pending_req *req = data; + if (!dbus_pending_call_get_completed(req->call)) dbus_pending_call_cancel(req->call); @@ -618,7 +623,7 @@ pending_req_finalize(req); } -static void last_number_call_reply(DBusPendingCall *call, void *user_data) +static void create_call_reply(DBusPendingCall *call, void *user_data) { DBusError err; DBusMessage *reply; @@ -630,9 +635,14 @@ if (dbus_set_error_from_message(&err, reply)) { error("csd replied with an error: %s, %s", err.name, err.message); - dbus_error_free(&err); - telephony_dial_number_rsp(telephony_device, + if (g_strcmp0(err.name, + "com.nokia.csd.Call.Error.CSInactive") == 0) + telephony_dial_number_rsp(telephony_device, + CME_ERROR_NO_NETWORK_SERVICE); + else + telephony_dial_number_rsp(telephony_device, CME_ERROR_AG_FAILURE); + dbus_error_free(&err); } else telephony_dial_number_rsp(telephony_device, CME_ERROR_NONE); @@ -648,7 +658,7 @@ ret = send_method_call(CSD_CALL_BUS_NAME, CSD_CALL_PATH, CSD_CALL_INTERFACE, "CreateFromLast", - last_number_call_reply, telephony_device, + create_call_reply, telephony_device, DBUS_TYPE_INVALID); if (ret < 0) telephony_dial_number_rsp(telephony_device, @@ -687,16 +697,12 @@ ret = send_method_call(CSD_CALL_BUS_NAME, CSD_CALL_PATH, CSD_CALL_INTERFACE, "Create", - NULL, NULL, + create_call_reply, telephony_device, DBUS_TYPE_STRING, &number, DBUS_TYPE_INVALID); - if (ret < 0) { + if (ret < 0) telephony_dial_number_rsp(telephony_device, CME_ERROR_AG_FAILURE); - return; - } - - telephony_dial_number_rsp(telephony_device, CME_ERROR_NONE); } void telephony_transmit_dtmf_req(void *telephony_device, char tone) @@ -1485,8 +1491,10 @@ } } -static void csd_call_free(struct csd_call *call) +static void csd_call_free(void *data) { + struct csd_call *call = data; + if (!call) return; @@ -1974,16 +1982,13 @@ g_slist_free(active_calls); active_calls = NULL; - g_slist_foreach(calls, (GFunc) csd_call_free, NULL); - g_slist_free(calls); + g_slist_free_full(calls, csd_call_free); calls = NULL; - g_slist_foreach(pending, (GFunc) pending_req_finalize, NULL); - g_slist_free(pending); + g_slist_free_full(pending, pending_req_finalize); pending = NULL; - g_slist_foreach(watches, (GFunc) remove_watch, NULL); - g_slist_free(watches); + g_slist_free_full(pending, remove_watch); watches = NULL; dbus_connection_unref(connection); diff -Nru bluez-4.91/audio/telephony-ofono.c bluez-4.96/audio/telephony-ofono.c --- bluez-4.91/audio/telephony-ofono.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/audio/telephony-ofono.c 2011-07-31 06:52:19.000000000 +0000 @@ -35,6 +35,9 @@ #include #include +#include + +#include "glib-helper.h" #include "log.h" #include "telephony.h" @@ -259,7 +262,7 @@ NULL, NULL, DBUS_TYPE_INVALID); } -static int release_answer_calls() +static int release_answer_calls(void) { DBG(""); return send_method_call(OFONO_BUS_NAME, modem_obj_path, @@ -638,8 +641,10 @@ return type == DBUS_TYPE_INVALID ? TRUE : FALSE; } -static void call_free(struct voice_call *vc) +static void call_free(void *data) { + struct voice_call *vc = data; + DBG("%s", vc->obj_path); if (vc->status == CALL_STATUS_ACTIVE) @@ -926,13 +931,6 @@ static int parse_network_properties(DBusMessageIter *properties) { - uint32_t features = AG_FEATURE_EC_ANDOR_NR | - AG_FEATURE_INBAND_RINGTONE | - AG_FEATURE_REJECT_A_CALL | - AG_FEATURE_ENHANCED_CALL_STATUS | - AG_FEATURE_ENHANCED_CALL_CONTROL | - AG_FEATURE_EXTENDED_ERROR_RESULT_CODES | - AG_FEATURE_THREE_WAY_CALLING; int i; /* Reset indicators */ @@ -959,9 +957,6 @@ dbus_message_iter_next(properties); } - telephony_ready_ind(features, ofono_indicators, BTRH_NOT_SUPPORTED, - chld_str); - return 0; } @@ -1034,8 +1029,7 @@ DBG("%s", path); - g_slist_foreach(calls, (GFunc) call_free, NULL); - g_slist_free(calls); + g_slist_free_full(calls, call_free); calls = NULL; g_free(net.operator_name); @@ -1553,6 +1547,13 @@ int telephony_init(void) { + uint32_t features = AG_FEATURE_EC_ANDOR_NR | + AG_FEATURE_INBAND_RINGTONE | + AG_FEATURE_REJECT_A_CALL | + AG_FEATURE_ENHANCED_CALL_STATUS | + AG_FEATURE_ENHANCED_CALL_CONTROL | + AG_FEATURE_EXTENDED_ERROR_RESULT_CODES | + AG_FEATURE_THREE_WAY_CALLING; const char *battery_cap = "battery"; int ret; guint watch; @@ -1593,6 +1594,9 @@ DBG("telephony_init() successfully"); + telephony_ready_ind(features, ofono_indicators, BTRH_NOT_SUPPORTED, + chld_str); + return ret; } @@ -1601,6 +1605,16 @@ g_dbus_remove_watch(connection, GPOINTER_TO_UINT(data)); } +static void pending_free(void *data) +{ + DBusPendingCall *call = data; + + if (!dbus_pending_call_get_completed(call)) + dbus_pending_call_cancel(call); + + dbus_pending_call_unref(call); +} + void telephony_exit(void) { DBG(""); @@ -1611,13 +1625,10 @@ if (modem_obj_path) modem_removed(modem_obj_path); - g_slist_foreach(watches, (GFunc) remove_watch, NULL); - g_slist_free(watches); + g_slist_free_full(watches, remove_watch); watches = NULL; - g_slist_foreach(pending, (GFunc) dbus_pending_call_cancel, NULL); - g_slist_foreach(pending, (GFunc) dbus_pending_call_unref, NULL); - g_slist_free(pending); + g_slist_free_full(pending, pending_free); pending = NULL; dbus_connection_unref(connection); diff -Nru bluez-4.91/audio/transport.c bluez-4.96/audio/transport.c --- bluez-4.91/audio/transport.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/audio/transport.c 2011-07-31 06:52:19.000000000 +0000 @@ -224,15 +224,6 @@ return TRUE; } -static gboolean remove_owner(gpointer data) -{ - struct media_owner *owner = data; - - media_transport_remove(owner->transport, owner); - - return FALSE; -} - static void a2dp_resume_complete(struct avdtp *session, struct avdtp_error *err, void *user_data) { @@ -279,8 +270,7 @@ return; fail: - /* Let the stream state change before removing the owner */ - g_idle_add(remove_owner, owner); + media_transport_remove(transport, owner); } static guint resume_a2dp(struct media_transport *transport, @@ -818,10 +808,13 @@ static void media_transport_free(void *data) { struct media_transport *transport = data; - GSList *l; + GSList *l = transport->owners; - for (l = transport->owners; l; l = l->next) - media_transport_remove(transport, l->data); + while (l) { + struct media_owner *owner = l->data; + l = l->next; + media_transport_remove(transport, owner); + } g_slist_free(transport->owners); @@ -925,3 +918,8 @@ MEDIA_TRANSPORT_INTERFACE, "Delay", DBUS_TYPE_UINT16, &transport->delay); } + +struct audio_device *media_transport_get_dev(struct media_transport *transport) +{ + return transport->device; +} \ No newline at end of file diff -Nru bluez-4.91/audio/transport.h bluez-4.96/audio/transport.h --- bluez-4.91/audio/transport.h 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/audio/transport.h 2011-07-31 06:52:19.000000000 +0000 @@ -32,6 +32,7 @@ void media_transport_destroy(struct media_transport *transport); const char *media_transport_get_path(struct media_transport *transport); +struct audio_device *media_transport_get_dev(struct media_transport *transport); void media_transport_update_delay(struct media_transport *transport, uint16_t delay); void transport_get_properties(struct media_transport *transport, diff -Nru bluez-4.91/audio/unix.c bluez-4.96/audio/unix.c --- bluez-4.91/audio/unix.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/audio/unix.c 2011-07-04 04:59:05.000000000 +0000 @@ -97,8 +97,10 @@ static int unix_sock = -1; -static void client_free(struct unix_client *client) +static void client_free(void *data) { + struct unix_client *client = data; + DBG("client_free(%p)", client); if (client->cancel && client->dev && client->req_id > 0) @@ -107,10 +109,7 @@ if (client->sock >= 0) close(client->sock); - if (client->caps) { - g_slist_foreach(client->caps, (GFunc) g_free, NULL); - g_slist_free(client->caps); - } + g_slist_free_full(client->caps, g_free); g_free(client->interface); g_free(client); @@ -629,7 +628,6 @@ char buf[BT_SUGGESTED_BUFFER_SIZE]; struct bt_get_capabilities_rsp *rsp = (void *) buf; struct a2dp_data *a2dp = &client->d.a2dp; - GSList *l; if (!g_slist_find(clients, client)) { DBG("Client disconnected during discovery"); @@ -649,8 +647,8 @@ ba2str(&client->dev->dst, rsp->destination); strncpy(rsp->object, client->dev->path, sizeof(rsp->object)); - for (l = seps; l; l = g_slist_next(l)) { - struct avdtp_remote_sep *rsep = l->data; + for (; seps; seps = g_slist_next(seps)) { + struct avdtp_remote_sep *rsep = seps->data; struct a2dp_sep *sep; struct avdtp_service_capability *cap; struct avdtp_stream *stream; @@ -1494,11 +1492,8 @@ !g_str_equal(client->interface, AUDIO_SOURCE_INTERFACE)) return -EIO; - if (client->caps) { - g_slist_foreach(client->caps, (GFunc) g_free, NULL); - g_slist_free(client->caps); - client->caps = NULL; - } + g_slist_free_full(client->caps, g_free); + client->caps = NULL; media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT, NULL, 0); @@ -1908,8 +1903,7 @@ void unix_exit(void) { - g_slist_foreach(clients, (GFunc) client_free, NULL); - g_slist_free(clients); + g_slist_free_full(clients, client_free); if (unix_sock >= 0) { close(unix_sock); unix_sock = -1; diff -Nru bluez-4.91/AUTHORS bluez-4.96/AUTHORS --- bluez-4.91/AUTHORS 2011-02-20 14:49:06.000000000 +0000 +++ bluez-4.96/AUTHORS 2011-07-04 04:59:05.000000000 +0000 @@ -12,7 +12,7 @@ Brad Midgley Henryk Ploetz Philip Blundell -Johan Hedberg +Johan Hedberg Claudio Takahasi Eduardo Rocha Denis Kenzior diff -Nru bluez-4.91/btio/btio.c bluez-4.96/btio/btio.c --- bluez-4.91/btio/btio.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/btio/btio.c 2011-07-31 06:52:19.000000000 +0000 @@ -40,6 +40,10 @@ #include "btio.h" +#ifndef BT_FLUSHABLE +#define BT_FLUSHABLE 8 +#endif + #define ERROR_FAILED(gerr, str, err) \ g_set_error(gerr, BT_IO_ERROR, BT_IO_ERROR_FAILED, \ str ": %s (%d)", strerror(err), err) @@ -59,6 +63,7 @@ uint16_t omtu; int master; uint8_t mode; + int flushable; }; struct connect { @@ -266,8 +271,9 @@ addr.l2_psm = htobs(psm); if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + int error = -errno; ERROR_FAILED(err, "l2cap_bind", errno); - return -1; + return error; } return 0; @@ -289,7 +295,7 @@ err = connect(sock, (struct sockaddr *) &addr, sizeof(addr)); if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) - return err; + return -errno; return 0; } @@ -485,8 +491,20 @@ return TRUE; } -static gboolean l2cap_set(int sock, int sec_level, uint16_t imtu, uint16_t omtu, - uint8_t mode, int master, GError **err) +static int l2cap_set_flushable(int sock, gboolean flushable) +{ + int f; + + f = flushable; + if (setsockopt(sock, SOL_BLUETOOTH, BT_FLUSHABLE, &f, sizeof(f)) < 0) + return -errno; + + return 0; +} + +static gboolean l2cap_set(int sock, int sec_level, uint16_t imtu, + uint16_t omtu, uint8_t mode, int master, + int flushable, GError **err) { if (imtu || omtu || mode) { struct l2cap_options l2o; @@ -519,6 +537,11 @@ return FALSE; } + if (flushable >= 0 && l2cap_set_flushable(sock, flushable) < 0) { + ERROR_FAILED(err, "l2cap_set_flushable", errno); + return FALSE; + } + if (sec_level && !set_sec_level(sock, BT_IO_L2CAP, sec_level, err)) return FALSE; @@ -536,8 +559,9 @@ addr.rc_channel = channel; if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + int error = -errno; ERROR_FAILED(err, "rfcomm_bind", errno); - return -1; + return error; } return 0; @@ -555,7 +579,7 @@ err = connect(sock, (struct sockaddr *) &addr, sizeof(addr)); if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) - return err; + return -errno; return 0; } @@ -582,8 +606,9 @@ bacpy(&addr.sco_bdaddr, src); if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + int error = -errno; ERROR_FAILED(err, "sco_bind", errno); - return -1; + return error; } return 0; @@ -600,7 +625,7 @@ err = connect(sock, (struct sockaddr *) &addr, sizeof(addr)); if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) - return err; + return -errno; return 0; } @@ -643,6 +668,7 @@ opts->master = -1; opts->sec_level = BT_IO_SEC_MEDIUM; opts->mode = L2CAP_MODE_BASIC; + opts->flushable = -1; while (opt != BT_IO_OPT_INVALID) { switch (opt) { @@ -698,6 +724,9 @@ case BT_IO_OPT_MODE: opts->mode = va_arg(args, int); break; + case BT_IO_OPT_FLUSHABLE: + opts->flushable = va_arg(args, gboolean); + break; default: g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS, "Unknown option %d", opt); @@ -750,6 +779,24 @@ return 0; } +static int l2cap_get_flushable(int sock, gboolean *flushable) +{ + int f; + socklen_t len; + + f = 0; + len = sizeof(f); + if (getsockopt(sock, SOL_BLUETOOTH, BT_FLUSHABLE, &f, &len) < 0) + return -errno; + + if (f) + *flushable = TRUE; + else + *flushable = FALSE; + + return 0; +} + static gboolean l2cap_get(int sock, GError **err, BtIOOption opt1, va_list args) { @@ -760,6 +807,7 @@ uint8_t dev_class[3]; uint16_t handle; socklen_t len; + gboolean flushable = FALSE; len = sizeof(l2o); memset(&l2o, 0, len); @@ -842,6 +890,13 @@ case BT_IO_OPT_MODE: *(va_arg(args, uint8_t *)) = l2o.mode; break; + case BT_IO_OPT_FLUSHABLE: + if (l2cap_get_flushable(sock, &flushable) < 0) { + ERROR_FAILED(err, "get_flushable", errno); + return FALSE; + } + *(va_arg(args, gboolean *)) = flushable; + break; default: g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS, "Unknown option %d", opt); @@ -1085,8 +1140,10 @@ } if (!(pfd.revents & POLLOUT)) { - int ret; - ret = read(sock, &c, 1); + if (read(sock, &c, 1) < 0) { + ERROR_FAILED(err, "read", errno); + return FALSE; + } } accept_add(io, connect, user_data, destroy); @@ -1115,7 +1172,7 @@ case BT_IO_L2RAW: case BT_IO_L2CAP: return l2cap_set(sock, opts.sec_level, opts.imtu, opts.omtu, - opts.mode, opts.master, err); + opts.mode, opts.master, opts.flushable, err); case BT_IO_RFCOMM: return rfcomm_set(sock, opts.sec_level, opts.master, err); case BT_IO_SCO: @@ -1156,7 +1213,7 @@ if (l2cap_bind(sock, &opts->src, server ? opts->psm : 0, opts->cid, err) < 0) goto failed; - if (!l2cap_set(sock, opts->sec_level, 0, 0, 0, -1, err)) + if (!l2cap_set(sock, opts->sec_level, 0, 0, 0, -1, -1, err)) goto failed; break; case BT_IO_L2CAP: @@ -1169,7 +1226,7 @@ opts->cid, err) < 0) goto failed; if (!l2cap_set(sock, opts->sec_level, opts->imtu, opts->omtu, - opts->mode, opts->master, err)) + opts->mode, opts->master, opts->flushable, err)) goto failed; break; case BT_IO_RFCOMM: diff -Nru bluez-4.91/btio/btio.h bluez-4.96/btio/btio.h --- bluez-4.91/btio/btio.h 2010-10-02 23:25:27.000000000 +0000 +++ bluez-4.96/btio/btio.h 2011-04-25 09:44:21.000000000 +0000 @@ -64,6 +64,7 @@ BT_IO_OPT_HANDLE, BT_IO_OPT_CLASS, BT_IO_OPT_MODE, + BT_IO_OPT_FLUSHABLE, } BtIOOption; typedef enum { diff -Nru bluez-4.91/ChangeLog bluez-4.96/ChangeLog --- bluez-4.91/ChangeLog 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/ChangeLog 2011-07-31 06:52:19.000000000 +0000 @@ -1,3 +1,44 @@ +ver 4.96: + Fix issue with race condition in AVDTP stream start. + Fix issue with global adapter offline switching. + Fix issue with pairing and No Bonding devices. + Add support for Nintendo Wii Remote pairing. + +ver 4.95: + Fix issue with AVCTP replies with invalid PID. + Fix issue with AVRCP and unknown packet types. + Fix issue with AVRCP not using NOT_IMPLEMENTED correctly. + Fix issue with AVDTP discovery if all endpoints are in use. + Fix issue with invalid memory writes and media support. + Fix issue with not removing device alias and unbonding. + Fix issue with device disconnects and offline mode handling. + Add support for setting adapter name based on machine-info. + Add support for systemd service configuration. + +ver 4.94: + Fix issue with invalid read of memory in various modules. + Fix issue with buffer overflow when sending AVDTP commands. + Fix issue with response to vendor dependent AVRCP commands. + Fix issue with headset when not able to reply with ERROR. + Fix issue with crash when creating a device from storage. + Fix issue with handling non UTF-8 devices names. + Add support for improved discovery procedure. + +ver 4.93: + Fix issue with property type and Health Main channel. + Fix issue with crash when removing devices. + Add support for hid2hci and udev integration. + +ver 4.92: + Fix issue with handling of A2DP suspend response. + Fix issue with crashing when acquiring A2DP stream. + Fix issue with missing check for valid SCO before shutdown. + Fix issue with waiting for POLLERR when disconnecting SCO. + Fix issue with disconnect after primary service discovery. + Fix issue with attribute interface registration. + Add support for primary services over BR/EDR. + Add support for flushable packets of A2DP media. + ver 4.91: Fix issue with LMP version string and hciconfig. Fix issue with missing discovery signal when scanning. diff -Nru bluez-4.91/compat/fakehid.c bluez-4.96/compat/fakehid.c --- bluez-4.91/compat/fakehid.c 2010-01-09 20:52:17.000000000 +0000 +++ bluez-4.96/compat/fakehid.c 2011-05-31 02:39:53.000000000 +0000 @@ -60,20 +60,19 @@ __io_canceled = 1; } -static void send_event(int fd, uint16_t type, uint16_t code, int32_t value) +static int send_event(int fd, uint16_t type, uint16_t code, int32_t value) { struct uinput_event event; - int len; if (fd <= fileno(stderr)) - return; + return -EINVAL; memset(&event, 0, sizeof(event)); event.type = type; event.code = code; event.value = value; - len = write(fd, &event, sizeof(event)); + return write(fd, &event, sizeof(event)); } static int uinput_create(char *name, int keyboard, int mouse) @@ -125,9 +124,10 @@ for (aux = KEY_RESERVED; aux <= KEY_UNKNOWN; aux++) ioctl(fd, UI_SET_KEYBIT, aux); - - //for (aux = LED_NUML; aux <= LED_MISC; aux++) - // ioctl(fd, UI_SET_LEDBIT, aux); + /* + *for (aux = LED_NUML; aux <= LED_MISC; aux++) + * ioctl(fd, UI_SET_LEDBIT, aux); + */ } if (mouse) { diff -Nru bluez-4.91/compat/hidd.c bluez-4.96/compat/hidd.c --- bluez-4.91/compat/hidd.c 2010-05-23 12:47:19.000000000 +0000 +++ bluez-4.96/compat/hidd.c 2011-05-31 02:39:53.000000000 +0000 @@ -237,16 +237,6 @@ return err; } -static void enable_sixaxis(int csk) -{ - const unsigned char buf[] = { - 0x53 /*HIDP_TRANS_SET_REPORT | HIDP_DATA_RTYPE_FEATURE*/, - 0xf4, 0x42, 0x03, 0x00, 0x00 }; - int err; - - err = write(csk, buf, sizeof(buf)); -} - static int create_device(int ctl, int csk, int isk, uint8_t subclass, int nosdp, int nocheck, int bootonly, int encrypt, int timeout) { struct hidp_connadd_req req; @@ -335,14 +325,10 @@ req.flags |= (1 << HIDP_BOOT_PROTOCOL_MODE); } - if (req.vendor == 0x054c && req.product == 0x0268) - enable_sixaxis(csk); - err = ioctl(ctl, HIDPCONNADD, &req); error: - if (req.rd_data) - free(req.rd_data); + free(req.rd_data); return err; } diff -Nru bluez-4.91/config.h.in bluez-4.96/config.h.in --- bluez-4.91/config.h.in 2011-03-29 08:54:24.000000000 +0000 +++ bluez-4.96/config.h.in 2011-07-31 06:52:45.000000000 +0000 @@ -30,6 +30,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H +/* Define to 1 if you have . */ +#undef HAVE_SYS_INOTIFY_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H @@ -49,6 +52,9 @@ /* Define to 1 if you need the dbus_watch_get_unix_fd() function. */ #undef NEED_DBUS_WATCH_GET_UNIX_FD +/* Define to 1 if you need g_slist_free_full() function. */ +#undef NEED_G_SLIST_FREE_FULL + /* Define to 1 if you need the ppoll() function. */ #undef NEED_PPOLL diff -Nru bluez-4.91/configure bluez-4.96/configure --- bluez-4.91/configure 2011-03-29 08:54:32.000000000 +0000 +++ bluez-4.96/configure 2011-07-31 06:52:53.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.63 for bluez 4.91. +# Generated by GNU Autoconf 2.63 for bluez 4.96. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. @@ -743,8 +743,8 @@ # Identity of this package. PACKAGE_NAME='bluez' PACKAGE_TARNAME='bluez' -PACKAGE_VERSION='4.91' -PACKAGE_STRING='bluez 4.91' +PACKAGE_VERSION='4.96' +PACKAGE_STRING='bluez 4.96' PACKAGE_BUGREPORT='' ac_default_prefix=/usr/local @@ -788,16 +788,21 @@ am__EXEEXT_TRUE LTLIBOBJS LIBOBJS +SYSTEMD_FALSE +SYSTEMD_TRUE +SYSTEMD_UNITDIR CAPNG_LIBS CAPNG_CFLAGS +THERMOMETERPLUGIN_FALSE +THERMOMETERPLUGIN_TRUE +WIIMOTEPLUGIN_FALSE +WIIMOTEPLUGIN_TRUE DBUSOOBPLUGIN_FALSE DBUSOOBPLUGIN_TRUE MAEMO6PLUGIN_FALSE MAEMO6PLUGIN_TRUE -CONFIGFILES_FALSE -CONFIGFILES_TRUE -UDEVRULES_FALSE -UDEVRULES_TRUE +DATAFILES_FALSE +DATAFILES_TRUE DFUTOOL_FALSE DFUTOOL_TRUE HID2HCI_FALSE @@ -824,8 +829,8 @@ PNATPLUGIN_TRUE ECHOPLUGIN_FALSE ECHOPLUGIN_TRUE -ATTRIBPLUGIN_FALSE -ATTRIBPLUGIN_TRUE +GATT_EXAMPLE_PLUGIN_FALSE +GATT_EXAMPLE_PLUGIN_TRUE READLINE_FALSE READLINE_TRUE HAL_FALSE @@ -836,6 +841,8 @@ HEALTHPLUGIN_TRUE SERVICEPLUGIN_FALSE SERVICEPLUGIN_TRUE +PROXIMITYPLUGIN_FALSE +PROXIMITYPLUGIN_TRUE SAPPLUGIN_FALSE SAPPLUGIN_TRUE NETWORKPLUGIN_FALSE @@ -861,6 +868,8 @@ READLINE_LIBS SNDFILE_LIBS SNDFILE_CFLAGS +UDEV_LIBS +UDEV_CFLAGS USB_LIBS USB_CFLAGS GSTREAMER_PLUGINSDIR @@ -921,7 +930,7 @@ LDFLAGS CFLAGS CC -UDEV_DATADIR +UDEV_DIR STORAGEDIR CONFIGDIR PKG_CONFIG @@ -1009,13 +1018,14 @@ enable_network enable_sap with_sap +enable_proximity enable_serial enable_input enable_audio enable_service enable_health enable_pnat -enable_attrib +enable_gatt_example enable_gstreamer enable_alsa enable_usb @@ -1030,14 +1040,16 @@ enable_dund enable_cups enable_test -enable_udevrules -enable_configfiles +enable_datafiles enable_debug with_telephony enable_maemo6 enable_dbusoob +enable_wiimote enable_hal +enable_thermometer enable_capng +with_systemdunitdir ' ac_precious_vars='build_alias host_alias @@ -1061,6 +1073,8 @@ GSTREAMER_LIBS USB_CFLAGS USB_LIBS +UDEV_CFLAGS +UDEV_LIBS SNDFILE_CFLAGS SNDFILE_LIBS CAPNG_CFLAGS @@ -1617,7 +1631,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures bluez 4.91 to adapt to many kinds of systems. +\`configure' configures bluez 4.96 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1687,7 +1701,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of bluez 4.91:";; + short | recursive ) echo "Configuration of bluez 4.96:";; esac cat <<\_ACEOF @@ -1711,13 +1725,14 @@ --disable-pie disable position independent executables flag --disable-network disable network plugin --enable-sap enable sap plugin + --enable-proximity enable proximity plugin --disable-serial disable serial plugin --disable-input disable input plugin --disable-audio disable audio plugin --disable-service disable service plugin --enable-health enable health plugin --enable-pnat enable pnat plugin - --enable-attrib enable attrib plugin + --enable-gatt-example enable GATT example plugin --enable-gstreamer enable GStreamer support --enable-alsa enable ALSA support --enable-usb enable USB support @@ -1732,12 +1747,13 @@ --enable-dund install DUN daemon --enable-cups install CUPS backend support --enable-test install test programs - --enable-udevrules install Bluetooth udev rules - --enable-configfiles install Bluetooth configuration files + --enable-datafiles install Bluetooth configuration and data files --enable-debug enable compiling with debugging information --enable-maemo6 compile with maemo6 plugin --enable-dbusoob compile with D-Bus OOB plugin + --enable-wiimote compile with Wii Remote plugin --enable-hal Use HAL to determine adapter class + --enable-thermometer enable thermometer plugin --enable-capng enable capabilities support Optional Packages: @@ -1749,6 +1765,8 @@ --with-ouifile=PATH Path to the oui.txt file [auto] --with-sap=DRIVER select SAP driver --with-telephony=DRIVER select telephony driver + --with-systemdunitdir=DIR + path to systemd system service directory Some influential environment variables: PKG_CONFIG path to pkg-config utility @@ -1777,6 +1795,8 @@ linker flags for GSTREAMER, overriding pkg-config USB_CFLAGS C compiler flags for USB, overriding pkg-config USB_LIBS linker flags for USB, overriding pkg-config + UDEV_CFLAGS C compiler flags for UDEV, overriding pkg-config + UDEV_LIBS linker flags for UDEV, overriding pkg-config SNDFILE_CFLAGS C compiler flags for SNDFILE, overriding pkg-config SNDFILE_LIBS @@ -1850,7 +1870,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -bluez configure 4.91 +bluez configure 4.96 generated by GNU Autoconf 2.63 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1864,7 +1884,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by bluez $as_me 4.91, which was +It was created by bluez $as_me 4.96, which was generated by GNU Autoconf 2.63. Invocation command line was $ $0 $@ @@ -2714,7 +2734,7 @@ # Define the identity of the package. PACKAGE='bluez' - VERSION='4.91' + VERSION='4.96' cat >>confdefs.h <<_ACEOF @@ -2972,11 +2992,9 @@ STORAGEDIR="${storagedir}" - UDEV_DATADIR="`$PKG_CONFIG --variable=udevdir udev`" - if (test -z "${UDEV_DATADIR}"); then - UDEV_DATADIR="${sysconfdir}/udev/rules.d" - else - UDEV_DATADIR="${UDEV_DATADIR}/rules.d" + UDEV_DIR="`$PKG_CONFIG --variable=udevdir udev`" + if (test -z "${UDEV_DIR}"); then + UDEV_DIR="/lib/udev" fi @@ -5373,13 +5391,13 @@ else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:5376: $ac_compile\"" >&5) + (eval echo "\"\$as_me:5394: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:5379: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:5397: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:5382: output\"" >&5) + (eval echo "\"\$as_me:5400: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -6584,7 +6602,7 @@ ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 6587 "configure"' > conftest.$ac_ext + echo '#line 6605 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -8407,11 +8425,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8410: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8428: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:8414: \$? = $ac_status" >&5 + echo "$as_me:8432: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -8746,11 +8764,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8749: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8767: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:8753: \$? = $ac_status" >&5 + echo "$as_me:8771: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -8851,11 +8869,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8854: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8872: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:8858: \$? = $ac_status" >&5 + echo "$as_me:8876: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -8906,11 +8924,11 @@ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8909: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8927: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:8913: \$? = $ac_status" >&5 + echo "$as_me:8931: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -11709,7 +11727,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11712 "configure" +#line 11730 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11805,7 +11823,7 @@ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 11808 "configure" +#line 11826 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -12205,6 +12223,146 @@ fi +if test "${ac_cv_header_sys_inotify_h+set}" = set; then + { $as_echo "$as_me:$LINENO: checking for sys/inotify.h" >&5 +$as_echo_n "checking for sys/inotify.h... " >&6; } +if test "${ac_cv_header_sys_inotify_h+set}" = set; then + $as_echo_n "(cached) " >&6 +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_sys_inotify_h" >&5 +$as_echo "$ac_cv_header_sys_inotify_h" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:$LINENO: checking sys/inotify.h usability" >&5 +$as_echo_n "checking sys/inotify.h usability... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:$LINENO: checking sys/inotify.h presence" >&5 +$as_echo_n "checking sys/inotify.h presence... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { $as_echo "$as_me:$LINENO: WARNING: sys/inotify.h: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: sys/inotify.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: sys/inotify.h: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: sys/inotify.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { $as_echo "$as_me:$LINENO: WARNING: sys/inotify.h: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: sys/inotify.h: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: sys/inotify.h: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: sys/inotify.h: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: sys/inotify.h: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: sys/inotify.h: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: sys/inotify.h: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: sys/inotify.h: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: sys/inotify.h: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: sys/inotify.h: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: sys/inotify.h: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: sys/inotify.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ $as_echo "$as_me:$LINENO: checking for sys/inotify.h" >&5 +$as_echo_n "checking for sys/inotify.h... " >&6; } +if test "${ac_cv_header_sys_inotify_h+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_header_sys_inotify_h=$ac_header_preproc +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_sys_inotify_h" >&5 +$as_echo "$ac_cv_header_sys_inotify_h" >&6; } + +fi +if test "x$ac_cv_header_sys_inotify_h" = x""yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SYS_INOTIFY_H 1 +_ACEOF + +else + { { $as_echo "$as_me:$LINENO: error: inotify headers are required and missing" >&5 +$as_echo "$as_me: error: inotify headers are required and missing" >&2;} + { (exit 1); exit 1; }; } +fi + + pkg_failed=no @@ -12502,6 +12660,81 @@ $as_echo "yes" >&6; } dummy=yes fi + { $as_echo "$as_me:$LINENO: checking for g_slist_free_full in -lglib-2.0" >&5 +$as_echo_n "checking for g_slist_free_full in -lglib-2.0... " >&6; } +if test "${ac_cv_lib_glib_2_0_g_slist_free_full+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lglib-2.0 $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char g_slist_free_full (); +int +main () +{ +return g_slist_free_full (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_lib_glib_2_0_g_slist_free_full=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_glib_2_0_g_slist_free_full=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_glib_2_0_g_slist_free_full" >&5 +$as_echo "$ac_cv_lib_glib_2_0_g_slist_free_full" >&6; } +if test "x$ac_cv_lib_glib_2_0_g_slist_free_full" = x""yes; then + dummy=yes +else + +cat >>confdefs.h <<\_ACEOF +#define NEED_G_SLIST_FREE_FULL 1 +_ACEOF + +fi + @@ -12946,6 +13179,77 @@ pkg_failed=no +{ $as_echo "$as_me:$LINENO: checking for UDEV" >&5 +$as_echo_n "checking for UDEV... " >&6; } + +if test -n "$UDEV_CFLAGS"; then + pkg_cv_UDEV_CFLAGS="$UDEV_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"libudev\"") >&5 + ($PKG_CONFIG --exists --print-errors "libudev") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + pkg_cv_UDEV_CFLAGS=`$PKG_CONFIG --cflags "libudev" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$UDEV_LIBS"; then + pkg_cv_UDEV_LIBS="$UDEV_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { ($as_echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"libudev\"") >&5 + ($PKG_CONFIG --exists --print-errors "libudev") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + pkg_cv_UDEV_LIBS=`$PKG_CONFIG --libs "libudev" 2>/dev/null` +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + UDEV_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libudev" 2>&1` + else + UDEV_PKG_ERRORS=`$PKG_CONFIG --print-errors "libudev" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$UDEV_PKG_ERRORS" >&5 + + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + udev_found=no +elif test $pkg_failed = untried; then + udev_found=no +else + UDEV_CFLAGS=$pkg_cv_UDEV_CFLAGS + UDEV_LIBS=$pkg_cv_UDEV_LIBS + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + udev_found=yes +fi + + + + + +pkg_failed=no { $as_echo "$as_me:$LINENO: checking for SNDFILE" >&5 $as_echo_n "checking for SNDFILE... " >&6; } @@ -13246,10 +13550,11 @@ serial_enable=yes network_enable=yes sap_enable=no + proximity_enable=no service_enable=yes health_enable=no pnat_enable=no - attrib_enable=no + gatt_example_enable=no tracer_enable=no tools_enable=yes hidd_enable=no @@ -13261,12 +13566,13 @@ pcmcia_enable=no hid2hci_enable=no dfutool_enable=no - udevrules_enable=yes - configfiles_enable=yes + datafiles_enable=yes telephony_driver=dummy maemo6_enable=no sap_driver=dummy dbusoob_enable=no + wiimote_enable=no + thermometer_enable=no # Check whether --enable-optimization was given. if test "${enable_optimization+set}" = set; then @@ -13319,6 +13625,14 @@ SAP_DRIVER=sap-${sap_driver}.c + # Check whether --enable-proximity was given. +if test "${enable_proximity+set}" = set; then + enableval=$enable_proximity; + proximity_enable=${enableval} + +fi + + # Check whether --enable-serial was given. if test "${enable_serial+set}" = set; then enableval=$enable_serial; @@ -13367,10 +13681,10 @@ fi - # Check whether --enable-attrib was given. -if test "${enable_attrib+set}" = set; then - enableval=$enable_attrib; - attrib_enable=${enableval} + # Check whether --enable-gatt-example was given. +if test "${enable_gatt_example+set}" = set; then + enableval=$enable_gatt_example; + gatt_example_enable=${enableval} fi @@ -13487,18 +13801,10 @@ fi - # Check whether --enable-udevrules was given. -if test "${enable_udevrules+set}" = set; then - enableval=$enable_udevrules; - udevrules_enable=${enableval} - -fi - - - # Check whether --enable-configfiles was given. -if test "${enable_configfiles+set}" = set; then - enableval=$enable_configfiles; - configfiles_enable=${enableval} + # Check whether --enable-datafiles was given. +if test "${enable_datafiles+set}" = set; then + enableval=$enable_datafiles; + datafiles_enable=${enableval} fi @@ -13539,6 +13845,14 @@ fi + # Check whether --enable-wiimote was given. +if test "${enable_wiimote+set}" = set; then + enableval=$enable_wiimote; + wiimote_enable=${enableval} + +fi + + # Check whether --enable-hal was given. if test "${enable_hal+set}" = set; then enableval=$enable_hal; @@ -13547,6 +13861,14 @@ fi + # Check whether --enable-thermometer was given. +if test "${enable_thermometer+set}" = set; then + enableval=$enable_thermometer; + thermometer_enable=${enableval} + +fi + + if (test "${fortify_enable}" = "yes"); then CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2" fi @@ -13653,6 +13975,14 @@ SAPPLUGIN_FALSE= fi + if test "${proximity_enable}" = "yes"; then + PROXIMITYPLUGIN_TRUE= + PROXIMITYPLUGIN_FALSE='#' +else + PROXIMITYPLUGIN_TRUE='#' + PROXIMITYPLUGIN_FALSE= +fi + if test "${service_enable}" = "yes"; then SERVICEPLUGIN_TRUE= SERVICEPLUGIN_FALSE='#' @@ -13693,12 +14023,12 @@ READLINE_FALSE= fi - if test "${attrib_enable}" = "yes"; then - ATTRIBPLUGIN_TRUE= - ATTRIBPLUGIN_FALSE='#' + if test "${gatt_example_enable}" = "yes"; then + GATT_EXAMPLE_PLUGIN_TRUE= + GATT_EXAMPLE_PLUGIN_FALSE='#' else - ATTRIBPLUGIN_TRUE='#' - ATTRIBPLUGIN_FALSE= + GATT_EXAMPLE_PLUGIN_TRUE='#' + GATT_EXAMPLE_PLUGIN_FALSE= fi if test "no" = "yes"; then @@ -13789,7 +14119,7 @@ PCMCIA_FALSE= fi - if test "${hid2hci_enable}" = "yes" && test "${usb_found}" = "yes"; then + if test "${hid2hci_enable}" = "yes" && test "${usb_found}" = "yes" && test "${udev_found}" = "yes"; then HID2HCI_TRUE= HID2HCI_FALSE='#' else @@ -13805,20 +14135,12 @@ DFUTOOL_FALSE= fi - if test "${udevrules_enable}" = "yes"; then - UDEVRULES_TRUE= - UDEVRULES_FALSE='#' -else - UDEVRULES_TRUE='#' - UDEVRULES_FALSE= -fi - - if test "${configfiles_enable}" = "yes"; then - CONFIGFILES_TRUE= - CONFIGFILES_FALSE='#' + if test "${datafiles_enable}" = "yes"; then + DATAFILES_TRUE= + DATAFILES_FALSE='#' else - CONFIGFILES_TRUE='#' - CONFIGFILES_FALSE= + DATAFILES_TRUE='#' + DATAFILES_FALSE= fi if test "${maemo6_enable}" = "yes"; then @@ -13837,6 +14159,22 @@ DBUSOOBPLUGIN_FALSE= fi + if test "${wiimote_enable}" = "yes"; then + WIIMOTEPLUGIN_TRUE= + WIIMOTEPLUGIN_FALSE='#' +else + WIIMOTEPLUGIN_TRUE='#' + WIIMOTEPLUGIN_FALSE= +fi + + if test "${thermometer_enable}" = "yes"; then + THERMOMETERPLUGIN_TRUE= + THERMOMETERPLUGIN_FALSE='#' +else + THERMOMETERPLUGIN_TRUE='#' + THERMOMETERPLUGIN_FALSE= +fi + # Check whether --enable-capng was given. @@ -13925,7 +14263,28 @@ fi -ac_config_files="$ac_config_files Makefile scripts/bluetooth.rules doc/version.xml src/bluetoothd.8 bluez.pc" + +# Check whether --with-systemdunitdir was given. +if test "${with_systemdunitdir+set}" = set; then + withval=$with_systemdunitdir; path_systemdunit=${withval} +else + path_systemdunit="`$PKG_CONFIG --variable=systemdsystemunitdir systemd`" +fi + +if (test -n "${path_systemdunit}"); then + SYSTEMD_UNITDIR="${path_systemdunit}" + +fi + if test -n "${path_systemdunit}"; then + SYSTEMD_TRUE= + SYSTEMD_FALSE='#' +else + SYSTEMD_TRUE='#' + SYSTEMD_FALSE= +fi + + +ac_config_files="$ac_config_files Makefile scripts/bluetooth.rules doc/version.xml src/bluetoothd.8 src/bluetooth.service bluez.pc" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -14123,6 +14482,13 @@ Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi +if test -z "${PROXIMITYPLUGIN_TRUE}" && test -z "${PROXIMITYPLUGIN_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"PROXIMITYPLUGIN\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"PROXIMITYPLUGIN\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi if test -z "${SERVICEPLUGIN_TRUE}" && test -z "${SERVICEPLUGIN_FALSE}"; then { { $as_echo "$as_me:$LINENO: error: conditional \"SERVICEPLUGIN\" was never defined. Usually this means the macro was only invoked conditionally." >&5 @@ -14158,10 +14524,10 @@ Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi -if test -z "${ATTRIBPLUGIN_TRUE}" && test -z "${ATTRIBPLUGIN_FALSE}"; then - { { $as_echo "$as_me:$LINENO: error: conditional \"ATTRIBPLUGIN\" was never defined. +if test -z "${GATT_EXAMPLE_PLUGIN_TRUE}" && test -z "${GATT_EXAMPLE_PLUGIN_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"GATT_EXAMPLE_PLUGIN\" was never defined. Usually this means the macro was only invoked conditionally." >&5 -$as_echo "$as_me: error: conditional \"ATTRIBPLUGIN\" was never defined. +$as_echo "$as_me: error: conditional \"GATT_EXAMPLE_PLUGIN\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi @@ -14256,17 +14622,10 @@ Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi -if test -z "${UDEVRULES_TRUE}" && test -z "${UDEVRULES_FALSE}"; then - { { $as_echo "$as_me:$LINENO: error: conditional \"UDEVRULES\" was never defined. -Usually this means the macro was only invoked conditionally." >&5 -$as_echo "$as_me: error: conditional \"UDEVRULES\" was never defined. -Usually this means the macro was only invoked conditionally." >&2;} - { (exit 1); exit 1; }; } -fi -if test -z "${CONFIGFILES_TRUE}" && test -z "${CONFIGFILES_FALSE}"; then - { { $as_echo "$as_me:$LINENO: error: conditional \"CONFIGFILES\" was never defined. +if test -z "${DATAFILES_TRUE}" && test -z "${DATAFILES_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"DATAFILES\" was never defined. Usually this means the macro was only invoked conditionally." >&5 -$as_echo "$as_me: error: conditional \"CONFIGFILES\" was never defined. +$as_echo "$as_me: error: conditional \"DATAFILES\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi @@ -14284,6 +14643,27 @@ Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi +if test -z "${WIIMOTEPLUGIN_TRUE}" && test -z "${WIIMOTEPLUGIN_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"WIIMOTEPLUGIN\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"WIIMOTEPLUGIN\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${THERMOMETERPLUGIN_TRUE}" && test -z "${THERMOMETERPLUGIN_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"THERMOMETERPLUGIN\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"THERMOMETERPLUGIN\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${SYSTEMD_TRUE}" && test -z "${SYSTEMD_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"SYSTEMD\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"SYSTEMD\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi : ${CONFIG_STATUS=./config.status} ac_write_fail=0 @@ -14606,7 +14986,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by bluez $as_me 4.91, which was +This file was extended by bluez $as_me 4.96, which was generated by GNU Autoconf 2.63. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14669,7 +15049,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ -bluez config.status 4.91 +bluez config.status 4.96 configured by $0, generated by GNU Autoconf 2.63, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" @@ -15054,6 +15434,7 @@ "scripts/bluetooth.rules") CONFIG_FILES="$CONFIG_FILES scripts/bluetooth.rules" ;; "doc/version.xml") CONFIG_FILES="$CONFIG_FILES doc/version.xml" ;; "src/bluetoothd.8") CONFIG_FILES="$CONFIG_FILES src/bluetoothd.8" ;; + "src/bluetooth.service") CONFIG_FILES="$CONFIG_FILES src/bluetooth.service" ;; "bluez.pc") CONFIG_FILES="$CONFIG_FILES bluez.pc" ;; *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 diff -Nru bluez-4.91/configure.ac bluez-4.96/configure.ac --- bluez-4.91/configure.ac 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/configure.ac 2011-07-31 06:52:19.000000000 +0000 @@ -1,5 +1,5 @@ AC_PREREQ(2.60) -AC_INIT(bluez, 4.91) +AC_INIT(bluez, 4.96) AM_INIT_AUTOMAKE([foreign subdir-objects]) AM_CONFIG_HEADER(config.h) @@ -35,11 +35,16 @@ AC_CHECK_LIB(dl, dlopen, dummy=yes, AC_MSG_ERROR(dynamic linking loader is required)) +AC_CHECK_HEADER([sys/inotify.h], + [AC_DEFINE([HAVE_SYS_INOTIFY_H], 1, + [Define to 1 if you have .])], + [AC_MSG_ERROR(inotify headers are required and missing)]) AC_PATH_DBUS AC_PATH_GLIB AC_PATH_ALSA AC_PATH_GSTREAMER AC_PATH_USB +AC_PATH_UDEV AC_PATH_SNDFILE AC_PATH_OUI AC_PATH_READLINE @@ -56,5 +61,14 @@ AC_DEFINE(HAVE_CAPNG, 1, [Define to 1 if you have capabilities library.]) fi +AC_ARG_WITH([systemdunitdir], AC_HELP_STRING([--with-systemdunitdir=DIR], + [path to systemd system service directory]), [path_systemdunit=${withval}], + [path_systemdunit="`$PKG_CONFIG --variable=systemdsystemunitdir systemd`"]) +if (test -n "${path_systemdunit}"); then + SYSTEMD_UNITDIR="${path_systemdunit}" + AC_SUBST(SYSTEMD_UNITDIR) +fi +AM_CONDITIONAL(SYSTEMD, test -n "${path_systemdunit}") + AC_OUTPUT(Makefile scripts/bluetooth.rules doc/version.xml - src/bluetoothd.8 bluez.pc) + src/bluetoothd.8 src/bluetooth.service bluez.pc) diff -Nru bluez-4.91/cups/hcrp.c bluez-4.96/cups/hcrp.c --- bluez-4.91/cups/hcrp.c 2010-01-09 20:52:17.000000000 +0000 +++ bluez-4.96/cups/hcrp.c 2011-05-31 02:39:53.000000000 +0000 @@ -94,8 +94,13 @@ memcpy(buf, &hdr, HCRP_PDU_HDR_SIZE); memcpy(buf + HCRP_PDU_HDR_SIZE, &cp, HCRP_CREDIT_GRANT_CP_SIZE); len = write(sk, buf, HCRP_PDU_HDR_SIZE + HCRP_CREDIT_GRANT_CP_SIZE); + if (len < 0) + return len; len = read(sk, buf, sizeof(buf)); + if (len < 0) + return len; + memcpy(&hdr, buf, HCRP_PDU_HDR_SIZE); memcpy(&rp, buf + HCRP_PDU_HDR_SIZE, HCRP_CREDIT_GRANT_RP_SIZE); @@ -119,8 +124,13 @@ hdr.plen = htons(0); memcpy(buf, &hdr, HCRP_PDU_HDR_SIZE); len = write(sk, buf, HCRP_PDU_HDR_SIZE); + if (len < 0) + return len; len = read(sk, buf, sizeof(buf)); + if (len < 0) + return len; + memcpy(&hdr, buf, HCRP_PDU_HDR_SIZE); memcpy(&rp, buf + HCRP_PDU_HDR_SIZE, HCRP_CREDIT_REQUEST_RP_SIZE); @@ -147,8 +157,13 @@ hdr.plen = htons(0); memcpy(buf, &hdr, HCRP_PDU_HDR_SIZE); len = write(sk, buf, HCRP_PDU_HDR_SIZE); + if (len < 0) + return len; len = read(sk, buf, sizeof(buf)); + if (len < 0) + return len; + memcpy(&hdr, buf, HCRP_PDU_HDR_SIZE); memcpy(&rp, buf + HCRP_PDU_HDR_SIZE, HCRP_GET_LPT_STATUS_RP_SIZE); diff -Nru bluez-4.91/debian/bluetooth-dbus.conf bluez-4.96/debian/bluetooth-dbus.conf --- bluez-4.91/debian/bluetooth-dbus.conf 2011-04-15 05:11:42.000000000 +0000 +++ bluez-4.96/debian/bluetooth-dbus.conf 2011-08-12 17:51:13.000000000 +0000 @@ -30,6 +30,7 @@ + diff -Nru bluez-4.91/debian/bluez_agent.udev bluez-4.96/debian/bluez_agent.udev --- bluez-4.91/debian/bluez_agent.udev 2011-04-15 05:11:42.000000000 +0000 +++ bluez-4.96/debian/bluez_agent.udev 2011-08-12 17:51:13.000000000 +0000 @@ -3,6 +3,6 @@ ( . /lib/udev/hotplug.functions - wait_for_file /usr/sbin/hid2hci - exec /usr/sbin/hid2hci "$@" + wait_for_file /lib/udev/hid2hci + exec /lib/udev/hid2hci "$@" ) & diff -Nru bluez-4.91/debian/bluez-alsa.install bluez-4.96/debian/bluez-alsa.install --- bluez-4.91/debian/bluez-alsa.install 2011-04-15 05:11:42.000000000 +0000 +++ bluez-4.96/debian/bluez-alsa.install 2011-08-12 17:51:13.000000000 +0000 @@ -1 +1 @@ -debian/tmp/usr/lib/alsa-lib/*.so +debian/tmp/usr/lib/*/alsa-lib/*.so diff -Nru bluez-4.91/debian/bluez.bluetooth.default bluez-4.96/debian/bluez.bluetooth.default --- bluez-4.91/debian/bluez.bluetooth.default 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/debian/bluez.bluetooth.default 2011-08-12 17:51:13.000000000 +0000 @@ -0,0 +1,20 @@ +# Defaults for bluez + +# start bluetooth on boot? +# compatibility note: if this variable is _not_ found bluetooth will start +BLUETOOTH_ENABLED=1 + +# This setting used to switch HID devices (e.g mouse/keyboad) to HCI mode, that +# is you will have bluetooth functionality from your dongle instead of only +# HID. This is accomplished for supported devices by udev in +# /lib/udev/rules.d/62-bluez-hid2hci.rules by invoking hid2hci with correct +# parameters. +# See /usr/share/doc/bluez/NEWS.Debian.gz for further information. + +# Older daemons like pand dund and hidd can be found in bluez-compat package as +# they are deprecated and provided for backward compatibility only. + +# Note that not every bluetooth dongle is capable of switching back to HID mode, +# see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=355497 +HID2HCI_ENABLED=0 +HID2HCI_UNDO=0 diff -Nru bluez-4.91/debian/bluez.bluetooth.init bluez-4.96/debian/bluez.bluetooth.init --- bluez-4.91/debian/bluez.bluetooth.init 2011-04-15 05:11:42.000000000 +0000 +++ bluez-4.96/debian/bluez.bluetooth.init 2011-08-12 17:51:13.000000000 +0000 @@ -24,35 +24,161 @@ DESC=bluetooth DAEMON=/usr/sbin/bluetoothd +HCIATTACH=/usr/sbin/hciattach -test -f /usr/sbin/bluetoothd || exit 0 +HID2HCI_ENABLED=1 +HID2HCI_UNDO=1 +UART_CONF=/etc/bluetooth/uart + +RFCOMM_NAME=rfcomm +RFCOMM=/usr/bin/$RFCOMM_NAME +RFCOMM_CONF=/etc/bluetooth/$RFCOMM_NAME.conf +SDPTOOL=/usr/bin/sdptool + +SSD_OPTIONS="--oknodo --quiet --exec $DAEMON" + +test -f $DAEMON || exit 0 + +# FIXME: any of the sourced files may fail if/with syntax errors +test -f /etc/default/bluetooth && . /etc/default/bluetooth test -f /etc/default/rcS && . /etc/default/rcS . /lib/lsb/init-functions set -e -case "$1" in +# FIXME: this function is possibly a no-op +run_sdptool() +{ + # declaring IFS local in this function, removes the need to + # save/restore it + local IFS o + + test -x $SDPTOOL || return 1 + +# FIXME: where does SDPTOOL_OPTIONS come from? + if ! test -z "$SDPTOOL_OPTIONS" ; then + IFS=";" + for o in $SDPTOOL_OPTIONS ; do + #echo "execing $SDPTOOL $o" + IFS=" " + if [ "$VERBOSE" != no ]; then + $SDPTOOL $o + else + $SDPTOOL $o >/dev/null 2>&1 + fi + done + fi +} + +hci_input() +{ + log_progress_msg "switching to HID/HCI no longer done in init script, see /usr/share/doc/bluez/NEWS.Debian.gz" || : +} +alias enable_hci_input=hci_input +alias disable_hci_input=hci_input + +start_uarts() +{ + [ -f $HCIATTACH ] && [ -f $UART_CONF ] || return + grep -v '^#' $UART_CONF | while read i; do + if [ "$VERBOSE" != no ]; then + $HCIATTACH $i + else + $HCIATTACH $i >/dev/null 2>&1 + fi + done +} + +stop_uarts() +{ + killall ${HCIATTACH##*/} >/dev/null 2>&1 || : +} + +start_rfcomm() +{ + if [ -x $RFCOMM ] && [ -f $RFCOMM_CONF ] ; then + # rfcomm must always succeed for now: users + # may not yet have an rfcomm-enabled kernel + if [ "$VERBOSE" != no ]; then + log_progress_msg "${RFCOMM##*/}" + $RFCOMM -f $RFCOMM_CONF bind all || : + else + $RFCOMM -f $RFCOMM_CONF bind all >/dev/null 2>&1 || : + fi + fi +} + +stop_rfcomm() +{ + if [ -x $RFCOMM ] ; then + if [ "$VERBOSE" != no ]; then + log_progress_msg "${RFCOMM##*/}" + $RFCOMM unbind all || : + else + $RFCOMM unbind all >/dev/null 2>&1 || : + fi + fi +} + +restart_rfcomm() +{ + if [ -x $RFCOMM ] && [ -f $RFCOMM_CONF ] ; then + if [ "$VERBOSE" != no ]; then + log_progress_msg "${RFCOMM##*/}" + $RFCOMM unbind all || : + $RFCOMM -f $RFCOMM_CONF bind all || : + else + $RFCOMM unbind all >/dev/null 2>&1|| : + $RFCOMM -f $RFCOMM_CONF bind all >/dev/null 2>&1 || : + fi + fi +} + +case $1 in start) - #currently this init script exists only because of what appears to be - #an egg and chicken problem - # bluetoothd normally starts up by udev rules. it needs dbus to function, - # but dbus doesn't start up until after udev finishes triggering - # log_daemon_msg "Starting $DESC" - if [ ! -f /sbin/udevadm.upgrade ]; then - udevadm trigger --subsystem-match=bluetooth --action=add - log_progress_msg "bluetoothd" + if test "$BLUETOOTH_ENABLED" = 0; then + log_progress_msg "disabled. see /etc/default/bluetooth" + log_end_msg 0 + exit 0 + fi + + start-stop-daemon --start $SSD_OPTIONS + log_progress_msg "${DAEMON##*/}" + + run_sdptool || : + + start_uarts || : + + if test "$HID2HCI_ENABLED" = 1; then + enable_hci_input + fi + start_rfcomm || : + + if test "$HIDD_ENABLED" = 1 || + test "$PAND_ENABLED" = 1 || test "$DUND_ENABLED" = 1; then + log_progress_msg "compatibily daemons not started, see bluez-compat package" fi log_end_msg 0 ;; stop) log_daemon_msg "Stopping $DESC" - pkill -TERM bluetoothd || true - log_progress_msg "bluetoothd" + if test "$BLUETOOTH_ENABLED" = 0; then + log_progress_msg "disabled." + log_end_msg 0 + exit 0 + fi + stop_rfcomm || : + if test "$HID2HCI_UNDO" = 1; then + disable_hci_input + fi + start-stop-daemon --stop $SSD_OPTIONS + log_progress_msg "${DAEMON}" + stop_uarts || : log_end_msg 0 ;; restart|force-reload) @@ -65,7 +191,6 @@ ;; *) N=/etc/init.d/bluetooth - # echo "Usage: $N {start|stop|restart|reload|force-reload|status}" >&2 echo "Usage: $N {start|stop|restart|force-reload|status}" >&2 exit 1 ;; diff -Nru bluez-4.91/debian/bluez.install bluez-4.96/debian/bluez.install --- bluez-4.91/debian/bluez.install 2011-04-15 05:11:42.000000000 +0000 +++ bluez-4.96/debian/bluez.install 2011-09-28 16:44:11.000000000 +0000 @@ -5,4 +5,3 @@ debian/tmp/usr/sbin/* debian/tmp/usr/bin/* debian/tmp/usr/share/man/man* -debian/tmp/lib/udev/* diff -Nru bluez-4.91/debian/bluez.postinst bluez-4.96/debian/bluez.postinst --- bluez-4.91/debian/bluez.postinst 2011-04-15 05:11:42.000000000 +0000 +++ bluez-4.96/debian/bluez.postinst 2011-08-12 17:51:13.000000000 +0000 @@ -1,6 +1,8 @@ #!/bin/sh # snippet from http://www.dpkg.org/dpkg/ConffileHandling +set -e + # Move a conffile without triggering a dpkg question mv_conffile() { OLDCONFFILE="$1" @@ -13,7 +15,6 @@ fi } -set -e case "$1" in configure) if [ -e /etc/init.d/bluez-utils ]; then @@ -43,6 +44,8 @@ fi ;; + abort-upgrade|abort-remove|abort-deconfigure) + ;; *) echo "postinst called with unknown argument \`$1'" >&2 diff -Nru bluez-4.91/debian/bluez.preinst bluez-4.96/debian/bluez.preinst --- bluez-4.91/debian/bluez.preinst 2011-04-15 05:11:42.000000000 +0000 +++ bluez-4.96/debian/bluez.preinst 2011-08-12 17:51:13.000000000 +0000 @@ -57,10 +57,6 @@ mv -f "$base.dpkg-bak" "$base.conf" fi fi - - if dpkg --compare-versions "$2" le "4.45-1"; then - rm_conffile bluez "/etc/default/bluetooth" - fi esac #DEBHELPER# diff -Nru bluez-4.91/debian/changelog bluez-4.96/debian/changelog --- bluez-4.91/debian/changelog 2011-04-15 05:21:12.000000000 +0000 +++ bluez-4.96/debian/changelog 2011-09-28 16:46:11.000000000 +0000 @@ -1,65 +1,161 @@ -bluez (4.91-0ubuntu1linaro1) natty; urgency=low +bluez (4.96-0ubuntu3~linaro1) natty; urgency=low - * debian/patches/snowball.patch: Add support for ST-Ericsson CG2900 - chip. Thanks to Mario Boikov . Closes - LP: #758804. + * Backport to Natty, Ubuntu LEB + * Disable hid2hci is it's still provided by udev at Natty - -- Steve Langasek Thu, 14 Apr 2011 22:16:49 -0700 + -- Ricardo Salveti de Araujo Wed, 28 Sep 2011 13:45:34 -0300 -bluez (4.91-0ubuntu1) natty; urgency=low +bluez (4.96-0ubuntu3) oneiric; urgency=low - * New upstream release - * debian/libbluetooth3.symbols: - - Updated + * Mark bluez Multi-Arch: foreign and bluez-alsa Multi-Arch: same; no other + changes required to make bluez-alsa multiarch-friendly. - -- Robert Ancell Tue, 05 Apr 2011 10:09:16 +1000 + -- Steve Langasek Fri, 12 Aug 2011 11:33:37 -0700 -bluez (4.90-0ubuntu1) natty; urgency=low +bluez (4.96-0ubuntu2) oneiric; urgency=low - * New upstream release + * debian/control: build against libnl3-dev. - -- Robert Ancell Thu, 24 Mar 2011 10:27:09 +1100 + -- Mathieu Trudel-Lapierre Mon, 08 Aug 2011 12:34:46 -0400 -bluez (4.89-0ubuntu1) natty; urgency=low +bluez (4.96-0ubuntu1) oneiric; urgency=low - * New upstream release + * New upstream version - -- Robert Ancell Mon, 21 Feb 2011 11:50:59 +1100 + -- Sebastien Bacher Mon, 01 Aug 2011 16:07:29 +0200 -bluez (4.88-0ubuntu1) natty; urgency=low +bluez (4.95-0ubuntu1) oneiric; urgency=low - * New upstream release + * New upstream release. + * Resynchronize with Debian unstable, remaining changes: + - debian/source_bluez.py, debian/bluez.install: + + apport hook made by Baptiste Mille-Mathias. + - debian/rules: don't use simple-patchsys. + - debian/source/format: use source format 3.0. + - debian/patches/pkg-config-install-paths.patch: install bluez-alsa plugin + to the multiarch path, now that alsa-lib has transitioned. + * debian/patches/02_disable_hal.patch: refreshed. + * debian/patches/pkg-config-install-paths.patch: refreshed. + * debian/control, debian/rules: run autoreconf when building as required by + pkg-config-install-paths.patch. + + -- Mathieu Trudel-Lapierre Thu, 28 Jul 2011 16:47:35 -0400 - -- Robert Ancell Mon, 14 Feb 2011 15:48:03 +1100 +bluez (4.94-2) unstable; urgency=medium -bluez (4.87-1ubuntu1) natty; urgency=low + * Add udev to Replaces and Breaks field (Closes: #628904). + * Fix typo from deamon to daemon (Closes: 629901). - * Merge from debian experimental. Remaining changes: (LP: #708770) - - debian/bluetooth-dbus.conf: - + Allow access to the D-Bus resource "org.bluez" also for the "lp" - group so that the "bluetooth" CUPS backend can access when it is - run by CUPS for discovery of Bluetooth printers. - - debian/bluez.bluetooth.default: - + Drop. Doesn't do anything now. - - debian/bluez.preinst: - + Cleanup /etc/default/bluetooth as it's not used anymore. - - debian/control: - + Add udev to build-depends. Allows pkg-config to query udev data - directory variable. - - debian/rules: - + Don't build hid2hci anymore. It's part of udev now. - + Don't install bluez_agent.udev, doesn't work in Ubuntu. - + Drop simple-patchsys.mk - - debian/source/format: Use source format 3.0. - - debian/source_bluez.py, debian/bluez.install: - + Apport hook made by Baptiste Mille-Mathias. - - debian/bluez.bluetooth.init: - + Drop most calls in this script as now all it serves as - is to workaround a problem with dbus not being ready early - enough. Once dbus is started by an upstart service, this - should be able to be converted to an upstart service too. + -- Nobuhiro Iwamatsu Thu, 09 Jun 2011 21:48:21 +0900 + +bluez (4.94-1) unstable; urgency=medium + + * New upstream release. + * Update debian/control. + - Add ppc64 to Architecture. + - Add version depency of udev (Closes: #628904, #628765). + * Remove debian/patches/03_fix_udevdir.patch. + Applied to upstream. + * Update debian/bluez.bluetooth.init. + Applied patch from Cristian Ionescu-Idbohrn (Closes: #628491). + * Update debian/bluez.postinst. + Add abort-upgrade, abort-remove and abort-deconfigure target + to bluez.postinst. + * Fix return code of hid2hci. + Add patch 03-Fix-return-code-of-hid2hci.patch + * Fix work Logitech keyboard (Closes: #626975) + Add patch 04-Fix-bluetooth-hid2hci.rules.patch + + -- Nobuhiro Iwamatsu Wed, 01 Jun 2011 15:30:01 +0900 + +bluez (4.94-0ubuntu3) oneiric; urgency=low + + * Fix LP: #815625 - build with --enable-hid2hci now that hid2hci has been + removed from udev + - update debian/rules + * bluez Breaks/Replaces udev <= 168-0ubuntu1 + - update debian/control + + -- Chris Coulson Mon, 25 Jul 2011 15:57:14 +0100 + +bluez (4.94-0ubuntu2) oneiric; urgency=low + + * debian/patches/pkg-config-install-paths.patch: install bluez-alsa plugin + to the multiarch path, now that alsa-lib has transitioned. + + -- Steve Langasek Thu, 21 Jul 2011 16:53:48 +0200 + +bluez (4.94-0ubuntu1) oneiric; urgency=low + + * Resynchronize on Debian, remaining diff: + * debian/bluez.bluetooth.default: + - Drop. Doesn't do anything now. + * debian/control: + - use arch: any rather than a list of architectures + * debian/bluez.bluetooth.init: + - Drop most calls in this script as now all it serves as is to + workaround a problem with dbus not being ready early enough. Once dbus is + started by an upstart service, this should be able to be converted + to an upstart service too. + * debian/rules: + - Don't build hid2hci anymore. It's part of udev now. + - Don't install bluez_agent.udev, doesn't work in Ubuntu. + - Don't use simple-patchsys + * debian/source_bluez.py, debian/bluez.install: + - apport hook made by Baptiste Mille-Mathias. + * debian/source/format: + - use source format 3.0. + + -- Sebastien Bacher Mon, 06 Jun 2011 18:11:44 +0200 + +bluez (4.93-3) unstable; urgency=low + + * Fix install hid2hci to /lib/udev. + + -- Nobuhiro Iwamatsu Tue, 31 May 2011 19:42:33 +0900 + +bluez (4.93-2) unstable; urgency=low + + * Update debian/README.Debian.gz. + Add description of bluez-simple-agent (Closes: #488306, #384680). + * Update debian/bluez_agent.udev and debian/bluez.bluetooth.init. + Fix path of hid2hci (Closes: #628491). + * Add debian/patches/03_fix_udevdir.patch. + + -- Nobuhiro Iwamatsu Tue, 31 May 2011 18:04:29 +0900 + +bluez (4.93-1) unstable; urgency=low + + * New upstream release. + * Update debian/control. + - Add libudev-dev to Build-Depends. + * Update debian/bluetooth-dbus.conf. + Add policy for lp group. + + -- Nobuhiro Iwamatsu Fri, 20 May 2011 10:31:07 +0900 + +bluez (4.91-1) unstable; urgency=low + + * New upstream release. + * Updte debian/control + + Update to S-V 3.9.2: no changes needed. + + Remove libdbus-1-dev from Build-Depends. + This is interpolated by libdbus-1-dev. + * Update debian/libbluetooth3.symbols. + + -- Nobuhiro Iwamatsu Tue, 12 Apr 2011 11:50:49 +0900 + +bluez (4.89-1) unstable; urgency=low + + * New upstream release. - -- Artur Rona Thu, 27 Jan 2011 18:00:26 +0100 + -- Nobuhiro Iwamatsu Sat, 05 Mar 2011 17:08:40 +0900 + +bluez (4.87-2) unstable; urgency=low + + * Upload to unstable. + + -- Nobuhiro Iwamatsu Wed, 09 Feb 2011 01:38:45 +0900 bluez (4.87-1) experimental; urgency=low @@ -75,12 +171,6 @@ -- Nobuhiro Iwamatsu Mon, 24 Jan 2011 11:49:55 +0900 -bluez (4.85-0ubuntu1) natty; urgency=low - - * New upstream release - - -- Robert Ancell Tue, 18 Jan 2011 10:41:30 +1100 - bluez (4.84-1) experimental; urgency=low * New upstream release. @@ -90,12 +180,6 @@ -- Nobuhiro Iwamatsu Wed, 12 Jan 2011 17:23:25 +0900 -bluez (4.84-0ubuntu1) natty; urgency=low - - * New upstream release - - -- Robert Ancell Fri, 07 Jan 2011 13:21:49 +1100 - bluez (4.82-1) experimental; urgency=low * New upstream release. @@ -103,47 +187,6 @@ -- Nobuhiro Iwamatsu Mon, 20 Dec 2010 01:39:43 +0900 -bluez (4.82-0ubuntu1) natty; urgency=low - - * New upstream release - - -- Robert Ancell Mon, 20 Dec 2010 16:08:47 +1100 - -bluez (4.81-1ubuntu1) natty; urgency=low - - * debian/control: - - Add Vcs-Bzr link - * debian/rules: - - Drop simple-patchsys.mk - * debian/source/format: - - Use source format 3.0 - - [ Michael Terry ] - * Merge with Debian experimental (LP: #687701), remaining Ubuntu changes: - + debian/bluetooth-dbus.conf: - - Allow access to the D-Bus resource "org.bluez" also for the "lp" - group so that the "bluetooth" CUPS backend can access when it is - run by CUPS for discovery of Bluetooth printers. - + debian/bluez.bluetooth.default: - - Drop. Doesn't do anything now. - + debian/bluez.preinst: - - Cleanup /etc/default/bluetooth as it's not used anymore. - + debian/control: - - Add udev to build-depends. Allows pkg-config to query udev data - directory variable. - + debian/rules: - - Don't build hid2hci anymore. It's part of udev now. - - Don't install bluez_agent.udev, doesn't work in Ubuntu. - + debian/source_bluez.py, debian/bluez.install: - - Apport hook made by Baptiste Mille-Mathias. (LP: #545551) - + debian/bluez.bluetooth.init: - - Drop most calls in this script as now all it serves as - is to workaround a problem with dbus not being ready early - enough. Once dbus is started by an upstart service, this - should be able to be converted to an upstart service too. - - -- Robert Ancell Mon, 20 Dec 2010 14:59:20 +1100 - bluez (4.81-1) experimental; urgency=low * New upstream release. @@ -184,24 +227,6 @@ -- Nobuhiro Iwamatsu Wed, 28 Jul 2010 13:44:34 +0900 -bluez (4.69-0ubuntu2) maverick; urgency=low - - * debian/bluez.bluetooth.init: udev's default action for "trigger" changed - to "change", so explicitly request "add" actions; that's what our rule - matches on. Fixes detection of BT devices at boot. (LP: #621911) - - -- Martin Pitt Sun, 22 Aug 2010 16:58:16 +0200 - -bluez (4.69-0ubuntu1) maverick; urgency=low - - * New upstream version - * debian/control, debian/rules: - - use dh-autoreconf there - * debian/libbluetooth3.symbols: - - new version update - - -- Sebastien Bacher Thu, 12 Aug 2010 21:38:04 +0200 - bluez (4.66-1) unstable; urgency=low * New upstream release. @@ -228,21 +253,6 @@ -- Nobuhiro Iwamatsu Sat, 15 May 2010 15:44:23 +0900 -bluez (4.64-0ubuntu1) maverick; urgency=low - - * New upstream release: - - Fix invalid memory access in headset_get_nrec function. - - Fix issue with disconnect event on higher protocol layers. - - Fix issue with list parsing in sdp_set_supp_features function. - - Fix device object reference counting for SDP browse requests. - - Add missing memory checks whenever memory is allocated for SDP. - - Add support for exporting local services via D-Bus. - - Add more L2CAP Enhanced Retransmission test options. - * debian/patches/01_disable_hal.patch: - - updated - - -- Baptiste Mille-Mathias Tue, 02 May 2010 11:49:15 +0200 - bluez (4.63-2) unstable; urgency=low * Remove some contents from debian/NEWS. (Closes: #579817) @@ -264,43 +274,6 @@ -- Nobuhiro Iwamatsu Tue, 20 Apr 2010 06:08:24 +0900 -bluez (4.63-0ubuntu1) UNRELEASED; urgency=low - - * New upstream release. - - Fix avdtp_abort not canceling pending requests. - - Fix stale connection when abort gets rejected. - * debian/patches/01_disable_hal.patch: - - updated - - -- Baptiste Mille-Mathias Tue, 02 May 2010 11:35:38 +0200 - -bluez (4.62-0ubuntu1) UNRELEASED; urgency=low - - * New upstream release: - - Fix accidental symbol breakage with inquiry transmit power. - - Fix using invalid data from previous headset connection. - - Fix double free on AVDTP Abort response. - - Fix possible crash while verifying AVDTP version. - - Fix missing inuse flag when AVDTP stream is configured. - - Add support for Bluetooth controller types. - - -- Baptiste Mille-Mathias Sun, 02 May 2010 11:30:45 +0200 - -bluez (4.61-0ubuntu1) UNRELEASED; urgency=low - - * New upstream release: - - Fix issues with Read Inquiry Response Transmit Power Level. - - Fix possible invalid read when removing a temporary device. - - Fix mode restoration when remember_powered is false. - - Fix conference call releasing in telephony-maemo. - - Fix segmentation fault with authorization during headset disconnects. - - Add support for handling unanswered AVDTP request on disconnect. - - Add support for handling Inquiry Response Transmit Power Level. - - Add support for caching of remote host features. - - Add preliminary voice dialing support for HSP. - - -- Baptiste Mille-Mathias Sun, 02 May 2010 11:24:40 +0200 - bluez (4.60-1) unstable; urgency=low * New upstream release. @@ -309,78 +282,12 @@ -- Nobuhiro Iwamatsu Sat, 23 Jan 2010 16:03:01 +0900 -bluez (4.60-0ubuntu8) lucid; urgency=low - - * debian/rules: install serial.conf (LP: #544150) - - -- Baptiste Mille-Mathias Tue, 06 Apr 2010 21:07:22 +0200 - -bluez (4.60-0ubuntu7) lucid; urgency=low - - [ Baptiste Mille-Mathias ] - * Fixes to the apport hook to get the output stored in the report. - - -- James Westby Tue, 30 Mar 2010 15:02:03 -0400 - -bluez (4.60-0ubuntu6) lucid; urgency=low - - * debian/source_bluez.py: - - Apport hook made by Baptiste Mille-Mathias. (LP: #545551) - * debian/bluez.install: - - ship the new apport hook. - - -- Nigel Babu Wed, 24 Mar 2010 20:17:53 +0530 - -bluez (4.60-0ubuntu5) lucid; urgency=low - - * debian/patches/02_lower_sink_ranking.patch: - - restore this change it's not in the new version and still required - to unbreak the gstreamer easy codec installation - - -- Sebastien Bacher Fri, 26 Feb 2010 02:46:36 +0100 - -bluez (4.60-0ubuntu4) lucid; urgency=low - - * Revert previous upload as per - https://lists.ubuntu.com/archives/ubuntu-devel/2010-February/030283.html - - -- Harald Sitter Mon, 22 Feb 2010 22:28:47 +0100 - -bluez (4.60-0ubuntu3) lucid; urgency=low - - * bluetooth suggest bluez-gstreamer instead of recommending it. Not every - setup features GStreamer applications (e.g. a Kubuntu system) - - -- Harald Sitter Mon, 22 Feb 2010 20:56:16 +0100 - -bluez (4.60-0ubuntu2) lucid; urgency=low - - * Add 01_disable_hal.patch: Disable usage of Hal in the telephony plugins, - and disable the hal plugin. They do not do very useful things anyway, and - just cause hal to start up, which is expensive. - - -- Martin Pitt Mon, 15 Feb 2010 15:04:25 +0100 - -bluez (4.60-0ubuntu1) lucid; urgency=low - - * New upstream release (lp: #506149) - - -- Baptiste Mille-Mathias Mon, 11 Jan 2010 22:00:47 +0100 - bluez (4.57-1) unstable; urgency=low * New upstream bug fix release. -- Andrea Veri Thu, 12 Nov 2009 21:27:54 +0100 -bluez (4.57-0ubuntu1) karmic; urgency=low - - * New upstream release - * debian/patches/01_lower_sink_ranking.patch: - - dropped, now upstream - - -- Baptiste Mille-Mathias Sun, 01 Nov 2009 11:48:53 +0100 - bluez (4.56-2) unstable; urgency=low * debian/control: @@ -417,145 +324,6 @@ -- Andrea Veri Mon, 12 Oct 2009 15:40:02 +0200 -bluez (4.51-0ubuntu2) karmic; urgency=low - - * debian/patches/01_lower_sink_ranking.patch: - - lower the gsta2dpsink ranking so it's not autoconfigured, right now it - claims to handle mpeg but has no decoder for it which breaks easy codec - installation, the sink cannot be used without configuring a device - which means it doesn't need to be used by default, thanks slomo who - looked at the issue and adviced about the change (lp: #412927) - - -- Sebastien Bacher Thu, 24 Sep 2009 23:12:24 +0200 - -bluez (4.51-0ubuntu1) karmic; urgency=low - - * New upstream version. (LP: #420811) - - Add utility for basic AVDTP testing. - - Add support for configuring L2CAP FCS option. - - Fix discovery mode for CUPS 1.4.x and later. - - Fix global state tracking of audio service. - - Fix last issues with the new build system. - - Fix issue with missing manual pages in distribution. - - Fix issue with the configuration and state directories. - - Fix issue with creating include directory. - - Fix dependencies of include file generation. - - Add simple test program for basic GAP testing. - - Add support for confirmation requests to agent example. - - Add support for full non-recursive build. - - Add five millisecond delay for Simple Pairing auto-accept. - - Fix Class of Device setting when InitiallyPowered=false. - * Drop 10_bluetooth-cups-backend-report-printers-immediately.patch - as it's now upstream. - - -- Mario Limonciello Thu, 03 Sep 2009 12:20:43 -0500 - -bluez (4.48-0ubuntu2) karmic; urgency=low - - * debian/patches/10_bluetooth-cups-backend-report-printers-immediately.patch: - Let bluetooth CUPS backend immediately output a printer entry when it - discovers a printer instead of outputtting the whole printer list after the - timeout. This is needed for the new device discovery environment of CUPS. - (LP: #418465) - - -- Till Kamppeter Wed, 26 Aug 2009 18:42:33 +0200 - -bluez (4.48-0ubuntu1) karmic; urgency=low - - * New upstream version. - - Add library function for comparing UUID values. - - Add support for creating all plugins as builtins. - - Add support for async handling of service class changes. - - Add support for source interface to audio IPC. - - Fix device name settings when device is off or down. - - Fix issue with enabled SCO server when not necessary. - - Fix missing D-Bus access policy for CUPS backend. - - Fix discovery results of CUPS backend. - - Fix initialization handling of Maemo telephony. - * Drop cups-bluetooth-discovery-improvements.patch as it's now - upstream. - - -- Mario Limonciello Sun, 16 Aug 2009 23:43:06 -0500 - -bluez (4.47-0ubuntu2) karmic; urgency=low - - * debian/bluetooth-dbus.conf: Allow access to the D-Bus resource "org.bluez" - also for the "lp" group so that the "bluetooth" CUPS backend can access - when it is run by CUPS for discovery of Bluetooth printers. - * debian/patches/cups-bluetooth-discovery-improvements.patch: Improved - device discovery mode output of the "bluetooth" CUPS backend. Once, fill - the device make-and-model field, and second, let the device class be - "direct" and not network, so that the printer setup tools list the - Bluetooth printer as a local printer. (LP: #411610) - - -- Till Kamppeter Mon, 10 Aug 2009 21:18:33 +0200 - -bluez (4.47-0ubuntu1) karmic; urgency=low - - * New upstream version. (LP: #405263) - - Fixes issues with service record updates - - Adds native RFKILL support for 2.6.31+ - - Supports static serial proxy configurations - - Fixes many memory leaks and wrong pointer usages - - Support for A2DP sinks added - - -- Mario Limonciello Fri, 07 Aug 2009 11:34:48 -0500 - -bluez (4.45-0ubuntu4) karmic; urgency=low - - * Fix upgrade breakage from 4.45-0ubuntu{1,2} (lp: #399482) - - -- Michael Bienia Thu, 16 Jul 2009 11:04:02 +0200 - -bluez (4.45-0ubuntu3) karmic; urgency=low - - * debian/bluez.bluetooth.init: - - Guard the stop action in case bluetoothd isn't running. (LP: #399482) - - -- Mario Limonciello Tue, 14 Jul 2009 17:02:42 -0500 - -bluez (4.45-0ubuntu2) karmic; urgency=low - - * debian/bluez.bluetooth.init: - - Fix an error that broke LSB compliance in last upload (LP: #399158) - - Check for /sbin/udevadm.upgrade. If it exists, we shouldn't be running - any triggers. (LP: #399287) - - -- Mario Limonciello Tue, 14 Jul 2009 13:33:26 -0500 - -bluez (4.45-0ubuntu1) karmic; urgency=low - - * New upstream version. - - Improvements in audio support - - Ability to start bluetoothd from udev - - Fixes some Phonebook access interaction with EDS bugs. - - 3 way calling fixes with handsfree support. - * debian/bluez.bluetooth.default: - - Drop. Doesn't do anything now. - * debian/bluez.bluetooth.init: - - Drop most calls in this script as now all it serves as - is to workaround a problem with dbus not being ready early - enough. Once dbus is started by an upstart service, this - should be able to be converted to an upstart service too. - * debian/bluez.preinst: - - Cleanup /etc/default/bluetooth as it's not used anymore. - * debian/bluez.install: - - Install udev rule - * debian/rules: - - Enable udev rules. - - Remove mv line since we don't still have l2ping section patch. - - Drop references to init script. - * debian/control: - - Add udev to build-depends. Allows pkg-config to query udev data - directory variable. - * Drop unnecessary patches: - - 001_test_agent_default_adapter.patch (No longer applies, no longer necessary) - - 006_a2dpsink_marginal.patch (upstream) - - 003_configure_amd64_rpath.patch (no longer applies, not necessary) - - 005_l2ping_section.patch (upstream) - - -- Mario Limonciello Mon, 13 Jul 2009 18:01:11 -0500 - bluez (4.42-2) unstable; urgency=low * Fix "Bashisms in init script" (Closes: #534511) @@ -583,28 +351,6 @@ -- Filippo Giunchedi Sun, 21 Jun 2009 14:01:04 +0200 -bluez (4.41-0ubuntu2) karmic; urgency=low - - * debian/rules: - - Don't build hid2hci anymore. It's part of udev-extras now. - - -- Mario Limonciello Mon, 15 Jun 2009 01:25:04 -0500 - -bluez (4.41-0ubuntu1) karmic; urgency=low - - * Debian has adopted the Ubuntu bluez package. Merge - with debian packaging. Remaining delta: - - Drop 010_udev_rules_agent.patch. Ubuntu doesn't have - /lib/udev/hotplug.functions, so this wouldn't stand a chance - working. - - Don't advertise hid2hci in bluetooth.default or bluetooth.init - - Don't install bluez_agent.udev, doesn't work in Ubuntu. - * New upstream version (4.41): - - Multiple fixes for the audio subsystem - - Makes the Bluetooth daemon itself more and more stable. - - -- Mario Limonciello Tue, 09 Jun 2009 09:34:12 -0500 - bluez (4.40-2) unstable; urgency=low * Ship a libbluetooth3.symbols file instead of shlibs @@ -625,79 +371,6 @@ -- Filippo Giunchedi Fri, 22 May 2009 14:56:07 +0200 -bluez (4.40-0ubuntu1) karmic; urgency=low - - * New upstream release - - Add telephony driver for oFono telephony stack. - - Add support for Dell specific HID proxy switching. - - Add support for running hid2hci from udev. - - Add mapping for AVRCP Play and Pause to dedicated key codes. - - Fix AVRCP keycodes to better match existing X keymap support. - - Fix various quoting issues within telephony support. - - Fix memory allocation issue when generating PDUs for SDP. - - Fix race condition on device removal. - - Fix non-cancelable issue with CreateDevice method. - - Fix non-working CancelDiscovery method call. - * debian/rules: - - Adjust for upstream modifications to udev rules. - * debian/hid2hci.rules: - - Drop. This has been added upstream now. - * patches/hid2hci_pm-utils.patch: - - Drop for now, until a better solution has been developed. - hid2hci now requires arguments for the device, so it will probably - be better to reset the USB device upon entering or leaving S3. - * debian/bluez.bluetooth.init: - - Drop references to hid2hci - * debian/bluez.bluetooth.default: - - Drop references to hid2hci - - -- Mario Limonciello Tue, 19 May 2009 17:04:16 -0500 - -bluez (4.39-0ubuntu1) karmic; urgency=low - - * New upstream release (LP: #372428) - - Add workaround for dealing with unknown inquiry complete. - - Fix discovering when using software scheduler. - - Fix wrong NoInputNoOutput IO capability string. - - Fix race condition with agent during pairing. - - Fix agent cancellation for security mode 3 acceptor failure. - - Fix temporary flag removal when device creation fails. - - Fix hciattach to use ppoll instead of poll. - - Fix service class update when adapter is down. - - Fix service classes race condition during startup. - - Fix release of audio client before freeing the device. - * debian/rules: - - remove "--enable-hal" to DEB_CONFIGURE_EXTRA_FLAGS. This is not a - supported flag. - - -- Baptiste Mille-Mathias Wed, 13 May 2009 10:32:23 +0200 - -bluez (4.38-0ubuntu1) karmic; urgency=low - - * New upstream release - - Add support for builtin plugins. - - Add framework for adapter operations. - - Add constants for Enhanced Retransmission modes. - - Fix HCI socket leak in device_remove_bonding. - - Fix various format string issues. - - Fix crashes with various free functions. - - Fix issues with Headset and A2DP drivers to load again. - - Fix sending AVRCP button released passthrough messages - - Fix bug which prevent input devices to work after restart. - - Fix issue with interpretation of UUID-128 as channel. - - -- Baptiste Mille-Mathias Tue, 05 May 2009 22:47:19 +0200 - -bluez (4.37-0ubuntu1) karmic; urgency=low - - * New upstream version (LP: #367056) - * debian/hid2hci.rules: - - Update rule to work properly with newer version of udev. (LP: #330934) - * debian/rules: - - ALSA conf that gets installed is now called bluetooth.conf. - - -- Mario Limonciello Tue, 28 Apr 2009 09:40:54 -0500 - bluez (4.34-0exp1) experimental; urgency=low * First upload of bluez 4.x (Closes: #499529) @@ -727,65 +400,6 @@ -- Filippo Giunchedi Wed, 01 Apr 2009 12:20:01 +0200 -bluez (4.32-0ubuntu4) jaunty; urgency=low - - * debian/bluez-utils.preinst: Correct think-o. LP: #350393. - - -- Scott James Remnant Wed, 01 Apr 2009 09:47:32 +0100 - -bluez (4.32-0ubuntu3) jaunty; urgency=low - - * debian/bluez-utils.preinst: Remove /etc/modprobe.d/bluez on upgrade - - -- Scott James Remnant Wed, 25 Mar 2009 13:43:00 +0000 - -bluez (4.32-0ubuntu2) jaunty; urgency=low - - * No-change rebuild to fix lpia shared library dependencies. - - -- Colin Watson Thu, 19 Mar 2009 12:16:56 +0000 - -bluez (4.32-0ubuntu1) jaunty; urgency=low - - * New upstream release (LP: #) - - Fix broken SDP record handling. - - Fix SDP data buffer parsing. - - Fix more SDP memory leaks. - - Fix read scan enable calls. - - Fix A2DP stream handling. - - -- Baptiste Mille-Mathias Mon, 02 Mar 2009 08:06:39 +0100 - -bluez (4.31-0ubuntu1) jaunty; urgency=low - - * New upstream release (LP: #335045) - - Add support for new BtIO helper library. - - Fix AVDTP session close issue. - - Fix SDP memory leaks. - - Fix various uninitialized memory issues. - - Fix duplicate signal emissions. - - Fix property changes request handling. - - Fix class of device storage handling. - - -- Baptiste Mille-Mathias Thu, 26 Feb 2009 18:59:54 +0100 - -bluez (4.30-0ubuntu1) jaunty; urgency=low - - * New upstream release (LP: #329223) - - Add CID field to L2CAP socket address structure. - - Fix reset of authentication requirements after bonding. - - Fix storing of link keys when using dedicated bonding. - - Fix storing of pre-Bluetooth 2.1 link keys. - - Fix resetting trust settings on every reboot. - - Fix handling of local name changes. - - Fix memory leaks in hciconfig and hcitool - * debian/control: - - add ${misc:Depends} for each binary package as recommanded by lintian - * debian/bluez-utils.postrm: - - add #DEBHELPER# as requested by lintian - - -- Baptiste Mille-Mathias Fri, 13 Feb 2009 21:42:34 +0100 - bluez (4.29-0ubuntu1) jaunty; urgency=low * New upstream version (LP: #326811) diff -Nru bluez-4.91/debian/control bluez-4.96/debian/control --- bluez-4.91/debian/control 2011-04-15 05:22:03.000000000 +0000 +++ bluez-4.96/debian/control 2011-09-28 16:45:28.000000000 +0000 @@ -6,34 +6,31 @@ Uploaders: Andrea Veri , Nobuhiro Iwamatsu DM-Upload-Allowed: yes Build-Depends: debhelper (>= 7), + dh-autoreconf, autotools-dev, cdbs, flex, bison, gstreamer-tools, libasound2-dev, - libdbus-1-dev, libdbus-glib-1-dev, - libglib2.0-dev, - libgstreamer0.10-dev, - libgstreamer-plugins-base0.10-dev, - libnl-dev, + libglib2.0-dev (>= 2.16), + libgstreamer0.10-dev (>= 0.10.30), + libgstreamer-plugins-base0.10-dev (>= 0.10.30), + libnl3-dev, libsndfile1-dev, libusb-dev, libcap-ng-dev, - udev -XS-Debian-Vcs-Svn: svn://svn.debian.org/svn/pkg-bluetooth/packages/bluez/trunk -XS-Debian-Vcs-Browser: http://svn.debian.org/wsvn/pkg-bluetooth/packages/bluez/trunk -Vcs-Bzr: https://code.launchpad.net/~linaro-maintainers/ubuntu/bluez/natty/overlay + libudev-dev Homepage: http://www.bluez.org -Standards-Version: 3.9.1 +Standards-Version: 3.9.2 Package: libbluetooth3 Section: libs Conflicts: libsdp2 (<= 1.5-2) Replaces: libsdp2 (<= 1.5-2) Depends: ${shlibs:Depends}, ${misc:Depends} -Architecture: any +Architecture: amd64 armel i386 ia64 mips mipsel powerpc s390 sparc alpha armhf avr32 hppa m68k powerpcspe sh4 sparc64 ppc64 Description: Library to use the BlueZ Linux Bluetooth stack BlueZ is the official Linux Bluetooth protocol stack. It is an Open Source project distributed under GNU General Public License (GPL). @@ -46,7 +43,7 @@ Depends: libbluetooth3 (= ${binary:Version}), libc6-dev | libc-dev, ${misc:Depends} Suggests: pkg-config Priority: extra -Architecture: any +Architecture: amd64 armel i386 ia64 mips mipsel powerpc s390 sparc alpha armhf avr32 hppa m68k powerpcspe sh4 sparc64 ppc64 Description: Development files for using the BlueZ Linux Bluetooth library BlueZ is the official Linux Bluetooth protocol stack. It is an Open Source project distributed under GNU General Public License (GPL). @@ -60,8 +57,9 @@ by the Bluez bluetooth stack. Package: bluez -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, module-init-tools, udev | makedev, lsb-base, dbus, python-gobject, python-dbus +Architecture: amd64 armel i386 ia64 mips mipsel powerpc s390 sparc alpha armhf avr32 hppa m68k powerpcspe sh4 sparc64 ppc64 +Multi-Arch: foreign +Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, module-init-tools, udev, lsb-base, dbus, python-gobject, python-dbus Replaces: bluez-input, bluez-network, bluez-serial, bluez-utils (<= 3.36-3), bluez-audio (<= 3.36-3) Conflicts: bluez-utils (<= 3.36-3), bluez-audio (<= 3.36-3) Description: Bluetooth tools and daemons @@ -72,7 +70,8 @@ Package: bluez-alsa Replaces: bluez-audio -Architecture: any +Architecture: amd64 armel i386 ia64 mips mipsel powerpc s390 sparc alpha armhf avr32 hppa m68k powerpcspe sh4 sparc64 ppc64 +Multi-Arch: same Depends: ${shlibs:Depends}, ${misc:Depends}, bluez Description: Bluetooth ALSA support This package contains a driver operate with the ALSA stack. @@ -81,7 +80,7 @@ project distributed under GNU General Public License (GPL). Package: bluez-gstreamer -Architecture: any +Architecture: amd64 armel i386 ia64 mips mipsel powerpc s390 sparc alpha armhf avr32 hppa m68k powerpcspe sh4 sparc64 ppc64 Depends: ${shlibs:Depends}, ${misc:Depends}, bluez Replaces: bluez-audio Description: Bluetooth GStreamer support @@ -91,7 +90,7 @@ project distributed under GNU General Public License (GPL). Package: bluez-cups -Architecture: any +Architecture: amd64 armel i386 ia64 mips mipsel powerpc s390 sparc alpha armhf avr32 hppa m68k powerpcspe sh4 sparc64 ppc64 Depends: ${shlibs:Depends}, cups, ${misc:Depends} Description: Bluetooth printer driver for CUPS This package contains a driver to let CUPS print to Bluetooth-connected @@ -101,7 +100,7 @@ project distributed under GNU General Public License (GPL). Package: bluez-pcmcia-support -Architecture: any +Architecture: amd64 armel i386 ia64 mips mipsel powerpc s390 sparc alpha armhf avr32 hppa m68k powerpcspe sh4 sparc64 ppc64 Priority: extra Depends: pcmciautils, ${misc:Depends} Recommends: setserial @@ -113,7 +112,7 @@ project distributed under GNU General Public License (GPL). Package: bluez-compat -Architecture: any +Architecture: amd64 armel i386 ia64 mips mipsel powerpc s390 sparc alpha armhf avr32 hppa m68k powerpcspe sh4 sparc64 ppc64 Depends: ${shlibs:Depends}, ${misc:Depends} Description: BlueZ 3.x compatibility binaries This package provides the legacy binaries that were reminiscent of the @@ -130,7 +129,7 @@ Description: Transitional package This is a transitional package to assist with moving people to the BlueZ 4.x stack. - + Package: bluez-audio Depends: bluez-alsa (>= 4), bluez-gstreamer (>= 4) Architecture: all diff -Nru bluez-4.91/debian/libbluetooth3.symbols bluez-4.96/debian/libbluetooth3.symbols --- bluez-4.91/debian/libbluetooth3.symbols 2011-04-15 05:11:42.000000000 +0000 +++ bluez-4.96/debian/libbluetooth3.symbols 2011-08-12 17:51:13.000000000 +0000 @@ -1,17 +1,17 @@ libbluetooth.so.3 libbluetooth3 #MINVER# - ba2oui@Base 4.43 - ba2str@Base 4.43 - bachk@Base 4.43 - bafprintf@Base 4.43 - baprintf@Base 4.43 - basnprintf@Base 4.43 - basprintf@Base 4.43 - baswap@Base 4.43 - batostr@Base 4.43 - bt_compidtostr@Base 4.43 - bt_error@Base 4.43 - bt_free@Base 4.43 - bt_malloc@Base 4.43 + ba2oui@Base 4.91 + ba2str@Base 4.91 + bachk@Base 4.91 + bafprintf@Base 4.91 + baprintf@Base 4.91 + basnprintf@Base 4.91 + basprintf@Base 4.91 + baswap@Base 4.91 + batostr@Base 4.91 + bt_compidtostr@Base 4.91 + bt_error@Base 4.91 + bt_free@Base 4.91 + bt_malloc@Base 4.91 bt_string_to_uuid@Base 4.91 bt_uuid128_create@Base 4.91 bt_uuid16_create@Base 4.91 @@ -19,197 +19,197 @@ bt_uuid_cmp@Base 4.91 bt_uuid_to_string@Base 4.91 bt_uuid_to_uuid128@Base 4.91 - hci_authenticate_link@Base 4.43 - hci_bustostr@Base 4.43 - hci_change_link_key@Base 4.43 - hci_close_dev@Base 4.43 - hci_cmdtostr@Base 4.43 - hci_commandstostr@Base 4.43 - hci_create_connection@Base 4.43 - hci_delete_stored_link_key@Base 4.43 - hci_devba@Base 4.43 - hci_devid@Base 4.43 - hci_devinfo@Base 4.43 - hci_dflagstostr@Base 4.43 - hci_disconnect@Base 4.43 - hci_dtypetostr@Base 4.43 - hci_encrypt_link@Base 4.43 - hci_exit_park_mode@Base 4.43 - hci_for_each_dev@Base 4.43 - hci_get_route@Base 4.43 - hci_inquiry@Base 4.43 + hci_authenticate_link@Base 4.91 + hci_bustostr@Base 4.91 + hci_change_link_key@Base 4.91 + hci_close_dev@Base 4.91 + hci_cmdtostr@Base 4.91 + hci_commandstostr@Base 4.91 + hci_create_connection@Base 4.91 + hci_delete_stored_link_key@Base 4.91 + hci_devba@Base 4.91 + hci_devid@Base 4.91 + hci_devinfo@Base 4.91 + hci_dflagstostr@Base 4.91 + hci_disconnect@Base 4.91 + hci_dtypetostr@Base 4.91 + hci_encrypt_link@Base 4.91 + hci_exit_park_mode@Base 4.91 + hci_for_each_dev@Base 4.91 + hci_get_route@Base 4.91 + hci_inquiry@Base 4.91 hci_le_add_white_list@Base 4.91 hci_le_clear_white_list@Base 4.91 hci_le_conn_update@Base 4.91 - hci_le_create_conn@Base 4.66 + hci_le_create_conn@Base 4.91 hci_le_read_white_list_size@Base 4.91 hci_le_rm_white_list@Base 4.91 - hci_le_set_advertise_enable@Base 4.66 - hci_le_set_scan_enable@Base 4.66 - hci_le_set_scan_parameters@Base 4.66 - hci_lmtostr@Base 4.66 - hci_lptostr@Base 4.66 - hci_open_dev@Base 4.66 - hci_park_mode@Base 4.66 - hci_ptypetostr@Base 4.66 - hci_read_afh_map@Base 4.66 - hci_read_afh_mode@Base 4.66 - hci_read_bd_addr@Base 4.66 - hci_read_class_of_dev@Base 4.66 - hci_read_clock@Base 4.66 - hci_read_clock_offset@Base 4.66 - hci_read_current_iac_lap@Base 4.66 - hci_read_ext_inquiry_response@Base 4.66 - hci_read_inq_response_tx_power_level@Base 4.66 - hci_read_inquiry_mode@Base 4.66 - hci_read_inquiry_scan_type@Base 4.66 - hci_read_inquiry_transmit_power_level@Base 4.66 - hci_read_link_policy@Base 4.66 - hci_read_link_quality@Base 4.66 - hci_read_link_supervision_timeout@Base 4.66 - hci_read_local_commands@Base 4.66 - hci_read_local_ext_features@Base 4.66 - hci_read_local_features@Base 4.66 - hci_read_local_name@Base 4.66 - hci_read_local_oob_data@Base 4.66 - hci_read_local_version@Base 4.66 - hci_read_remote_ext_features@Base 4.66 - hci_read_remote_features@Base 4.66 - hci_read_remote_name@Base 4.66 - hci_read_remote_name_cancel@Base 4.66 - hci_read_remote_name_with_clock_offset@Base 4.66 - hci_read_remote_version@Base 4.66 - hci_read_rssi@Base 4.66 - hci_read_simple_pairing_mode@Base 4.66 - hci_read_stored_link_key@Base 4.66 - hci_read_transmit_power_level@Base 4.66 - hci_read_voice_setting@Base 4.66 - hci_scoptypetostr@Base 4.66 - hci_send_cmd@Base 4.66 - hci_send_req@Base 4.66 - hci_set_afh_classification@Base 4.66 - hci_strtolm@Base 4.66 - hci_strtolp@Base 4.66 - hci_strtoptype@Base 4.66 - hci_strtoscoptype@Base 4.66 - hci_strtover@Base 4.66 - hci_switch_role@Base 4.66 - hci_typetostr@Base 4.66 - hci_vertostr@Base 4.66 - hci_write_afh_mode@Base 4.66 - hci_write_class_of_dev@Base 4.66 - hci_write_current_iac_lap@Base 4.66 - hci_write_ext_inquiry_response@Base 4.66 - hci_write_inquiry_mode@Base 4.66 - hci_write_inquiry_scan_type@Base 4.66 - hci_write_inquiry_transmit_power_level@Base 4.66 - hci_write_link_policy@Base 4.66 - hci_write_link_supervision_timeout@Base 4.66 - hci_write_local_name@Base 4.66 - hci_write_simple_pairing_mode@Base 4.66 - hci_write_stored_link_key@Base 4.66 - hci_write_voice_setting@Base 4.66 - lmp_featurestostr@Base 4.66 - lmp_strtover@Base 4.66 - lmp_vertostr@Base 4.66 - sdp_append_to_buf@Base 4.66 - sdp_append_to_pdu@Base 4.66 - sdp_attr_add@Base 4.66 - sdp_attr_add_new@Base 4.66 - sdp_attr_remove@Base 4.66 - sdp_attr_replace@Base 4.66 - sdp_attrid_comp_func@Base 4.66 - sdp_close@Base 4.66 - sdp_connect@Base 4.66 - sdp_copy_record@Base 4.66 - sdp_create@Base 4.66 - sdp_data_alloc@Base 4.66 - sdp_data_alloc_with_length@Base 4.66 - sdp_data_free@Base 4.66 - sdp_data_get@Base 4.66 - sdp_device_record_register@Base 4.66 - sdp_device_record_register_binary@Base 4.66 - sdp_device_record_unregister@Base 4.66 - sdp_device_record_unregister_binary@Base 4.66 - sdp_device_record_update@Base 4.66 - sdp_device_record_update_binary@Base 4.66 - sdp_extract_attr@Base 4.66 - sdp_extract_pdu@Base 4.66 - sdp_extract_seqtype@Base 4.66 - sdp_gen_pdu@Base 4.66 - sdp_gen_record_pdu@Base 4.66 - sdp_gen_tid@Base 4.66 - sdp_general_inquiry@Base 4.66 - sdp_get_access_protos@Base 4.66 - sdp_get_add_access_protos@Base 4.66 - sdp_get_database_state@Base 4.66 - sdp_get_error@Base 4.66 - sdp_get_group_id@Base 4.66 - sdp_get_int_attr@Base 4.66 - sdp_get_lang_attr@Base 4.66 - sdp_get_profile_descs@Base 4.66 - sdp_get_proto_desc@Base 4.66 - sdp_get_proto_port@Base 4.66 - sdp_get_record_state@Base 4.66 - sdp_get_server_ver@Base 4.66 - sdp_get_service_avail@Base 4.66 - sdp_get_service_id@Base 4.66 - sdp_get_service_ttl@Base 4.66 - sdp_get_socket@Base 4.66 - sdp_get_string_attr@Base 4.66 - sdp_get_supp_feat@Base 4.66 - sdp_get_uuidseq_attr@Base 4.66 - sdp_list_append@Base 4.66 - sdp_list_free@Base 4.66 - sdp_list_insert_sorted@Base 4.66 - sdp_list_remove@Base 4.66 - sdp_pattern_add_uuid@Base 4.66 - sdp_pattern_add_uuidseq@Base 4.66 - sdp_process@Base 4.66 - sdp_profile_uuid2strn@Base 4.66 - sdp_proto_uuid2strn@Base 4.66 - sdp_record_alloc@Base 4.66 - sdp_record_free@Base 4.66 - sdp_record_print@Base 4.66 - sdp_record_register@Base 4.66 - sdp_record_unregister@Base 4.66 - sdp_record_update@Base 4.66 - sdp_send_req_w4_rsp@Base 4.66 - sdp_seq_alloc@Base 4.66 - sdp_seq_alloc_with_length@Base 4.66 - sdp_seq_append@Base 4.66 - sdp_service_attr_async@Base 4.66 - sdp_service_attr_req@Base 4.66 - sdp_service_search_async@Base 4.66 - sdp_service_search_attr_async@Base 4.66 - sdp_service_search_attr_req@Base 4.66 - sdp_service_search_req@Base 4.66 - sdp_set_access_protos@Base 4.66 - sdp_set_add_access_protos@Base 4.66 - sdp_set_attrid@Base 4.66 - sdp_set_group_id@Base 4.66 - sdp_set_info_attr@Base 4.66 - sdp_set_lang_attr@Base 4.66 - sdp_set_notify@Base 4.66 - sdp_set_profile_descs@Base 4.66 - sdp_set_seq_len@Base 4.66 - sdp_set_service_id@Base 4.66 - sdp_set_supp_feat@Base 4.66 - sdp_set_url_attr@Base 4.66 - sdp_set_uuidseq_attr@Base 4.66 - sdp_svclass_uuid2strn@Base 4.66 - sdp_uuid128_cmp@Base 4.66 - sdp_uuid128_create@Base 4.66 - sdp_uuid128_to_uuid@Base 4.66 - sdp_uuid16_cmp@Base 4.66 - sdp_uuid16_create@Base 4.66 - sdp_uuid16_to_uuid128@Base 4.66 - sdp_uuid2strn@Base 4.66 - sdp_uuid32_create@Base 4.66 - sdp_uuid32_to_uuid128@Base 4.66 - sdp_uuid_cmp@Base 4.66 - sdp_uuid_extract@Base 4.66 - sdp_uuid_to_proto@Base 4.66 - sdp_uuid_to_uuid128@Base 4.66 - str2ba@Base 4.66 - strtoba@Base 4.66 + hci_le_set_advertise_enable@Base 4.91 + hci_le_set_scan_enable@Base 4.91 + hci_le_set_scan_parameters@Base 4.91 + hci_lmtostr@Base 4.91 + hci_lptostr@Base 4.91 + hci_open_dev@Base 4.91 + hci_park_mode@Base 4.91 + hci_ptypetostr@Base 4.91 + hci_read_afh_map@Base 4.91 + hci_read_afh_mode@Base 4.91 + hci_read_bd_addr@Base 4.91 + hci_read_class_of_dev@Base 4.91 + hci_read_clock@Base 4.91 + hci_read_clock_offset@Base 4.91 + hci_read_current_iac_lap@Base 4.91 + hci_read_ext_inquiry_response@Base 4.91 + hci_read_inq_response_tx_power_level@Base 4.91 + hci_read_inquiry_mode@Base 4.91 + hci_read_inquiry_scan_type@Base 4.91 + hci_read_inquiry_transmit_power_level@Base 4.91 + hci_read_link_policy@Base 4.91 + hci_read_link_quality@Base 4.91 + hci_read_link_supervision_timeout@Base 4.91 + hci_read_local_commands@Base 4.91 + hci_read_local_ext_features@Base 4.91 + hci_read_local_features@Base 4.91 + hci_read_local_name@Base 4.91 + hci_read_local_oob_data@Base 4.91 + hci_read_local_version@Base 4.91 + hci_read_remote_ext_features@Base 4.91 + hci_read_remote_features@Base 4.91 + hci_read_remote_name@Base 4.91 + hci_read_remote_name_cancel@Base 4.91 + hci_read_remote_name_with_clock_offset@Base 4.91 + hci_read_remote_version@Base 4.91 + hci_read_rssi@Base 4.91 + hci_read_simple_pairing_mode@Base 4.91 + hci_read_stored_link_key@Base 4.91 + hci_read_transmit_power_level@Base 4.91 + hci_read_voice_setting@Base 4.91 + hci_scoptypetostr@Base 4.91 + hci_send_cmd@Base 4.91 + hci_send_req@Base 4.91 + hci_set_afh_classification@Base 4.91 + hci_strtolm@Base 4.91 + hci_strtolp@Base 4.91 + hci_strtoptype@Base 4.91 + hci_strtoscoptype@Base 4.91 + hci_strtover@Base 4.91 + hci_switch_role@Base 4.91 + hci_typetostr@Base 4.91 + hci_vertostr@Base 4.91 + hci_write_afh_mode@Base 4.91 + hci_write_class_of_dev@Base 4.91 + hci_write_current_iac_lap@Base 4.91 + hci_write_ext_inquiry_response@Base 4.91 + hci_write_inquiry_mode@Base 4.91 + hci_write_inquiry_scan_type@Base 4.91 + hci_write_inquiry_transmit_power_level@Base 4.91 + hci_write_link_policy@Base 4.91 + hci_write_link_supervision_timeout@Base 4.91 + hci_write_local_name@Base 4.91 + hci_write_simple_pairing_mode@Base 4.91 + hci_write_stored_link_key@Base 4.91 + hci_write_voice_setting@Base 4.91 + lmp_featurestostr@Base 4.91 + lmp_strtover@Base 4.91 + lmp_vertostr@Base 4.91 + sdp_append_to_buf@Base 4.91 + sdp_append_to_pdu@Base 4.91 + sdp_attr_add@Base 4.91 + sdp_attr_add_new@Base 4.91 + sdp_attr_remove@Base 4.91 + sdp_attr_replace@Base 4.91 + sdp_attrid_comp_func@Base 4.91 + sdp_close@Base 4.91 + sdp_connect@Base 4.91 + sdp_copy_record@Base 4.91 + sdp_create@Base 4.91 + sdp_data_alloc@Base 4.91 + sdp_data_alloc_with_length@Base 4.91 + sdp_data_free@Base 4.91 + sdp_data_get@Base 4.91 + sdp_device_record_register@Base 4.91 + sdp_device_record_register_binary@Base 4.91 + sdp_device_record_unregister@Base 4.91 + sdp_device_record_unregister_binary@Base 4.91 + sdp_device_record_update@Base 4.91 + sdp_device_record_update_binary@Base 4.91 + sdp_extract_attr@Base 4.91 + sdp_extract_pdu@Base 4.91 + sdp_extract_seqtype@Base 4.91 + sdp_gen_pdu@Base 4.91 + sdp_gen_record_pdu@Base 4.91 + sdp_gen_tid@Base 4.91 + sdp_general_inquiry@Base 4.91 + sdp_get_access_protos@Base 4.91 + sdp_get_add_access_protos@Base 4.91 + sdp_get_database_state@Base 4.91 + sdp_get_error@Base 4.91 + sdp_get_group_id@Base 4.91 + sdp_get_int_attr@Base 4.91 + sdp_get_lang_attr@Base 4.91 + sdp_get_profile_descs@Base 4.91 + sdp_get_proto_desc@Base 4.91 + sdp_get_proto_port@Base 4.91 + sdp_get_record_state@Base 4.91 + sdp_get_server_ver@Base 4.91 + sdp_get_service_avail@Base 4.91 + sdp_get_service_id@Base 4.91 + sdp_get_service_ttl@Base 4.91 + sdp_get_socket@Base 4.91 + sdp_get_string_attr@Base 4.91 + sdp_get_supp_feat@Base 4.91 + sdp_get_uuidseq_attr@Base 4.91 + sdp_list_append@Base 4.91 + sdp_list_free@Base 4.91 + sdp_list_insert_sorted@Base 4.91 + sdp_list_remove@Base 4.91 + sdp_pattern_add_uuid@Base 4.91 + sdp_pattern_add_uuidseq@Base 4.91 + sdp_process@Base 4.91 + sdp_profile_uuid2strn@Base 4.91 + sdp_proto_uuid2strn@Base 4.91 + sdp_record_alloc@Base 4.91 + sdp_record_free@Base 4.91 + sdp_record_print@Base 4.91 + sdp_record_register@Base 4.91 + sdp_record_unregister@Base 4.91 + sdp_record_update@Base 4.91 + sdp_send_req_w4_rsp@Base 4.91 + sdp_seq_alloc@Base 4.91 + sdp_seq_alloc_with_length@Base 4.91 + sdp_seq_append@Base 4.91 + sdp_service_attr_async@Base 4.91 + sdp_service_attr_req@Base 4.91 + sdp_service_search_async@Base 4.91 + sdp_service_search_attr_async@Base 4.91 + sdp_service_search_attr_req@Base 4.91 + sdp_service_search_req@Base 4.91 + sdp_set_access_protos@Base 4.91 + sdp_set_add_access_protos@Base 4.91 + sdp_set_attrid@Base 4.91 + sdp_set_group_id@Base 4.91 + sdp_set_info_attr@Base 4.91 + sdp_set_lang_attr@Base 4.91 + sdp_set_notify@Base 4.91 + sdp_set_profile_descs@Base 4.91 + sdp_set_seq_len@Base 4.91 + sdp_set_service_id@Base 4.91 + sdp_set_supp_feat@Base 4.91 + sdp_set_url_attr@Base 4.91 + sdp_set_uuidseq_attr@Base 4.91 + sdp_svclass_uuid2strn@Base 4.91 + sdp_uuid128_cmp@Base 4.91 + sdp_uuid128_create@Base 4.91 + sdp_uuid128_to_uuid@Base 4.91 + sdp_uuid16_cmp@Base 4.91 + sdp_uuid16_create@Base 4.91 + sdp_uuid16_to_uuid128@Base 4.91 + sdp_uuid2strn@Base 4.91 + sdp_uuid32_create@Base 4.91 + sdp_uuid32_to_uuid128@Base 4.91 + sdp_uuid_cmp@Base 4.91 + sdp_uuid_extract@Base 4.91 + sdp_uuid_to_proto@Base 4.91 + sdp_uuid_to_uuid128@Base 4.91 + str2ba@Base 4.91 + strtoba@Base 4.91 diff -Nru bluez-4.91/debian/patches/01_lower_sink_ranking.patch bluez-4.96/debian/patches/01_lower_sink_ranking.patch --- bluez-4.91/debian/patches/01_lower_sink_ranking.patch 2011-04-15 05:11:42.000000000 +0000 +++ bluez-4.96/debian/patches/01_lower_sink_ranking.patch 2011-08-12 17:51:13.000000000 +0000 @@ -1,9 +1,9 @@ # http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=571595 -Index: bluez-4.91/audio/gsta2dpsink.c -=================================================================== ---- bluez-4.91.orig/audio/gsta2dpsink.c 2011-02-14 07:40:34.000000000 +1100 -+++ bluez-4.91/audio/gsta2dpsink.c 2011-04-05 10:12:02.731315917 +1000 -@@ -725,6 +725,6 @@ +diff --git a/audio/gsta2dpsink.c b/audio/gsta2dpsink.c +index 52b65e5..89794fb 100644 +--- a/audio/gsta2dpsink.c ++++ b/audio/gsta2dpsink.c +@@ -697,6 +697,6 @@ static void gst_a2dp_sink_init(GstA2dpSink *self, gboolean gst_a2dp_sink_plugin_init(GstPlugin *plugin) { return gst_element_register(plugin, "a2dpsink", diff -Nru bluez-4.91/debian/patches/02_disable_hal.patch bluez-4.96/debian/patches/02_disable_hal.patch --- bluez-4.91/debian/patches/02_disable_hal.patch 2011-04-15 05:11:42.000000000 +0000 +++ bluez-4.96/debian/patches/02_disable_hal.patch 2011-08-12 17:51:13.000000000 +0000 @@ -5,10 +5,10 @@ Updated by Nobuhiro Iwamatsu Debian BTS: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=599023 -Index: bluez-4.91/audio/telephony-maemo5.c +Index: bluez-4.95/audio/telephony-maemo5.c =================================================================== ---- bluez-4.91.orig/audio/telephony-maemo5.c 2010-12-19 06:12:17.000000000 +1100 -+++ bluez-4.91/audio/telephony-maemo5.c 2011-04-05 10:12:06.121315919 +1000 +--- bluez-4.95.orig/audio/telephony-maemo5.c 2011-07-14 20:54:49.377762138 -0400 ++++ bluez-4.95/audio/telephony-maemo5.c 2011-07-14 20:55:20.777762197 -0400 @@ -1385,6 +1385,7 @@ return type == DBUS_TYPE_INVALID ? TRUE : FALSE; } @@ -70,11 +70,11 @@ return 0; } -Index: bluez-4.91/audio/telephony-maemo6.c +Index: bluez-4.95/audio/telephony-maemo6.c =================================================================== ---- bluez-4.91.orig/audio/telephony-maemo6.c 2011-03-29 19:53:53.000000000 +1100 -+++ bluez-4.91/audio/telephony-maemo6.c 2011-04-05 10:12:06.121315919 +1000 -@@ -1369,6 +1369,7 @@ +--- bluez-4.95.orig/audio/telephony-maemo6.c 2011-07-14 20:54:49.377762138 -0400 ++++ bluez-4.95/audio/telephony-maemo6.c 2011-07-14 20:55:44.647762245 -0400 +@@ -1372,6 +1372,7 @@ return type == DBUS_TYPE_INVALID ? TRUE : FALSE; } @@ -82,15 +82,15 @@ static void hal_battery_level_reply(DBusPendingCall *call, void *user_data) { DBusError err; -@@ -1484,6 +1485,7 @@ +@@ -1487,6 +1488,7 @@ dbus_message_iter_next(&array); } } +#endif /* Disable hal */ - static void csd_call_free(struct csd_call *call) + static void csd_call_free(void *data) { -@@ -1834,9 +1836,11 @@ +@@ -1839,9 +1841,11 @@ else if (dbus_message_is_signal(msg, CSD_CSNET_SIGNAL, "SignalBarsChanged")) handle_signal_bars_changed(msg); @@ -102,7 +102,7 @@ else if (dbus_message_is_signal(msg, SSC_DBUS_IFACE, "modem_state_changed_ind")) handle_modem_state(msg); -@@ -1855,6 +1859,7 @@ +@@ -1860,6 +1864,7 @@ watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch)); } @@ -110,7 +110,7 @@ static void hal_find_device_reply(DBusPendingCall *call, void *user_data) { DBusError err; -@@ -1905,6 +1910,8 @@ +@@ -1910,6 +1915,8 @@ remove_pending(call); } @@ -119,7 +119,7 @@ int telephony_init(void) { const char *battery_cap = "battery"; -@@ -1944,6 +1951,7 @@ +@@ -1949,6 +1956,7 @@ telephony_ready_ind(features, maemo_indicators, BTRH_NOT_SUPPORTED, chld_str); @@ -127,20 +127,20 @@ if (send_method_call("org.freedesktop.Hal", "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager", -@@ -1952,7 +1960,7 @@ +@@ -1957,7 +1965,7 @@ DBUS_TYPE_STRING, &battery_cap, DBUS_TYPE_INVALID) < 0) error("Unable to send HAL method call"); - -+#endif ++#endif return 0; } -Index: bluez-4.91/audio/telephony-ofono.c +Index: bluez-4.95/audio/telephony-ofono.c =================================================================== ---- bluez-4.91.orig/audio/telephony-ofono.c 2011-03-29 19:53:53.000000000 +1100 -+++ bluez-4.91/audio/telephony-ofono.c 2011-04-05 10:12:06.121315919 +1000 -@@ -1350,6 +1350,7 @@ +--- bluez-4.95.orig/audio/telephony-ofono.c 2011-07-14 20:54:49.367762136 -0400 ++++ bluez-4.95/audio/telephony-ofono.c 2011-07-14 20:55:20.787762196 -0400 +@@ -1341,6 +1341,7 @@ return TRUE; } @@ -148,7 +148,7 @@ static void hal_battery_level_reply(DBusPendingCall *call, void *user_data) { DBusMessage *reply; -@@ -1533,6 +1534,7 @@ +@@ -1524,6 +1525,7 @@ dbus_message_unref(reply); remove_pending(call); } @@ -156,7 +156,7 @@ static void handle_service_connect(DBusConnection *conn, void *user_data) { -@@ -1581,6 +1583,7 @@ +@@ -1579,6 +1581,7 @@ watches = g_slist_prepend(watches, GUINT_TO_POINTER(watch)); @@ -164,7 +164,7 @@ ret = send_method_call("org.freedesktop.Hal", "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager", -@@ -1590,7 +1593,7 @@ +@@ -1588,7 +1591,7 @@ DBUS_TYPE_INVALID); if (ret < 0) return ret; @@ -172,4 +172,4 @@ +#endif DBG("telephony_init() successfully"); - return ret; + telephony_ready_ind(features, ofono_indicators, BTRH_NOT_SUPPORTED, diff -Nru bluez-4.91/debian/patches/03-Fix-return-code-of-hid2hci.patch bluez-4.96/debian/patches/03-Fix-return-code-of-hid2hci.patch --- bluez-4.91/debian/patches/03-Fix-return-code-of-hid2hci.patch 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/debian/patches/03-Fix-return-code-of-hid2hci.patch 2011-08-12 17:51:13.000000000 +0000 @@ -0,0 +1,69 @@ +From 244c2206d5ff0893f7500e17dc30af98ce779fec Mon Sep 17 00:00:00 2001 +From: Nobuhiro Iwamatsu +Date: Thu, 9 Jun 2011 12:54:17 +0900 +Subject: [PATCH] Fix return code of hid2hci + +hid2hci already return 1. +This set 0 to default retuen code and add error code. +--- + tools/hid2hci.c | 10 ++++++++-- + 1 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/tools/hid2hci.c b/tools/hid2hci.c +index 45a3a3d..da278cb 100644 +--- a/tools/hid2hci.c ++++ b/tools/hid2hci.c +@@ -240,7 +240,7 @@ int main(int argc, char *argv[]) + enum mode mode = HCI; + const char *devpath = NULL; + int err = -1; +- int rc = 1; ++ int rc = 0; + + for (;;) { + int option; +@@ -288,13 +288,16 @@ int main(int argc, char *argv[]) + } + + udev = udev_new(); +- if (udev == NULL) ++ if (udev == NULL) { ++ rc = errno; + goto exit; ++ } + + snprintf(syspath, sizeof(syspath), "%s/%s", udev_get_sys_path(udev), devpath); + udev_dev = udev_device_new_from_syspath(udev, syspath); + if (udev_dev == NULL) { + fprintf(stderr, "error: could not find '%s'\n", devpath); ++ rc = errno; + goto exit; + } + +@@ -312,6 +315,7 @@ int main(int argc, char *argv[]) + dev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device"); + if (dev == NULL) { + fprintf(stderr, "error: could not find usb_device for '%s'\n", devpath); ++ rc = errno; + goto exit; + } + } +@@ -320,6 +324,7 @@ int main(int argc, char *argv[]) + if (handle == NULL) { + fprintf(stderr, "error: unable to handle '%s'\n", + udev_device_get_syspath(dev)); ++ rc = errno; + goto exit; + } + err = usb_switch(handle, mode); +@@ -331,6 +336,7 @@ int main(int argc, char *argv[]) + device = udev_device_get_devnode(udev_dev); + if (device == NULL) { + fprintf(stderr, "error: could not find hiddev device node\n"); ++ rc = errno; + goto exit; + } + err = hid_switch_logitech(device); +-- +1.7.5.3 + diff -Nru bluez-4.91/debian/patches/04-Fix-bluetooth-hid2hci.rules.patch bluez-4.96/debian/patches/04-Fix-bluetooth-hid2hci.rules.patch --- bluez-4.91/debian/patches/04-Fix-bluetooth-hid2hci.rules.patch 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/debian/patches/04-Fix-bluetooth-hid2hci.rules.patch 2011-08-12 17:51:13.000000000 +0000 @@ -0,0 +1,28 @@ +From f274ce220b4adbc0af792140901b0a327404a13b Mon Sep 17 00:00:00 2001 +From: Nobuhiro Iwamatsu +Date: Thu, 9 Jun 2011 12:57:30 +0900 +Subject: [PATCH 2/2] Fix bluetooth-hid2hci.rules + +Apply from http://permalink.gmane.org/gmane.linux.bluez.kernel/13457. +--- + scripts/bluetooth-hid2hci.rules | 4 +--- + 1 files changed, 1 insertions(+), 3 deletions(-) + +diff --git a/scripts/bluetooth-hid2hci.rules b/scripts/bluetooth-hid2hci.rules +index 3b36629..0687c8a 100644 +--- a/scripts/bluetooth-hid2hci.rules ++++ b/scripts/bluetooth-hid2hci.rules +@@ -11,9 +11,7 @@ ATTR{bInterfaceClass}=="03", ATTR{bInterfaceSubClass}=="01", ATTR{bInterfaceProt + RUN+="hid2hci --method=dell --devpath=%p", ENV{HID2HCI_SWITCH}="1" + + # Logitech devices +-KERNEL=="hiddev*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c70[35e]", \ +- RUN+="hid2hci --method=logitech-hid --devpath=%p" +-KERNEL=="hidraw*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c70[4abc]|c71[34bc]", \ ++KERNEL=="hiddev*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c70[345abce]|c71[34bc]", \ + RUN+="hid2hci --method=logitech-hid --devpath=%p" + + ENV{DEVTYPE}!="usb_device", GOTO="hid2hci_end" +-- +1.7.5.3 + diff -Nru bluez-4.91/debian/patches/05-Fix-typo-from-deamon-to-daemon.patch bluez-4.96/debian/patches/05-Fix-typo-from-deamon-to-daemon.patch --- bluez-4.91/debian/patches/05-Fix-typo-from-deamon-to-daemon.patch 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/debian/patches/05-Fix-typo-from-deamon-to-daemon.patch 2011-08-12 17:51:13.000000000 +0000 @@ -0,0 +1,39 @@ +From 61091f445090f2fb5d5bc761f34e74b3b734a7ed Mon Sep 17 00:00:00 2001 +From: Nobuhiro Iwamatsu +Date: Thu, 9 Jun 2011 22:51:45 +0900 +Subject: [PATCH] Fix typo from deamon to daemon + +--- + src/log.c | 2 +- + tracer/main.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/log.c b/src/log.c +index 6fbbba9..2c492e9 100644 +--- a/src/log.c ++++ b/src/log.c +@@ -111,7 +111,7 @@ void __btd_log_init(const char *debug, int detach) + + openlog("bluetoothd", option, LOG_DAEMON); + +- syslog(LOG_INFO, "Bluetooth deamon %s", VERSION); ++ syslog(LOG_INFO, "Bluetooth daemon %s", VERSION); + } + + void __btd_log_cleanup(void) +diff --git a/tracer/main.c b/tracer/main.c +index 0806ffe..3b37f59 100644 +--- a/tracer/main.c ++++ b/tracer/main.c +@@ -118,7 +118,7 @@ int main(int argc, char *argv[]) + + openlog("hcitrace", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); + +- syslog(LOG_INFO, "HCI trace deamon %s", VERSION); ++ syslog(LOG_INFO, "HCI trace daemon %s", VERSION); + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; +-- +1.7.5.3 + diff -Nru bluez-4.91/debian/patches/pkg-config-install-paths.patch bluez-4.96/debian/patches/pkg-config-install-paths.patch --- bluez-4.91/debian/patches/pkg-config-install-paths.patch 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/debian/patches/pkg-config-install-paths.patch 2011-08-12 17:51:13.000000000 +0000 @@ -0,0 +1,26 @@ +Index: bluez/Makefile.am +=================================================================== +--- bluez.orig/Makefile.am ++++ bluez/Makefile.am +@@ -280,7 +280,7 @@ + + + if ALSA +-alsadir = $(libdir)/alsa-lib ++alsadir = $(ALSA_LIBDIR)/alsa-lib + + alsa_LTLIBRARIES = audio/libasound_module_pcm_bluetooth.la \ + audio/libasound_module_ctl_bluetooth.la +Index: bluez/acinclude.m4 +=================================================================== +--- bluez.orig/acinclude.m4 ++++ bluez/acinclude.m4 +@@ -132,6 +132,8 @@ + AC_CHECK_LIB(rt, clock_gettime, ALSA_LIBS="$ALSA_LIBS -lrt", alsa_found=no) + AC_SUBST(ALSA_CFLAGS) + AC_SUBST(ALSA_LIBS) ++ ALSA_LIBDIR=`$PKG_CONFIG --variable=libdir alsa 2>/dev/null` ++ AC_SUBST(ALSA_LIBDIR) + ]) + + AC_DEFUN([AC_PATH_USB], [ diff -Nru bluez-4.91/debian/patches/series bluez-4.96/debian/patches/series --- bluez-4.91/debian/patches/series 2011-04-15 05:25:36.000000000 +0000 +++ bluez-4.96/debian/patches/series 2011-08-12 17:51:13.000000000 +0000 @@ -1,3 +1,3 @@ 01_lower_sink_ranking.patch 02_disable_hal.patch -snowball.patch +pkg-config-install-paths.patch diff -Nru bluez-4.91/debian/patches/snowball.patch bluez-4.96/debian/patches/snowball.patch --- bluez-4.91/debian/patches/snowball.patch 2011-04-15 05:25:36.000000000 +0000 +++ bluez-4.96/debian/patches/snowball.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -Description: Add support for ST-Ericsson CG2900 chip -Author: Mario Boikov -Acked-by: Steve Langasek -Bug-Ubuntu: https://bugs.launchpad.net/bugs/758804 - -=== modified file 'tools/hciattach.c' -Index: lp.758804/tools/hciattach.c -=================================================================== ---- lp.758804.orig/tools/hciattach.c -+++ lp.758804/tools/hciattach.c -@@ -1066,6 +1066,11 @@ - { "texasalt", 0x0000, 0x0000, HCI_UART_LL, 115200, 115200, - FLOW_CTL, DISABLE_PM, NULL, texasalt, NULL }, - -+ /* ST-Ericsson CG2900 GPS FM Bluetooth combo controller */ -+ { "cg2900", 0x0000, 0x0000, HCI_UART_STE, 115200, 115200, -+ FLOW_CTL, NULL, NULL }, -+ -+ - /* ST Microelectronics minikits based on STLC2410/STLC2415 */ - { "st", 0x0000, 0x0000, HCI_UART_H4, 57600, 115200, - FLOW_CTL, DISABLE_PM, NULL, st }, -Index: lp.758804/tools/hciattach.h -=================================================================== ---- lp.758804.orig/tools/hciattach.h -+++ lp.758804/tools/hciattach.h -@@ -39,6 +39,7 @@ - #define HCI_UART_H4DS 3 - #define HCI_UART_LL 4 - #define HCI_UART_ATH3K 5 -+#define HCI_UART_STE 5 - - #define HCI_UART_RAW_DEVICE 0 - diff -Nru bluez-4.91/debian/README.Debian bluez-4.96/debian/README.Debian --- bluez-4.91/debian/README.Debian 2011-04-15 05:11:42.000000000 +0000 +++ bluez-4.96/debian/README.Debian 2011-08-12 17:51:13.000000000 +0000 @@ -37,6 +37,13 @@ bluetooth-applet (bluez-gnome or gnome-bluetooth packages). A minimal command-line agent is also provided by bluez-simple-agent. +For example, you can execute bluez-simple-agent as follows. + +$ bluez-simple-agent hci0 XX:XX:XX:XX:XX:XX (Address of target device) +RequestPinCode (/org/bluez/27392/hci0/dev_XX_XX_XX_XX_XX_XX) +Enter PIN Code: 0000 +Release + Headset support --------------- There's support for bluetooth headset both via ALSA and GStreamer, respectively diff -Nru bluez-4.91/debian/rules bluez-4.96/debian/rules --- bluez-4.91/debian/rules 2011-04-15 05:11:42.000000000 +0000 +++ bluez-4.96/debian/rules 2011-09-28 16:43:57.000000000 +0000 @@ -2,6 +2,7 @@ # build rules for bluez include /usr/share/cdbs/1/rules/buildcore.mk +include /usr/share/cdbs/1/rules/autoreconf.mk include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/class/autotools.mk @@ -27,12 +28,13 @@ --enable-udevrules \ --enable-configfiles \ --enable-capng +# --enable-hid2hci DEB_DESTDIR := $(CURDIR)/debian/tmp TEST_PROGRAM_LIST = simple-agent simple-service test-adapter test-audio test-device \ test-discovery test-input test-manager test-network test-serial \ - test-service test-telephony + test-service test-telephony #install/bluetooth:: #install -D -m 0644 $(CURDIR)/debian/bluetooth.override \ @@ -48,15 +50,15 @@ $(CURDIR)/debian/bluez/etc/bluetooth/network.conf install -D -m 0644 $(CURDIR)/serial/serial.conf \ $(CURDIR)/debian/bluez/etc/bluetooth/serial.conf - + # udev rules, actually upstream version is changed with # sed -i 's@RUN+="/usr/sbin/hid2hci@RUN+="/lib/udev/bluez@' # scripts/bluetooth-hid2hci.rules # and the diff is in debian/patches/010_udev_rules_agent.patch - #install -D -m 0644 $(CURDIR)/scripts/bluetooth-hid2hci.rules \ - # $(CURDIR)/debian/bluez/lib/udev/rules.d/62-bluez-hid2hci.rules - #install -D -m 0755 $(CURDIR)/debian/bluez_agent.udev \ - # $(CURDIR)/debian/bluez/lib/udev/bluez +# install -D -m 0644 $(CURDIR)/scripts/bluetooth-hid2hci.rules \ +# $(CURDIR)/debian/bluez/lib/udev/rules.d/62-bluez-hid2hci.rules +# install -D -m 0755 $(CURDIR)/debian/bluez_agent.udev \ +# $(CURDIR)/debian/bluez/lib/udev/bluez # misc install -D -m 0755 $(CURDIR)/test/agent \ diff -Nru bluez-4.91/doc/adapter-api.txt bluez-4.96/doc/adapter-api.txt --- bluez-4.91/doc/adapter-api.txt 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/doc/adapter-api.txt 2011-07-04 04:59:05.000000000 +0000 @@ -228,7 +228,7 @@ boolean Powered [readwrite] Switch an adapter on or off. This will also set the - appropiate connectable state. + appropriate connectable state. boolean Discoverable [readwrite] diff -Nru bluez-4.91/doc/agent-api.txt bluez-4.96/doc/agent-api.txt --- bluez-4.91/doc/agent-api.txt 2010-01-09 20:52:17.000000000 +0000 +++ bluez-4.96/doc/agent-api.txt 2011-05-31 02:39:53.000000000 +0000 @@ -57,6 +57,10 @@ During the pairing process this method might be called multiple times to update the entered value. + Note that the passkey will always be a 6-digit number, + so the display should be zero-padded at the start if + the value contains less than 6 digits. + void RequestConfirmation(object device, uint32 passkey) This method gets called when the service daemon @@ -65,6 +69,10 @@ To confirm the value it should return an empty reply or an error in case the passkey is invalid. + Note that the passkey will always be a 6-digit number, + so the display should be zero-padded at the start if + the value contains less than 6 digits. + Possible errors: org.bluez.Error.Rejected org.bluez.Error.Canceled diff -Nru bluez-4.91/doc/attribute-api.txt bluez-4.96/doc/attribute-api.txt --- bluez-4.91/doc/attribute-api.txt 2011-03-16 00:34:27.000000000 +0000 +++ bluez-4.96/doc/attribute-api.txt 2011-07-04 04:59:05.000000000 +0000 @@ -12,7 +12,7 @@ Local services are children of the adapter object path. Remote services are children of the remote device object path. This doesn't solve the -problem where local atttributes can have different instances based on +problem where local attributes can have different instances based on the remote device. In general the idea is to also represent SDP records as services so that diff -Nru bluez-4.91/doc/audio-api.txt bluez-4.96/doc/audio-api.txt --- bluez-4.91/doc/audio-api.txt 2010-01-09 20:52:17.000000000 +0000 +++ bluez-4.96/doc/audio-api.txt 2011-07-04 04:59:05.000000000 +0000 @@ -81,7 +81,7 @@ Cancel the incoming call indication. - void Play() + void Play() {deprecated} Open the audio connection to the headset. @@ -430,7 +430,7 @@ Service availability indicatior of AG, where: 0 implies no service. No Home/Roam network available. - 1 implies presense of service. Home/Roam network + 1 implies presence of service. Home/Roam network available. uint16 SignalStrength [readonly] diff -Nru bluez-4.91/gdbus/object.c bluez-4.96/gdbus/object.c --- bluez-4.91/gdbus/object.c 2011-01-20 07:49:26.000000000 +0000 +++ bluez-4.96/gdbus/object.c 2011-07-31 06:52:19.000000000 +0000 @@ -76,7 +76,7 @@ /* Gather enough data to have a single complete type */ for (len = 0; len < (sizeof(type) - 1) && sig[i]; len++, i++) { - switch (sig[i]){ + switch (sig[i]) { case '(': struct_level++; break; @@ -255,14 +255,13 @@ for (list = pending_security; list; list = list->next) { struct security_data *secdata = list->data; - DBusHandlerResult result; if (secdata->pending != pending) continue; pending_security = g_slist_remove(pending_security, secdata); - result = process_message(connection, secdata->message, + process_message(connection, secdata->message, secdata->method, secdata->iface_user_data); dbus_message_unref(secdata->message); diff -Nru bluez-4.91/health/hdp.c bluez-4.96/health/hdp.c --- bluez-4.91/health/hdp.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/health/hdp.c 2011-07-31 06:52:19.000000000 +0000 @@ -3,9 +3,6 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos. - * Authors: - * Santiago Carot Nemesio - * Jose Antonio Santos-Cadenas * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,7 +34,7 @@ #include #include #include -#include +#include #include #include "../src/dbus-common.h" #include @@ -260,7 +257,7 @@ return -1; } -static uint8_t get_app_id() +static uint8_t get_app_id(void) { uint8_t id = next_app_id; @@ -587,7 +584,6 @@ g_dbus_send_message(dc_data->conn, reply); hdp_tmp_dc_data_unref(dc_data); g_error_free(gerr); - gerr = NULL; /* Send abort request because remote side is now in PENDING state */ if (!mcap_mdl_abort(mdl, abort_mdl_cb, NULL, NULL, &gerr)) { @@ -1288,7 +1284,7 @@ DBG("Mcl uncached %s", path); } -static void check_devices_mcl() +static void check_devices_mcl(void) { struct hdp_device *dev; GSList *l, *to_delete = NULL; @@ -1471,7 +1467,7 @@ hdp_create_data_unref(dc_data); } -static void *generate_echo_packet() +static void *generate_echo_packet(void) { uint8_t *buf; int i; @@ -1736,7 +1732,6 @@ error("%s", gerr->message); g_error_free(gerr); - gerr = NULL; reply = g_dbus_create_reply(hdp_conn->msg, DBUS_TYPE_OBJECT_PATH, &hdp_chan->path, @@ -1758,7 +1753,6 @@ "%s", gerr->message); g_dbus_send_message(user_data->conn, reply); g_error_free(gerr); - gerr = NULL; /* Send abort request because remote side is now in PENDING */ /* state. Then we have to delete it because we couldn't */ @@ -2058,7 +2052,7 @@ path = g_strdup(device->fr->path); else path = g_strdup(""); - dict_append_entry(&dict, "MainChannel", DBUS_TYPE_STRING, &path); + dict_append_entry(&dict, "MainChannel", DBUS_TYPE_OBJECT_PATH, &path); g_free(path); dbus_message_iter_close_container(&iter, &dict); @@ -2193,7 +2187,7 @@ return 0; } -void hdp_manager_stop() +void hdp_manager_stop(void) { g_dbus_unregister_interface(connection, MANAGER_PATH, HEALTH_MANAGER); diff -Nru bluez-4.91/health/hdp.h bluez-4.96/health/hdp.h --- bluez-4.91/health/hdp.h 2010-10-14 15:18:02.000000000 +0000 +++ bluez-4.96/health/hdp.h 2011-07-31 06:52:19.000000000 +0000 @@ -3,9 +3,6 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos. - * Authors: - * Santiago Carot Nemesio - * Jose Antonio Santos-Cadenas * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,6 +27,6 @@ void hdp_device_unregister(struct btd_device *device); int hdp_manager_start(DBusConnection *conn); -void hdp_manager_stop(); +void hdp_manager_stop(void); gboolean hdp_set_mcl_cb(struct hdp_device *device, GError **err); diff -Nru bluez-4.91/health/hdp_main.c bluez-4.96/health/hdp_main.c --- bluez-4.91/health/hdp_main.c 2010-09-21 16:41:10.000000000 +0000 +++ bluez-4.96/health/hdp_main.c 2011-07-31 06:52:19.000000000 +0000 @@ -3,9 +3,6 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos. - * Authors: - * Santiago Carot Nemesio - * Jose Antonio Santos-Cadenas * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff -Nru bluez-4.91/health/hdp_manager.c bluez-4.96/health/hdp_manager.c --- bluez-4.91/health/hdp_manager.c 2010-09-21 16:41:10.000000000 +0000 +++ bluez-4.96/health/hdp_manager.c 2011-07-31 06:52:19.000000000 +0000 @@ -3,9 +3,6 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos. - * Authors: - * Santiago Carot Nemesio - * Jose Antonio Santos-Cadenas * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff -Nru bluez-4.91/health/hdp_manager.h bluez-4.96/health/hdp_manager.h --- bluez-4.91/health/hdp_manager.h 2010-09-21 16:41:10.000000000 +0000 +++ bluez-4.96/health/hdp_manager.h 2011-07-31 06:52:19.000000000 +0000 @@ -3,9 +3,6 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos. - * Authors: - * Santiago Carot Nemesio - * Jose Antonio Santos-Cadenas * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff -Nru bluez-4.91/health/hdp_types.h bluez-4.96/health/hdp_types.h --- bluez-4.91/health/hdp_types.h 2011-02-13 20:40:34.000000000 +0000 +++ bluez-4.96/health/hdp_types.h 2011-07-31 06:52:19.000000000 +0000 @@ -3,9 +3,6 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos. - * Authors: - * Santiago Carot Nemesio - * Jose Antonio Santos-Cadenas * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff -Nru bluez-4.91/health/hdp_util.c bluez-4.96/health/hdp_util.c --- bluez-4.91/health/hdp_util.c 2010-11-20 20:25:14.000000000 +0000 +++ bluez-4.96/health/hdp_util.c 2011-07-31 06:52:19.000000000 +0000 @@ -3,9 +3,6 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos. - * Authors: - * Santiago Carot Nemesio - * Jose Antonio Santos-Cadenas * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,7 +31,7 @@ #include #include -#include +#include #include #include diff -Nru bluez-4.91/health/hdp_util.h bluez-4.96/health/hdp_util.h --- bluez-4.91/health/hdp_util.h 2010-11-20 20:25:14.000000000 +0000 +++ bluez-4.96/health/hdp_util.h 2011-07-31 06:52:19.000000000 +0000 @@ -3,9 +3,6 @@ * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos. - * Authors: - * Santiago Carot Nemesio - * Jose Antonio Santos-Cadenas * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff -Nru bluez-4.91/health/mcap.c bluez-4.96/health/mcap.c --- bluez-4.91/health/mcap.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/health/mcap.c 2011-07-31 06:52:19.000000000 +0000 @@ -4,10 +4,6 @@ * * Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos. * - * Authors: - * Santiago Carot-Nemesio - * Jose Antonio Santos-Cadenas - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -685,11 +681,10 @@ static struct mcap_mcl *find_mcl(GSList *list, const bdaddr_t *addr) { - GSList *l; struct mcap_mcl *mcl; - for (l = list; l; l = l->next) { - mcl = l->data; + for (; list; list = list->next) { + mcl = list->data; if (!bacmp(&mcl->addr, addr)) return mcl; @@ -792,7 +787,7 @@ last->ctrl &= ~MCAP_CTRL_CACHED; if (last->ctrl & MCAP_CTRL_CONN) { /* We have to release this MCL if */ - /* connection is not succesful */ + /* connection is not successful */ last->ctrl |= MCAP_CTRL_FREE; } else { mcap_mcl_release(last); diff -Nru bluez-4.91/health/mcap.h bluez-4.96/health/mcap.h --- bluez-4.91/health/mcap.h 2010-09-21 16:41:10.000000000 +0000 +++ bluez-4.96/health/mcap.h 2011-07-31 06:52:19.000000000 +0000 @@ -5,11 +5,6 @@ * Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos. * Copyright (C) 2010 Signove * - * Authors: - * Santiago Carot-Nemesio - * Jose Antonio Santos-Cadenas - * Elvis Pfützenreuter - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or diff -Nru bluez-4.91/health/mcap_internal.h bluez-4.96/health/mcap_internal.h --- bluez-4.91/health/mcap_internal.h 2010-11-20 20:25:14.000000000 +0000 +++ bluez-4.96/health/mcap_internal.h 2011-07-31 06:52:19.000000000 +0000 @@ -4,10 +4,6 @@ * * Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos. * - * Authors: - * Santiago Carot-Nemesio - * Jose Antonio Santos-Cadenas - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or diff -Nru bluez-4.91/health/mcap_lib.h bluez-4.96/health/mcap_lib.h --- bluez-4.91/health/mcap_lib.h 2010-11-20 20:25:14.000000000 +0000 +++ bluez-4.96/health/mcap_lib.h 2011-07-31 06:52:19.000000000 +0000 @@ -4,10 +4,6 @@ * * Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos. * - * Authors: - * Santiago Carot-Nemesio - * Jose Antonio Santos-Cadenas - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or diff -Nru bluez-4.91/health/mcap_sync.c bluez-4.96/health/mcap_sync.c --- bluez-4.91/health/mcap_sync.c 2011-03-16 00:34:27.000000000 +0000 +++ bluez-4.96/health/mcap_sync.c 2011-07-31 06:52:19.000000000 +0000 @@ -5,11 +5,6 @@ * Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos. * Copyright (C) 2010 Signove * - * Authors: - * Santiago Carot-Nemesio - * Jose Antonio Santos-Cadenas - * Elvis Pfützenreuter - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or diff -Nru bluez-4.91/input/device.c bluez-4.96/input/device.c --- bluez-4.91/input/device.c 2011-02-13 20:40:34.000000000 +0000 +++ bluez-4.96/input/device.c 2011-05-31 02:39:53.000000000 +0000 @@ -90,14 +90,12 @@ GSList *connections; }; -GSList *devices = NULL; +static GSList *devices = NULL; static struct input_device *find_device_by_path(GSList *list, const char *path) { - GSList *l; - - for (l = list; l; l = l->next) { - struct input_device *idev = l->data; + for (; list; list = list->next) { + struct input_device *idev = list->data; if (!strcmp(idev->path, path)) return idev; @@ -108,10 +106,8 @@ static struct input_conn *find_connection(GSList *list, const char *pattern) { - GSList *l; - - for (l = list; l; l = l->next) { - struct input_conn *iconn = l->data; + for (; list; list = list->next) { + struct input_conn *iconn = list->data; if (!strcasecmp(iconn->uuid, pattern)) return iconn; @@ -247,17 +243,16 @@ return key; } -static void send_event(int fd, uint16_t type, uint16_t code, int32_t value) +static int send_event(int fd, uint16_t type, uint16_t code, int32_t value) { struct uinput_event event; - int err; memset(&event, 0, sizeof(event)); event.type = type; event.code = code; event.value = value; - err = write(fd, &event, sizeof(event)); + return write(fd, &event, sizeof(event)); } static void send_key(int fd, uint16_t key) diff -Nru bluez-4.91/input/manager.c bluez-4.96/input/manager.c --- bluez-4.91/input/manager.c 2010-05-23 12:47:19.000000000 +0000 +++ bluez-4.96/input/manager.c 2011-05-31 02:39:53.000000000 +0000 @@ -86,7 +86,7 @@ const gchar *path = device_get_path(device); const sdp_record_t *record; sdp_list_t *protos; - uint8_t ch; + int ch; bdaddr_t src, dst; DBG("path %s", path); diff -Nru bluez-4.91/input/server.c bluez-4.96/input/server.c --- bluez-4.91/input/server.c 2010-05-23 12:47:19.000000000 +0000 +++ bluez-4.96/input/server.c 2011-07-04 04:59:05.000000000 +0000 @@ -62,6 +62,7 @@ { uint16_t psm; bdaddr_t src, dst; + char address[18]; GError *gerr = NULL; int ret; @@ -82,17 +83,21 @@ return; } - DBG("Incoming connection on PSM %d", psm); + ba2str(&dst, address); + DBG("Incoming connection from %s on PSM %d", address, psm); ret = input_device_set_channel(&src, &dst, psm, chan); if (ret == 0) return; + error("Refusing input device connect: %s (%d)", strerror(-ret), -ret); + /* Send unplug virtual cable to unknown devices */ if (ret == -ENOENT && psm == L2CAP_PSM_HIDP_CTRL) { unsigned char unplug = 0x15; - int err, sk = g_io_channel_unix_get_fd(chan); - err = write(sk, &unplug, sizeof(unplug)); + int sk = g_io_channel_unix_get_fd(chan); + if (write(sk, &unplug, sizeof(unplug)) < 0) + error("Unable to send virtual cable unplug"); } g_io_channel_shutdown(chan, TRUE, NULL); @@ -156,7 +161,11 @@ } if (server->confirm) { - error("Refusing connection: setup in progress"); + char address[18]; + + ba2str(&dst, address); + error("Refusing connection from %s: setup in progress", + address); goto drop; } diff -Nru bluez-4.91/lib/bluetooth.c bluez-4.96/lib/bluetooth.c --- bluez-4.91/lib/bluetooth.c 2011-03-16 00:34:27.000000000 +0000 +++ bluez-4.96/lib/bluetooth.c 2011-07-04 04:59:05.000000000 +0000 @@ -462,6 +462,32 @@ return "RDA Microelectronics"; case 98: return "Gibson Guitars"; + case 99: + return "MiCommand Inc."; + case 100: + return "Band XI International, LLC"; + case 101: + return "Hewlett-Packard Company"; + case 102: + return "9Solutions Oy"; + case 103: + return "GN Netcom A/S"; + case 104: + return "General Motors"; + case 105: + return "A&D Engineering, Inc."; + case 106: + return "MindTree Ltd."; + case 107: + return "Polar Electro OY"; + case 108: + return "Beautiful Enterprise Co., Ltd."; + case 109: + return "BriarTek, Inc."; + case 110: + return "Summit Data Communications, Inc."; + case 111: + return "Sound ID"; case 65535: return "internal use"; default: diff -Nru bluez-4.91/lib/hci.c bluez-4.96/lib/hci.c --- bluez-4.91/lib/hci.c 2011-03-16 00:34:27.000000000 +0000 +++ bluez-4.96/lib/hci.c 2011-05-03 08:20:36.000000000 +0000 @@ -2291,7 +2291,7 @@ } *fec = rp.fec; - memcpy(data, rp.data, 240); + memcpy(data, rp.data, HCI_MAX_EIR_LENGTH); return 0; } @@ -2304,7 +2304,7 @@ memset(&cp, 0, sizeof(cp)); cp.fec = fec; - memcpy(cp.data, data, 240); + memcpy(cp.data, data, HCI_MAX_EIR_LENGTH); memset(&rq, 0, sizeof(rq)); rq.ogf = OGF_HOST_CTL; diff -Nru bluez-4.91/lib/hci.h bluez-4.96/lib/hci.h --- bluez-4.91/lib/hci.h 2011-03-16 00:34:27.000000000 +0000 +++ bluez-4.96/lib/hci.h 2011-04-25 09:44:21.000000000 +0000 @@ -791,16 +791,18 @@ } __attribute__ ((packed)) delete_stored_link_key_rp; #define DELETE_STORED_LINK_KEY_RP_SIZE 3 +#define HCI_MAX_NAME_LENGTH 248 + #define OCF_CHANGE_LOCAL_NAME 0x0013 typedef struct { - uint8_t name[248]; + uint8_t name[HCI_MAX_NAME_LENGTH]; } __attribute__ ((packed)) change_local_name_cp; #define CHANGE_LOCAL_NAME_CP_SIZE 248 #define OCF_READ_LOCAL_NAME 0x0014 typedef struct { uint8_t status; - uint8_t name[248]; + uint8_t name[HCI_MAX_NAME_LENGTH]; } __attribute__ ((packed)) read_local_name_rp; #define READ_LOCAL_NAME_RP_SIZE 249 @@ -1071,18 +1073,20 @@ } __attribute__ ((packed)) write_afh_mode_rp; #define WRITE_AFH_MODE_RP_SIZE 1 +#define HCI_MAX_EIR_LENGTH 240 + #define OCF_READ_EXT_INQUIRY_RESPONSE 0x0051 typedef struct { uint8_t status; uint8_t fec; - uint8_t data[240]; + uint8_t data[HCI_MAX_EIR_LENGTH]; } __attribute__ ((packed)) read_ext_inquiry_response_rp; #define READ_EXT_INQUIRY_RESPONSE_RP_SIZE 242 #define OCF_WRITE_EXT_INQUIRY_RESPONSE 0x0052 typedef struct { uint8_t fec; - uint8_t data[240]; + uint8_t data[HCI_MAX_EIR_LENGTH]; } __attribute__ ((packed)) write_ext_inquiry_response_cp; #define WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE 241 typedef struct { @@ -1386,7 +1390,7 @@ uint8_t status; uint8_t handle; uint16_t length; - uint8_t fragment[248]; + uint8_t fragment[HCI_MAX_NAME_LENGTH]; } __attribute__ ((packed)) read_local_amp_assoc_rp; #define READ_LOCAL_AMP_ASSOC_RP_SIZE 252 @@ -1395,7 +1399,7 @@ uint8_t handle; uint16_t length_so_far; uint16_t assoc_length; - uint8_t fragment[248]; + uint8_t fragment[HCI_MAX_NAME_LENGTH]; } __attribute__ ((packed)) write_remote_amp_assoc_cp; #define WRITE_REMOTE_AMP_ASSOC_CP_SIZE 253 typedef struct { @@ -1722,7 +1726,7 @@ typedef struct { uint8_t status; bdaddr_t bdaddr; - uint8_t name[248]; + uint8_t name[HCI_MAX_NAME_LENGTH]; } __attribute__ ((packed)) evt_remote_name_req_complete; #define EVT_REMOTE_NAME_REQ_COMPLETE_SIZE 255 @@ -1983,7 +1987,7 @@ uint8_t dev_class[3]; uint16_t clock_offset; int8_t rssi; - uint8_t data[240]; + uint8_t data[HCI_MAX_EIR_LENGTH]; } __attribute__ ((packed)) extended_inquiry_info; #define EXTENDED_INQUIRY_INFO_SIZE 254 diff -Nru bluez-4.91/lib/l2cap.h bluez-4.96/lib/l2cap.h --- bluez-4.91/lib/l2cap.h 2010-04-28 15:35:11.000000000 +0000 +++ bluez-4.96/lib/l2cap.h 2011-07-31 06:52:19.000000000 +0000 @@ -83,6 +83,18 @@ #define L2CAP_INFO_REQ 0x0a #define L2CAP_INFO_RSP 0x0b +/* L2CAP extended feature mask */ +#define L2CAP_FEAT_FLOWCTL 0x00000001 +#define L2CAP_FEAT_RETRANS 0x00000002 +#define L2CAP_FEAT_BIDIR_QOS 0x00000004 +#define L2CAP_FEAT_ERTM 0x00000008 +#define L2CAP_FEAT_STREAMING 0x00000010 +#define L2CAP_FEAT_FCS 0x00000020 +#define L2CAP_FEAT_EXT_FLOW 0x00000040 +#define L2CAP_FEAT_FIXED_CHAN 0x00000080 +#define L2CAP_FEAT_EXT_WINDOW 0x00000100 +#define L2CAP_FEAT_UCD 0x00000200 + /* L2CAP structures */ typedef struct { uint16_t len; @@ -147,6 +159,8 @@ #define L2CAP_CONF_UNACCEPT 0x0001 #define L2CAP_CONF_REJECT 0x0002 #define L2CAP_CONF_UNKNOWN 0x0003 +#define L2CAP_CONF_PENDING 0x0004 +#define L2CAP_CONF_EFS_REJECT 0x0005 typedef struct { uint8_t type; @@ -160,6 +174,7 @@ #define L2CAP_CONF_QOS 0x03 #define L2CAP_CONF_RFC 0x04 #define L2CAP_CONF_FCS 0x05 +#define L2CAP_CONF_EFS 0x06 #define L2CAP_CONF_MAX_SIZE 22 @@ -169,6 +184,10 @@ #define L2CAP_MODE_ERTM 0x03 #define L2CAP_MODE_STREAMING 0x04 +#define L2CAP_SERVTYPE_NOTRAFFIC 0x00 +#define L2CAP_SERVTYPE_BESTEFFORT 0x01 +#define L2CAP_SERVTYPE_GUARANTEED 0x02 + typedef struct { uint16_t dcid; uint16_t scid; diff -Nru bluez-4.91/lib/mgmt.h bluez-4.96/lib/mgmt.h --- bluez-4.91/lib/mgmt.h 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/lib/mgmt.h 2011-07-04 04:59:05.000000000 +0000 @@ -51,6 +51,10 @@ uint16_t index[0]; } __packed; +/* Reserve one extra byte for names in management messages so that they + * are always guaranteed to be nul-terminated */ +#define MGMT_MAX_NAME_LENGTH (HCI_MAX_NAME_LENGTH + 1) + #define MGMT_OP_READ_INFO 0x0004 struct mgmt_rp_read_info { uint8_t type; @@ -65,7 +69,7 @@ uint16_t manufacturer; uint8_t hci_ver; uint16_t hci_rev; - uint8_t name[249]; + uint8_t name[MGMT_MAX_NAME_LENGTH]; } __packed; struct mgmt_mode { @@ -176,7 +180,7 @@ #define MGMT_OP_SET_LOCAL_NAME 0x0017 struct mgmt_cp_set_local_name { - uint8_t name[249]; + uint8_t name[MGMT_MAX_NAME_LENGTH]; } __packed; #define MGMT_OP_READ_LOCAL_OOB_DATA 0x0018 @@ -197,6 +201,20 @@ bdaddr_t bdaddr; } __packed; +#define MGMT_OP_START_DISCOVERY 0x001B + +#define MGMT_OP_STOP_DISCOVERY 0x001C + +#define MGMT_OP_BLOCK_DEVICE 0x001D +struct mgmt_cp_block_device { + bdaddr_t bdaddr; +} __packed; + +#define MGMT_OP_UNBLOCK_DEVICE 0x001E +struct mgmt_cp_unblock_device { + bdaddr_t bdaddr; +} __packed; + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { uint16_t opcode; @@ -228,8 +246,8 @@ #define MGMT_EV_NEW_KEY 0x000A struct mgmt_ev_new_key { + uint8_t store_hint; struct mgmt_key_info key; - uint8_t old_key_type; } __packed; #define MGMT_EV_DEVICE_CONNECTED 0x000B @@ -251,11 +269,13 @@ #define MGMT_EV_PIN_CODE_REQUEST 0x000E struct mgmt_ev_pin_code_request { bdaddr_t bdaddr; + uint8_t secure; } __packed; #define MGMT_EV_USER_CONFIRM_REQUEST 0x000F struct mgmt_ev_user_confirm_request { bdaddr_t bdaddr; + uint8_t confirm_hint; uint32_t value; } __packed; @@ -267,5 +287,21 @@ #define MGMT_EV_LOCAL_NAME_CHANGED 0x0011 struct mgmt_ev_local_name_changed { - uint8_t name[249]; + uint8_t name[MGMT_MAX_NAME_LENGTH]; } __packed; + +#define MGMT_EV_DEVICE_FOUND 0x0012 +struct mgmt_ev_device_found { + bdaddr_t bdaddr; + uint8_t dev_class[3]; + int8_t rssi; + uint8_t eir[HCI_MAX_EIR_LENGTH]; +} __packed; + +#define MGMT_EV_REMOTE_NAME 0x0013 +struct mgmt_ev_remote_name { + bdaddr_t bdaddr; + uint8_t name[MGMT_MAX_NAME_LENGTH]; +} __packed; + +#define MGMT_EV_DISCOVERING 0x0014 diff -Nru bluez-4.91/lib/sdp.c bluez-4.96/lib/sdp.c --- bluez-4.91/lib/sdp.c 2011-03-16 00:34:27.000000000 +0000 +++ bluez-4.96/lib/sdp.c 2011-05-31 02:39:53.000000000 +0000 @@ -673,7 +673,7 @@ int data_type = 0; uint8_t *p = buf->data + buf->data_size; - *p++ = dtd; + *p = dtd; data_type = sdp_get_data_type(buf, dtd); buf->data_size += data_type; @@ -688,7 +688,6 @@ *p++ = SDP_UINT16; buf->data_size = sizeof(uint8_t); bt_put_unaligned(htons(attr), (uint16_t *) p); - p += sizeof(uint16_t); buf->data_size += sizeof(uint16_t); } @@ -900,7 +899,7 @@ } if (!is_seq && !is_alt) { - if (src && buf && buf->buf_size >= buf->data_size + data_size) { + if (src && buf->buf_size >= buf->data_size + data_size) { memcpy(buf->data + buf->data_size, src, data_size); buf->data_size += data_size; } else if (dtd != SDP_DATA_NIL) { @@ -1021,7 +1020,6 @@ } sdp_uuid16_create(uuid, ntohs(bt_get_unaligned((uint16_t *) p))); *scanned += sizeof(uint16_t); - p += sizeof(uint16_t); } else if (type == SDP_UUID32) { if (bufsize < (int) sizeof(uint32_t)) { SDPERR("Not enough room for 32-bit UUID"); @@ -1029,7 +1027,6 @@ } sdp_uuid32_create(uuid, ntohl(bt_get_unaligned((uint32_t *) p))); *scanned += sizeof(uint32_t); - p += sizeof(uint32_t); } else { if (bufsize < (int) sizeof(uint128_t)) { SDPERR("Not enough room for 128-bit UUID"); @@ -1037,7 +1034,6 @@ } sdp_uuid128_create(uuid, p); *scanned += sizeof(uint128_t); - p += sizeof(uint128_t); } return 0; } @@ -1798,7 +1794,7 @@ for (q = 0, p = list; p; q = p, p = p->next) if (f(p->data, d) >= 0) break; - // insert between q and p; if !q insert at head + /* insert between q and p; if !q insert at head */ if (q) q->next = n; else @@ -2021,25 +2017,34 @@ curr_data = sdpdata->val.dataseq; while (curr_data) { sdp_data_t *pCode = curr_data; - sdp_data_t *pEncoding = pCode->next; - sdp_data_t *pOffset = pEncoding->next; - if (pEncoding && pOffset) { - lang = malloc(sizeof(sdp_lang_attr_t)); - if (!lang) { - sdp_list_free(*langSeq, free); - *langSeq = NULL; - return -1; - } - lang->code_ISO639 = pCode->val.uint16; - lang->encoding = pEncoding->val.uint16; - lang->base_offset = pOffset->val.uint16; - SDPDBG("code_ISO639 : 0x%02x\n", lang->code_ISO639); - SDPDBG("encoding : 0x%02x\n", lang->encoding); - SDPDBG("base_offfset : 0x%02x\n", lang->base_offset); - *langSeq = sdp_list_append(*langSeq, lang); + sdp_data_t *pEncoding; + sdp_data_t *pOffset; + + pEncoding = pCode->next; + if (!pEncoding) + break; + + pOffset = pEncoding->next; + if (!pOffset) + break; + + lang = malloc(sizeof(sdp_lang_attr_t)); + if (!lang) { + sdp_list_free(*langSeq, free); + *langSeq = NULL; + return -1; } + lang->code_ISO639 = pCode->val.uint16; + lang->encoding = pEncoding->val.uint16; + lang->base_offset = pOffset->val.uint16; + SDPDBG("code_ISO639 : 0x%02x\n", lang->code_ISO639); + SDPDBG("encoding : 0x%02x\n", lang->encoding); + SDPDBG("base_offfset : 0x%02x\n", lang->base_offset); + *langSeq = sdp_list_append(*langSeq, lang); + curr_data = pOffset->next; } + return 0; } @@ -2757,10 +2762,8 @@ if (dst->data_size == 0 && dtd == 0) { /* create initial sequence */ *p = SDP_SEQ8; - p += sizeof(uint8_t); dst->data_size += sizeof(uint8_t); /* reserve space for sequence size */ - p += sizeof(uint8_t); dst->data_size += sizeof(uint8_t); } @@ -2772,12 +2775,9 @@ short offset = sizeof(uint8_t) + sizeof(uint8_t); memmove(dst->data + offset + 1, dst->data + offset, dst->data_size - offset); - p = dst->data; *p = SDP_SEQ16; - p += sizeof(uint8_t); dst->data_size += 1; } - p = dst->data; dtd = *(uint8_t *) p; p += sizeof(uint8_t); switch (dtd) { @@ -3111,7 +3111,7 @@ return sdp_device_record_update(session, BDADDR_ANY, rec); } -sdp_record_t *sdp_record_alloc() +sdp_record_t *sdp_record_alloc(void) { sdp_record_t *rec = malloc(sizeof(sdp_record_t)); @@ -3196,7 +3196,7 @@ sdp_buf_t buf; int i, seqlen = sdp_list_len(seq); - // Fill up the value and the dtd arrays + /* Fill up the value and the dtd arrays */ SDPDBG(""); SDPDBG("Seq length : %d\n", seqlen); @@ -3319,7 +3319,7 @@ uint32_t reqsize = 0, _reqsize; uint32_t rspsize = 0, rsplen; int seqlen = 0; - int total_rec_count, rec_count; + int rec_count; unsigned scanned, pdata_len; uint8_t *pdata, *_pdata; uint8_t *reqbuf, *rspbuf; @@ -3338,16 +3338,16 @@ pdata = reqbuf + sizeof(sdp_pdu_hdr_t); reqsize = sizeof(sdp_pdu_hdr_t); - // add service class IDs for search + /* add service class IDs for search */ seqlen = gen_searchseq_pdu(pdata, search); SDPDBG("Data seq added : %d\n", seqlen); - // set the length and increment the pointer + /* set the length and increment the pointer */ reqsize += seqlen; pdata += seqlen; - // specify the maximum svc rec count that client expects + /* specify the maximum svc rec count that client expects */ bt_put_unaligned(htons(max_rec_num), (uint16_t *) pdata); reqsize += sizeof(uint16_t); pdata += sizeof(uint16_t); @@ -3357,11 +3357,11 @@ *rsp = NULL; do { - // Add continuation state or NULL (first time) + /* Add continuation state or NULL (first time) */ reqsize = _reqsize + copy_cstate(_pdata, SDP_REQ_BUFFER_SIZE - _reqsize, cstate); - // Set the request header's param length + /* Set the request header's param length */ reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); reqhdr->tid = htons(sdp_gen_tid(session)); @@ -3397,8 +3397,7 @@ goto end; } - // net service record match count - total_rec_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); + /* net service record match count */ pdata += sizeof(uint16_t); scanned += sizeof(uint16_t); pdata_len -= sizeof(uint16_t); @@ -3511,17 +3510,17 @@ pdata = reqbuf + sizeof(sdp_pdu_hdr_t); reqsize = sizeof(sdp_pdu_hdr_t); - // add the service record handle + /* add the service record handle */ bt_put_unaligned(htonl(handle), (uint32_t *) pdata); reqsize += sizeof(uint32_t); pdata += sizeof(uint32_t); - // specify the response limit + /* specify the response limit */ bt_put_unaligned(htons(65535), (uint16_t *) pdata); reqsize += sizeof(uint16_t); pdata += sizeof(uint16_t); - // get attr seq PDU form + /* get attr seq PDU form */ seqlen = gen_attridseq_pdu(pdata, attrids, reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32); if (seqlen == -1) { @@ -3532,18 +3531,18 @@ reqsize += seqlen; SDPDBG("Attr list length : %d\n", seqlen); - // save before Continuation State + /* save before Continuation State */ _pdata = pdata; _reqsize = reqsize; do { int status; - // add NULL continuation state + /* add NULL continuation state */ reqsize = _reqsize + copy_cstate(_pdata, SDP_REQ_BUFFER_SIZE - _reqsize, cstate); - // set the request header's param length + /* set the request header's param length */ reqhdr->tid = htons(sdp_gen_tid(session)); reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); @@ -3574,7 +3573,10 @@ pdata += sizeof(uint16_t); pdata_len -= sizeof(uint16_t); - // if continuation state set need to re-issue request before parsing + /* + * if continuation state set need to re-issue request before + * parsing + */ if (pdata_len < rsp_count + sizeof(uint8_t)) { SDPERR("Unexpected end of packet: continuation state data missing"); goto end; @@ -3594,7 +3596,7 @@ cstate = cstate_len > 0 ? (sdp_cstate_t *) (pdata + rsp_count) : 0; - // build concatenated response buffer + /* build concatenated response buffer */ rsp_concat_buf.data = realloc(rsp_concat_buf.data, rsp_concat_buf.data_size + rsp_count); rsp_concat_buf.buf_size = rsp_concat_buf.data_size + rsp_count; targetPtr = rsp_concat_buf.data + rsp_concat_buf.data_size; @@ -3755,16 +3757,16 @@ reqhdr->tid = htons(sdp_gen_tid(session)); reqhdr->pdu_id = SDP_SVC_SEARCH_REQ; - // generate PDU + /* generate PDU */ pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t); t->reqsize = sizeof(sdp_pdu_hdr_t); - // add service class IDs for search + /* add service class IDs for search */ seqlen = gen_searchseq_pdu(pdata, search); SDPDBG("Data seq added : %d\n", seqlen); - // now set the length and increment the pointer + /* now set the length and increment the pointer */ t->reqsize += seqlen; pdata += seqlen; @@ -3772,7 +3774,7 @@ t->reqsize += sizeof(uint16_t); pdata += sizeof(uint16_t); - // set the request header's param length + /* set the request header's param length */ cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL); reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t)); @@ -3856,21 +3858,21 @@ reqhdr->tid = htons(sdp_gen_tid(session)); reqhdr->pdu_id = SDP_SVC_ATTR_REQ; - // generate PDU + /* generate PDU */ pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t); t->reqsize = sizeof(sdp_pdu_hdr_t); - // add the service record handle + /* add the service record handle */ bt_put_unaligned(htonl(handle), (uint32_t *) pdata); t->reqsize += sizeof(uint32_t); pdata += sizeof(uint32_t); - // specify the response limit + /* specify the response limit */ bt_put_unaligned(htons(65535), (uint16_t *) pdata); t->reqsize += sizeof(uint16_t); pdata += sizeof(uint16_t); - // get attr seq PDU form + /* get attr seq PDU form */ seqlen = gen_attridseq_pdu(pdata, attrid_list, reqtype == SDP_ATTR_REQ_INDIVIDUAL? SDP_UINT16 : SDP_UINT32); if (seqlen == -1) { @@ -3878,12 +3880,12 @@ goto end; } - // now set the length and increment the pointer + /* now set the length and increment the pointer */ t->reqsize += seqlen; pdata += seqlen; SDPDBG("Attr list length : %d\n", seqlen); - // set the request header's param length + /* set the request header's param length */ cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL); reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t)); @@ -3968,16 +3970,16 @@ reqhdr->tid = htons(sdp_gen_tid(session)); reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ; - // generate PDU + /* generate PDU */ pdata = t->reqbuf + sizeof(sdp_pdu_hdr_t); t->reqsize = sizeof(sdp_pdu_hdr_t); - // add service class IDs for search + /* add service class IDs for search */ seqlen = gen_searchseq_pdu(pdata, search); SDPDBG("Data seq added : %d\n", seqlen); - // now set the length and increment the pointer + /* now set the length and increment the pointer */ t->reqsize += seqlen; pdata += seqlen; @@ -3987,7 +3989,7 @@ SDPDBG("Max attr byte count : %d\n", SDP_MAX_ATTR_LEN); - // get attr seq PDU form + /* get attr seq PDU form */ seqlen = gen_attridseq_pdu(pdata, attrid_list, reqtype == SDP_ATTR_REQ_INDIVIDUAL ? SDP_UINT16 : SDP_UINT32); if (seqlen == -1) { @@ -3999,7 +4001,7 @@ SDPDBG("Attr list length : %d\n", seqlen); t->reqsize += seqlen; - // set the request header's param length + /* set the request header's param length */ cstate_len = copy_cstate(pdata, SDP_REQ_BUFFER_SIZE - t->reqsize, NULL); reqhdr->plen = htons((t->reqsize + cstate_len) - sizeof(sdp_pdu_hdr_t)); @@ -4164,15 +4166,13 @@ */ plen = sizeof(uint16_t) + rsp_count; - pdata += sizeof(uint16_t); // points to attribute list + pdata += sizeof(uint16_t); /* points to attribute list */ status = 0x0000; break; case SDP_ERROR_RSP: status = ntohs(bt_get_unaligned((uint16_t *) pdata)); size = ntohs(rsphdr->plen); - /* error code + error info */ - plen = size; goto end; default: t->err = EPROTO; @@ -4210,13 +4210,13 @@ reqhdr->tid = htons(sdp_gen_tid(session)); - // add continuation state + /* add continuation state */ cstate_len = copy_cstate(t->reqbuf + t->reqsize, SDP_REQ_BUFFER_SIZE - t->reqsize, pcstate); reqsize = t->reqsize + cstate_len; - // set the request header's param length + /* set the request header's param length */ reqhdr->plen = htons(reqsize - sizeof(sdp_pdu_hdr_t)); if (sdp_send_req(session, t->reqbuf, reqsize) < 0) { @@ -4318,11 +4318,11 @@ reqhdr = (sdp_pdu_hdr_t *) reqbuf; reqhdr->pdu_id = SDP_SVC_SEARCH_ATTR_REQ; - // generate PDU + /* generate PDU */ pdata = reqbuf + sizeof(sdp_pdu_hdr_t); reqsize = sizeof(sdp_pdu_hdr_t); - // add service class IDs for search + /* add service class IDs for search */ seqlen = gen_searchseq_pdu(pdata, search); SDPDBG("Data seq added : %d\n", seqlen); @@ -4391,7 +4391,7 @@ rsp_count = ntohs(bt_get_unaligned((uint16_t *) pdata)); attr_list_len += rsp_count; - pdata += sizeof(uint16_t); // pdata points to attribute list + pdata += sizeof(uint16_t); /* pdata points to attribute list */ pdata_len -= sizeof(uint16_t); if (pdata_len < rsp_count + sizeof(uint8_t)) { diff -Nru bluez-4.91/lib/sdp_lib.h bluez-4.96/lib/sdp_lib.h --- bluez-4.91/lib/sdp_lib.h 2010-05-23 12:47:19.000000000 +0000 +++ bluez-4.96/lib/sdp_lib.h 2011-05-31 02:39:53.000000000 +0000 @@ -90,7 +90,7 @@ int state; int local; int flags; - uint16_t tid; // Current transaction ID + uint16_t tid; /* Current transaction ID */ void *priv; } sdp_session_t; diff -Nru bluez-4.91/Makefile.am bluez-4.96/Makefile.am --- bluez-4.91/Makefile.am 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/Makefile.am 2011-07-31 06:52:19.000000000 +0000 @@ -3,6 +3,8 @@ lib_LTLIBRARIES = +noinst_LIBRARIES = + noinst_LTLIBRARIES = bin_PROGRAMS = @@ -23,7 +25,7 @@ include_HEADERS = -if CONFIGFILES +if DATAFILES dbusdir = $(sysconfdir)/dbus-1/system.d dbus_DATA = src/bluetooth.conf @@ -35,6 +37,12 @@ statedir = $(localstatedir)/lib/bluetooth state_DATA = + +if SYSTEMD +systemdunitdir = @SYSTEMD_UNITDIR@ + +systemdunit_DATA = src/bluetooth.service +endif endif plugindir = $(libdir)/bluetooth/plugins @@ -47,18 +55,17 @@ lib/rfcomm.h lib/bnep.h lib/cmtp.h lib/hidp.h local_headers = $(foreach file,$(lib_headers), lib/bluetooth/$(notdir $(file))) +BUILT_SOURCES = $(local_headers) + include_HEADERS += $(lib_headers) lib_LTLIBRARIES += lib/libbluetooth.la lib_libbluetooth_la_SOURCES = $(lib_headers) \ lib/bluetooth.c lib/hci.c lib/sdp.c lib/uuid.c -lib_libbluetooth_la_LDFLAGS = -version-info 14:0:11 +lib_libbluetooth_la_LDFLAGS = -version-info 14:4:11 lib_libbluetooth_la_DEPENDENCIES = $(local_headers) -CLEANFILES += $(local_headers) - - if SBC noinst_LTLIBRARIES += sbc/libsbc.la @@ -89,7 +96,8 @@ endif attrib_sources = attrib/att.h attrib/att.c attrib/gatt.h attrib/gatt.c \ - attrib/gattrib.h attrib/gattrib.c + attrib/gattrib.h attrib/gattrib.c attrib/client.h \ + attrib/client.c gdbus_sources = gdbus/gdbus.h gdbus/mainloop.c gdbus/watch.c \ gdbus/object.c gdbus/polkit.c @@ -136,7 +144,7 @@ audio/telephony.h audio/a2dp-codecs.h builtin_nodist += audio/telephony.c -noinst_LIBRARIES = audio/libtelephony.a +noinst_LIBRARIES += audio/libtelephony.a audio_libtelephony_a_SOURCES = audio/telephony.h audio/telephony-dummy.c \ audio/telephony-maemo5.c audio/telephony-ofono.c \ @@ -152,9 +160,9 @@ builtin_nodist += sap/sap.c -noinst_LIBRARIES = sap/libsap.a +noinst_LIBRARIES += sap/libsap.a -sap_libsap_a_SOURCES = sap/sap.h sap/sap-dummy.c +sap_libsap_a_SOURCES = sap/sap.h sap/sap-dummy.c sap/sap-u8500.c endif if INPUTPLUGIN @@ -183,29 +191,21 @@ network/connection.h network/connection.c endif +if PROXIMITYPLUGIN +builtin_modules += proximity +builtin_sources += proximity/main.c \ + proximity/manager.h proximity/manager.c \ + proximity/monitor.h proximity/monitor.c +endif + if SERVICEPLUGIN builtin_modules += service builtin_sources += plugins/service.c endif -if ATTRIBPLUGIN - -if READLINE -bin_PROGRAMS += attrib/gatttool - -attrib_gatttool_SOURCES = attrib/gatttool.c attrib/att.c attrib/gatt.c \ - attrib/gattrib.c btio/btio.c \ - src/glib-helper.h src/glib-helper.c \ - attrib/gatttool.h attrib/interactive.c \ - attrib/utils.c -attrib_gatttool_LDADD = lib/libbluetooth.la @GLIB_LIBS@ @READLINE_LIBS@ -endif - -builtin_modules += attrib -builtin_sources += attrib/main.c \ - attrib/manager.h attrib/manager.c \ - attrib/client.h attrib/client.c \ - attrib/example.h attrib/example.c +if GATT_EXAMPLE_PLUGIN +builtin_modules += gatt_example +builtin_sources += plugins/gatt-example.c endif if HEALTHPLUGIN @@ -216,6 +216,13 @@ health/hdp_util.h health/hdp_util.c endif +if THERMOMETERPLUGIN +builtin_modules += thermometer +builtin_sources += thermometer/main.c \ + thermometer/manager.h thermometer/manager.c \ + thermometer/thermometer.h thermometer/thermometer.c +endif + builtin_modules += hciops mgmtops builtin_sources += plugins/hciops.c plugins/mgmtops.c @@ -232,6 +239,14 @@ builtin_modules += storage builtin_sources += plugins/storage.c +builtin_modules += adaptername +builtin_sources += plugins/adaptername.c + +if WIIMOTEPLUGIN +builtin_modules += wiimote +builtin_sources += plugins/wiimote.c +endif + if MAEMO6PLUGIN builtin_modules += maemo6 builtin_sources += plugins/maemo6.c @@ -262,10 +277,10 @@ src/error.h src/error.c \ src/manager.h src/manager.c \ src/adapter.h src/adapter.c \ - src/device.h src/device.c \ + src/device.h src/device.c src/attio.h \ src/dbus-common.c src/dbus-common.h \ src/event.h src/event.c \ - src/oob.h src/oob.c + src/oob.h src/oob.c src/eir.h src/eir.c src_bluetoothd_LDADD = lib/libbluetooth.la @GLIB_LIBS@ @DBUS_LIBS@ \ @CAPNG_LIBS@ -ldl -lrt src_bluetoothd_LDFLAGS = -Wl,--export-dynamic \ @@ -281,7 +296,7 @@ man_MANS = src/bluetoothd.8 -if CONFIGFILES +if DATAFILES conf_DATA += src/main.conf endif @@ -290,7 +305,7 @@ input/input.conf serial/serial.conf \ audio/audio.conf audio/telephony-dummy.c \ audio/telephony-maemo5.c audio/telephony-ofono.c \ - audio/telephony-maemo6.c sap/sap-dummy.c + audio/telephony-maemo6.c sap/sap-dummy.c sap/sap-u8500.c if ALSA @@ -312,7 +327,7 @@ audio_libasound_module_ctl_bluetooth_la_LIBADD = lib/libbluetooth.la @ALSA_LIBS@ audio_libasound_module_ctl_bluetooth_la_CFLAGS = @ALSA_CFLAGS@ -if CONFIGFILES +if DATAFILES alsaconfdir = $(datadir)/alsa alsaconf_DATA = audio/bluetooth.conf @@ -347,8 +362,8 @@ include Makefile.tools -if UDEVRULES -rulesdir = @UDEV_DATADIR@ +if DATAFILES +rulesdir = @UDEV_DIR@/rules.d udev_files = scripts/bluetooth.rules @@ -357,7 +372,11 @@ endif if PCMCIA +udevdir = @UDEV_DIR@ + udev_files += scripts/bluetooth-serial.rules + +dist_udev_SCRIPTS = scripts/bluetooth_serial endif rules_DATA = $(foreach file,$(udev_files), scripts/97-$(notdir $(file))) @@ -368,12 +387,6 @@ EXTRA_DIST += scripts/bluetooth.rules \ scripts/bluetooth-hid2hci.rules scripts/bluetooth-serial.rules -if PCMCIA -udevdir = $(libexecdir)/udev - -dist_udev_SCRIPTS = scripts/bluetooth_serial -endif - EXTRA_DIST += doc/manager-api.txt \ doc/adapter-api.txt doc/device-api.txt \ doc/service-api.txt doc/agent-api.txt doc/attribute-api.txt \ @@ -399,7 +412,7 @@ pkgconfig_DATA = bluez.pc -DISTCHECK_CONFIGURE_FLAGS = --disable-udevrules --enable-attrib +DISTCHECK_CONFIGURE_FLAGS = --disable-datafiles DISTCLEANFILES = $(pkgconfig_DATA) diff -Nru bluez-4.91/Makefile.in bluez-4.96/Makefile.in --- bluez-4.91/Makefile.in 2011-03-29 08:54:30.000000000 +0000 +++ bluez-4.96/Makefile.in 2011-07-31 06:52:51.000000000 +0000 @@ -43,8 +43,7 @@ $(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_6) \ $(am__EXEEXT_7) sbin_PROGRAMS = src/bluetoothd$(EXEEXT) $(am__EXEEXT_13) \ - $(am__EXEEXT_14) $(am__EXEEXT_15) $(am__EXEEXT_16) \ - $(am__EXEEXT_17) + $(am__EXEEXT_14) $(am__EXEEXT_15) $(am__EXEEXT_16) noinst_PROGRAMS = $(am__EXEEXT_8) $(am__EXEEXT_9) $(am__EXEEXT_10) \ $(am__EXEEXT_11) $(am__EXEEXT_12) @SBC_TRUE@am__append_1 = sbc/libsbc.la @@ -76,56 +75,65 @@ @AUDIOPLUGIN_TRUE@ audio/telephony.h audio/a2dp-codecs.h @AUDIOPLUGIN_TRUE@am__append_11 = audio/telephony.c -@SAPPLUGIN_TRUE@am__append_12 = sap -@SAPPLUGIN_TRUE@am__append_13 = sap/main.c \ +@AUDIOPLUGIN_TRUE@am__append_12 = audio/libtelephony.a +@SAPPLUGIN_TRUE@am__append_13 = sap +@SAPPLUGIN_TRUE@am__append_14 = sap/main.c \ @SAPPLUGIN_TRUE@ sap/manager.h sap/manager.c \ @SAPPLUGIN_TRUE@ sap/server.h sap/server.c \ @SAPPLUGIN_TRUE@ sap/sap.h -@SAPPLUGIN_TRUE@am__append_14 = sap/sap.c -@INPUTPLUGIN_TRUE@am__append_15 = input -@INPUTPLUGIN_TRUE@am__append_16 = input/main.c \ +@SAPPLUGIN_TRUE@am__append_15 = sap/sap.c +@SAPPLUGIN_TRUE@am__append_16 = sap/libsap.a +@INPUTPLUGIN_TRUE@am__append_17 = input +@INPUTPLUGIN_TRUE@am__append_18 = input/main.c \ @INPUTPLUGIN_TRUE@ input/manager.h input/manager.c \ @INPUTPLUGIN_TRUE@ input/server.h input/server.c \ @INPUTPLUGIN_TRUE@ input/device.h input/device.c \ @INPUTPLUGIN_TRUE@ input/fakehid.c input/fakehid.h -@SERIALPLUGIN_TRUE@am__append_17 = serial -@SERIALPLUGIN_TRUE@am__append_18 = serial/main.c \ +@SERIALPLUGIN_TRUE@am__append_19 = serial +@SERIALPLUGIN_TRUE@am__append_20 = serial/main.c \ @SERIALPLUGIN_TRUE@ serial/manager.h serial/manager.c \ @SERIALPLUGIN_TRUE@ serial/proxy.h serial/proxy.c \ @SERIALPLUGIN_TRUE@ serial/port.h serial/port.c -@NETWORKPLUGIN_TRUE@am__append_19 = network -@NETWORKPLUGIN_TRUE@am__append_20 = network/main.c \ +@NETWORKPLUGIN_TRUE@am__append_21 = network +@NETWORKPLUGIN_TRUE@am__append_22 = network/main.c \ @NETWORKPLUGIN_TRUE@ network/manager.h network/manager.c \ @NETWORKPLUGIN_TRUE@ network/common.h network/common.c \ @NETWORKPLUGIN_TRUE@ network/server.h network/server.c \ @NETWORKPLUGIN_TRUE@ network/connection.h network/connection.c -@SERVICEPLUGIN_TRUE@am__append_21 = service -@SERVICEPLUGIN_TRUE@am__append_22 = plugins/service.c -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@am__append_23 = attrib/gatttool -@ATTRIBPLUGIN_TRUE@am__append_24 = attrib -@ATTRIBPLUGIN_TRUE@am__append_25 = attrib/main.c \ -@ATTRIBPLUGIN_TRUE@ attrib/manager.h attrib/manager.c \ -@ATTRIBPLUGIN_TRUE@ attrib/client.h attrib/client.c \ -@ATTRIBPLUGIN_TRUE@ attrib/example.h attrib/example.c - -@HEALTHPLUGIN_TRUE@am__append_26 = health -@HEALTHPLUGIN_TRUE@am__append_27 = health/hdp_main.c health/hdp_types.h \ +@PROXIMITYPLUGIN_TRUE@am__append_23 = proximity +@PROXIMITYPLUGIN_TRUE@am__append_24 = proximity/main.c \ +@PROXIMITYPLUGIN_TRUE@ proximity/manager.h proximity/manager.c \ +@PROXIMITYPLUGIN_TRUE@ proximity/monitor.h proximity/monitor.c + +@SERVICEPLUGIN_TRUE@am__append_25 = service +@SERVICEPLUGIN_TRUE@am__append_26 = plugins/service.c +@GATT_EXAMPLE_PLUGIN_TRUE@am__append_27 = gatt_example +@GATT_EXAMPLE_PLUGIN_TRUE@am__append_28 = plugins/gatt-example.c +@HEALTHPLUGIN_TRUE@am__append_29 = health +@HEALTHPLUGIN_TRUE@am__append_30 = health/hdp_main.c health/hdp_types.h \ @HEALTHPLUGIN_TRUE@ health/hdp_manager.h health/hdp_manager.c \ @HEALTHPLUGIN_TRUE@ health/hdp.h health/hdp.c \ @HEALTHPLUGIN_TRUE@ health/hdp_util.h health/hdp_util.c -@HAL_TRUE@am__append_28 = hal -@HAL_TRUE@am__append_29 = plugins/hal.c -@HAL_FALSE@am__append_30 = formfactor -@HAL_FALSE@am__append_31 = plugins/formfactor.c -@MAEMO6PLUGIN_TRUE@am__append_32 = maemo6 -@MAEMO6PLUGIN_TRUE@am__append_33 = plugins/maemo6.c -@DBUSOOBPLUGIN_TRUE@am__append_34 = dbusoob -@DBUSOOBPLUGIN_TRUE@am__append_35 = plugins/dbusoob.c +@THERMOMETERPLUGIN_TRUE@am__append_31 = thermometer +@THERMOMETERPLUGIN_TRUE@am__append_32 = thermometer/main.c \ +@THERMOMETERPLUGIN_TRUE@ thermometer/manager.h thermometer/manager.c \ +@THERMOMETERPLUGIN_TRUE@ thermometer/thermometer.h thermometer/thermometer.c + +@HAL_TRUE@am__append_33 = hal +@HAL_TRUE@am__append_34 = plugins/hal.c +@HAL_FALSE@am__append_35 = formfactor +@HAL_FALSE@am__append_36 = plugins/formfactor.c +@WIIMOTEPLUGIN_TRUE@am__append_37 = wiimote +@WIIMOTEPLUGIN_TRUE@am__append_38 = plugins/wiimote.c +@MAEMO6PLUGIN_TRUE@am__append_39 = maemo6 +@MAEMO6PLUGIN_TRUE@am__append_40 = plugins/maemo6.c +@DBUSOOBPLUGIN_TRUE@am__append_41 = dbusoob +@DBUSOOBPLUGIN_TRUE@am__append_42 = plugins/dbusoob.c DIST_COMMON = README $(am__configure_deps) \ $(am__dist_udev_SCRIPTS_DIST) $(dist_man_MANS) \ $(include_HEADERS) $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ @@ -133,63 +141,65 @@ $(srcdir)/config.h.in $(top_srcdir)/configure \ $(top_srcdir)/doc/version.xml.in \ $(top_srcdir)/scripts/bluetooth.rules.in \ + $(top_srcdir)/src/bluetooth.service.in \ $(top_srcdir)/src/bluetoothd.8.in AUTHORS COPYING COPYING.LIB \ ChangeLog INSTALL NEWS TODO compile config.guess config.sub \ depcomp install-sh ltmain.sh missing tools/lexer.c \ tools/parser.c tools/parser.h ylwrap -@CONFIGFILES_TRUE@@TOOLS_TRUE@am__append_36 = tools/rfcomm.conf -@TOOLS_TRUE@am__append_37 = tools/rfcomm tools/l2ping \ +@DATAFILES_TRUE@@TOOLS_TRUE@am__append_43 = tools/rfcomm.conf +@TOOLS_TRUE@am__append_44 = tools/rfcomm tools/l2ping \ @TOOLS_TRUE@ tools/hcitool tools/sdptool tools/ciptool -@TOOLS_TRUE@am__append_38 = tools/hciattach tools/hciconfig -@TOOLS_TRUE@am__append_39 = tools/avinfo tools/ppporc \ +@TOOLS_TRUE@am__append_45 = tools/hciattach tools/hciconfig +@TOOLS_TRUE@am__append_46 = tools/avinfo tools/ppporc \ @TOOLS_TRUE@ tools/hcieventmask tools/hcisecfilter -@TOOLS_TRUE@am__append_40 = tools/rfcomm.1 tools/l2ping.8 \ +@READLINE_TRUE@@TOOLS_TRUE@am__append_47 = attrib/gatttool +@TOOLS_TRUE@am__append_48 = tools/rfcomm.1 tools/l2ping.8 \ @TOOLS_TRUE@ tools/hciattach.8 tools/hciconfig.8 \ @TOOLS_TRUE@ tools/hcitool.1 tools/sdptool.1 tools/ciptool.1 -@TOOLS_FALSE@am__append_41 = tools/rfcomm.1 tools/l2ping.8 \ +@TOOLS_FALSE@am__append_49 = tools/rfcomm.1 tools/l2ping.8 \ @TOOLS_FALSE@ tools/hciattach.8 tools/hciconfig.8 \ @TOOLS_FALSE@ tools/hcitool.1 tools/sdptool.1 tools/ciptool.1 -@TRACER_TRUE@am__append_42 = tracer/hcitrace -@BCCMD_TRUE@am__append_43 = tools/bccmd -@BCCMD_TRUE@@USB_TRUE@am__append_44 = tools/csr_usb.c -@BCCMD_TRUE@@USB_TRUE@am__append_45 = @USB_LIBS@ -@BCCMD_TRUE@am__append_46 = tools/bccmd.8 -@BCCMD_FALSE@am__append_47 = tools/bccmd.8 -@HID2HCI_TRUE@am__append_48 = tools/hid2hci -@HID2HCI_TRUE@am__append_49 = tools/hid2hci.8 -@HID2HCI_FALSE@am__append_50 = tools/hid2hci.8 -@DFUTOOL_TRUE@am__append_51 = tools/dfutool -@DFUTOOL_TRUE@am__append_52 = tools/dfutool.1 -@DFUTOOL_FALSE@am__append_53 = tools/dfutool.1 -@USB_TRUE@am__append_54 = tools/dfubabel tools/avctrl +@TRACER_TRUE@am__append_50 = tracer/hcitrace +@BCCMD_TRUE@am__append_51 = tools/bccmd +@BCCMD_TRUE@@USB_TRUE@am__append_52 = tools/csr_usb.c +@BCCMD_TRUE@@USB_TRUE@am__append_53 = @USB_LIBS@ +@BCCMD_TRUE@am__append_54 = tools/bccmd.8 +@BCCMD_FALSE@am__append_55 = tools/bccmd.8 +@HID2HCI_TRUE@udev_PROGRAMS = tools/hid2hci$(EXEEXT) +@HID2HCI_TRUE@am__append_56 = tools/hid2hci.8 +@HID2HCI_FALSE@am__append_57 = tools/hid2hci.8 +@DFUTOOL_TRUE@am__append_58 = tools/dfutool +@DFUTOOL_TRUE@am__append_59 = tools/dfutool.1 +@DFUTOOL_FALSE@am__append_60 = tools/dfutool.1 +@USB_TRUE@am__append_61 = tools/dfubabel tools/avctrl @CUPS_TRUE@cups_PROGRAMS = cups/bluetooth$(EXEEXT) -@TEST_TRUE@am__append_55 = test/hciemu -@TEST_TRUE@am__append_56 = test/l2test test/rctest -@TEST_TRUE@am__append_57 = test/gaptest test/sdptest test/scotest \ +@TEST_TRUE@am__append_62 = test/hciemu +@TEST_TRUE@am__append_63 = test/l2test test/rctest +@TEST_TRUE@am__append_64 = test/gaptest test/sdptest test/scotest \ @TEST_TRUE@ test/attest test/hstest test/avtest test/ipctest \ @TEST_TRUE@ test/lmptest test/bdaddr test/agent \ @TEST_TRUE@ test/btiotest test/test-textfile \ @TEST_TRUE@ test/uuidtest -@TEST_TRUE@am__append_58 = test/rctest.1 test/hciemu.1 -@TEST_TRUE@am__append_59 = test/bdaddr.8 -@TEST_FALSE@am__append_60 = test/rctest.1 test/hciemu.1 test/bdaddr.8 -@HIDD_TRUE@am__append_61 = compat/hidd -@HIDD_TRUE@am__append_62 = compat/hidd.1 -@HIDD_FALSE@am__append_63 = compat/hidd.1 -@PAND_TRUE@am__append_64 = compat/pand -@PAND_TRUE@am__append_65 = compat/pand.1 -@PAND_FALSE@am__append_66 = compat/pand.1 -@DUND_TRUE@am__append_67 = compat/dund -@DUND_TRUE@am__append_68 = compat/dund.1 -@DUND_FALSE@am__append_69 = compat/dund.1 -@HID2HCI_TRUE@@UDEVRULES_TRUE@am__append_70 = scripts/bluetooth-hid2hci.rules -@PCMCIA_TRUE@@UDEVRULES_TRUE@am__append_71 = scripts/bluetooth-serial.rules -@MCAP_TRUE@am__append_72 = -I$(builddir)/health +@TEST_TRUE@am__append_65 = test/rctest.1 test/hciemu.1 +@TEST_TRUE@am__append_66 = test/bdaddr.8 +@TEST_FALSE@am__append_67 = test/rctest.1 test/hciemu.1 test/bdaddr.8 +@HIDD_TRUE@am__append_68 = compat/hidd +@HIDD_TRUE@am__append_69 = compat/hidd.1 +@HIDD_FALSE@am__append_70 = compat/hidd.1 +@PAND_TRUE@am__append_71 = compat/pand +@PAND_TRUE@am__append_72 = compat/pand.1 +@PAND_FALSE@am__append_73 = compat/pand.1 +@DUND_TRUE@am__append_74 = compat/dund +@DUND_TRUE@am__append_75 = compat/dund.1 +@DUND_FALSE@am__append_76 = compat/dund.1 +@DATAFILES_TRUE@@HID2HCI_TRUE@am__append_77 = scripts/bluetooth-hid2hci.rules +@DATAFILES_TRUE@@PCMCIA_TRUE@am__append_78 = scripts/bluetooth-serial.rules +@MCAP_TRUE@am__append_79 = -I$(builddir)/health subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ @@ -201,7 +211,7 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = scripts/bluetooth.rules doc/version.xml \ - src/bluetoothd.8 bluez.pc + src/bluetoothd.8 src/bluetooth.service bluez.pc CONFIG_CLEAN_VPATH_FILES = LIBRARIES = $(noinst_LIBRARIES) ARFLAGS = cru @@ -225,8 +235,10 @@ audio_libtelephony_a_OBJECTS = $(am_audio_libtelephony_a_OBJECTS) sap_libsap_a_AR = $(AR) $(ARFLAGS) sap_libsap_a_LIBADD = -am__sap_libsap_a_SOURCES_DIST = sap/sap.h sap/sap-dummy.c -@SAPPLUGIN_TRUE@am_sap_libsap_a_OBJECTS = sap/sap-dummy.$(OBJEXT) +am__sap_libsap_a_SOURCES_DIST = sap/sap.h sap/sap-dummy.c \ + sap/sap-u8500.c +@SAPPLUGIN_TRUE@am_sap_libsap_a_OBJECTS = sap/sap-dummy.$(OBJEXT) \ +@SAPPLUGIN_TRUE@ sap/sap-u8500.$(OBJEXT) sap_libsap_a_OBJECTS = $(am_sap_libsap_a_OBJECTS) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ @@ -253,10 +265,11 @@ "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" \ "$(DESTDIR)$(bindir)" "$(DESTDIR)$(cupsdir)" \ "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(udevdir)" \ - "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)" \ - "$(DESTDIR)$(alsaconfdir)" "$(DESTDIR)$(confdir)" \ - "$(DESTDIR)$(dbusdir)" "$(DESTDIR)$(pkgconfigdir)" \ - "$(DESTDIR)$(rulesdir)" "$(DESTDIR)$(statedir)" \ + "$(DESTDIR)$(udevdir)" "$(DESTDIR)$(man1dir)" \ + "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(alsaconfdir)" \ + "$(DESTDIR)$(confdir)" "$(DESTDIR)$(dbusdir)" \ + "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(rulesdir)" \ + "$(DESTDIR)$(statedir)" "$(DESTDIR)$(systemdunitdir)" \ "$(DESTDIR)$(includedir)" LTLIBRARIES = $(alsa_LTLIBRARIES) $(gstreamer_LTLIBRARIES) \ $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) @@ -347,11 +360,10 @@ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(sbc_libsbc_la_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ @SBC_TRUE@am_sbc_libsbc_la_rpath = -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@am__EXEEXT_1 = \ -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@ attrib/gatttool$(EXEEXT) -@TOOLS_TRUE@am__EXEEXT_2 = tools/rfcomm$(EXEEXT) tools/l2ping$(EXEEXT) \ +@TOOLS_TRUE@am__EXEEXT_1 = tools/rfcomm$(EXEEXT) tools/l2ping$(EXEEXT) \ @TOOLS_TRUE@ tools/hcitool$(EXEEXT) tools/sdptool$(EXEEXT) \ @TOOLS_TRUE@ tools/ciptool$(EXEEXT) +@READLINE_TRUE@@TOOLS_TRUE@am__EXEEXT_2 = attrib/gatttool$(EXEEXT) @DFUTOOL_TRUE@am__EXEEXT_3 = tools/dfutool$(EXEEXT) @TEST_TRUE@am__EXEEXT_4 = test/l2test$(EXEEXT) test/rctest$(EXEEXT) @HIDD_TRUE@am__EXEEXT_5 = compat/hidd$(EXEEXT) @@ -376,26 +388,23 @@ @TOOLS_TRUE@ tools/hciconfig$(EXEEXT) @TRACER_TRUE@am__EXEEXT_14 = tracer/hcitrace$(EXEEXT) @BCCMD_TRUE@am__EXEEXT_15 = tools/bccmd$(EXEEXT) -@HID2HCI_TRUE@am__EXEEXT_16 = tools/hid2hci$(EXEEXT) -@TEST_TRUE@am__EXEEXT_17 = test/hciemu$(EXEEXT) +@TEST_TRUE@am__EXEEXT_16 = test/hciemu$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) $(cups_PROGRAMS) $(noinst_PROGRAMS) \ - $(sbin_PROGRAMS) + $(sbin_PROGRAMS) $(udev_PROGRAMS) am__attrib_gatttool_SOURCES_DIST = attrib/gatttool.c attrib/att.c \ - attrib/gatt.c attrib/gattrib.c btio/btio.c src/glib-helper.h \ - src/glib-helper.c attrib/gatttool.h attrib/interactive.c \ - attrib/utils.c -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@am_attrib_gatttool_OBJECTS = \ -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@ attrib/gatttool.$(OBJEXT) \ -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@ attrib/att.$(OBJEXT) \ -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@ attrib/gatt.$(OBJEXT) \ -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@ attrib/gattrib.$(OBJEXT) \ -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@ btio/btio.$(OBJEXT) \ -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@ src/glib-helper.$(OBJEXT) \ -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@ attrib/interactive.$(OBJEXT) \ -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@ attrib/utils.$(OBJEXT) + attrib/gatt.c attrib/gattrib.c btio/btio.c attrib/gatttool.h \ + attrib/interactive.c attrib/utils.c +@READLINE_TRUE@@TOOLS_TRUE@am_attrib_gatttool_OBJECTS = \ +@READLINE_TRUE@@TOOLS_TRUE@ attrib/gatttool.$(OBJEXT) \ +@READLINE_TRUE@@TOOLS_TRUE@ attrib/att.$(OBJEXT) \ +@READLINE_TRUE@@TOOLS_TRUE@ attrib/gatt.$(OBJEXT) \ +@READLINE_TRUE@@TOOLS_TRUE@ attrib/gattrib.$(OBJEXT) \ +@READLINE_TRUE@@TOOLS_TRUE@ btio/btio.$(OBJEXT) \ +@READLINE_TRUE@@TOOLS_TRUE@ attrib/interactive.$(OBJEXT) \ +@READLINE_TRUE@@TOOLS_TRUE@ attrib/utils.$(OBJEXT) attrib_gatttool_OBJECTS = $(am_attrib_gatttool_OBJECTS) -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@attrib_gatttool_DEPENDENCIES = \ -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@ lib/libbluetooth.la +@READLINE_TRUE@@TOOLS_TRUE@attrib_gatttool_DEPENDENCIES = \ +@READLINE_TRUE@@TOOLS_TRUE@ lib/libbluetooth.la am__compat_dund_SOURCES_DIST = compat/dund.c compat/dund.h \ compat/lib.h compat/sdp.h compat/sdp.c compat/dun.c \ compat/msdun.c src/textfile.h src/textfile.c @@ -462,29 +471,33 @@ serial/proxy.c serial/port.h serial/port.c network/main.c \ network/manager.h network/manager.c network/common.h \ network/common.c network/server.h network/server.c \ - network/connection.h network/connection.c plugins/service.c \ - attrib/main.c attrib/manager.h attrib/manager.c \ - attrib/client.h attrib/client.c attrib/example.h \ - attrib/example.c health/hdp_main.c health/hdp_types.h \ - health/hdp_manager.h health/hdp_manager.c health/hdp.h \ - health/hdp.c health/hdp_util.h health/hdp_util.c \ + network/connection.h network/connection.c proximity/main.c \ + proximity/manager.h proximity/manager.c proximity/monitor.h \ + proximity/monitor.c plugins/service.c plugins/gatt-example.c \ + health/hdp_main.c health/hdp_types.h health/hdp_manager.h \ + health/hdp_manager.c health/hdp.h health/hdp.c \ + health/hdp_util.h health/hdp_util.c thermometer/main.c \ + thermometer/manager.h thermometer/manager.c \ + thermometer/thermometer.h thermometer/thermometer.c \ plugins/hciops.c plugins/mgmtops.c plugins/hal.c \ - plugins/formfactor.c plugins/storage.c plugins/maemo6.c \ - plugins/dbusoob.c attrib/att.h attrib/att.c attrib/gatt.h \ - attrib/gatt.c attrib/gattrib.h attrib/gattrib.c btio/btio.h \ - btio/btio.c health/mcap_lib.h health/mcap_internal.h \ - health/mcap.h health/mcap.c health/mcap_sync.c \ - src/bluetooth.ver src/main.c src/log.h src/log.c src/rfkill.c \ - src/hcid.h src/sdpd.h src/sdpd-server.c src/sdpd-request.c \ - src/sdpd-service.c src/sdpd-database.c src/attrib-server.h \ - src/attrib-server.c src/sdp-xml.h src/sdp-xml.c src/textfile.h \ - src/textfile.c src/glib-helper.h src/glib-helper.c src/oui.h \ - src/oui.c src/uinput.h src/ppoll.h src/plugin.h src/plugin.c \ - src/storage.h src/storage.c src/agent.h src/agent.c \ - src/error.h src/error.c src/manager.h src/manager.c \ - src/adapter.h src/adapter.c src/device.h src/device.c \ - src/dbus-common.c src/dbus-common.h src/event.h src/event.c \ - src/oob.h src/oob.c + plugins/formfactor.c plugins/storage.c plugins/adaptername.c \ + plugins/wiimote.c plugins/maemo6.c plugins/dbusoob.c \ + attrib/att.h attrib/att.c attrib/gatt.h attrib/gatt.c \ + attrib/gattrib.h attrib/gattrib.c attrib/client.h \ + attrib/client.c btio/btio.h btio/btio.c health/mcap_lib.h \ + health/mcap_internal.h health/mcap.h health/mcap.c \ + health/mcap_sync.c src/bluetooth.ver src/main.c src/log.h \ + src/log.c src/rfkill.c src/hcid.h src/sdpd.h src/sdpd-server.c \ + src/sdpd-request.c src/sdpd-service.c src/sdpd-database.c \ + src/attrib-server.h src/attrib-server.c src/sdp-xml.h \ + src/sdp-xml.c src/textfile.h src/textfile.c src/glib-helper.h \ + src/glib-helper.c src/oui.h src/oui.c src/uinput.h src/ppoll.h \ + src/plugin.h src/plugin.c src/storage.h src/storage.c \ + src/agent.h src/agent.c src/error.h src/error.c src/manager.h \ + src/manager.c src/adapter.h src/adapter.c src/device.h \ + src/device.c src/attio.h src/dbus-common.c src/dbus-common.h \ + src/event.h src/event.c src/oob.h src/oob.c src/eir.h \ + src/eir.c @PNATPLUGIN_TRUE@am__objects_3 = plugins/pnat.$(OBJEXT) @ECHOPLUGIN_TRUE@am__objects_4 = plugins/echo.$(OBJEXT) @AUDIOPLUGIN_TRUE@am__objects_5 = audio/main.$(OBJEXT) \ @@ -514,33 +527,40 @@ @NETWORKPLUGIN_TRUE@ network/common.$(OBJEXT) \ @NETWORKPLUGIN_TRUE@ network/server.$(OBJEXT) \ @NETWORKPLUGIN_TRUE@ network/connection.$(OBJEXT) -@SERVICEPLUGIN_TRUE@am__objects_10 = plugins/service.$(OBJEXT) -@ATTRIBPLUGIN_TRUE@am__objects_11 = attrib/main.$(OBJEXT) \ -@ATTRIBPLUGIN_TRUE@ attrib/manager.$(OBJEXT) \ -@ATTRIBPLUGIN_TRUE@ attrib/client.$(OBJEXT) \ -@ATTRIBPLUGIN_TRUE@ attrib/example.$(OBJEXT) -@HEALTHPLUGIN_TRUE@am__objects_12 = health/hdp_main.$(OBJEXT) \ +@PROXIMITYPLUGIN_TRUE@am__objects_10 = proximity/main.$(OBJEXT) \ +@PROXIMITYPLUGIN_TRUE@ proximity/manager.$(OBJEXT) \ +@PROXIMITYPLUGIN_TRUE@ proximity/monitor.$(OBJEXT) +@SERVICEPLUGIN_TRUE@am__objects_11 = plugins/service.$(OBJEXT) +@GATT_EXAMPLE_PLUGIN_TRUE@am__objects_12 = \ +@GATT_EXAMPLE_PLUGIN_TRUE@ plugins/gatt-example.$(OBJEXT) +@HEALTHPLUGIN_TRUE@am__objects_13 = health/hdp_main.$(OBJEXT) \ @HEALTHPLUGIN_TRUE@ health/hdp_manager.$(OBJEXT) \ @HEALTHPLUGIN_TRUE@ health/hdp.$(OBJEXT) \ @HEALTHPLUGIN_TRUE@ health/hdp_util.$(OBJEXT) -@HAL_TRUE@am__objects_13 = plugins/hal.$(OBJEXT) -@HAL_FALSE@am__objects_14 = plugins/formfactor.$(OBJEXT) -@MAEMO6PLUGIN_TRUE@am__objects_15 = plugins/maemo6.$(OBJEXT) -@DBUSOOBPLUGIN_TRUE@am__objects_16 = plugins/dbusoob.$(OBJEXT) -am__objects_17 = $(am__objects_3) $(am__objects_4) $(am__objects_5) \ +@THERMOMETERPLUGIN_TRUE@am__objects_14 = thermometer/main.$(OBJEXT) \ +@THERMOMETERPLUGIN_TRUE@ thermometer/manager.$(OBJEXT) \ +@THERMOMETERPLUGIN_TRUE@ thermometer/thermometer.$(OBJEXT) +@HAL_TRUE@am__objects_15 = plugins/hal.$(OBJEXT) +@HAL_FALSE@am__objects_16 = plugins/formfactor.$(OBJEXT) +@WIIMOTEPLUGIN_TRUE@am__objects_17 = plugins/wiimote.$(OBJEXT) +@MAEMO6PLUGIN_TRUE@am__objects_18 = plugins/maemo6.$(OBJEXT) +@DBUSOOBPLUGIN_TRUE@am__objects_19 = plugins/dbusoob.$(OBJEXT) +am__objects_20 = $(am__objects_3) $(am__objects_4) $(am__objects_5) \ $(am__objects_6) $(am__objects_7) $(am__objects_8) \ $(am__objects_9) $(am__objects_10) $(am__objects_11) \ - $(am__objects_12) plugins/hciops.$(OBJEXT) \ - plugins/mgmtops.$(OBJEXT) $(am__objects_13) $(am__objects_14) \ - plugins/storage.$(OBJEXT) $(am__objects_15) $(am__objects_16) -am__objects_18 = attrib/att.$(OBJEXT) attrib/gatt.$(OBJEXT) \ - attrib/gattrib.$(OBJEXT) -am__objects_19 = btio/btio.$(OBJEXT) -@MCAP_TRUE@am__objects_20 = health/mcap.$(OBJEXT) \ + $(am__objects_12) $(am__objects_13) $(am__objects_14) \ + plugins/hciops.$(OBJEXT) plugins/mgmtops.$(OBJEXT) \ + $(am__objects_15) $(am__objects_16) plugins/storage.$(OBJEXT) \ + plugins/adaptername.$(OBJEXT) $(am__objects_17) \ + $(am__objects_18) $(am__objects_19) +am__objects_21 = attrib/att.$(OBJEXT) attrib/gatt.$(OBJEXT) \ + attrib/gattrib.$(OBJEXT) attrib/client.$(OBJEXT) +am__objects_22 = btio/btio.$(OBJEXT) +@MCAP_TRUE@am__objects_23 = health/mcap.$(OBJEXT) \ @MCAP_TRUE@ health/mcap_sync.$(OBJEXT) -am__objects_21 = $(am__objects_20) -am_src_bluetoothd_OBJECTS = $(am__objects_2) $(am__objects_17) \ - $(am__objects_18) $(am__objects_19) $(am__objects_21) \ +am__objects_24 = $(am__objects_23) +am_src_bluetoothd_OBJECTS = $(am__objects_2) $(am__objects_20) \ + $(am__objects_21) $(am__objects_22) $(am__objects_24) \ src/main.$(OBJEXT) src/log.$(OBJEXT) src/rfkill.$(OBJEXT) \ src/sdpd-server.$(OBJEXT) src/sdpd-request.$(OBJEXT) \ src/sdpd-service.$(OBJEXT) src/sdpd-database.$(OBJEXT) \ @@ -550,12 +570,12 @@ src/agent.$(OBJEXT) src/error.$(OBJEXT) src/manager.$(OBJEXT) \ src/adapter.$(OBJEXT) src/device.$(OBJEXT) \ src/dbus-common.$(OBJEXT) src/event.$(OBJEXT) \ - src/oob.$(OBJEXT) -@AUDIOPLUGIN_TRUE@am__objects_22 = audio/telephony.$(OBJEXT) -@SAPPLUGIN_TRUE@am__objects_23 = sap/sap.$(OBJEXT) -am__objects_24 = $(am__objects_22) $(am__objects_23) -am__objects_25 = $(am__objects_24) -nodist_src_bluetoothd_OBJECTS = $(am__objects_25) + src/oob.$(OBJEXT) src/eir.$(OBJEXT) +@AUDIOPLUGIN_TRUE@am__objects_25 = audio/telephony.$(OBJEXT) +@SAPPLUGIN_TRUE@am__objects_26 = sap/sap.$(OBJEXT) +am__objects_27 = $(am__objects_25) $(am__objects_26) +am__objects_28 = $(am__objects_27) +nodist_src_bluetoothd_OBJECTS = $(am__objects_28) src_bluetoothd_OBJECTS = $(am_src_bluetoothd_OBJECTS) \ $(nodist_src_bluetoothd_OBJECTS) src_bluetoothd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ @@ -630,12 +650,12 @@ am__tools_bccmd_SOURCES_DIST = tools/bccmd.c tools/csr.h tools/csr.c \ tools/csr_hci.c tools/csr_h4.c tools/csr_3wire.c \ tools/csr_bcsp.c tools/ubcsp.h tools/ubcsp.c tools/csr_usb.c -@BCCMD_TRUE@@USB_TRUE@am__objects_26 = tools/csr_usb.$(OBJEXT) +@BCCMD_TRUE@@USB_TRUE@am__objects_29 = tools/csr_usb.$(OBJEXT) @BCCMD_TRUE@am_tools_bccmd_OBJECTS = tools/bccmd.$(OBJEXT) \ @BCCMD_TRUE@ tools/csr.$(OBJEXT) tools/csr_hci.$(OBJEXT) \ @BCCMD_TRUE@ tools/csr_h4.$(OBJEXT) tools/csr_3wire.$(OBJEXT) \ @BCCMD_TRUE@ tools/csr_bcsp.$(OBJEXT) tools/ubcsp.$(OBJEXT) \ -@BCCMD_TRUE@ $(am__objects_26) +@BCCMD_TRUE@ $(am__objects_29) tools_bccmd_OBJECTS = $(am_tools_bccmd_OBJECTS) am__DEPENDENCIES_1 = @BCCMD_TRUE@tools_bccmd_DEPENDENCIES = lib/libbluetooth.la \ @@ -808,7 +828,7 @@ NROFF = nroff MANS = $(dist_man_MANS) $(man_MANS) DATA = $(alsaconf_DATA) $(conf_DATA) $(dbus_DATA) $(pkgconfig_DATA) \ - $(rules_DATA) $(state_DATA) + $(rules_DATA) $(state_DATA) $(systemdunit_DATA) HEADERS = $(include_HEADERS) ETAGS = etags CTAGS = ctags @@ -903,8 +923,11 @@ SNDFILE_LIBS = @SNDFILE_LIBS@ STORAGEDIR = @STORAGEDIR@ STRIP = @STRIP@ +SYSTEMD_UNITDIR = @SYSTEMD_UNITDIR@ TELEPHONY_DRIVER = @TELEPHONY_DRIVER@ -UDEV_DATADIR = @UDEV_DATADIR@ +UDEV_CFLAGS = @UDEV_CFLAGS@ +UDEV_DIR = @UDEV_DIR@ +UDEV_LIBS = @UDEV_LIBS@ USB_CFLAGS = @USB_CFLAGS@ USB_LIBS = @USB_LIBS@ VERSION = @VERSION@ @@ -964,46 +987,49 @@ top_srcdir = @top_srcdir@ AM_MAKEFLAGS = --no-print-directory lib_LTLIBRARIES = lib/libbluetooth.la +noinst_LIBRARIES = $(am__append_12) $(am__append_16) noinst_LTLIBRARIES = $(am__append_1) -dist_man_MANS = $(am__append_40) $(am__append_46) $(am__append_49) \ - $(am__append_52) $(am__append_58) $(am__append_62) \ - $(am__append_65) $(am__append_68) +dist_man_MANS = $(am__append_48) $(am__append_54) $(am__append_56) \ + $(am__append_59) $(am__append_65) $(am__append_69) \ + $(am__append_72) $(am__append_75) dist_noinst_MANS = -CLEANFILES = $(local_headers) $(builtin_files) tools/lexer.c \ - tools/parser.c tools/parser.h $(rules_DATA) +CLEANFILES = $(builtin_files) tools/lexer.c tools/parser.c \ + tools/parser.h $(rules_DATA) EXTRA_DIST = plugins/hal.c plugins/formfactor.c src/genbuiltin \ src/bluetooth.conf src/main.conf network/network.conf \ input/input.conf serial/serial.conf audio/audio.conf \ audio/telephony-dummy.c audio/telephony-maemo5.c \ audio/telephony-ofono.c audio/telephony-maemo6.c \ - sap/sap-dummy.c audio/bluetooth.conf $(am__append_41) \ - tools/rfcomm.conf $(am__append_47) $(am__append_50) \ - $(am__append_53) tools/dfubabel.1 tools/avctrl.8 \ - $(am__append_59) $(am__append_60) test/apitest test/sap-client \ - test/hsplay test/hsmicro test/dbusdef.py \ + sap/sap-dummy.c sap/sap-u8500.c audio/bluetooth.conf \ + $(am__append_49) tools/rfcomm.conf $(am__append_55) \ + $(am__append_57) $(am__append_60) tools/dfubabel.1 \ + tools/avctrl.8 $(am__append_66) $(am__append_67) test/apitest \ + test/sap-client test/hsplay test/hsmicro test/dbusdef.py \ test/monitor-bluetooth test/list-devices test/test-discovery \ test/test-manager test/test-adapter test/test-device \ test/test-service test/test-serial test/test-telephony \ test/test-network test/simple-agent test/simple-service \ test/simple-endpoint test/test-audio test/test-input \ - test/test-attrib test/test-sap-server test/service-record.dtd \ - test/service-did.xml test/service-spp.xml test/service-opp.xml \ - test/service-ftp.xml $(am__append_63) $(am__append_66) \ - $(am__append_69) scripts/bluetooth.rules \ - scripts/bluetooth-hid2hci.rules scripts/bluetooth-serial.rules \ - doc/manager-api.txt doc/adapter-api.txt doc/device-api.txt \ - doc/service-api.txt doc/agent-api.txt doc/attribute-api.txt \ - doc/serial-api.txt doc/network-api.txt doc/input-api.txt \ - doc/audio-api.txt doc/control-api.txt doc/hfp-api.txt \ - doc/health-api.txt doc/sap-api.txt doc/media-api.txt \ - doc/assigned-numbers.txt + test/test-attrib test/test-sap-server test/test-oob \ + test/service-record.dtd test/service-did.xml \ + test/service-spp.xml test/service-opp.xml test/service-ftp.xml \ + $(am__append_70) $(am__append_73) $(am__append_76) \ + scripts/bluetooth.rules scripts/bluetooth-hid2hci.rules \ + scripts/bluetooth-serial.rules doc/manager-api.txt \ + doc/adapter-api.txt doc/device-api.txt doc/service-api.txt \ + doc/agent-api.txt doc/attribute-api.txt doc/serial-api.txt \ + doc/network-api.txt doc/input-api.txt doc/audio-api.txt \ + doc/control-api.txt doc/hfp-api.txt doc/health-api.txt \ + doc/sap-api.txt doc/media-api.txt doc/assigned-numbers.txt include_HEADERS = $(lib_headers) -@CONFIGFILES_TRUE@dbusdir = $(sysconfdir)/dbus-1/system.d -@CONFIGFILES_TRUE@dbus_DATA = src/bluetooth.conf -@CONFIGFILES_TRUE@confdir = $(sysconfdir)/bluetooth -@CONFIGFILES_TRUE@conf_DATA = src/main.conf $(am__append_36) -@CONFIGFILES_TRUE@statedir = $(localstatedir)/lib/bluetooth -@CONFIGFILES_TRUE@state_DATA = +@DATAFILES_TRUE@dbusdir = $(sysconfdir)/dbus-1/system.d +@DATAFILES_TRUE@dbus_DATA = src/bluetooth.conf +@DATAFILES_TRUE@confdir = $(sysconfdir)/bluetooth +@DATAFILES_TRUE@conf_DATA = src/main.conf $(am__append_43) +@DATAFILES_TRUE@statedir = $(localstatedir)/lib/bluetooth +@DATAFILES_TRUE@state_DATA = +@DATAFILES_TRUE@@SYSTEMD_TRUE@systemdunitdir = @SYSTEMD_UNITDIR@ +@DATAFILES_TRUE@@SYSTEMD_TRUE@systemdunit_DATA = src/bluetooth.service plugindir = $(libdir)/bluetooth/plugins plugin_LTLIBRARIES = lib_headers = lib/bluetooth.h lib/hci.h lib/hci_lib.h lib/mgmt.h \ @@ -1011,10 +1037,11 @@ lib/rfcomm.h lib/bnep.h lib/cmtp.h lib/hidp.h local_headers = $(foreach file,$(lib_headers), lib/bluetooth/$(notdir $(file))) +BUILT_SOURCES = $(local_headers) lib_libbluetooth_la_SOURCES = $(lib_headers) \ lib/bluetooth.c lib/hci.c lib/sdp.c lib/uuid.c -lib_libbluetooth_la_LDFLAGS = -version-info 14:0:11 +lib_libbluetooth_la_LDFLAGS = -version-info 14:4:11 lib_libbluetooth_la_DEPENDENCIES = $(local_headers) @SBC_TRUE@sbc_libsbc_la_SOURCES = sbc/sbc.h sbc/sbc.c sbc/sbc_math.h sbc/sbc_tables.h \ @SBC_TRUE@ sbc/sbc_primitives.h sbc/sbc_primitives.c \ @@ -1033,39 +1060,33 @@ @SBC_TRUE@@SNDFILE_TRUE@sbc_sbctester_LDADD = @SNDFILE_LIBS@ -lm @SBC_TRUE@@SNDFILE_TRUE@sbc_sbctest_CFLAGS = @SNDFILE_CFLAGS@ attrib_sources = attrib/att.h attrib/att.c attrib/gatt.h attrib/gatt.c \ - attrib/gattrib.h attrib/gattrib.c + attrib/gattrib.h attrib/gattrib.c attrib/client.h \ + attrib/client.c gdbus_sources = gdbus/gdbus.h gdbus/mainloop.c gdbus/watch.c \ gdbus/object.c gdbus/polkit.c btio_sources = btio/btio.h btio/btio.c builtin_modules = $(am__append_5) $(am__append_7) $(am__append_9) \ - $(am__append_12) $(am__append_15) $(am__append_17) \ - $(am__append_19) $(am__append_21) $(am__append_24) \ - $(am__append_26) hciops mgmtops $(am__append_28) \ - $(am__append_30) storage $(am__append_32) $(am__append_34) + $(am__append_13) $(am__append_17) $(am__append_19) \ + $(am__append_21) $(am__append_23) $(am__append_25) \ + $(am__append_27) $(am__append_29) $(am__append_31) hciops \ + mgmtops $(am__append_33) $(am__append_35) storage adaptername \ + $(am__append_37) $(am__append_39) $(am__append_41) builtin_sources = $(am__append_6) $(am__append_8) $(am__append_10) \ - $(am__append_13) $(am__append_16) $(am__append_18) \ - $(am__append_20) $(am__append_22) $(am__append_25) \ - $(am__append_27) plugins/hciops.c plugins/mgmtops.c \ - $(am__append_29) $(am__append_31) plugins/storage.c \ - $(am__append_33) $(am__append_35) -builtin_nodist = $(am__append_11) $(am__append_14) + $(am__append_14) $(am__append_18) $(am__append_20) \ + $(am__append_22) $(am__append_24) $(am__append_26) \ + $(am__append_28) $(am__append_30) $(am__append_32) \ + plugins/hciops.c plugins/mgmtops.c $(am__append_34) \ + $(am__append_36) plugins/storage.c plugins/adaptername.c \ + $(am__append_38) $(am__append_40) $(am__append_42) +builtin_nodist = $(am__append_11) $(am__append_15) mcap_sources = $(am__append_4) -@AUDIOPLUGIN_TRUE@noinst_LIBRARIES = audio/libtelephony.a -@SAPPLUGIN_TRUE@noinst_LIBRARIES = sap/libsap.a @AUDIOPLUGIN_TRUE@audio_libtelephony_a_SOURCES = audio/telephony.h audio/telephony-dummy.c \ @AUDIOPLUGIN_TRUE@ audio/telephony-maemo5.c audio/telephony-ofono.c \ @AUDIOPLUGIN_TRUE@ audio/telephony-maemo6.c -@SAPPLUGIN_TRUE@sap_libsap_a_SOURCES = sap/sap.h sap/sap-dummy.c -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@attrib_gatttool_SOURCES = attrib/gatttool.c attrib/att.c attrib/gatt.c \ -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@ attrib/gattrib.c btio/btio.c \ -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@ src/glib-helper.h src/glib-helper.c \ -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@ attrib/gatttool.h attrib/interactive.c \ -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@ attrib/utils.c - -@ATTRIBPLUGIN_TRUE@@READLINE_TRUE@attrib_gatttool_LDADD = lib/libbluetooth.la @GLIB_LIBS@ @READLINE_LIBS@ +@SAPPLUGIN_TRUE@sap_libsap_a_SOURCES = sap/sap.h sap/sap-dummy.c sap/sap-u8500.c src_bluetoothd_SOURCES = $(gdbus_sources) $(builtin_sources) \ $(attrib_sources) $(btio_sources) \ $(mcap_sources) src/bluetooth.ver \ @@ -1084,10 +1105,10 @@ src/error.h src/error.c \ src/manager.h src/manager.c \ src/adapter.h src/adapter.c \ - src/device.h src/device.c \ + src/device.h src/device.c src/attio.h \ src/dbus-common.c src/dbus-common.h \ src/event.h src/event.c \ - src/oob.h src/oob.c + src/oob.h src/oob.c src/eir.h src/eir.c src_bluetoothd_LDADD = lib/libbluetooth.la @GLIB_LIBS@ @DBUS_LIBS@ \ @CAPNG_LIBS@ -ldl -lrt @@ -1117,8 +1138,8 @@ @ALSA_TRUE@audio_libasound_module_ctl_bluetooth_la_LDFLAGS = -module -avoid-version #-export-symbols-regex [_]*snd_ctl_.* @ALSA_TRUE@audio_libasound_module_ctl_bluetooth_la_LIBADD = lib/libbluetooth.la @ALSA_LIBS@ @ALSA_TRUE@audio_libasound_module_ctl_bluetooth_la_CFLAGS = @ALSA_CFLAGS@ -@ALSA_TRUE@@CONFIGFILES_TRUE@alsaconfdir = $(datadir)/alsa -@ALSA_TRUE@@CONFIGFILES_TRUE@alsaconf_DATA = audio/bluetooth.conf +@ALSA_TRUE@@DATAFILES_TRUE@alsaconfdir = $(datadir)/alsa +@ALSA_TRUE@@DATAFILES_TRUE@alsaconf_DATA = audio/bluetooth.conf @AUDIOPLUGIN_TRUE@@GSTREAMER_TRUE@gstreamerdir = $(libdir)/gstreamer-0.10 @AUDIOPLUGIN_TRUE@@GSTREAMER_TRUE@gstreamer_LTLIBRARIES = audio/libgstbluetooth.la @AUDIOPLUGIN_TRUE@@GSTREAMER_TRUE@audio_libgstbluetooth_la_SOURCES = audio/gstbluetooth.c audio/gstpragma.h \ @@ -1168,6 +1189,12 @@ @TOOLS_TRUE@tools_avinfo_LDADD = lib/libbluetooth.la @TOOLS_TRUE@tools_ppporc_LDADD = lib/libbluetooth.la @TOOLS_TRUE@tools_hcieventmask_LDADD = lib/libbluetooth.la +@READLINE_TRUE@@TOOLS_TRUE@attrib_gatttool_SOURCES = attrib/gatttool.c attrib/att.c attrib/gatt.c \ +@READLINE_TRUE@@TOOLS_TRUE@ attrib/gattrib.c btio/btio.c \ +@READLINE_TRUE@@TOOLS_TRUE@ attrib/gatttool.h attrib/interactive.c \ +@READLINE_TRUE@@TOOLS_TRUE@ attrib/utils.c + +@READLINE_TRUE@@TOOLS_TRUE@attrib_gatttool_LDADD = lib/libbluetooth.la @GLIB_LIBS@ @READLINE_LIBS@ @TRACER_TRUE@tracer_hcitrace_SOURCES = tracer/main.c @TRACER_TRUE@tracer_hcitrace_LDADD = lib/libbluetooth.la \ @TRACER_TRUE@ @GLIB_LIBS@ @DBUS_LIBS@ @CAPNG_LIBS@ @@ -1176,9 +1203,11 @@ @BCCMD_TRUE@tools_bccmd_SOURCES = tools/bccmd.c tools/csr.h \ @BCCMD_TRUE@ tools/csr.c tools/csr_hci.c tools/csr_h4.c \ @BCCMD_TRUE@ tools/csr_3wire.c tools/csr_bcsp.c tools/ubcsp.h \ -@BCCMD_TRUE@ tools/ubcsp.c $(am__append_44) -@BCCMD_TRUE@tools_bccmd_LDADD = lib/libbluetooth.la $(am__append_45) -@HID2HCI_TRUE@tools_hid2hci_LDADD = @USB_LIBS@ +@BCCMD_TRUE@ tools/ubcsp.c $(am__append_52) +@BCCMD_TRUE@tools_bccmd_LDADD = lib/libbluetooth.la $(am__append_53) +@DATAFILES_TRUE@@PCMCIA_TRUE@udevdir = @UDEV_DIR@ +@HID2HCI_TRUE@udevdir = @UDEV_DIR@ +@HID2HCI_TRUE@tools_hid2hci_LDADD = @USB_LIBS@ @UDEV_LIBS@ @DFUTOOL_TRUE@tools_dfutool_SOURCES = tools/dfutool.c tools/dfu.h tools/dfu.c @DFUTOOL_TRUE@tools_dfutool_LDADD = @USB_LIBS@ @USB_TRUE@tools_dfubabel_LDADD = @USB_LIBS@ @@ -1223,28 +1252,27 @@ @DUND_TRUE@ src/textfile.h src/textfile.c @DUND_TRUE@compat_dund_LDADD = lib/libbluetooth.la -@UDEVRULES_TRUE@rulesdir = @UDEV_DATADIR@ -@UDEVRULES_TRUE@udev_files = scripts/bluetooth.rules $(am__append_70) \ -@UDEVRULES_TRUE@ $(am__append_71) -@UDEVRULES_TRUE@rules_DATA = $(foreach file,$(udev_files), scripts/97-$(notdir $(file))) -@PCMCIA_TRUE@udevdir = $(libexecdir)/udev -@PCMCIA_TRUE@dist_udev_SCRIPTS = scripts/bluetooth_serial +@DATAFILES_TRUE@rulesdir = @UDEV_DIR@/rules.d +@DATAFILES_TRUE@udev_files = scripts/bluetooth.rules $(am__append_77) \ +@DATAFILES_TRUE@ $(am__append_78) +@DATAFILES_TRUE@@PCMCIA_TRUE@dist_udev_SCRIPTS = scripts/bluetooth_serial +@DATAFILES_TRUE@rules_DATA = $(foreach file,$(udev_files), scripts/97-$(notdir $(file))) AM_YFLAGS = -d AM_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @CAPNG_CFLAGS@ \ -DBLUETOOTH_PLUGIN_BUILTIN -DPLUGINDIR=\""$(plugindir)"\" INCLUDES = -I$(builddir)/lib -I$(builddir)/src -I$(srcdir)/src \ -I$(srcdir)/audio -I$(srcdir)/sbc -I$(srcdir)/gdbus \ - -I$(srcdir)/attrib -I$(srcdir)/btio $(am__append_72) + -I$(srcdir)/attrib -I$(srcdir)/btio $(am__append_79) pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = bluez.pc -DISTCHECK_CONFIGURE_FLAGS = --disable-udevrules --enable-attrib +DISTCHECK_CONFIGURE_FLAGS = --disable-datafiles DISTCLEANFILES = $(pkgconfig_DATA) MAINTAINERCLEANFILES = Makefile.in \ aclocal.m4 configure config.h.in config.sub config.guess \ ltmain.sh depcomp compile missing install-sh mkinstalldirs ylwrap -all: config.h +all: $(BUILT_SOURCES) config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: @@ -1306,6 +1334,8 @@ cd $(top_builddir) && $(SHELL) ./config.status $@ src/bluetoothd.8: $(top_builddir)/config.status $(top_srcdir)/src/bluetoothd.8.in cd $(top_builddir) && $(SHELL) ./config.status $@ +src/bluetooth.service: $(top_builddir)/config.status $(top_srcdir)/src/bluetooth.service.in + cd $(top_builddir) && $(SHELL) ./config.status $@ bluez.pc: $(top_builddir)/config.status $(srcdir)/bluez.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ @@ -1337,6 +1367,8 @@ @: > sap/$(DEPDIR)/$(am__dirstamp) sap/sap-dummy.$(OBJEXT): sap/$(am__dirstamp) \ sap/$(DEPDIR)/$(am__dirstamp) +sap/sap-u8500.$(OBJEXT): sap/$(am__dirstamp) \ + sap/$(DEPDIR)/$(am__dirstamp) sap/libsap.a: $(sap_libsap_a_OBJECTS) $(sap_libsap_a_DEPENDENCIES) sap/$(am__dirstamp) $(AM_V_at)-rm -f sap/libsap.a $(AM_V_AR)$(sap_libsap_a_AR) sap/libsap.a $(sap_libsap_a_OBJECTS) $(sap_libsap_a_LIBADD) @@ -1676,6 +1708,49 @@ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list +install-udevPROGRAMS: $(udev_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(udevdir)" || $(MKDIR_P) "$(DESTDIR)$(udevdir)" + @list='$(udev_PROGRAMS)'; test -n "$(udevdir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(udevdir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(udevdir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-udevPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(udev_PROGRAMS)'; test -n "$(udevdir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(udevdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(udevdir)" && rm -f $$files + +clean-udevPROGRAMS: + @list='$(udev_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list attrib/$(am__dirstamp): @$(MKDIR_P) attrib @: > attrib/$(am__dirstamp) @@ -1698,14 +1773,6 @@ @: > btio/$(DEPDIR)/$(am__dirstamp) btio/btio.$(OBJEXT): btio/$(am__dirstamp) \ btio/$(DEPDIR)/$(am__dirstamp) -src/$(am__dirstamp): - @$(MKDIR_P) src - @: > src/$(am__dirstamp) -src/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) src/$(DEPDIR) - @: > src/$(DEPDIR)/$(am__dirstamp) -src/glib-helper.$(OBJEXT): src/$(am__dirstamp) \ - src/$(DEPDIR)/$(am__dirstamp) attrib/interactive.$(OBJEXT): attrib/$(am__dirstamp) \ attrib/$(DEPDIR)/$(am__dirstamp) attrib/utils.$(OBJEXT): attrib/$(am__dirstamp) \ @@ -1727,6 +1794,12 @@ compat/$(DEPDIR)/$(am__dirstamp) compat/msdun.$(OBJEXT): compat/$(am__dirstamp) \ compat/$(DEPDIR)/$(am__dirstamp) +src/$(am__dirstamp): + @$(MKDIR_P) src + @: > src/$(am__dirstamp) +src/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/$(DEPDIR) + @: > src/$(DEPDIR)/$(am__dirstamp) src/textfile.$(OBJEXT): src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) compat/dund$(EXEEXT): $(compat_dund_OBJECTS) $(compat_dund_DEPENDENCIES) compat/$(am__dirstamp) @@ -1886,16 +1959,22 @@ network/$(DEPDIR)/$(am__dirstamp) network/connection.$(OBJEXT): network/$(am__dirstamp) \ network/$(DEPDIR)/$(am__dirstamp) +proximity/$(am__dirstamp): + @$(MKDIR_P) proximity + @: > proximity/$(am__dirstamp) +proximity/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) proximity/$(DEPDIR) + @: > proximity/$(DEPDIR)/$(am__dirstamp) +proximity/main.$(OBJEXT): proximity/$(am__dirstamp) \ + proximity/$(DEPDIR)/$(am__dirstamp) +proximity/manager.$(OBJEXT): proximity/$(am__dirstamp) \ + proximity/$(DEPDIR)/$(am__dirstamp) +proximity/monitor.$(OBJEXT): proximity/$(am__dirstamp) \ + proximity/$(DEPDIR)/$(am__dirstamp) plugins/service.$(OBJEXT): plugins/$(am__dirstamp) \ plugins/$(DEPDIR)/$(am__dirstamp) -attrib/main.$(OBJEXT): attrib/$(am__dirstamp) \ - attrib/$(DEPDIR)/$(am__dirstamp) -attrib/manager.$(OBJEXT): attrib/$(am__dirstamp) \ - attrib/$(DEPDIR)/$(am__dirstamp) -attrib/client.$(OBJEXT): attrib/$(am__dirstamp) \ - attrib/$(DEPDIR)/$(am__dirstamp) -attrib/example.$(OBJEXT): attrib/$(am__dirstamp) \ - attrib/$(DEPDIR)/$(am__dirstamp) +plugins/gatt-example.$(OBJEXT): plugins/$(am__dirstamp) \ + plugins/$(DEPDIR)/$(am__dirstamp) health/$(am__dirstamp): @$(MKDIR_P) health @: > health/$(am__dirstamp) @@ -1910,6 +1989,18 @@ health/$(DEPDIR)/$(am__dirstamp) health/hdp_util.$(OBJEXT): health/$(am__dirstamp) \ health/$(DEPDIR)/$(am__dirstamp) +thermometer/$(am__dirstamp): + @$(MKDIR_P) thermometer + @: > thermometer/$(am__dirstamp) +thermometer/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) thermometer/$(DEPDIR) + @: > thermometer/$(DEPDIR)/$(am__dirstamp) +thermometer/main.$(OBJEXT): thermometer/$(am__dirstamp) \ + thermometer/$(DEPDIR)/$(am__dirstamp) +thermometer/manager.$(OBJEXT): thermometer/$(am__dirstamp) \ + thermometer/$(DEPDIR)/$(am__dirstamp) +thermometer/thermometer.$(OBJEXT): thermometer/$(am__dirstamp) \ + thermometer/$(DEPDIR)/$(am__dirstamp) plugins/hciops.$(OBJEXT): plugins/$(am__dirstamp) \ plugins/$(DEPDIR)/$(am__dirstamp) plugins/mgmtops.$(OBJEXT): plugins/$(am__dirstamp) \ @@ -1920,10 +2011,16 @@ plugins/$(DEPDIR)/$(am__dirstamp) plugins/storage.$(OBJEXT): plugins/$(am__dirstamp) \ plugins/$(DEPDIR)/$(am__dirstamp) +plugins/adaptername.$(OBJEXT): plugins/$(am__dirstamp) \ + plugins/$(DEPDIR)/$(am__dirstamp) +plugins/wiimote.$(OBJEXT): plugins/$(am__dirstamp) \ + plugins/$(DEPDIR)/$(am__dirstamp) plugins/maemo6.$(OBJEXT): plugins/$(am__dirstamp) \ plugins/$(DEPDIR)/$(am__dirstamp) plugins/dbusoob.$(OBJEXT): plugins/$(am__dirstamp) \ plugins/$(DEPDIR)/$(am__dirstamp) +attrib/client.$(OBJEXT): attrib/$(am__dirstamp) \ + attrib/$(DEPDIR)/$(am__dirstamp) health/mcap.$(OBJEXT): health/$(am__dirstamp) \ health/$(DEPDIR)/$(am__dirstamp) health/mcap_sync.$(OBJEXT): health/$(am__dirstamp) \ @@ -1944,6 +2041,8 @@ src/$(DEPDIR)/$(am__dirstamp) src/sdp-xml.$(OBJEXT): src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) +src/glib-helper.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) src/oui.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/plugin.$(OBJEXT): src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) @@ -1961,6 +2060,7 @@ src/$(DEPDIR)/$(am__dirstamp) src/event.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/oob.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/eir.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) audio/telephony.$(OBJEXT): audio/$(am__dirstamp) \ audio/$(DEPDIR)/$(am__dirstamp) sap/sap.$(OBJEXT): sap/$(am__dirstamp) sap/$(DEPDIR)/$(am__dirstamp) @@ -2226,13 +2326,10 @@ -rm -f *.$(OBJEXT) -rm -f attrib/att.$(OBJEXT) -rm -f attrib/client.$(OBJEXT) - -rm -f attrib/example.$(OBJEXT) -rm -f attrib/gatt.$(OBJEXT) -rm -f attrib/gattrib.$(OBJEXT) -rm -f attrib/gatttool.$(OBJEXT) -rm -f attrib/interactive.$(OBJEXT) - -rm -f attrib/main.$(OBJEXT) - -rm -f attrib/manager.$(OBJEXT) -rm -f attrib/utils.$(OBJEXT) -rm -f audio/a2dp.$(OBJEXT) -rm -f audio/audio_libasound_module_ctl_bluetooth_la-ctl_bluetooth.$(OBJEXT) @@ -2320,9 +2417,11 @@ -rm -f network/main.$(OBJEXT) -rm -f network/manager.$(OBJEXT) -rm -f network/server.$(OBJEXT) + -rm -f plugins/adaptername.$(OBJEXT) -rm -f plugins/dbusoob.$(OBJEXT) -rm -f plugins/echo.$(OBJEXT) -rm -f plugins/formfactor.$(OBJEXT) + -rm -f plugins/gatt-example.$(OBJEXT) -rm -f plugins/hal.$(OBJEXT) -rm -f plugins/hciops.$(OBJEXT) -rm -f plugins/maemo6.$(OBJEXT) @@ -2330,9 +2429,14 @@ -rm -f plugins/pnat.$(OBJEXT) -rm -f plugins/service.$(OBJEXT) -rm -f plugins/storage.$(OBJEXT) + -rm -f plugins/wiimote.$(OBJEXT) + -rm -f proximity/main.$(OBJEXT) + -rm -f proximity/manager.$(OBJEXT) + -rm -f proximity/monitor.$(OBJEXT) -rm -f sap/main.$(OBJEXT) -rm -f sap/manager.$(OBJEXT) -rm -f sap/sap-dummy.$(OBJEXT) + -rm -f sap/sap-u8500.$(OBJEXT) -rm -f sap/sap.$(OBJEXT) -rm -f sap/server.$(OBJEXT) -rm -f sbc/sbc_libsbc_la-sbc.$(OBJEXT) @@ -2360,6 +2464,7 @@ -rm -f src/attrib-server.$(OBJEXT) -rm -f src/dbus-common.$(OBJEXT) -rm -f src/device.$(OBJEXT) + -rm -f src/eir.$(OBJEXT) -rm -f src/error.$(OBJEXT) -rm -f src/event.$(OBJEXT) -rm -f src/glib-helper.$(OBJEXT) @@ -2393,6 +2498,9 @@ -rm -f test/sdptest.$(OBJEXT) -rm -f test/test-textfile.$(OBJEXT) -rm -f test/uuidtest.$(OBJEXT) + -rm -f thermometer/main.$(OBJEXT) + -rm -f thermometer/manager.$(OBJEXT) + -rm -f thermometer/thermometer.$(OBJEXT) -rm -f tools/avctrl.$(OBJEXT) -rm -f tools/avinfo.$(OBJEXT) -rm -f tools/bccmd.$(OBJEXT) @@ -2432,13 +2540,10 @@ @AMDEP_TRUE@@am__include@ @am__quote@attrib/$(DEPDIR)/att.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@attrib/$(DEPDIR)/client.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@attrib/$(DEPDIR)/example.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@attrib/$(DEPDIR)/gatt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@attrib/$(DEPDIR)/gattrib.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@attrib/$(DEPDIR)/gatttool.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@attrib/$(DEPDIR)/interactive.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@attrib/$(DEPDIR)/main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@attrib/$(DEPDIR)/manager.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@attrib/$(DEPDIR)/utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/a2dp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@audio/$(DEPDIR)/audio_libasound_module_ctl_bluetooth_la-ctl_bluetooth.Plo@am__quote@ @@ -2509,9 +2614,11 @@ @AMDEP_TRUE@@am__include@ @am__quote@network/$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@network/$(DEPDIR)/manager.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@network/$(DEPDIR)/server.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/adaptername.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/dbusoob.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/echo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/formfactor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/gatt-example.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/hal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/hciops.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/maemo6.Po@am__quote@ @@ -2519,9 +2626,14 @@ @AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/pnat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/service.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/storage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@plugins/$(DEPDIR)/wiimote.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@proximity/$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@proximity/$(DEPDIR)/manager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@proximity/$(DEPDIR)/monitor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sap/$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sap/$(DEPDIR)/manager.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sap/$(DEPDIR)/sap-dummy.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@sap/$(DEPDIR)/sap-u8500.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sap/$(DEPDIR)/sap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sap/$(DEPDIR)/server.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sbc/$(DEPDIR)/sbc_libsbc_la-sbc.Plo@am__quote@ @@ -2543,6 +2655,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/attrib-server.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dbus-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/device.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/eir.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/error.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/event.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/glib-helper.Po@am__quote@ @@ -2576,6 +2689,9 @@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/sdptest.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/test-textfile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/uuidtest.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@thermometer/$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@thermometer/$(DEPDIR)/manager.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@thermometer/$(DEPDIR)/thermometer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tools/$(DEPDIR)/avctrl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tools/$(DEPDIR)/avinfo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@tools/$(DEPDIR)/bccmd.Po@am__quote@ @@ -3009,6 +3125,26 @@ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(statedir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(statedir)" && rm -f $$files +install-systemdunitDATA: $(systemdunit_DATA) + @$(NORMAL_INSTALL) + test -z "$(systemdunitdir)" || $(MKDIR_P) "$(DESTDIR)$(systemdunitdir)" + @list='$(systemdunit_DATA)'; test -n "$(systemdunitdir)" || list=; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(systemdunitdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(systemdunitdir)" || exit $$?; \ + done + +uninstall-systemdunitDATA: + @$(NORMAL_UNINSTALL) + @list='$(systemdunit_DATA)'; test -n "$(systemdunitdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(systemdunitdir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(systemdunitdir)" && rm -f $$files install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" @@ -3243,16 +3379,18 @@ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am -check: check-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) \ $(MANS) $(DATA) $(HEADERS) config.h install-binPROGRAMS: install-libLTLIBRARIES installdirs: - for dir in "$(DESTDIR)$(alsadir)" "$(DESTDIR)$(gstreamerdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(cupsdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(udevdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(alsaconfdir)" "$(DESTDIR)$(confdir)" "$(DESTDIR)$(dbusdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(rulesdir)" "$(DESTDIR)$(statedir)" "$(DESTDIR)$(includedir)"; do \ + for dir in "$(DESTDIR)$(alsadir)" "$(DESTDIR)$(gstreamerdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(cupsdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(udevdir)" "$(DESTDIR)$(udevdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(alsaconfdir)" "$(DESTDIR)$(confdir)" "$(DESTDIR)$(dbusdir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(rulesdir)" "$(DESTDIR)$(statedir)" "$(DESTDIR)$(systemdunitdir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done -install: install-am +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am @@ -3296,6 +3434,8 @@ -rm -f network/$(am__dirstamp) -rm -f plugins/$(DEPDIR)/$(am__dirstamp) -rm -f plugins/$(am__dirstamp) + -rm -f proximity/$(DEPDIR)/$(am__dirstamp) + -rm -f proximity/$(am__dirstamp) -rm -f sap/$(DEPDIR)/$(am__dirstamp) -rm -f sap/$(am__dirstamp) -rm -f sbc/$(DEPDIR)/$(am__dirstamp) @@ -3306,6 +3446,8 @@ -rm -f src/$(am__dirstamp) -rm -f test/$(DEPDIR)/$(am__dirstamp) -rm -f test/$(am__dirstamp) + -rm -f thermometer/$(DEPDIR)/$(am__dirstamp) + -rm -f thermometer/$(am__dirstamp) -rm -f tools/$(DEPDIR)/$(am__dirstamp) -rm -f tools/$(am__dirstamp) -rm -f tracer/$(DEPDIR)/$(am__dirstamp) @@ -3318,6 +3460,7 @@ -rm -f tools/lexer.c -rm -f tools/parser.c -rm -f tools/parser.h + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am @@ -3325,11 +3468,12 @@ clean-generic clean-gstreamerLTLIBRARIES clean-libLTLIBRARIES \ clean-libtool clean-local clean-noinstLIBRARIES \ clean-noinstLTLIBRARIES clean-noinstPROGRAMS \ - clean-pluginLTLIBRARIES clean-sbinPROGRAMS mostlyclean-am + clean-pluginLTLIBRARIES clean-sbinPROGRAMS clean-udevPROGRAMS \ + mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf attrib/$(DEPDIR) audio/$(DEPDIR) btio/$(DEPDIR) compat/$(DEPDIR) cups/$(DEPDIR) gdbus/$(DEPDIR) health/$(DEPDIR) input/$(DEPDIR) lib/$(DEPDIR) network/$(DEPDIR) plugins/$(DEPDIR) sap/$(DEPDIR) sbc/$(DEPDIR) serial/$(DEPDIR) src/$(DEPDIR) test/$(DEPDIR) tools/$(DEPDIR) tracer/$(DEPDIR) + -rm -rf attrib/$(DEPDIR) audio/$(DEPDIR) btio/$(DEPDIR) compat/$(DEPDIR) cups/$(DEPDIR) gdbus/$(DEPDIR) health/$(DEPDIR) input/$(DEPDIR) lib/$(DEPDIR) network/$(DEPDIR) plugins/$(DEPDIR) proximity/$(DEPDIR) sap/$(DEPDIR) sbc/$(DEPDIR) serial/$(DEPDIR) src/$(DEPDIR) test/$(DEPDIR) thermometer/$(DEPDIR) tools/$(DEPDIR) tracer/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags @@ -3350,7 +3494,8 @@ install-confDATA install-cupsPROGRAMS install-dbusDATA \ install-dist_udevSCRIPTS install-gstreamerLTLIBRARIES \ install-includeHEADERS install-man install-pkgconfigDATA \ - install-pluginLTLIBRARIES install-rulesDATA install-stateDATA + install-pluginLTLIBRARIES install-rulesDATA install-stateDATA \ + install-systemdunitDATA install-udevPROGRAMS install-dvi: install-dvi-am @@ -3382,7 +3527,7 @@ maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf attrib/$(DEPDIR) audio/$(DEPDIR) btio/$(DEPDIR) compat/$(DEPDIR) cups/$(DEPDIR) gdbus/$(DEPDIR) health/$(DEPDIR) input/$(DEPDIR) lib/$(DEPDIR) network/$(DEPDIR) plugins/$(DEPDIR) sap/$(DEPDIR) sbc/$(DEPDIR) serial/$(DEPDIR) src/$(DEPDIR) test/$(DEPDIR) tools/$(DEPDIR) tracer/$(DEPDIR) + -rm -rf attrib/$(DEPDIR) audio/$(DEPDIR) btio/$(DEPDIR) compat/$(DEPDIR) cups/$(DEPDIR) gdbus/$(DEPDIR) health/$(DEPDIR) input/$(DEPDIR) lib/$(DEPDIR) network/$(DEPDIR) plugins/$(DEPDIR) proximity/$(DEPDIR) sap/$(DEPDIR) sbc/$(DEPDIR) serial/$(DEPDIR) src/$(DEPDIR) test/$(DEPDIR) thermometer/$(DEPDIR) tools/$(DEPDIR) tracer/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -3406,34 +3551,36 @@ uninstall-includeHEADERS uninstall-libLTLIBRARIES \ uninstall-man uninstall-pkgconfigDATA \ uninstall-pluginLTLIBRARIES uninstall-rulesDATA \ - uninstall-sbinPROGRAMS uninstall-stateDATA + uninstall-sbinPROGRAMS uninstall-stateDATA \ + uninstall-systemdunitDATA uninstall-udevPROGRAMS uninstall-man: uninstall-man1 uninstall-man8 -.MAKE: all install-am install-strip +.MAKE: all check install install-am install-strip .PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \ clean-alsaLTLIBRARIES clean-binPROGRAMS clean-cupsPROGRAMS \ clean-generic clean-gstreamerLTLIBRARIES clean-libLTLIBRARIES \ clean-libtool clean-local clean-noinstLIBRARIES \ clean-noinstLTLIBRARIES clean-noinstPROGRAMS \ - clean-pluginLTLIBRARIES clean-sbinPROGRAMS ctags dist dist-all \ - dist-bzip2 dist-gzip dist-lzma dist-shar dist-tarZ dist-xz \ - dist-zip distcheck distclean distclean-compile \ - distclean-generic distclean-hdr distclean-libtool \ - distclean-tags distcleancheck distdir distuninstallcheck dvi \ - dvi-am html html-am info info-am install \ - install-alsaLTLIBRARIES install-alsaconfDATA install-am \ - install-binPROGRAMS install-confDATA install-cupsPROGRAMS \ - install-data install-data-am install-dbusDATA \ - install-dist_udevSCRIPTS install-dvi install-dvi-am \ - install-exec install-exec-am install-gstreamerLTLIBRARIES \ - install-html install-html-am install-includeHEADERS \ - install-info install-info-am install-libLTLIBRARIES \ - install-man install-man1 install-man8 install-pdf \ - install-pdf-am install-pkgconfigDATA install-pluginLTLIBRARIES \ - install-ps install-ps-am install-rulesDATA \ - install-sbinPROGRAMS install-stateDATA install-strip \ + clean-pluginLTLIBRARIES clean-sbinPROGRAMS clean-udevPROGRAMS \ + ctags dist dist-all dist-bzip2 dist-gzip dist-lzma dist-shar \ + dist-tarZ dist-xz dist-zip distcheck distclean \ + distclean-compile distclean-generic distclean-hdr \ + distclean-libtool distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-alsaLTLIBRARIES install-alsaconfDATA \ + install-am install-binPROGRAMS install-confDATA \ + install-cupsPROGRAMS install-data install-data-am \ + install-dbusDATA install-dist_udevSCRIPTS install-dvi \ + install-dvi-am install-exec install-exec-am \ + install-gstreamerLTLIBRARIES install-html install-html-am \ + install-includeHEADERS install-info install-info-am \ + install-libLTLIBRARIES install-man install-man1 install-man8 \ + install-pdf install-pdf-am install-pkgconfigDATA \ + install-pluginLTLIBRARIES install-ps install-ps-am \ + install-rulesDATA install-sbinPROGRAMS install-stateDATA \ + install-strip install-systemdunitDATA install-udevPROGRAMS \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ @@ -3444,7 +3591,8 @@ uninstall-includeHEADERS uninstall-libLTLIBRARIES \ uninstall-man uninstall-man1 uninstall-man8 \ uninstall-pkgconfigDATA uninstall-pluginLTLIBRARIES \ - uninstall-rulesDATA uninstall-sbinPROGRAMS uninstall-stateDATA + uninstall-rulesDATA uninstall-sbinPROGRAMS uninstall-stateDATA \ + uninstall-systemdunitDATA uninstall-udevPROGRAMS @TOOLS_TRUE@tools/kword.c: tools/parser.h diff -Nru bluez-4.91/Makefile.tools bluez-4.96/Makefile.tools --- bluez-4.91/Makefile.tools 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/Makefile.tools 2011-07-04 04:59:05.000000000 +0000 @@ -1,6 +1,6 @@ if TOOLS -if CONFIGFILES +if DATAFILES conf_DATA += tools/rfcomm.conf endif @@ -49,6 +49,16 @@ tools_hcieventmask_LDADD = lib/libbluetooth.la +if READLINE +bin_PROGRAMS += attrib/gatttool + +attrib_gatttool_SOURCES = attrib/gatttool.c attrib/att.c attrib/gatt.c \ + attrib/gattrib.c btio/btio.c \ + attrib/gatttool.h attrib/interactive.c \ + attrib/utils.c +attrib_gatttool_LDADD = lib/libbluetooth.la @GLIB_LIBS@ @READLINE_LIBS@ +endif + dist_man_MANS += tools/rfcomm.1 tools/l2ping.8 \ tools/hciattach.8 tools/hciconfig.8 \ tools/hcitool.1 tools/sdptool.1 tools/ciptool.1 @@ -90,9 +100,11 @@ endif if HID2HCI -sbin_PROGRAMS += tools/hid2hci +udevdir = @UDEV_DIR@ + +udev_PROGRAMS = tools/hid2hci -tools_hid2hci_LDADD = @USB_LIBS@ +tools_hid2hci_LDADD = @USB_LIBS@ @UDEV_LIBS@ dist_man_MANS += tools/hid2hci.8 else @@ -195,8 +207,8 @@ test/test-telephony test/test-network test/simple-agent \ test/simple-service test/simple-endpoint test/test-audio \ test/test-input test/test-attrib test/test-sap-server \ - test/service-record.dtd test/service-did.xml test/service-spp.xml \ - test/service-opp.xml test/service-ftp.xml + test/test-oob test/service-record.dtd test/service-did.xml \ + test/service-spp.xml test/service-opp.xml test/service-ftp.xml if HIDD diff -Nru bluez-4.91/network/common.c bluez-4.96/network/common.c --- bluez-4.91/network/common.c 2010-07-13 07:08:59.000000000 +0000 +++ bluez-4.96/network/common.c 2011-05-31 02:39:53.000000000 +0000 @@ -229,6 +229,11 @@ close(sk); + if (err < 0) { + error("Could not bring down %s", devname); + return err; + } + return 0; } diff -Nru bluez-4.91/network/connection.c bluez-4.96/network/connection.c --- bluez-4.91/network/connection.c 2011-01-20 07:49:26.000000000 +0000 +++ bluez-4.96/network/connection.c 2011-07-04 04:59:05.000000000 +0000 @@ -85,10 +85,8 @@ static struct network_peer *find_peer(GSList *list, const char *path) { - GSList *l; - - for (l = list; l; l = l->next) { - struct network_peer *peer = l->data; + for (; list; list = list->next) { + struct network_peer *peer = list->data; if (!strcmp(peer->path, path)) return peer; @@ -99,10 +97,8 @@ static struct network_conn *find_connection(GSList *list, uint16_t id) { - GSList *l; - - for (l = list; l; l = l->next) { - struct network_conn *nc = l->data; + for (; list; list = list->next) { + struct network_conn *nc = list->data; if (nc->id == id) return nc; @@ -481,8 +477,10 @@ return reply; } -static void connection_free(struct network_conn *nc) +static void connection_free(void *data) { + struct network_conn *nc = data; + if (nc->dc_id) device_remove_disconnect_watch(nc->peer->device, nc->dc_id); @@ -494,8 +492,7 @@ static void peer_free(struct network_peer *peer) { - g_slist_foreach(peer->connections, (GFunc) connection_free, NULL); - g_slist_free(peer->connections); + g_slist_free_full(peer->connections, connection_free); btd_device_unref(peer->device); g_free(peer->path); g_free(peer); diff -Nru bluez-4.91/network/server.c bluez-4.96/network/server.c --- bluez-4.91/network/server.c 2011-03-16 00:34:27.000000000 +0000 +++ bluez-4.96/network/server.c 2011-07-04 04:59:05.000000000 +0000 @@ -88,10 +88,8 @@ static struct network_adapter *find_adapter(GSList *list, struct btd_adapter *adapter) { - GSList *l; - - for (l = list; l; l = l->next) { - struct network_adapter *na = l->data; + for (; list; list = list->next) { + struct network_adapter *na = list->data; if (na->adapter == adapter) return na; @@ -102,10 +100,8 @@ static struct network_server *find_server(GSList *list, uint16_t id) { - GSList *l; - - for (l = list; l; l = l->next) { - struct network_server *ns = l->data; + for (; list; list = list->next) { + struct network_server *ns = list->data; if (ns->id == id) return ns; @@ -681,10 +677,7 @@ g_free(ns->name); g_free(ns->bridge); - if (ns->sessions) { - g_slist_foreach(ns->sessions, (GFunc) session_free, NULL); - g_slist_free(ns->sessions); - } + g_slist_free_full(ns->sessions, session_free); g_free(ns); } diff -Nru bluez-4.91/plugins/adaptername.c bluez-4.96/plugins/adaptername.c --- bluez-4.91/plugins/adaptername.c 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/plugins/adaptername.c 2011-07-31 06:52:19.000000000 +0000 @@ -0,0 +1,324 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 Red Hat, Inc. + * Copyright (C) 2004-2010 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Bastien Nocera + * Marcel Holtmann (for expand_name) + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include + +#include "plugin.h" +#include "hcid.h" /* For main_opts */ +#include "adapter.h" +#include "manager.h" +#include "device.h" /* Needed for storage.h */ +#include "storage.h" +#include "log.h" + +#include +#define EVENT_SIZE (sizeof (struct inotify_event)) +#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16)) + +#define MACHINE_INFO_DIR "/etc/" +#define MACHINE_INFO_FILE "machine-info" + +static GIOChannel *inotify = NULL; +static int watch_fd = -1; + +/* This file is part of systemd's hostnamed functionality: + * http://0pointer.de/public/systemd-man/machine-info.html + * http://www.freedesktop.org/wiki/Software/systemd/hostnamed + */ +static char *read_pretty_host_name(void) +{ + char *contents, *ret; + char **lines; + guint i; + + if (g_file_get_contents(MACHINE_INFO_DIR MACHINE_INFO_FILE, + &contents, NULL, NULL) == FALSE) + return NULL; + + lines = g_strsplit_set(contents, "\r\n", 0); + g_free(contents); + + if (lines == NULL) + return NULL; + + ret = NULL; + for (i = 0; lines[i] != NULL; i++) { + if (g_str_has_prefix(lines[i], "PRETTY_HOSTNAME=")) { + ret = g_strdup(lines[i] + strlen("PRETTY_HOSTNAME=")); + break; + } + } + + g_strfreev(lines); + + return ret; +} + +/* + * Device name expansion + * %d - device id + * %h - hostname + */ +static char *expand_name(char *dst, int size, char *str, int dev_id) +{ + register int sp, np, olen; + char *opt, buf[10]; + + if (!str || !dst) + return NULL; + + sp = np = 0; + while (np < size - 1 && str[sp]) { + switch (str[sp]) { + case '%': + opt = NULL; + + switch (str[sp+1]) { + case 'd': + sprintf(buf, "%d", dev_id); + opt = buf; + break; + + case 'h': + opt = main_opts.host_name; + break; + + case '%': + dst[np++] = str[sp++]; + /* fall through */ + default: + sp++; + continue; + } + + if (opt) { + /* substitute */ + olen = strlen(opt); + if (np + olen < size - 1) + memcpy(dst + np, opt, olen); + np += olen; + } + sp += 2; + continue; + + case '\\': + sp++; + /* fall through */ + default: + dst[np++] = str[sp++]; + break; + } + } + dst[np] = '\0'; + return dst; +} + +static int get_default_adapter_id(void) +{ + struct btd_adapter *default_adapter; + + default_adapter = manager_get_default_adapter(); + if (default_adapter == NULL) + return -1; + + return adapter_get_dev_id(default_adapter); +} + +static void set_pretty_name(struct btd_adapter *adapter, + const char *pretty_hostname) +{ + int current_id; + int default_adapter; + + default_adapter = get_default_adapter_id(); + current_id = adapter_get_dev_id(adapter); + + /* Allow us to change the name */ + adapter_set_allow_name_changes(adapter, TRUE); + + /* If it's the first device, let's assume it will be the + * default one, as we're not told when the default adapter + * changes */ + if (default_adapter < 0) + default_adapter = current_id; + + if (default_adapter != current_id) { + char *str; + + /* +1 because we don't want an adapter called "Foobar's + * laptop #0" */ + str = g_strdup_printf("%s #%d", pretty_hostname, + current_id + 1); + DBG("Setting name '%s' for device 'hci%d'", str, current_id); + + adapter_update_local_name(adapter, str); + g_free(str); + } else { + DBG("Setting name '%s' for device 'hci%d'", pretty_hostname, + current_id); + adapter_update_local_name(adapter, pretty_hostname); + } + + /* And disable the name change now */ + adapter_set_allow_name_changes(adapter, FALSE); +} + +static int adaptername_probe(struct btd_adapter *adapter) +{ + int current_id; + char name[MAX_NAME_LENGTH + 1]; + char *pretty_hostname; + bdaddr_t bdaddr; + + pretty_hostname = read_pretty_host_name(); + if (pretty_hostname != NULL) { + set_pretty_name(adapter, pretty_hostname); + g_free(pretty_hostname); + return 0; + } + + adapter_set_allow_name_changes(adapter, TRUE); + adapter_get_address(adapter, &bdaddr); + current_id = adapter_get_dev_id(adapter); + + if (read_local_name(&bdaddr, name) < 0) + expand_name(name, MAX_NAME_LENGTH, main_opts.name, current_id); + + DBG("Setting name '%s' for device 'hci%d'", name, current_id); + adapter_update_local_name(adapter, name); + + return 0; +} + +static gboolean handle_inotify_cb(GIOChannel *channel, GIOCondition cond, + gpointer data) +{ + char buf[EVENT_BUF_LEN]; + GIOStatus err; + gsize len, i; + gboolean changed; + + changed = FALSE; + + err = g_io_channel_read_chars(channel, buf, EVENT_BUF_LEN, &len, NULL); + if (err != G_IO_STATUS_NORMAL) { + error("Error reading inotify event: %d\n", err); + return FALSE; + } + + i = 0; + while (i < len) { + struct inotify_event *pevent = (struct inotify_event *) &buf[i]; + + /* check that it's ours */ + if (pevent->len && pevent->name != NULL && + strcmp(pevent->name, MACHINE_INFO_FILE) == 0) + changed = TRUE; + + i += EVENT_SIZE + pevent->len; + } + + if (changed != FALSE) { + DBG(MACHINE_INFO_DIR MACHINE_INFO_FILE + " changed, changing names for adapters"); + manager_foreach_adapter((adapter_cb) adaptername_probe, NULL); + } + + return TRUE; +} + +static void adaptername_remove(struct btd_adapter *adapter) +{ +} + +static struct btd_adapter_driver adaptername_driver = { + .name = "adaptername", + .probe = adaptername_probe, + .remove = adaptername_remove, +}; + +static int adaptername_init(void) +{ + int err; + int inot_fd; + guint32 mask; + + err = btd_register_adapter_driver(&adaptername_driver); + if (err < 0) + return err; + + inot_fd = inotify_init(); + if (inot_fd < 0) { + error("Failed to setup inotify"); + return 0; + } + + mask = IN_CLOSE_WRITE; + mask |= IN_DELETE; + mask |= IN_CREATE; + mask |= IN_MOVED_FROM; + mask |= IN_MOVED_TO; + + watch_fd = inotify_add_watch(inot_fd, MACHINE_INFO_DIR, mask); + if (watch_fd < 0) { + error("Failed to setup watch for '%s'", MACHINE_INFO_DIR); + close(inot_fd); + return 0; + } + + inotify = g_io_channel_unix_new(inot_fd); + g_io_channel_set_close_on_unref(inotify, TRUE); + g_io_channel_set_encoding(inotify, NULL, NULL); + g_io_channel_set_flags(inotify, G_IO_FLAG_NONBLOCK, NULL); + g_io_add_watch(inotify, G_IO_IN, handle_inotify_cb, NULL); + + return 0; +} + +static void adaptername_exit(void) +{ + if (watch_fd >= 0) + close(watch_fd); + if (inotify != NULL) { + g_io_channel_shutdown(inotify, FALSE, NULL); + g_io_channel_unref(inotify); + } + + btd_unregister_adapter_driver(&adaptername_driver); +} + +BLUETOOTH_PLUGIN_DEFINE(adaptername, VERSION, + BLUETOOTH_PLUGIN_PRIORITY_LOW, adaptername_init, adaptername_exit) diff -Nru bluez-4.91/plugins/formfactor.c bluez-4.96/plugins/formfactor.c --- bluez-4.91/plugins/formfactor.c 2010-11-30 14:50:47.000000000 +0000 +++ bluez-4.96/plugins/formfactor.c 2011-07-31 06:52:19.000000000 +0000 @@ -104,7 +104,7 @@ return 0; } - formfactor = chassis_map[chassis_type * 2]; + formfactor = chassis_map[chassis_type * 2 + 1]; if (formfactor != NULL) { if (g_str_equal(formfactor, "laptop") == TRUE) minor |= (1 << 2) | (1 << 3); diff -Nru bluez-4.91/plugins/gatt-example.c bluez-4.96/plugins/gatt-example.c --- bluez-4.91/plugins/gatt-example.c 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/plugins/gatt-example.c 2011-04-25 09:44:21.000000000 +0000 @@ -0,0 +1,498 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2010 Nokia Corporation + * Copyright (C) 2010 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "plugin.h" +#include "hcid.h" +#include "log.h" +#include "attrib-server.h" +#include "att.h" + +/* FIXME: Not defined by SIG? UUID128? */ +#define OPCODES_SUPPORTED_UUID 0xA001 +#define BATTERY_STATE_SVC_UUID 0xA002 +#define BATTERY_STATE_UUID 0xA003 +#define THERM_HUMIDITY_SVC_UUID 0xA004 +#define MANUFACTURER_SVC_UUID 0xA005 +#define TEMPERATURE_UUID 0xA006 +#define FMT_CELSIUS_UUID 0xA007 +#define FMT_OUTSIDE_UUID 0xA008 +#define RELATIVE_HUMIDITY_UUID 0xA009 +#define FMT_PERCENT_UUID 0xA00A +#define BLUETOOTH_SIG_UUID 0xA00B +#define MANUFACTURER_NAME_UUID 0xA00C +#define MANUFACTURER_SERIAL_UUID 0xA00D +#define VENDOR_SPECIFIC_SVC_UUID 0xA00E +#define VENDOR_SPECIFIC_TYPE_UUID 0xA00F +#define FMT_KILOGRAM_UUID 0xA010 +#define FMT_HANGING_UUID 0xA011 + +static GSList *sdp_handles = NULL; + +static void register_battery_service(void) +{ + uint16_t start_handle, h; + const int svc_size = 4; + uint32_t sdp_handle; + uint8_t atval[256]; + bt_uuid_t uuid; + + start_handle = attrib_db_find_avail(svc_size); + if (start_handle == 0) { + error("Not enough free handles to register service"); + return; + } + + DBG("start_handle=0x%04x", start_handle); + + h = start_handle; + + /* Battery state service: primary service definition */ + bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID); + att_put_u16(BATTERY_STATE_SVC_UUID, &atval[0]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2); + + /* Battery: battery state characteristic */ + bt_uuid16_create(&uuid, GATT_CHARAC_UUID); + atval[0] = ATT_CHAR_PROPER_READ; + att_put_u16(h + 1, &atval[1]); + att_put_u16(BATTERY_STATE_UUID, &atval[3]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); + + /* Battery: battery state attribute */ + bt_uuid16_create(&uuid, BATTERY_STATE_UUID); + atval[0] = 0x04; + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 1); + + /* Battery: Client Characteristic Configuration */ + bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID); + atval[0] = 0x00; + atval[1] = 0x00; + attrib_db_add(h++, &uuid, ATT_NONE, ATT_AUTHENTICATION, atval, 2); + + g_assert(h - start_handle == svc_size); + + /* Add an SDP record for the above service */ + sdp_handle = attrib_create_sdp(start_handle, "Battery State Service"); + if (sdp_handle) + sdp_handles = g_slist_prepend(sdp_handles, + GUINT_TO_POINTER(sdp_handle)); +} + +static void register_termometer_service(const uint16_t manuf1[2], + const uint16_t manuf2[2]) +{ + const char *desc_out_temp = "Outside Temperature"; + const char *desc_out_hum = "Outside Relative Humidity"; + uint16_t start_handle, h; + const int svc_size = 11; + uint32_t sdp_handle; + uint8_t atval[256]; + bt_uuid_t uuid; + int len; + + start_handle = attrib_db_find_avail(svc_size); + if (start_handle == 0) { + error("Not enough free handles to register service"); + return; + } + + DBG("start_handle=0x%04x manuf1=0x%04x-0x%04x, manuf2=0x%04x-0x%04x", + start_handle, manuf1[0], manuf1[1], manuf2[0], manuf2[1]); + + h = start_handle; + + /* Thermometer: primary service definition */ + bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID); + att_put_u16(THERM_HUMIDITY_SVC_UUID, &atval[0]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2); + + bt_uuid16_create(&uuid, GATT_INCLUDE_UUID); + + /* Thermometer: Include */ + if (manuf1[0] && manuf1[1]) { + att_put_u16(manuf1[0], &atval[0]); + att_put_u16(manuf1[1], &atval[2]); + att_put_u16(MANUFACTURER_SVC_UUID, &atval[4]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, + 6); + } + + /* Thermometer: Include */ + if (manuf2[0] && manuf2[1]) { + att_put_u16(manuf2[0], &atval[0]); + att_put_u16(manuf2[1], &atval[2]); + att_put_u16(VENDOR_SPECIFIC_SVC_UUID, &atval[4]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, + 6); + } + + /* Thermometer: temperature characteristic */ + bt_uuid16_create(&uuid, GATT_CHARAC_UUID); + atval[0] = ATT_CHAR_PROPER_READ; + att_put_u16(h + 1, &atval[1]); + att_put_u16(TEMPERATURE_UUID, &atval[3]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); + + /* Thermometer: temperature characteristic value */ + bt_uuid16_create(&uuid, TEMPERATURE_UUID); + atval[0] = 0x8A; + atval[1] = 0x02; + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2); + + /* Thermometer: temperature characteristic format */ + bt_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID); + atval[0] = 0x0E; + atval[1] = 0xFE; + att_put_u16(FMT_CELSIUS_UUID, &atval[2]); + atval[4] = 0x01; + att_put_u16(FMT_OUTSIDE_UUID, &atval[5]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 7); + + /* Thermometer: characteristic user description */ + bt_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID); + len = strlen(desc_out_temp); + strncpy((char *) atval, desc_out_temp, len); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len); + + /* Thermometer: relative humidity characteristic */ + bt_uuid16_create(&uuid, GATT_CHARAC_UUID); + atval[0] = ATT_CHAR_PROPER_READ; + att_put_u16(h + 1, &atval[1]); + att_put_u16(RELATIVE_HUMIDITY_UUID, &atval[3]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); + + /* Thermometer: relative humidity value */ + bt_uuid16_create(&uuid, RELATIVE_HUMIDITY_UUID); + atval[0] = 0x27; + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 1); + + /* Thermometer: relative humidity characteristic format */ + bt_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID); + atval[0] = 0x04; + atval[1] = 0x00; + att_put_u16(FMT_PERCENT_UUID, &atval[2]); + att_put_u16(BLUETOOTH_SIG_UUID, &atval[4]); + att_put_u16(FMT_OUTSIDE_UUID, &atval[6]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 8); + + /* Thermometer: characteristic user description */ + bt_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID); + len = strlen(desc_out_hum); + strncpy((char *) atval, desc_out_hum, len); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len); + + g_assert(h - start_handle == svc_size); + + /* Add an SDP record for the above service */ + sdp_handle = attrib_create_sdp(start_handle, "Thermometer"); + if (sdp_handle) + sdp_handles = g_slist_prepend(sdp_handles, + GUINT_TO_POINTER(sdp_handle)); +} + +static void register_manuf1_service(uint16_t range[2]) +{ + const char *manufacturer_name1 = "ACME Temperature Sensor"; + const char *serial1 = "237495-3282-A"; + uint16_t start_handle, h; + const int svc_size = 5; + uint8_t atval[256]; + bt_uuid_t uuid; + int len; + + start_handle = attrib_db_find_avail(svc_size); + if (start_handle == 0) { + error("Not enough free handles to register service"); + return; + } + + DBG("start_handle=0x%04x", start_handle); + + h = start_handle; + + /* Secondary Service: Manufacturer Service */ + bt_uuid16_create(&uuid, GATT_SND_SVC_UUID); + att_put_u16(MANUFACTURER_SVC_UUID, &atval[0]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2); + + /* Manufacturer name characteristic definition */ + bt_uuid16_create(&uuid, GATT_CHARAC_UUID); + atval[0] = ATT_CHAR_PROPER_READ; + att_put_u16(h + 1, &atval[1]); + att_put_u16(MANUFACTURER_NAME_UUID, &atval[3]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); + + /* Manufacturer name characteristic value */ + bt_uuid16_create(&uuid, MANUFACTURER_NAME_UUID); + len = strlen(manufacturer_name1); + strncpy((char *) atval, manufacturer_name1, len); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len); + + /* Manufacturer serial number characteristic */ + bt_uuid16_create(&uuid, GATT_CHARAC_UUID); + atval[0] = ATT_CHAR_PROPER_READ; + att_put_u16(h + 1, &atval[1]); + att_put_u16(MANUFACTURER_SERIAL_UUID, &atval[3]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); + + /* Manufacturer serial number characteristic value */ + bt_uuid16_create(&uuid, MANUFACTURER_SERIAL_UUID); + len = strlen(serial1); + strncpy((char *) atval, serial1, len); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len); + + g_assert(h - start_handle == svc_size); + + range[0] = start_handle; + range[1] = start_handle + svc_size - 1; +} + +static void register_manuf2_service(uint16_t range[2]) +{ + const char *manufacturer_name2 = "ACME Weighing Scales"; + const char *serial2 = "11267-2327A00239"; + uint16_t start_handle, h; + const int svc_size = 5; + uint8_t atval[256]; + bt_uuid_t uuid; + int len; + + start_handle = attrib_db_find_avail(svc_size); + if (start_handle == 0) { + error("Not enough free handles to register service"); + return; + } + + DBG("start_handle=0x%04x", start_handle); + + h = start_handle; + + /* Secondary Service: Manufacturer Service */ + bt_uuid16_create(&uuid, GATT_SND_SVC_UUID); + att_put_u16(MANUFACTURER_SVC_UUID, &atval[0]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2); + + /* Manufacturer name characteristic definition */ + bt_uuid16_create(&uuid, GATT_CHARAC_UUID); + atval[0] = ATT_CHAR_PROPER_READ; + att_put_u16(h + 1, &atval[1]); + att_put_u16(MANUFACTURER_NAME_UUID, &atval[3]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); + + /* Manufacturer name attribute */ + bt_uuid16_create(&uuid, MANUFACTURER_NAME_UUID); + len = strlen(manufacturer_name2); + strncpy((char *) atval, manufacturer_name2, len); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len); + + /* Characteristic: serial number */ + bt_uuid16_create(&uuid, GATT_CHARAC_UUID); + atval[0] = ATT_CHAR_PROPER_READ; + att_put_u16(h + 1, &atval[1]); + att_put_u16(MANUFACTURER_SERIAL_UUID, &atval[3]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); + + /* Serial number characteristic value */ + bt_uuid16_create(&uuid, MANUFACTURER_SERIAL_UUID); + len = strlen(serial2); + strncpy((char *) atval, serial2, len); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len); + + g_assert(h - start_handle == svc_size); + + range[0] = start_handle; + range[1] = start_handle + svc_size - 1; +} + +static void register_vendor_service(uint16_t range[2]) +{ + uint16_t start_handle, h; + const int svc_size = 3; + uint8_t atval[256]; + bt_uuid_t uuid; + + start_handle = attrib_db_find_avail(svc_size); + if (start_handle == 0) { + error("Not enough free handles to register service"); + return; + } + + DBG("start_handle=0x%04x", start_handle); + + h = start_handle; + + /* Secondary Service: Vendor Specific Service */ + bt_uuid16_create(&uuid, GATT_SND_SVC_UUID); + att_put_u16(VENDOR_SPECIFIC_SVC_UUID, &atval[0]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 2); + + /* Vendor Specific Type characteristic definition */ + bt_uuid16_create(&uuid, GATT_CHARAC_UUID); + atval[0] = ATT_CHAR_PROPER_READ; + att_put_u16(h + 1, &atval[1]); + att_put_u16(VENDOR_SPECIFIC_TYPE_UUID, &atval[3]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 5); + + /* Vendor Specific Type characteristic value */ + bt_uuid16_create(&uuid, VENDOR_SPECIFIC_TYPE_UUID); + atval[0] = 0x56; + atval[1] = 0x65; + atval[2] = 0x6E; + atval[3] = 0x64; + atval[4] = 0x6F; + atval[5] = 0x72; + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 6); + + g_assert(h - start_handle == svc_size); + + range[0] = start_handle; + range[1] = start_handle + svc_size - 1; +} + +static void register_weight_service(const uint16_t vendor[2]) +{ + const char *desc_weight = "Rucksack Weight"; + const uint128_t char_weight_uuid_btorder = { + .data = { 0x80, 0x88, 0xF2, 0x18, 0x90, 0x2C, 0x45, 0x0B, + 0xB6, 0xC4, 0x62, 0x89, 0x1E, 0x8C, 0x25, 0xE9 } }; + const uint128_t prim_weight_uuid_btorder = { + .data = { 0x4F, 0x0A, 0xC0, 0x96, 0x35, 0xD4, 0x49, 0x11, + 0x96, 0x31, 0xDE, 0xA8, 0xDC, 0x74, 0xEE, 0xFE } }; + uint128_t char_weight_uuid; + uint16_t start_handle, h; + const int svc_size = 6; + uint32_t sdp_handle; + uint8_t atval[256]; + bt_uuid_t uuid; + int len; + + btoh128(&char_weight_uuid_btorder, &char_weight_uuid); + + start_handle = attrib_db_find_avail(svc_size); + if (start_handle == 0) { + error("Not enough free handles to register service"); + return; + } + + DBG("start_handle=0x%04x, vendor=0x%04x-0x%04x", start_handle, + vendor[0], vendor[1]); + + h = start_handle; + + /* Weight service: primary service definition */ + bt_uuid16_create(&uuid, GATT_PRIM_SVC_UUID); + memcpy(atval, &prim_weight_uuid_btorder, 16); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 16); + + if (vendor[0] && vendor[1]) { + /* Weight: include */ + bt_uuid16_create(&uuid, GATT_INCLUDE_UUID); + att_put_u16(vendor[0], &atval[0]); + att_put_u16(vendor[1], &atval[2]); + att_put_u16(MANUFACTURER_SVC_UUID, &atval[4]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, + 6); + } + + /* Weight: characteristic */ + bt_uuid16_create(&uuid, GATT_CHARAC_UUID); + atval[0] = ATT_CHAR_PROPER_READ; + att_put_u16(h + 1, &atval[1]); + memcpy(&atval[3], &char_weight_uuid_btorder, 16); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 19); + + /* Weight: characteristic value */ + bt_uuid128_create(&uuid, char_weight_uuid); + atval[0] = 0x82; + atval[1] = 0x55; + atval[2] = 0x00; + atval[3] = 0x00; + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 4); + + /* Weight: characteristic format */ + bt_uuid16_create(&uuid, GATT_CHARAC_FMT_UUID); + atval[0] = 0x08; + atval[1] = 0xFD; + att_put_u16(FMT_KILOGRAM_UUID, &atval[2]); + att_put_u16(BLUETOOTH_SIG_UUID, &atval[4]); + att_put_u16(FMT_HANGING_UUID, &atval[6]); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, 8); + + /* Weight: characteristic user description */ + bt_uuid16_create(&uuid, GATT_CHARAC_USER_DESC_UUID); + len = strlen(desc_weight); + strncpy((char *) atval, desc_weight, len); + attrib_db_add(h++, &uuid, ATT_NONE, ATT_NOT_PERMITTED, atval, len); + + g_assert(h - start_handle == svc_size); + + /* Add an SDP record for the above service */ + sdp_handle = attrib_create_sdp(start_handle, "Weight Service"); + if (sdp_handle) + sdp_handles = g_slist_prepend(sdp_handles, + GUINT_TO_POINTER(sdp_handle)); +} + +static int gatt_example_init(void) +{ + uint16_t manuf1_range[2] = {0, 0}, manuf2_range[2] = {0, 0}; + uint16_t vendor_range[2] = {0, 0}; + + if (!main_opts.attrib_server) { + DBG("Attribute server is disabled"); + return -1; + } + + register_battery_service(); + register_manuf1_service(manuf1_range); + register_manuf2_service(manuf2_range); + register_termometer_service(manuf1_range, manuf2_range); + register_vendor_service(vendor_range); + register_weight_service(vendor_range); + + return 0; +} + +static void gatt_example_exit(void) +{ + if (!main_opts.attrib_server) + return; + + while (sdp_handles) { + uint32_t handle = GPOINTER_TO_UINT(sdp_handles->data); + + attrib_free_sdp(handle); + sdp_handles = g_slist_remove(sdp_handles, sdp_handles->data); + } +} + +BLUETOOTH_PLUGIN_DEFINE(gatt_example, VERSION, BLUETOOTH_PLUGIN_PRIORITY_LOW, + gatt_example_init, gatt_example_exit) diff -Nru bluez-4.91/plugins/hciops.c bluez-4.96/plugins/hciops.c --- bluez-4.91/plugins/hciops.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/plugins/hciops.c 2011-07-04 04:59:05.000000000 +0000 @@ -40,6 +40,7 @@ #include +#include "glib-helper.h" #include "hcid.h" #include "sdpd.h" #include "btio.h" @@ -51,12 +52,32 @@ #include "event.h" #include "manager.h" #include "oob.h" +#include "eir.h" + +#define DISCOV_HALTED 0 +#define DISCOV_INQ 1 +#define DISCOV_SCAN 2 + +#define TIMEOUT_BR_LE_SCAN 5120 /* TGAP(100)/2 */ +#define TIMEOUT_LE_SCAN 10240 /* TGAP(gen_disc_scan_min) */ + +#define LENGTH_BR_INQ 0x08 +#define LENGTH_BR_LE_INQ 0x04 + +static int hciops_start_scanning(int index, int timeout); static int child_pipe[2] = { -1, -1 }; static guint child_io_id = 0; static guint ctl_io_id = 0; +enum adapter_type { + BR_EDR, + LE_ONLY, + BR_EDR_LE, + UNKNOWN, +}; + /* Commands sent by kernel on starting an adapter */ enum { PENDING_BDADDR, @@ -65,11 +86,6 @@ PENDING_NAME, }; -struct uuid_info { - uuid_t uuid; - uint8_t svc_hint; -}; - struct bt_conn { struct dev_info *dev; bdaddr_t bdaddr; @@ -96,12 +112,15 @@ int sk; bdaddr_t bdaddr; char name[249]; - uint8_t eir[240]; + uint8_t eir[HCI_MAX_EIR_LENGTH]; uint8_t features[8]; + uint8_t extfeatures[8]; uint8_t ssp_mode; int8_t tx_power; + int discov_state; + uint32_t current_cod; uint32_t wanted_cod; uint32_t pending_cod; @@ -133,8 +152,85 @@ GSList *uuids; GSList *connections; + + guint stop_scan_id; } *devs = NULL; +static inline int get_state(int index) +{ + struct dev_info *dev = &devs[index]; + + return dev->discov_state; +} + +static inline gboolean is_resolvname_enabled(void) +{ + return main_opts.name_resolv ? TRUE : FALSE; +} + +static void set_state(int index, int state) +{ + struct btd_adapter *adapter; + struct dev_info *dev = &devs[index]; + + if (dev->discov_state == state) + return; + + adapter = manager_find_adapter_by_id(index); + if (!adapter) { + error("No matching adapter found"); + return; + } + + dev->discov_state = state; + + DBG("hci%d: new state %d", index, dev->discov_state); + + switch (dev->discov_state) { + case DISCOV_HALTED: + if (adapter_get_state(adapter) == STATE_SUSPENDED) + return; + + if (is_resolvname_enabled() && + adapter_has_discov_sessions(adapter)) + adapter_set_state(adapter, STATE_RESOLVNAME); + else + adapter_set_state(adapter, STATE_IDLE); + break; + case DISCOV_INQ: + case DISCOV_SCAN: + adapter_set_state(adapter, STATE_DISCOV); + break; + } +} + +static inline gboolean is_le_capable(int index) +{ + struct dev_info *dev = &devs[index]; + + return (main_opts.le && dev->features[4] & LMP_LE && + dev->extfeatures[0] & LMP_HOST_LE) ? TRUE : FALSE; +} + +static inline gboolean is_bredr_capable(int index) +{ + struct dev_info *dev = &devs[index]; + + return (dev->features[4] & LMP_NO_BREDR) == 0 ? TRUE : FALSE; +} + +static int get_adapter_type(int index) +{ + if (is_le_capable(index) && is_bredr_capable(index)) + return BR_EDR_LE; + else if (is_le_capable(index)) + return LE_ONLY; + else if (is_bredr_capable(index)) + return BR_EDR; + + return UNKNOWN; +} + static int ignore_device(struct hci_dev_info *di) { return hci_test_bit(HCI_RAW, &di->flags) || di->type >> 4 != HCI_BREDR; @@ -153,6 +249,7 @@ dev->registered = registered; dev->already_up = already_up; dev->io_capability = 0x03; /* No Input No Output */ + dev->discov_state = DISCOV_HALTED; return dev; } @@ -472,24 +569,13 @@ static int hciops_stop_inquiry(int index) { struct dev_info *dev = &devs[index]; - struct hci_dev_info di; - int err; DBG("hci%d", index); - if (hci_devinfo(index, &di) < 0) + if (hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_INQUIRY_CANCEL, 0, 0) < 0) return -errno; - if (hci_test_bit(HCI_INQUIRY, &di.flags)) - err = hci_send_cmd(dev->sk, OGF_LINK_CTL, - OCF_INQUIRY_CANCEL, 0, 0); - else - err = hci_send_cmd(dev->sk, OGF_LINK_CTL, - OCF_EXIT_PERIODIC_INQUIRY, 0, 0); - if (err < 0) - err = -errno; - - return err; + return 0; } static gboolean init_adapter(int index) @@ -873,7 +959,7 @@ /* Some buggy controller combinations generate a changed * combination key for legacy pairing even when there's no * previous key */ - if ((!conn || conn->rem_auth == 0xff) && old_key_type == 0xff) + if (conn->rem_auth == 0xff && old_key_type == 0xff) key_type = 0x00; else if (old_key_type != 0xff) key_type = old_key_type; @@ -1259,7 +1345,7 @@ goto reject; } - err = btd_event_request_pin(&dev->bdaddr, dba); + err = btd_event_request_pin(&dev->bdaddr, dba, FALSE); if (err < 0) { error("PIN code negative reply: %s", strerror(-err)); goto reject; @@ -1271,56 +1357,6 @@ hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba); } -static void start_inquiry(bdaddr_t *local, uint8_t status, gboolean periodic) -{ - struct btd_adapter *adapter; - int state; - - /* Don't send the signal if the cmd failed */ - if (status) { - error("Inquiry Failed with status 0x%02x", status); - return; - } - - adapter = manager_find_adapter(local); - if (!adapter) { - error("Unable to find matching adapter"); - return; - } - - state = adapter_get_state(adapter); - - if (periodic) - state |= STATE_PINQ; - else - state |= STATE_STDINQ; - - adapter_set_state(adapter, state); -} - -static void inquiry_complete(bdaddr_t *local, uint8_t status, - gboolean periodic) -{ - struct btd_adapter *adapter; - int state; - - /* Don't send the signal if the cmd failed */ - if (status) { - error("Inquiry Failed with status 0x%02x", status); - return; - } - - adapter = manager_find_adapter(local); - if (!adapter) { - error("Unable to find matching adapter"); - return; - } - - state = adapter_get_state(adapter); - state &= ~(STATE_STDINQ | STATE_PINQ); - adapter_set_state(adapter, state); -} - static inline void remote_features_notify(int index, void *ptr) { struct dev_info *dev = &devs[index]; @@ -1396,167 +1432,6 @@ init_adapter(index); } -#define SIZEOF_UUID128 16 - -static void eir_generate_uuid128(GSList *list, uint8_t *ptr, uint16_t *eir_len) -{ - int i, k, uuid_count = 0; - uint16_t len = *eir_len; - uint8_t *uuid128; - gboolean truncated = FALSE; - - /* Store UUIDs in place, skip 2 bytes to write type and length later */ - uuid128 = ptr + 2; - - for (; list; list = list->next) { - struct uuid_info *uuid = list->data; - uint8_t *uuid128_data = uuid->uuid.value.uuid128.data; - - if (uuid->uuid.type != SDP_UUID128) - continue; - - /* Stop if not enough space to put next UUID128 */ - if ((len + 2 + SIZEOF_UUID128) > EIR_DATA_LENGTH) { - truncated = TRUE; - break; - } - - /* Check for duplicates, EIR data is Little Endian */ - for (i = 0; i < uuid_count; i++) { - for (k = 0; k < SIZEOF_UUID128; k++) { - if (uuid128[i * SIZEOF_UUID128 + k] != - uuid128_data[SIZEOF_UUID128 - 1 - k]) - break; - } - if (k == SIZEOF_UUID128) - break; - } - - if (i < uuid_count) - continue; - - /* EIR data is Little Endian */ - for (k = 0; k < SIZEOF_UUID128; k++) - uuid128[uuid_count * SIZEOF_UUID128 + k] = - uuid128_data[SIZEOF_UUID128 - 1 - k]; - - len += SIZEOF_UUID128; - uuid_count++; - } - - if (uuid_count > 0 || truncated) { - /* EIR Data length */ - ptr[0] = (uuid_count * SIZEOF_UUID128) + 1; - /* EIR Data type */ - ptr[1] = truncated ? EIR_UUID128_SOME : EIR_UUID128_ALL; - len += 2; - *eir_len = len; - } -} - -static void create_ext_inquiry_response(int index, uint8_t *data) -{ - struct dev_info *dev = &devs[index]; - GSList *l; - uint8_t *ptr = data; - uint16_t eir_len = 0; - uint16_t uuid16[EIR_DATA_LENGTH / 2]; - int i, uuid_count = 0; - gboolean truncated = FALSE; - size_t name_len; - - name_len = strlen(dev->name); - - if (name_len > 0) { - /* EIR Data type */ - if (name_len > 48) { - name_len = 48; - ptr[1] = EIR_NAME_SHORT; - } else - ptr[1] = EIR_NAME_COMPLETE; - - /* EIR Data length */ - ptr[0] = name_len + 1; - - memcpy(ptr + 2, dev->name, name_len); - - eir_len += (name_len + 2); - ptr += (name_len + 2); - } - - if (dev->tx_power != 0) { - *ptr++ = 2; - *ptr++ = EIR_TX_POWER; - *ptr++ = (uint8_t) dev->tx_power; - eir_len += 3; - } - - if (dev->did_vendor != 0x0000) { - uint16_t source = 0x0002; - *ptr++ = 9; - *ptr++ = EIR_DEVICE_ID; - *ptr++ = (source & 0x00ff); - *ptr++ = (source & 0xff00) >> 8; - *ptr++ = (dev->did_vendor & 0x00ff); - *ptr++ = (dev->did_vendor & 0xff00) >> 8; - *ptr++ = (dev->did_product & 0x00ff); - *ptr++ = (dev->did_product & 0xff00) >> 8; - *ptr++ = (dev->did_version & 0x00ff); - *ptr++ = (dev->did_version & 0xff00) >> 8; - eir_len += 10; - } - - /* Group all UUID16 types */ - for (l = dev->uuids; l != NULL; l = g_slist_next(l)) { - struct uuid_info *uuid = l->data; - - if (uuid->uuid.type != SDP_UUID16) - continue; - - if (uuid->uuid.value.uuid16 < 0x1100) - continue; - - if (uuid->uuid.value.uuid16 == PNP_INFO_SVCLASS_ID) - continue; - - /* Stop if not enough space to put next UUID16 */ - if ((eir_len + 2 + sizeof(uint16_t)) > EIR_DATA_LENGTH) { - truncated = TRUE; - break; - } - - /* Check for duplicates */ - for (i = 0; i < uuid_count; i++) - if (uuid16[i] == uuid->uuid.value.uuid16) - break; - - if (i < uuid_count) - continue; - - uuid16[uuid_count++] = uuid->uuid.value.uuid16; - eir_len += sizeof(uint16_t); - } - - if (uuid_count > 0) { - /* EIR Data length */ - ptr[0] = (uuid_count * sizeof(uint16_t)) + 1; - /* EIR Data type */ - ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL; - - ptr += 2; - eir_len += 2; - - for (i = 0; i < uuid_count; i++) { - *ptr++ = (uuid16[i] & 0x00ff); - *ptr++ = (uuid16[i] & 0xff00) >> 8; - } - } - - /* Group all UUID128 types */ - if (eir_len <= EIR_DATA_LENGTH - 2) - eir_generate_uuid128(dev->uuids, ptr, &eir_len); -} - static void update_ext_inquiry_response(int index) { struct dev_info *dev = &devs[index]; @@ -1575,7 +1450,8 @@ memset(&cp, 0, sizeof(cp)); - create_ext_inquiry_response(index, cp.data); + eir_create(dev->name, dev->tx_power, dev->did_vendor, dev->did_product, + dev->did_version, dev->uuids, cp.data); if (memcmp(cp.data, dev->eir, sizeof(cp.data)) == 0) return; @@ -1658,7 +1534,6 @@ { struct dev_info *dev = &devs[index]; read_simple_pairing_mode_rp *rp = ptr; - struct btd_adapter *adapter; DBG("hci%d status %u", index, rp->status); @@ -1667,37 +1542,23 @@ dev->ssp_mode = rp->mode; update_ext_inquiry_response(index); - - adapter = manager_find_adapter(&dev->bdaddr); - if (!adapter) { - error("No matching adapter found"); - return; - } - - adapter_update_ssp_mode(adapter, rp->mode); } static void read_local_ext_features_complete(int index, const read_local_ext_features_rp *rp) { - struct btd_adapter *adapter; + struct dev_info *dev = &devs[index]; DBG("hci%d status %u", index, rp->status); if (rp->status) return; - adapter = manager_find_adapter_by_id(index); - if (!adapter) { - error("No matching adapter found"); - return; - } - /* Local Extended feature page number is 1 */ if (rp->page_num != 1) return; - btd_adapter_update_local_ext_features(adapter, rp->features); + memcpy(dev->extfeatures, rp->features, sizeof(dev->extfeatures)); } static void read_bd_addr_complete(int index, read_bd_addr_rp *rp) @@ -1722,14 +1583,23 @@ init_adapter(index); } +static inline void cs_inquiry_evt(int index, uint8_t status) +{ + if (status) { + error("Inquiry Failed with status 0x%02x", status); + return; + } + + set_state(index, DISCOV_INQ); +} + static inline void cmd_status(int index, void *ptr) { - struct dev_info *dev = &devs[index]; evt_cmd_status *evt = ptr; uint16_t opcode = btohs(evt->opcode); if (opcode == cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY)) - start_inquiry(&dev->bdaddr, evt->status, FALSE); + cs_inquiry_evt(index, evt->status); } static void read_scan_complete(int index, uint8_t status, void *ptr) @@ -1850,6 +1720,60 @@ oob_read_local_data_complete(adapter, rp->hash, rp->randomizer); } +static inline void inquiry_complete_evt(int index, uint8_t status) +{ + int adapter_type; + struct btd_adapter *adapter; + + if (status) { + error("Inquiry Failed with status 0x%02x", status); + return; + } + + adapter = manager_find_adapter_by_id(index); + if (!adapter) { + error("No matching adapter found"); + return; + } + + adapter_type = get_adapter_type(index); + + if (adapter_type == BR_EDR_LE && + adapter_has_discov_sessions(adapter)) { + int err = hciops_start_scanning(index, TIMEOUT_BR_LE_SCAN); + if (err < 0) + set_state(index, DISCOV_HALTED); + } else { + set_state(index, DISCOV_HALTED); + } +} + +static inline void cc_inquiry_cancel(int index, uint8_t status) +{ + if (status) { + error("Inquiry Cancel Failed with status 0x%02x", status); + return; + } + + set_state(index, DISCOV_HALTED); +} + +static inline void cc_le_set_scan_enable(int index, uint8_t status) +{ + int state; + + if (status) { + error("LE Set Scan Enable Failed with status 0x%02x", status); + return; + } + + state = get_state(index); + if (state == DISCOV_SCAN) + set_state(index, DISCOV_HALTED); + else + set_state(index, DISCOV_SCAN); +} + static inline void cmd_complete(int index, void *ptr) { struct dev_info *dev = &devs[index]; @@ -1874,20 +1798,14 @@ ptr += sizeof(evt_cmd_complete); read_bd_addr_complete(index, ptr); break; - case cmd_opcode_pack(OGF_LINK_CTL, OCF_PERIODIC_INQUIRY): - start_inquiry(&dev->bdaddr, status, TRUE); - break; - case cmd_opcode_pack(OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY): - inquiry_complete(&dev->bdaddr, status, TRUE); - break; case cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL): - inquiry_complete(&dev->bdaddr, status, FALSE); + cc_inquiry_cancel(index, status); break; case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_LE_HOST_SUPPORTED): write_le_host_complete(index, status); break; case cmd_opcode_pack(OGF_LE_CTL, OCF_LE_SET_SCAN_ENABLE): - btd_event_le_set_scan_enable_complete(&dev->bdaddr, status); + cc_le_set_scan_enable(index, status); break; case cmd_opcode_pack(OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME): if (!status) @@ -1972,6 +1890,10 @@ uint8_t num = *(uint8_t *) ptr++; int i; + /* Skip if it is not in Inquiry state */ + if (get_state(index) != DISCOV_INQ) + return; + for (i = 0; i < num; i++) { inquiry_info *info = ptr; uint32_t class = info->dev_class[0] | @@ -2250,19 +2172,31 @@ { struct dev_info *dev = &devs[index]; le_advertising_info *info; - uint8_t num_reports; + uint8_t num_reports, rssi, eir[HCI_MAX_EIR_LENGTH]; const uint8_t RSSI_SIZE = 1; num_reports = meta->data[0]; info = (le_advertising_info *) &meta->data[1]; - btd_event_advertising_report(&dev->bdaddr, info); + rssi = *(info->data + info->length); + + memset(eir, 0, sizeof(eir)); + memcpy(eir, info->data, info->length); + + btd_event_device_found(&dev->bdaddr, &info->bdaddr, 0, rssi, eir); + num_reports--; while (num_reports--) { info = (le_advertising_info *) (info->data + info->length + RSSI_SIZE); - btd_event_advertising_report(&dev->bdaddr, info); + rssi = *(info->data + info->length); + + memset(eir, 0, sizeof(eir)); + memcpy(eir, info->data, info->length); + + btd_event_device_found(&dev->bdaddr, &info->bdaddr, 0, rssi, + eir); } } @@ -2295,19 +2229,17 @@ if (dev->watch_id > 0) g_source_remove(dev->watch_id); + if (dev->stop_scan_id > 0) + g_source_remove(dev->stop_scan_id); + if (dev->io != NULL) g_io_channel_unref(dev->io); hci_close_dev(dev->sk); - g_slist_foreach(dev->keys, (GFunc) g_free, NULL); - g_slist_free(dev->keys); - - g_slist_foreach(dev->uuids, (GFunc) g_free, NULL); - g_slist_free(dev->uuids); - - g_slist_foreach(dev->connections, (GFunc) conn_free, NULL); - g_slist_free(dev->connections); + g_slist_free_full(dev->keys, g_free); + g_slist_free_full(dev->uuids, g_free); + g_slist_free_full(dev->connections, g_free); init_dev_info(index, -1, dev->registered, dev->already_up); } @@ -2382,7 +2314,7 @@ case EVT_INQUIRY_COMPLETE: evt = (evt_cmd_status *) ptr; - inquiry_complete(&dev->bdaddr, evt->status, FALSE); + inquiry_complete_evt(index, evt->status); break; case EVT_INQUIRY_RESULT: @@ -2666,7 +2598,7 @@ struct dev_info *dev = &devs[index]; struct hci_conn_list_req *cl; struct hci_conn_info *ci; - int err, i; + int i; DBG("hci%d", index); @@ -2692,8 +2624,6 @@ conn->handle = ci->handle; } - err = 0; - failed: g_free(cl); } @@ -2985,43 +2915,24 @@ return err; } -static int hciops_start_inquiry(int index, uint8_t length, gboolean periodic) +static int hciops_start_inquiry(int index, uint8_t length) { struct dev_info *dev = &devs[index]; uint8_t lap[3] = { 0x33, 0x8b, 0x9e }; - int err; - - DBG("hci%d length %u periodic %d", index, length, periodic); - - if (periodic) { - periodic_inquiry_cp cp; - - memset(&cp, 0, sizeof(cp)); - memcpy(&cp.lap, lap, 3); - cp.max_period = htobs(24); - cp.min_period = htobs(16); - cp.length = length; - cp.num_rsp = 0x00; + inquiry_cp inq_cp; - err = hci_send_cmd(dev->sk, OGF_LINK_CTL, - OCF_PERIODIC_INQUIRY, - PERIODIC_INQUIRY_CP_SIZE, &cp); - } else { - inquiry_cp inq_cp; + DBG("hci%d length %u", index, length); - memset(&inq_cp, 0, sizeof(inq_cp)); - memcpy(&inq_cp.lap, lap, 3); - inq_cp.length = length; - inq_cp.num_rsp = 0x00; + memset(&inq_cp, 0, sizeof(inq_cp)); + memcpy(&inq_cp.lap, lap, 3); + inq_cp.length = length; + inq_cp.num_rsp = 0x00; - err = hci_send_cmd(dev->sk, OGF_LINK_CTL, - OCF_INQUIRY, INQUIRY_CP_SIZE, &inq_cp); - } - - if (err < 0) - err = -errno; + if (hci_send_cmd(dev->sk, OGF_LINK_CTL, + OCF_INQUIRY, INQUIRY_CP_SIZE, &inq_cp) < 0) + return -errno; - return err; + return 0; } static int le_set_scan_enable(int index, uint8_t enable) @@ -3042,10 +2953,25 @@ return 0; } -static int hciops_start_scanning(int index) +static gboolean stop_le_scan_cb(gpointer user_data) +{ + struct dev_info *dev = user_data; + int err; + + err = le_set_scan_enable(dev->id, 0); + if (err < 0) + return TRUE; + + dev->stop_scan_id = 0; + + return FALSE; +} + +static int hciops_start_scanning(int index, int timeout) { struct dev_info *dev = &devs[index]; le_set_scan_parameters_cp cp; + int err; DBG("hci%d", index); @@ -3062,13 +2988,27 @@ LE_SET_SCAN_PARAMETERS_CP_SIZE, &cp) < 0) return -errno; - return le_set_scan_enable(index, 1); + err = le_set_scan_enable(index, 1); + if (err < 0) + return err; + + /* Schedule a le scan disable in 'timeout' milliseconds */ + dev->stop_scan_id = g_timeout_add(timeout, stop_le_scan_cb, dev); + + return 0; } static int hciops_stop_scanning(int index) { + struct dev_info *dev = &devs[index]; + DBG("hci%d", index); + if (dev->stop_scan_id > 0) { + g_source_remove(dev->stop_scan_id); + dev->stop_scan_id = 0; + } + return le_set_scan_enable(index, 0); } @@ -3131,6 +3071,38 @@ return 0; } +static int hciops_start_discovery(int index) +{ + int adapter_type = get_adapter_type(index); + + switch (adapter_type) { + case BR_EDR_LE: + return hciops_start_inquiry(index, LENGTH_BR_LE_INQ); + case BR_EDR: + return hciops_start_inquiry(index, LENGTH_BR_INQ); + case LE_ONLY: + return hciops_start_scanning(index, TIMEOUT_LE_SCAN); + default: + return -EINVAL; + } +} + +static int hciops_stop_discovery(int index) +{ + struct dev_info *dev = &devs[index]; + + DBG("index %d", index); + + switch (dev->discov_state) { + case DISCOV_INQ: + return hciops_stop_inquiry(index); + case DISCOV_SCAN: + return hciops_stop_scanning(index); + default: + return -EINVAL; + } +} + static int hciops_fast_connectable(int index, gboolean enable) { struct dev_info *dev = &devs[index]; @@ -3240,28 +3212,6 @@ return 0; } -static int hciops_read_local_version(int index, struct hci_version *ver) -{ - struct dev_info *dev = &devs[index]; - - DBG("hci%d", index); - - memcpy(ver, &dev->ver, sizeof(*ver)); - - return 0; -} - -static int hciops_read_local_features(int index, uint8_t *features) -{ - struct dev_info *dev = &devs[index]; - - DBG("hci%d", index); - - memcpy(features, dev->features, 8); - - return 0; -} - static int hciops_disconnect(int index, bdaddr_t *bdaddr) { DBG("hci%d", index); @@ -3296,7 +3246,8 @@ return 0; } -static int hciops_pincode_reply(int index, bdaddr_t *bdaddr, const char *pin) +static int hciops_pincode_reply(int index, bdaddr_t *bdaddr, const char *pin, + size_t pin_len) { struct dev_info *dev = &devs[index]; char addr[18]; @@ -3307,14 +3258,13 @@ if (pin) { pin_code_reply_cp pr; - size_t len = strlen(pin); - dev->pin_length = len; + dev->pin_length = pin_len; memset(&pr, 0, sizeof(pr)); bacpy(&pr.bdaddr, bdaddr); - memcpy(pr.pin_code, pin, len); - pr.pin_len = len; + memcpy(pr.pin_code, pin, pin_len); + pr.pin_len = pin_len; err = hci_send_cmd(dev->sk, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr); @@ -3691,10 +3641,8 @@ .set_discoverable = hciops_set_discoverable, .set_pairable = hciops_set_pairable, .set_limited_discoverable = hciops_set_limited_discoverable, - .start_inquiry = hciops_start_inquiry, - .stop_inquiry = hciops_stop_inquiry, - .start_scanning = hciops_start_scanning, - .stop_scanning = hciops_stop_scanning, + .start_discovery = hciops_start_discovery, + .stop_discovery = hciops_stop_discovery, .resolve_name = hciops_resolve_name, .cancel_resolve_name = hciops_cancel_resolve_name, .set_name = hciops_set_name, @@ -3705,8 +3653,6 @@ .block_device = hciops_block_device, .unblock_device = hciops_unblock_device, .get_conn_list = hciops_get_conn_list, - .read_local_version = hciops_read_local_version, - .read_local_features = hciops_read_local_features, .disconnect = hciops_disconnect, .remove_bonding = hciops_remove_bonding, .pincode_reply = hciops_pincode_reply, diff -Nru bluez-4.91/plugins/mgmtops.c bluez-4.96/plugins/mgmtops.c --- bluez-4.91/plugins/mgmtops.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/plugins/mgmtops.c 2011-07-04 04:59:05.000000000 +0000 @@ -207,7 +207,7 @@ { struct controller_info *info; struct btd_adapter *adapter; - gboolean pairable, discoverable; + gboolean pairable; uint8_t on_mode; if (index > max_index) { @@ -238,8 +238,6 @@ btd_adapter_get_mode(adapter, NULL, &on_mode, &pairable); - discoverable = (on_mode == MODE_DISCOVERABLE); - if (on_mode == MODE_DISCOVERABLE && !info->discoverable) mgmt_set_discoverable(index, TRUE); else if (on_mode == MODE_CONNECTABLE && !info->connectable) @@ -407,9 +405,10 @@ info = &controllers[index]; - btd_event_link_key_notify(&info->bdaddr, &ev->key.bdaddr, - ev->key.val, ev->key.type, - ev->key.pin_len); + if (ev->store_hint) + btd_event_link_key_notify(&info->bdaddr, &ev->key.bdaddr, + ev->key.val, ev->key.type, + ev->key.pin_len); btd_event_bonding_complete(&info->bdaddr, &ev->key.bdaddr, 0); } @@ -493,7 +492,8 @@ btd_event_bonding_complete(&info->bdaddr, &ev->bdaddr, ev->status); } -static int mgmt_pincode_reply(int index, bdaddr_t *bdaddr, const char *pin) +static int mgmt_pincode_reply(int index, bdaddr_t *bdaddr, const char *pin, + size_t pin_len) { char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_pin_code_reply)]; struct mgmt_hdr *hdr = (void *) buf; @@ -501,7 +501,7 @@ char addr[18]; ba2str(bdaddr, addr); - DBG("index %d addr %s pin %s", index, addr, pin ? pin : ""); + DBG("index %d addr %s pinlen %zu", index, addr, pin_len); memset(buf, 0, sizeof(buf)); @@ -518,9 +518,7 @@ buf_len = sizeof(*hdr) + sizeof(*cp); } else { struct mgmt_cp_pin_code_reply *cp; - size_t pin_len; - pin_len = strlen(pin); if (pin_len > 16) return -EINVAL; @@ -565,10 +563,10 @@ info = &controllers[index]; - err = btd_event_request_pin(&info->bdaddr, &ev->bdaddr); + err = btd_event_request_pin(&info->bdaddr, &ev->bdaddr, ev->secure); if (err < 0) { error("btd_event_request_pin: %s", strerror(-err)); - mgmt_pincode_reply(index, &ev->bdaddr, NULL); + mgmt_pincode_reply(index, &ev->bdaddr, NULL, 0); } } @@ -601,6 +599,26 @@ return 0; } +struct confirm_data { + int index; + bdaddr_t bdaddr; +}; + +static gboolean confirm_accept(gpointer user_data) +{ + struct confirm_data *data = user_data; + struct controller_info *info = &controllers[data->index]; + + DBG("auto-accepting incoming pairing request"); + + if (data->index > max_index || !info->valid) + return FALSE; + + mgmt_confirm_reply(data->index, &data->bdaddr, TRUE); + + return FALSE; +} + static void mgmt_user_confirm_request(int sk, uint16_t index, void *buf, size_t len) { @@ -616,7 +634,7 @@ ba2str(&ev->bdaddr, addr); - DBG("hci%u %s", index, addr); + DBG("hci%u %s confirm_hint %u", index, addr, ev->confirm_hint); if (index > max_index) { error("Unexpected index %u in user_confirm_request event", @@ -624,6 +642,18 @@ return; } + if (ev->confirm_hint) { + struct confirm_data *data; + + data = g_new0(struct confirm_data, 1); + data->index = index; + bacpy(&data->bdaddr, &ev->bdaddr); + + g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, 1, + confirm_accept, data, g_free); + return; + } + info = &controllers[index]; err = btd_event_user_confirm(&info->bdaddr, &ev->bdaddr, @@ -1171,6 +1201,12 @@ case MGMT_OP_REMOVE_REMOTE_OOB_DATA: DBG("remove_remote_oob_data complete"); break; + case MGMT_OP_BLOCK_DEVICE: + DBG("block_device complete"); + break; + case MGMT_OP_UNBLOCK_DEVICE: + DBG("unblock_device complete"); + break; default: error("Unknown command complete for opcode %u", opcode); break; @@ -1257,6 +1293,98 @@ adapter_update_local_name(adapter, (char *) ev->name); } +static void mgmt_device_found(int sk, uint16_t index, void *buf, size_t len) +{ + struct mgmt_ev_device_found *ev = buf; + struct controller_info *info; + char addr[18]; + uint8_t *eir; + uint32_t cls; + + if (len < sizeof(*ev)) { + error("Too small mgmt_device_found event packet"); + return; + } + + if (index > max_index) { + error("Unexpected index %u in device_found event", index); + return; + } + + info = &controllers[index]; + + cls = ev->dev_class[0] | (ev->dev_class[1] << 8) | + (ev->dev_class[2] << 16); + + if (ev->eir[0] == 0) + eir = NULL; + else + eir = ev->eir; + + ba2str(&ev->bdaddr, addr); + DBG("hci%u addr %s, class %u rssi %d %s", index, addr, cls, + ev->rssi, eir ? "eir" : ""); + + btd_event_device_found(&info->bdaddr, &ev->bdaddr, cls, ev->rssi, eir); +} + +static void mgmt_remote_name(int sk, uint16_t index, void *buf, size_t len) +{ + struct mgmt_ev_remote_name *ev = buf; + struct controller_info *info; + char addr[18]; + + if (len < sizeof(*ev)) { + error("Too small mgmt_remote_name packet"); + return; + } + + if (index > max_index) { + error("Unexpected index %u in remote_name event", index); + return; + } + + info = &controllers[index]; + + ba2str(&ev->bdaddr, addr); + DBG("hci%u addr %s, name %s", index, addr, ev->name); + + btd_event_remote_name(&info->bdaddr, &ev->bdaddr, 0, (char *) ev->name); +} + +static void mgmt_discovering(int sk, uint16_t index, void *buf, size_t len) +{ + struct mgmt_mode *ev = buf; + struct controller_info *info; + struct btd_adapter *adapter; + int state; + + if (len < sizeof(*ev)) { + error("Too small discovering event"); + return; + } + + DBG("Controller %u discovering %u", index, ev->val); + + if (index > max_index) { + error("Unexpected index %u in discovering event", index); + return; + } + + info = &controllers[index]; + + adapter = manager_find_adapter(&info->bdaddr); + if (!adapter) + return; + + if (ev->val) + state = STATE_DISCOV; + else + state = STATE_IDLE; + + adapter_set_state(adapter, state); +} + static gboolean mgmt_event(GIOChannel *io, GIOCondition cond, gpointer user_data) { char buf[MGMT_BUF_SIZE]; @@ -1352,6 +1480,15 @@ case MGMT_EV_LOCAL_NAME_CHANGED: mgmt_local_name_changed(sk, index, buf + MGMT_HDR_SIZE, len); break; + case MGMT_EV_DEVICE_FOUND: + mgmt_device_found(sk, index, buf + MGMT_HDR_SIZE, len); + break; + case MGMT_EV_REMOTE_NAME: + mgmt_remote_name(sk, index, buf + MGMT_HDR_SIZE, len); + break; + case MGMT_EV_DISCOVERING: + mgmt_discovering(sk, index, buf + MGMT_HDR_SIZE, len); + break; default: error("Unknown Management opcode %u (index %u)", opcode, index); break; @@ -1451,28 +1588,36 @@ return -ENOSYS; } -static int mgmt_start_inquiry(int index, uint8_t length, gboolean periodic) +static int mgmt_start_discovery(int index) { - DBG("index %d length %u periodic %d", index, length, periodic); - return -ENOSYS; -} + struct mgmt_hdr hdr; -static int mgmt_stop_inquiry(int index) -{ DBG("index %d", index); - return -ENOSYS; -} -static int mgmt_start_scanning(int index) -{ - DBG("index %d", index); - return -ENOSYS; + memset(&hdr, 0, sizeof(hdr)); + hdr.opcode = htobs(MGMT_OP_START_DISCOVERY); + hdr.index = htobs(index); + + if (write(mgmt_sock, &hdr, sizeof(hdr)) < 0) + return -errno; + + return 0; } -static int mgmt_stop_scanning(int index) +static int mgmt_stop_discovery(int index) { + struct mgmt_hdr hdr; + DBG("index %d", index); - return -ENOSYS; + + memset(&hdr, 0, sizeof(hdr)); + hdr.opcode = htobs(MGMT_OP_STOP_DISCOVERY); + hdr.index = htobs(index); + + if (write(mgmt_sock, &hdr, sizeof(hdr)) < 0) + return -errno; + + return 0; } static int mgmt_resolve_name(int index, bdaddr_t *bdaddr) @@ -1552,63 +1697,68 @@ static int mgmt_block_device(int index, bdaddr_t *bdaddr) { + char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_block_device)]; + struct mgmt_hdr *hdr = (void *) buf; + struct mgmt_cp_block_device *cp; + size_t buf_len; char addr[18]; ba2str(bdaddr, addr); DBG("index %d addr %s", index, addr); - return -ENOSYS; + memset(buf, 0, sizeof(buf)); + + hdr->opcode = htobs(MGMT_OP_BLOCK_DEVICE); + hdr->len = htobs(sizeof(*cp)); + hdr->index = htobs(index); + + cp = (void *) &buf[sizeof(*hdr)]; + bacpy(&cp->bdaddr, bdaddr); + + buf_len = sizeof(*hdr) + sizeof(*cp); + + if (write(mgmt_sock, buf, buf_len) < 0) + return -errno; + + return 0; } static int mgmt_unblock_device(int index, bdaddr_t *bdaddr) { + char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_unblock_device)]; + struct mgmt_hdr *hdr = (void *) buf; + struct mgmt_cp_unblock_device *cp; + size_t buf_len; char addr[18]; ba2str(bdaddr, addr); DBG("index %d addr %s", index, addr); - return -ENOSYS; -} - -static int mgmt_get_conn_list(int index, GSList **conns) -{ - struct controller_info *info = &controllers[index]; - - DBG("index %d", index); - - *conns = info->connections; - info->connections = NULL; - - return 0; -} + memset(buf, 0, sizeof(buf)); -static int mgmt_read_local_version(int index, struct hci_version *ver) -{ - struct controller_info *info = &controllers[index]; + hdr->opcode = htobs(MGMT_OP_UNBLOCK_DEVICE); + hdr->len = htobs(sizeof(*cp)); + hdr->index = htobs(index); - DBG("index %d", index); + cp = (void *) &buf[sizeof(*hdr)]; + bacpy(&cp->bdaddr, bdaddr); - if (!info->valid) - return -ENODEV; + buf_len = sizeof(*hdr) + sizeof(*cp); - memset(ver, 0, sizeof(*ver)); - ver->manufacturer = info->manufacturer; - ver->hci_ver = info->hci_ver; - ver->hci_rev = info->hci_rev; + if (write(mgmt_sock, buf, buf_len) < 0) + return -errno; return 0; } -static int mgmt_read_local_features(int index, uint8_t *features) +static int mgmt_get_conn_list(int index, GSList **conns) { struct controller_info *info = &controllers[index]; DBG("index %d", index); - if (!info->valid) - return -ENODEV; - - memcpy(features, info->features, 8); + *conns = info->connections; + info->connections = NULL; return 0; } @@ -1886,10 +2036,8 @@ .set_discoverable = mgmt_set_discoverable, .set_pairable = mgmt_set_pairable, .set_limited_discoverable = mgmt_set_limited_discoverable, - .start_inquiry = mgmt_start_inquiry, - .stop_inquiry = mgmt_stop_inquiry, - .start_scanning = mgmt_start_scanning, - .stop_scanning = mgmt_stop_scanning, + .start_discovery = mgmt_start_discovery, + .stop_discovery = mgmt_stop_discovery, .resolve_name = mgmt_resolve_name, .cancel_resolve_name = mgmt_cancel_resolve_name, .set_name = mgmt_set_name, @@ -1900,8 +2048,6 @@ .block_device = mgmt_block_device, .unblock_device = mgmt_unblock_device, .get_conn_list = mgmt_get_conn_list, - .read_local_version = mgmt_read_local_version, - .read_local_features = mgmt_read_local_features, .disconnect = mgmt_disconnect, .remove_bonding = mgmt_remove_bonding, .pincode_reply = mgmt_pincode_reply, diff -Nru bluez-4.91/plugins/wiimote.c bluez-4.96/plugins/wiimote.c --- bluez-4.91/plugins/wiimote.c 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/plugins/wiimote.c 2011-07-31 06:52:19.000000000 +0000 @@ -0,0 +1,111 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 David Herrmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "plugin.h" +#include "adapter.h" +#include "device.h" +#include "log.h" +#include "storage.h" + +/* + * Nintendo Wii Remote devices require the bdaddr of the host as pin input for + * authentication. This plugin registers a pin-callback and forces this pin + * to be used for authentication. + * + * There are two ways to place the wiimote into discoverable mode. + * - Pressing the red-sync button on the back of the wiimote. This module + * supports pairing via this method. Auto-reconnect should be possible after + * the device was paired once. + * - Pressing the 1+2 buttons on the front of the wiimote. This module does + * not support this method since this method never enables auto-reconnect. + * Hence, pairing is not needed. Use it without pairing if you want. + * After connecting the wiimote you should immediately connect to the input + * service of the wiimote. If you don't, the wiimote will close the connection. + * The wiimote waits about 5 seconds until it turns off again. + * Auto-reconnect is only enabled when pairing with the wiimote via the red + * sync-button and then connecting to the input service. If you do not connect + * to the input service, then auto-reconnect is not enabled. + * If enabled, the wiimote connects to the host automatically when any button + * is pressed. + */ + +static ssize_t wii_pincb(struct btd_adapter *adapter, struct btd_device *device, + char *pinbuf) +{ + uint16_t vendor, product; + bdaddr_t sba, dba; + char src_addr[18], dst_addr[18]; + + adapter_get_address(adapter, &sba); + device_get_address(device, &dba); + ba2str(&sba, src_addr); + ba2str(&dba, dst_addr); + + if (0 == read_device_id(src_addr, dst_addr, NULL, &vendor, &product, + NULL)) { + if (vendor == 0x057e && product == 0x0306) { + DBG("Forcing fixed pin on detected wiimote %s", dst_addr); + memcpy(pinbuf, &sba, 6); + return 6; + } + } + + return 0; +} + +static int wii_probe(struct btd_adapter *adapter) +{ + btd_adapter_register_pin_cb(adapter, wii_pincb); + + return 0; +} + +static void wii_remove(struct btd_adapter *adapter) +{ + btd_adapter_unregister_pin_cb(adapter, wii_pincb); +} + +static struct btd_adapter_driver wii_driver = { + .name = "wiimote", + .probe = wii_probe, + .remove = wii_remove, +}; + +static int wii_init(void) +{ + return btd_register_adapter_driver(&wii_driver); +} + +static void wii_exit(void) +{ + btd_unregister_adapter_driver(&wii_driver); +} + +BLUETOOTH_PLUGIN_DEFINE(wiimote, VERSION, + BLUETOOTH_PLUGIN_PRIORITY_LOW, wii_init, wii_exit) diff -Nru bluez-4.91/proximity/main.c bluez-4.96/proximity/main.c --- bluez-4.91/proximity/main.c 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/proximity/main.c 2011-07-31 06:52:19.000000000 +0000 @@ -0,0 +1,60 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 Nokia Corporation + * Copyright (C) 2011 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include + +#include "plugin.h" +#include "manager.h" + +static DBusConnection *connection = NULL; + +static int proximity_init(void) +{ + connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (connection == NULL) + return -EIO; + + if (proximity_manager_init(connection) < 0) { + dbus_connection_unref(connection); + return -EIO; + } + + return 0; +} + +static void proximity_exit(void) +{ + proximity_manager_exit(); + dbus_connection_unref(connection); +} + +BLUETOOTH_PLUGIN_DEFINE(proximity, VERSION, + BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, + proximity_init, proximity_exit) diff -Nru bluez-4.91/proximity/manager.c bluez-4.96/proximity/manager.c --- bluez-4.91/proximity/manager.c 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/proximity/manager.c 2011-07-31 06:52:19.000000000 +0000 @@ -0,0 +1,84 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 Nokia Corporation + * Copyright (C) 2011 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include "adapter.h" +#include "device.h" +#include "monitor.h" +#include "manager.h" + +#define LINK_LOSS_UUID "00001803-0000-1000-8000-00805f9b34fb" + +static DBusConnection *connection = NULL; + +static int attio_device_probe(struct btd_device *device, GSList *uuids) +{ + return 0; +} + +static void attio_device_remove(struct btd_device *device) +{ +} + +static struct btd_device_driver monitor_driver = { + .name = "Proximity GATT Driver", + .uuids = BTD_UUIDS(LINK_LOSS_UUID), + .probe = attio_device_probe, + .remove = attio_device_remove, +}; + +int proximity_manager_init(DBusConnection *conn) +{ + int ret; + /* TODO: Add Proximity Monitor/Reporter config */ + + /* TODO: Register Proximity Monitor/Reporter drivers */ + ret = btd_register_device_driver(&monitor_driver); + if (ret < 0) + return ret; + + connection = dbus_connection_ref(conn); + + ret = monitor_register(connection); + + if (ret < 0) { + dbus_connection_unref(connection); + return ret; + } + + return 0; +} + +void proximity_manager_exit(void) +{ + monitor_unregister(connection); + btd_unregister_device_driver(&monitor_driver); + dbus_connection_unref(connection); +} diff -Nru bluez-4.91/proximity/manager.h bluez-4.96/proximity/manager.h --- bluez-4.91/proximity/manager.h 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/proximity/manager.h 2011-07-31 06:52:19.000000000 +0000 @@ -0,0 +1,26 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 Nokia Corporation + * Copyright (C) 2011 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +int proximity_manager_init(DBusConnection *conn); +void proximity_manager_exit(void); diff -Nru bluez-4.91/proximity/monitor.c bluez-4.96/proximity/monitor.c --- bluez-4.91/proximity/monitor.c 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/proximity/monitor.c 2011-07-31 06:52:19.000000000 +0000 @@ -0,0 +1,84 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 Nokia Corporation + * Copyright (C) 2011 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "log.h" + +#include "monitor.h" + +#define PROXIMITY_INTERFACE "org.bluez.Proximity" +#define PROXIMITY_PATH "/org/bluez/proximity" + +static DBusMessage *get_properties(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + return dbus_message_new_method_return(msg); +} + +static DBusMessage *set_property(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + return dbus_message_new_method_return(msg); +} + +static GDBusMethodTable monitor_methods[] = { + { "GetProperties", "", "a{sv}", get_properties }, + { "SetProperty", "sv", "", set_property, + G_DBUS_METHOD_FLAG_ASYNC}, + { } +}; + +static GDBusSignalTable monitor_signals[] = { + { "PropertyChanged", "sv" }, + { } +}; + +int monitor_register(DBusConnection *conn) +{ + int ret = -1; + + if (g_dbus_register_interface(conn, PROXIMITY_PATH, + PROXIMITY_INTERFACE, + monitor_methods, monitor_signals, + NULL, NULL, NULL) == TRUE) { + DBG("Registered interface %s on path %s", PROXIMITY_INTERFACE, + PROXIMITY_PATH); + ret = 0; + + } + + error("D-Bus failed to register %s interface", PROXIMITY_INTERFACE); + + return ret; +} + +void monitor_unregister(DBusConnection *conn) +{ + g_dbus_unregister_interface(conn, PROXIMITY_PATH, PROXIMITY_INTERFACE); +} diff -Nru bluez-4.91/proximity/monitor.h bluez-4.96/proximity/monitor.h --- bluez-4.91/proximity/monitor.h 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/proximity/monitor.h 2011-07-31 06:52:19.000000000 +0000 @@ -0,0 +1,26 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 Nokia Corporation + * Copyright (C) 2011 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +int monitor_register(DBusConnection *conn); +void monitor_unregister(DBusConnection *conn); diff -Nru bluez-4.91/sap/sap-dummy.c bluez-4.96/sap/sap-dummy.c --- bluez-4.91/sap/sap-dummy.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/sap/sap-dummy.c 2011-04-25 09:44:21.000000000 +0000 @@ -260,11 +260,15 @@ return dbus_message_new_method_return(msg); } -static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg, +static DBusMessage *disconnect_immediate(DBusConnection *conn, DBusMessage *msg, void *data) { + if (sim_card_conn_status == SIM_DISCONNECTED) + return g_dbus_create_error(msg, "org.bluez.Error.Failed", + "Already disconnected."); + sim_card_conn_status = SIM_DISCONNECTED; - sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_NOT_ACCESSIBLE); + sap_disconnect_ind(sap_data, SAP_DISCONNECTION_TYPE_IMMEDIATE); return dbus_message_new_method_return(msg); } @@ -284,15 +288,28 @@ DBUS_TYPE_INVALID)) return invalid_args(msg); - if (status) { + switch (status) { + case 0: /* card removed */ + sim_card_conn_status = SIM_MISSING; + sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_REMOVED); + break; + + case 1: /* card inserted */ if (sim_card_conn_status == SIM_MISSING) { sim_card_conn_status = SIM_CONNECTED; sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_INSERTED); } - } else { - sim_card_conn_status = SIM_MISSING; - sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_REMOVED); + break; + + case 2: /* card not longer available*/ + sim_card_conn_status = SIM_POWERED_OFF; + sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_NOT_ACCESSIBLE); + break; + + default: + return g_dbus_create_error(msg, "org.bluez.Error.Failed", + "Unknown card status. Use 0, 1 or 2."); } DBG("Card status changed to %d", status); @@ -303,7 +320,7 @@ static GDBusMethodTable dummy_methods[] = { { "OngoingCall", "b", "", ongoing_call}, { "MaxMessageSize", "u", "", max_msg_size}, - { "Disconnect", "", "", disconnect}, + { "DisconnectImmediate", "", "", disconnect_immediate}, { "CardStatus", "u", "", card_status}, { } }; diff -Nru bluez-4.91/sap/sap.h bluez-4.96/sap/sap.h --- bluez-4.91/sap/sap.h 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/sap/sap.h 2011-07-04 04:59:05.000000000 +0000 @@ -84,17 +84,6 @@ struct sap_parameter param[0]; } __attribute__((packed)); -enum { - ICC_READER_UNSPECIFIED_ERROR, /* No further information available */ - ICC_READER_NOT_PRESENT, /* Card Reader removed or not present */ - ICC_READER_BUSY, /* Card Reader in use */ - ICC_READER_CARD_POWERED_ON, /* Card in reader and is powered on */ - ICC_READER_DEACTIVATED, /* Card Reader deactivated */ - ICC_READER_CARD_POWERED_OFF, /* Card in reader, but powered off */ - ICC_READER_NO_CARD, /* No card in reader */ - ICC_READER_LAST -}; - #define SAP_BUF_SIZE 512 #define SAP_MSG_HEADER_SIZE 4 @@ -184,3 +173,4 @@ /* Event indication. Implemented by server.c*/ int sap_status_ind(void *sap_device, uint8_t status_change); +int sap_disconnect_ind(void *sap_device, uint8_t disc_type); diff -Nru bluez-4.91/sap/sap-u8500.c bluez-4.96/sap/sap-u8500.c --- bluez-4.91/sap/sap-u8500.c 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/sap/sap-u8500.c 2011-07-31 06:52:19.000000000 +0000 @@ -0,0 +1,725 @@ +/* + * BlueZ - Bluetooth protocol stack for Linux + * + * SAP Driver for ST-Ericsson U8500 platform + * + * Copyright (C) 2010-2011 ST-Ericsson SA + * + * Author: Waldemar Rymarkiewicz for + * ST-Ericsson. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "log.h" +#include "sap.h" + +#define STE_SIMD_SOCK "/dev/socket/catd_a" +#define STE_CLIENT_TAG 0x0000 + +#ifdef STE_SAP_DEBUG +#define DBG_VERBOSE(fmt, arg...) DBG(fmt, arg) +#else +#define DBG_VERBOSE(fmt...) +#endif + +#define sap_error(fmt, arg...) do { \ + error("STE U8500 SAP: " fmt, ## arg); \ + } while (0) + +#define sap_info(fmt, arg...) do { \ + info("STE U8500 SAP: " fmt, ## arg); \ + } while (0) + +struct ste_message { + uint16_t len; + uint16_t id; + uint32_t client_tag; + uint8_t payload[0]; +} __attribute__((packed)); + +#define STE_MSG_PAYLOAD_SIZE(msg) (msg->len - sizeof(*msg) + sizeof(msg->len)) + +enum ste_protocol { + STE_START_SAP_REQ = 0x2D01, + STE_START_SAP_RSP = 0x2E01, + STE_END_SAP_REQ = 0x2D02, + STE_END_SAP_RSP = 0x2E02, + STE_POWER_OFF_REQ = 0x2D03, + STE_POWER_OFF_RSP = 0x2E03, + STE_POWER_ON_REQ = 0x2D04, + STE_POWER_ON_RSP = 0x2E04, + STE_RESET_REQ = 0x2D05, + STE_RESET_RSP = 0x2E05, + STE_SEND_APDU_REQ = 0x2D06, + STE_SEND_APDU_RSP = 0x2E06, + STE_GET_ATR_REQ = 0x2D07, + STE_GET_ATR_RSP = 0x2E07, + STE_GET_STATUS_REQ = 0x2D08, + STE_GET_STATUS_RSP = 0x2E08, + STE_STATUS_IND = 0x2F02 +}; + +enum ste_msg { + STE_SEND_APDU_MSG, + STE_GET_ATR_MSG, + STE_POWER_OFF_MSG, + STE_POWER_ON_MSG, + STE_RESET_MSG, + STE_GET_STATUS_MSG, + STE_MSG_MAX, +}; + +enum ste_status { + STE_STATUS_OK = 0x00000000, + STE_STATUS_FAILURE = 0x00000001, +}; + +enum ste_card_status { + STE_CARD_STATUS_UNKNOWN = 0x00, + STE_CARD_STATUS_ACTIVE = 0x01, + STE_CARD_STATUS_NOT_ACTIVE = 0x02, + STE_CARD_STATUS_MISSING = 0x03, + STE_CARD_STATUS_INVALID = 0x04, + STE_CARD_STATUS_DISCONNECTED = 0x05, +}; + +/* Card reader status bits as described in GSM 11.14, Section 12.33 + * Bits 0-2 are for card reader identity and always zeros. */ +#define ICC_READER_REMOVABLE (1 << 3) +#define ICC_READER_PRESENT (1 << 4) +#define ICC_READER_ID1 (1 << 5) +#define ICC_READER_CARD_PRESENT (1 << 6) +#define ICC_READER_CARD_POWERED (1 << 7) + +enum ste_state { + STE_DISABLED, /* Reader not present or removed */ + STE_POWERED_OFF, /* Card in the reader but powered off */ + STE_NO_CARD, /* No card in the reader */ + STE_ENABLED, /* Card in the reader and powered on */ + STE_STATE_MAX +}; + +struct ste_u8500 { + GIOChannel *io; + enum ste_state state; + void *sap_data; +}; + +typedef int(*recv_state_change_cb)(void *sap, uint8_t result); +typedef int(*recv_pdu_cb)(void *sap, uint8_t result, uint8_t *data, + uint16_t len); + +static struct ste_u8500 u8500; + +static const uint8_t sim2sap_result[STE_MSG_MAX][STE_STATE_MAX] = { + /* SAP results for SEND APDU message */ + { + SAP_RESULT_ERROR_NOT_ACCESSIBLE, /* STE_DISABLED */ + SAP_RESULT_ERROR_POWERED_OFF, /* STE_POWERED_OFF */ + SAP_RESULT_ERROR_CARD_REMOVED, /* STE_NO_CARD */ + SAP_RESULT_ERROR_NO_REASON /* STE_ENABLED */ + }, + + /* SAP results for GET_ATR message */ + { + SAP_RESULT_ERROR_NO_REASON, + SAP_RESULT_ERROR_POWERED_OFF, + SAP_RESULT_ERROR_CARD_REMOVED, + SAP_RESULT_ERROR_NO_REASON + }, + + /* SAP results POWER OFF message */ + { + SAP_RESULT_ERROR_NO_REASON, + SAP_RESULT_ERROR_POWERED_OFF, + SAP_RESULT_ERROR_CARD_REMOVED, + SAP_RESULT_ERROR_NO_REASON + }, + + /* SAP results POWER ON message */ + { + SAP_RESULT_ERROR_NO_REASON, + SAP_RESULT_ERROR_NOT_ACCESSIBLE, + SAP_RESULT_ERROR_CARD_REMOVED, + SAP_RESULT_ERROR_POWERED_ON + }, + + /* SAP results SIM RESET message */ + { + SAP_RESULT_ERROR_NO_REASON, + SAP_RESULT_ERROR_POWERED_OFF, + SAP_RESULT_ERROR_CARD_REMOVED, + SAP_RESULT_ERROR_NOT_ACCESSIBLE + }, + + /* SAP results GET STATUS message */ + { + SAP_RESULT_ERROR_NO_REASON, + SAP_RESULT_ERROR_NO_REASON, + SAP_RESULT_ERROR_NO_REASON, + SAP_RESULT_ERROR_NO_REASON + } +}; + +static uint8_t get_sap_result(enum ste_msg msg, uint32_t status) +{ + if (!u8500.io) + return SAP_RESULT_ERROR_NO_REASON; + + switch (status) { + case STE_STATUS_OK: + return SAP_RESULT_OK; + + case STE_STATUS_FAILURE: + return sim2sap_result[msg][u8500.state]; + + default: + DBG("Can't convert a result (status %u)", status); + return SAP_RESULT_ERROR_NO_REASON; + } +} + +static int get_sap_reader_status(uint32_t card_status, uint8_t *icc_status) +{ + /* Card reader is present, not removable and not ID-1 size. */ + *icc_status = ICC_READER_PRESENT; + + switch (card_status) { + case STE_CARD_STATUS_ACTIVE: + *icc_status |= ICC_READER_CARD_POWERED; + + case STE_CARD_STATUS_NOT_ACTIVE: + case STE_CARD_STATUS_INVALID: + *icc_status |= ICC_READER_CARD_PRESENT; + + case STE_CARD_STATUS_MISSING: + case STE_CARD_STATUS_DISCONNECTED: + return 0; + + default: + DBG("Can't convert reader status %u", card_status); + + case STE_CARD_STATUS_UNKNOWN: + return -1; + } +} + +static uint8_t get_sap_status_change(uint32_t card_status) +{ + if (!u8500.io) + return SAP_STATUS_CHANGE_UNKNOWN_ERROR; + + switch (card_status) { + case STE_CARD_STATUS_UNKNOWN: + return SAP_STATUS_CHANGE_UNKNOWN_ERROR; + + case STE_CARD_STATUS_ACTIVE: + u8500.state = STE_ENABLED; + return SAP_STATUS_CHANGE_CARD_RESET; + + case STE_CARD_STATUS_NOT_ACTIVE: + u8500.state = STE_DISABLED; + return SAP_STATUS_CHANGE_CARD_NOT_ACCESSIBLE; + + case STE_CARD_STATUS_MISSING: + u8500.state = STE_DISABLED; + return SAP_STATUS_CHANGE_CARD_REMOVED; + + case STE_CARD_STATUS_INVALID: + u8500.state = STE_DISABLED; + return SAP_STATUS_CHANGE_CARD_NOT_ACCESSIBLE; + + default: + DBG("Can't convert status change %u", card_status); + return SAP_STATUS_CHANGE_UNKNOWN_ERROR; + } +} + +static int send_message(GIOChannel *io, void *buf, size_t size) +{ + gsize written; + + DBG_VERBOSE("io %p, size %zu", io, size); + + if (g_io_channel_write_chars(io, buf, size, &written, NULL) != + G_IO_STATUS_NORMAL) + return -EIO; + + return written; +} + +static int send_request(GIOChannel *io, uint16_t id, + struct sap_parameter *param) +{ + int ret; + struct ste_message *msg; + size_t size = sizeof(*msg); + + DBG_VERBOSE("io %p", io); + + if (param) + size += param->len; + + msg = g_try_malloc0(size); + if (!msg) { + sap_error("sending request failed: %s", strerror(ENOMEM)); + return -ENOMEM; + } + + msg->len = size - sizeof(msg->len); + msg->id = id; + msg->client_tag = STE_CLIENT_TAG; + + if (param) + memcpy(msg->payload, param->val, param->len); + + ret = send_message(io, msg, size); + if (ret < 0) { + sap_error("sending request failed: %s", strerror(-ret)); + } else if (ret != (int) size) { + sap_error("sending request failed: %d out of %zu bytes sent", + ret, size); + ret = -EIO; + } + + g_free(msg); + + return ret; +} + +static void recv_status(uint32_t status) +{ + sap_status_ind(u8500.sap_data, get_sap_status_change(status)); +} + +static void recv_card_status(uint32_t status, uint8_t *param) +{ + uint32_t *card_status; + uint8_t result; + uint8_t iccrs; + + if (status != STE_STATUS_OK) + return; + + card_status = (uint32_t *)param; + + if (get_sap_reader_status(*card_status, &iccrs) < 0) + result = SAP_RESULT_ERROR_NO_REASON; + else + result = get_sap_result(STE_GET_STATUS_MSG, status); + + sap_transfer_card_reader_status_rsp(u8500.sap_data, result, iccrs); +} + +static void recv_state_change(uint32_t ste_msg, uint32_t status, + uint32_t new_state, recv_state_change_cb callback) +{ + if (status != STE_STATUS_OK) + return; + + u8500.state = new_state; + + if (callback) + callback(u8500.sap_data, get_sap_result(ste_msg, status)); +} + +static void recv_pdu(uint32_t ste_msg, struct ste_message *msg, uint32_t status, + uint8_t *param, recv_pdu_cb callback) +{ + uint8_t *data = NULL; + uint8_t result; + int size = 0; + + if (status == STE_STATUS_OK) { + data = param; + size = STE_MSG_PAYLOAD_SIZE(msg) - sizeof(status); + } + + result = get_sap_result(ste_msg, status); + + if (callback) + callback(u8500.sap_data, result, data, size); +} + +static void simd_close(void) +{ + DBG("io %p", u8500.io); + + if (u8500.io) { + g_io_channel_shutdown(u8500.io, TRUE, NULL); + g_io_channel_unref(u8500.io); + } + + u8500.state = STE_DISABLED; + u8500.io = NULL; + u8500.sap_data = NULL; +} + +static void recv_response(struct ste_message *msg) +{ + uint32_t status; + uint8_t *param; + + DBG_VERBOSE("msg_id 0x%x", msg->id); + + if (msg->id == STE_END_SAP_RSP) { + sap_disconnect_rsp(u8500.sap_data); + simd_close(); + return; + } + + param = msg->payload; + status = *(uint32_t *)param; + param += sizeof(status); + + DBG_VERBOSE("status 0x%x", status); + + switch (msg->id) { + case STE_START_SAP_RSP: + if (status == STE_STATUS_OK) { + sap_connect_rsp(u8500.sap_data, SAP_STATUS_OK, 0); + } else { + sap_connect_rsp(u8500.sap_data, + SAP_STATUS_CONNECTION_FAILED, 0); + simd_close(); + } + break; + + case STE_SEND_APDU_RSP: + recv_pdu(STE_SEND_APDU_MSG, msg, status, param, + sap_transfer_apdu_rsp); + break; + + case STE_GET_ATR_RSP: + recv_pdu(STE_GET_ATR_MSG, msg, status, param, + sap_transfer_atr_rsp); + break; + + case STE_POWER_OFF_RSP: + recv_state_change(STE_POWER_OFF_MSG, status, STE_POWERED_OFF, + sap_power_sim_off_rsp); + break; + + case STE_POWER_ON_RSP: + recv_state_change(STE_POWER_ON_MSG, status, STE_ENABLED, + sap_power_sim_on_rsp); + break; + + case STE_RESET_RSP: + recv_state_change(STE_RESET_MSG, status, STE_ENABLED, + sap_reset_sim_rsp); + break; + + case STE_GET_STATUS_RSP: + recv_card_status(status, param); + break; + + case STE_STATUS_IND: + recv_status(status); + break; + + default: + sap_error("unsupported message received (id 0x%x)", msg->id); + } +} + +static int recv_message(void *buf, size_t size) +{ + uint8_t *iter = buf; + struct ste_message *msg = buf; + + do { + DBG_VERBOSE("size %zu msg->len %u.", size, msg->len); + + if (size < sizeof(*msg)) { + sap_error("invalid message received (%zu bytes)", size); + return -EBADMSG; + } + + /* Message must be complete. */ + if (size < (msg->len + sizeof(msg->len))) { + sap_error("incomplete message received (%zu bytes)", + size); + return -EBADMSG; + } + + recv_response(msg); + + /* Reduce total buffer size by just handled frame size. */ + size -= msg->len + sizeof(msg->len); + + /* Move msg pointer to the next message if any. */ + iter += msg->len + sizeof(msg->len); + msg = (struct ste_message *)iter; + } while (size > 0); + + return 0; +} + +static gboolean simd_data_cb(GIOChannel *io, GIOCondition cond, gpointer data) +{ + char buf[SAP_BUF_SIZE]; + gsize bytes_read; + GIOStatus gstatus; + + if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR)) { + DBG("Error condition on sim socket (0x%x)", cond); + return FALSE; + } + + gstatus = g_io_channel_read_chars(io, buf, sizeof(buf), &bytes_read, + NULL); + if (gstatus != G_IO_STATUS_NORMAL) { + sap_error("error while reading from channel (%d)", gstatus); + return TRUE; + } + + if (recv_message(buf, bytes_read) < 0) + sap_error("error while parsing STE Sim message"); + + return TRUE; +} + +static void simd_watch(int sock, void *sap_data) +{ + GIOChannel *io; + + DBG("sock %d, sap_data %p ", sock, sap_data); + + io = g_io_channel_unix_new(sock); + + g_io_channel_set_close_on_unref(io, TRUE); + g_io_channel_set_encoding(io, NULL, NULL); + g_io_channel_set_buffered(io, FALSE); + + u8500.io = io; + u8500.sap_data = sap_data; + u8500.state = STE_DISABLED; + + g_io_add_watch_full(io, G_PRIORITY_DEFAULT, + G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, + simd_data_cb, NULL, NULL); +} + +static int simd_connect(void *sap_data) +{ + struct sockaddr_un addr; + int sock; + int err; + + /* Already connected to simd */ + if (u8500.io) + return -EALREADY; + + sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + err = errno; + sap_error("creating socket failed: %s", strerror(err)); + return -err; + } + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + memcpy(addr.sun_path, STE_SIMD_SOCK, sizeof(STE_SIMD_SOCK) - 1); + + if (connect(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + err = errno; + sap_error("connect to the socket failed: %s", strerror(err)); + goto failed; + } + + if (fcntl(sock, F_SETFL, O_NONBLOCK) > 0) { + err = errno; + sap_error("setting up socket failed: %s", strerror(err)); + goto failed; + } + + simd_watch(sock, sap_data); + + return 0; + +failed: + close(sock); + return -err; +} + +void sap_connect_req(void *sap_device, uint16_t maxmsgsize) +{ + DBG("sap_device %p maxmsgsize %u", sap_device, maxmsgsize); + + sap_info("connect request"); + + if (simd_connect(sap_device) < 0) { + sap_connect_rsp(sap_device, SAP_STATUS_CONNECTION_FAILED, 0); + return; + } + + if (send_request(u8500.io, STE_START_SAP_REQ, NULL) < 0) { + sap_connect_rsp(sap_device, SAP_STATUS_CONNECTION_FAILED, + SAP_BUF_SIZE); + simd_close(); + } +} + +void sap_disconnect_req(void *sap_device, uint8_t linkloss) +{ + DBG("sap_device %p linkloss %u", sap_device, linkloss); + + sap_info("disconnect request %s", linkloss ? "by link loss" : ""); + + if (u8500.state == STE_DISABLED) { + sap_disconnect_rsp(sap_device); + simd_close(); + return; + } + + if (linkloss) { + simd_close(); + return; + } + + if (send_request(u8500.io, STE_END_SAP_REQ, NULL) < 0) { + sap_disconnect_rsp(sap_device); + return; + } +} + +void sap_transfer_apdu_req(void *sap_device, struct sap_parameter *param) +{ + uint8_t result; + + DBG_VERBOSE("sap_device %p param %p", sap_device, param); + + if (u8500.state != STE_ENABLED) { + result = get_sap_result(STE_SEND_APDU_MSG, STE_STATUS_FAILURE); + sap_transfer_apdu_rsp(sap_device, result, NULL, 0); + return; + } + + if (send_request(u8500.io, STE_SEND_APDU_REQ, param) < 0) + sap_transfer_apdu_rsp(sap_device, SAP_RESULT_ERROR_NO_DATA, + NULL, 0); +} + +void sap_transfer_atr_req(void *sap_device) +{ + uint8_t result; + + DBG("sap_device %p", sap_device); + + if (u8500.state != STE_ENABLED) { + result = get_sap_result(STE_GET_ATR_MSG, STE_STATUS_FAILURE); + sap_transfer_atr_rsp(sap_device, result, NULL, 0); + return; + } + + if (send_request(u8500.io, STE_GET_ATR_REQ, NULL) < 0) + sap_transfer_atr_rsp(sap_device, SAP_RESULT_ERROR_NO_DATA, NULL, + 0); +} + +void sap_power_sim_off_req(void *sap_device) +{ + uint8_t result; + + DBG("sap_device %p", sap_device); + + if (u8500.state != STE_ENABLED) { + result = get_sap_result(STE_POWER_OFF_MSG, STE_STATUS_FAILURE); + sap_power_sim_off_rsp(sap_device, result); + return; + } + + if (send_request(u8500.io, STE_POWER_OFF_REQ, NULL) < 0) + sap_power_sim_off_rsp(sap_device, SAP_RESULT_ERROR_NO_REASON); +} + +void sap_power_sim_on_req(void *sap_device) +{ + uint8_t result; + + DBG("sap_device %p", sap_device); + + if (u8500.state != STE_POWERED_OFF) { + result = get_sap_result(STE_POWER_ON_MSG, STE_STATUS_FAILURE); + sap_power_sim_on_rsp(sap_device, result); + return; + } + + if (send_request(u8500.io, STE_POWER_ON_REQ, NULL) < 0) + sap_power_sim_on_rsp(sap_device, SAP_RESULT_ERROR_NO_REASON); +} + +void sap_reset_sim_req(void *sap_device) +{ + uint8_t result; + + DBG("sap_device %p", sap_device); + + if (u8500.state != STE_ENABLED) { + result = get_sap_result(STE_RESET_MSG, STE_STATUS_FAILURE); + sap_reset_sim_rsp(sap_device, result); + return; + } + + if (send_request(u8500.io, STE_RESET_REQ, NULL) < 0) + sap_reset_sim_rsp(sap_device, SAP_RESULT_ERROR_NO_REASON); +} + +void sap_transfer_card_reader_status_req(void *sap_device) +{ + uint8_t result; + + DBG("sap_device %p", sap_device); + + if (u8500.state == STE_DISABLED) { + result = get_sap_result(STE_GET_STATUS_MSG, STE_STATUS_FAILURE); + sap_transfer_card_reader_status_rsp(sap_device, result, 0); + return; + } + + if (send_request(u8500.io, STE_GET_STATUS_REQ, NULL) < 0) + sap_transfer_card_reader_status_rsp(sap_device, + SAP_RESULT_ERROR_NO_DATA, 0); +} + +void sap_set_transport_protocol_req(void *sap_device, + struct sap_parameter *param) +{ + DBG("sap_device %p", sap_device); + + sap_transport_protocol_rsp(sap_device, SAP_RESULT_NOT_SUPPORTED); +} + +int sap_init(void) +{ + u8500.state = STE_DISABLED; + info("STE U8500 SAP driver initialized"); + return 0; +} + +void sap_exit(void) +{ +} diff -Nru bluez-4.91/sap/server.c bluez-4.96/sap/server.c --- bluez-4.91/sap/server.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/sap/server.c 2011-07-31 06:52:19.000000000 +0000 @@ -48,9 +48,8 @@ #define SAP_SERVER_INTERFACE "org.bluez.SimAccess" #define SAP_UUID "0000112D-0000-1000-8000-00805F9B34FB" #define SAP_SERVER_CHANNEL 8 -#define SAP_BUF_SIZE 512 -#define PADDING4(x) (4 - (x & 0x03)) +#define PADDING4(x) ((4 - (x & 0x03)) & 0x03) #define PARAMETER_SIZE(x) (sizeof(struct sap_parameter) + x + PADDING4(x)) #define SAP_NO_REQ 0xFF @@ -254,22 +253,24 @@ if (!conn || !buf) return -EINVAL; - DBG("size %zu", size); + DBG("conn %p, size %zu", conn, size); gstatus = g_io_channel_write_chars(conn->io, buf, size, &written, - &gerr); + &gerr); if (gstatus != G_IO_STATUS_NORMAL) { if (gerr) g_error_free(gerr); error("write error (0x%02x).", gstatus); - return -EINVAL; + return -EIO; } - if (written != size) - error("write error.(written %zu size %zu)", written, size); + if (written != size) { + error("written %zu bytes out of %zu", written, size); + return -EIO; + } - return 0; + return written; } static int disconnect_ind(void *sap_device, uint8_t disc_type) @@ -338,8 +339,6 @@ return; error_rsp: - error("Processing error (param %p state %d pr 0x%02x)", param, - conn->state, conn->processing_req); sap_error_rsp(conn); } @@ -349,11 +348,9 @@ switch (disc_type) { case SAP_DISCONNECTION_TYPE_GRACEFUL: - if (conn->state == SAP_STATE_DISCONNECTED) - goto error_req; - - if (conn->state == SAP_STATE_CONNECT_IN_PROGRESS) - goto error_req; + if (conn->state == SAP_STATE_DISCONNECTED || + conn->state == SAP_STATE_CONNECT_IN_PROGRESS) + return -EPERM; if (conn->state == SAP_STATE_CONNECTED) { conn->state = SAP_STATE_GRACEFUL_DISCONNECT; @@ -367,11 +364,9 @@ return 0; case SAP_DISCONNECTION_TYPE_IMMEDIATE: - if (conn->state == SAP_STATE_DISCONNECTED) - goto error_req; - - if (conn->state == SAP_STATE_CONNECT_IN_PROGRESS) - goto error_req; + if (conn->state == SAP_STATE_DISCONNECTED || + conn->state == SAP_STATE_CONNECT_IN_PROGRESS) + return -EPERM; if (conn->state == SAP_STATE_CONNECTED || conn->state == SAP_STATE_GRACEFUL_DISCONNECT) { @@ -387,8 +382,10 @@ case SAP_DISCONNECTION_TYPE_CLIENT: if (conn->state != SAP_STATE_CONNECTED && - conn->state != SAP_STATE_GRACEFUL_DISCONNECT) - goto error_rsp; + conn->state != SAP_STATE_GRACEFUL_DISCONNECT) { + sap_error_rsp(conn); + return -EPERM; + } conn->state = SAP_STATE_CLIENT_DISCONNECT; conn->processing_req = SAP_NO_REQ; @@ -402,13 +399,6 @@ error("Unknown disconnection type (0x%02x).", disc_type); return -EINVAL; } - -error_rsp: - sap_error_rsp(conn); -error_req: - error("Processing error (state %d pr 0x%02x)", conn->state, - conn->processing_req); - return -EPERM; } static void transfer_apdu_req(struct sap_connection *conn, @@ -434,8 +424,6 @@ return; error_rsp: - error("Processing error (param %p state %d pr 0x%02x)", param, - conn->state, conn->processing_req); sap_error_rsp(conn); } @@ -455,8 +443,6 @@ return; error_rsp: - error("Processing error (state %d pr 0x%02x)", conn->state, - conn->processing_req); sap_error_rsp(conn); } @@ -476,8 +462,6 @@ return; error_rsp: - error("Processing error (state %d pr 0x%02x)", conn->state, - conn->processing_req); sap_error_rsp(conn); } @@ -497,8 +481,6 @@ return; error_rsp: - error("Processing error (state %d pr 0x%02x)", conn->state, - conn->processing_req); sap_error_rsp(conn); } @@ -518,8 +500,6 @@ return; error_rsp: - error("Processing error (state %d pr 0x%02x param)", conn->state, - conn->processing_req); sap_error_rsp(conn); } @@ -539,8 +519,6 @@ return; error_rsp: - error("Processing error (state %d pr 0x%02x)", conn->state, - conn->processing_req); sap_error_rsp(conn); } @@ -564,8 +542,6 @@ return; error_rsp: - error("Processing error (param %p state %d pr 0x%02x)", param, - conn->state, conn->processing_req); sap_error_rsp(conn); } @@ -967,6 +943,9 @@ memset(&msg, 0, sizeof(msg)); msg.id = SAP_ERROR_RESP; + error("SAP error (state %d pr 0x%02x).", conn->state, + conn->processing_req); + return send_message(conn, &msg, sizeof(msg)); } @@ -1001,10 +980,16 @@ return send_message(sap_device, buf, size); } -static int handle_cmd(void *data, void *buf, size_t size) +int sap_disconnect_ind(void *sap_device, uint8_t disc_type) +{ + struct sap_connection *conn = sap_device; + + return disconnect_req(conn, SAP_DISCONNECTION_TYPE_IMMEDIATE); +} + +static int handle_cmd(struct sap_connection *conn, void *buf, size_t size) { struct sap_message *msg = buf; - struct sap_connection *conn = data; if (!conn) return -EINVAL; @@ -1048,12 +1033,12 @@ set_transport_protocol_req(conn, msg->param); return 0; default: - DBG("SAP unknown message."); + DBG("Unknown SAP message id 0x%02x.", msg->id); break; } error_rsp: - DBG("Bad request message format."); + DBG("Invalid SAP message format."); sap_error_rsp(conn); return -EBADMSG; } @@ -1077,12 +1062,14 @@ static gboolean sap_io_cb(GIOChannel *io, GIOCondition cond, gpointer data) { + struct sap_connection *conn = data; + char buf[SAP_BUF_SIZE]; size_t bytes_read = 0; GError *gerr = NULL; GIOStatus gstatus; - DBG("io %p", io); + DBG("conn %p io %p", conn, io); if (cond & G_IO_NVAL) { DBG("ERR (G_IO_NVAL) on rfcomm socket."); @@ -1100,7 +1087,7 @@ } gstatus = g_io_channel_read_chars(io, buf, sizeof(buf) - 1, - &bytes_read, &gerr); + &bytes_read, &gerr); if (gstatus != G_IO_STATUS_NORMAL) { if (gerr) g_error_free(gerr); @@ -1108,8 +1095,8 @@ return TRUE; } - if (handle_cmd(data, buf, bytes_read) < 0) - error("Invalid SAP message."); + if (handle_cmd(conn, buf, bytes_read) < 0) + error("SAP protocol processing failure."); return TRUE; } @@ -1135,7 +1122,6 @@ conn->state == SAP_STATE_GRACEFUL_DISCONNECT) sap_disconnect_req(NULL, 1); - conn->io = NULL; sap_conn_remove(conn); } } @@ -1144,7 +1130,7 @@ { struct sap_connection *conn = data; - DBG("io %p gerr %p data %p ", io, gerr, data); + DBG("conn %p, io %p", conn, io); if (!conn) return; @@ -1163,13 +1149,13 @@ struct sap_connection *conn = data; GError *gerr = NULL; - DBG("derr %p data %p ", derr, data); + DBG("conn %p", conn); if (!conn) return; if (derr && dbus_error_is_set(derr)) { - error("Access denied: %s", derr->message); + error("Access has been denied (%s)", derr->message); sap_conn_remove(conn); return; } @@ -1181,7 +1167,7 @@ return; } - DBG("Client has been authorized."); + DBG("Access has been granted."); } static void connect_confirm_cb(GIOChannel *io, gpointer data) @@ -1189,14 +1175,16 @@ struct sap_connection *conn = server->conn; GError *gerr = NULL; bdaddr_t src, dst; + char dstaddr[18]; int err; - DBG("io %p data %p ", io, data); + DBG("conn %p io %p", conn, io); if (!io) return; if (conn) { + DBG("Another SAP connection already exists."); g_io_channel_shutdown(io, TRUE, NULL); return; } @@ -1226,23 +1214,24 @@ return; } - err = btd_request_authorization(&src, &dst, SAP_UUID, - connect_auth_cb, conn); + ba2str(&dst, dstaddr); + + err = btd_request_authorization(&src, &dst, SAP_UUID, connect_auth_cb, + conn); if (err < 0) { - DBG("Authorization denied: %d %s", err, strerror(err)); + error("Authorization failure (err %d)", err); sap_conn_remove(conn); return; } - DBG("SAP incoming connection (sock %d) authorization.", - g_io_channel_unix_get_fd(io)); + DBG("Authorizing incomming SAP connection from %s", dstaddr); } static inline DBusMessage *message_failed(DBusMessage *msg, const char *description) { - return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", - "%s", description); + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "%s", + description); } static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg, @@ -1250,8 +1239,6 @@ { struct sap_server *server = data; - DBG("server %p", server); - if (!server) return message_failed(msg, "Server internal error."); @@ -1262,7 +1249,7 @@ if (disconnect_req(server->conn, SAP_DISCONNECTION_TYPE_GRACEFUL) < 0) return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", - "There is no active connection"); + "There is no active connection"); return dbus_message_new_method_return(msg); } @@ -1291,7 +1278,7 @@ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); connected = (conn->state == SAP_STATE_CONNECTED || - conn->state == SAP_STATE_GRACEFUL_DISCONNECT); + conn->state == SAP_STATE_GRACEFUL_DISCONNECT); dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, &connected); dbus_message_iter_close_container(&iter, &dict); @@ -1325,8 +1312,8 @@ { struct sap_server *server = data; - DBG("Unregistered interface %s on path %s", - SAP_SERVER_INTERFACE, server->path); + DBG("Unregistered interface %s on path %s", SAP_SERVER_INTERFACE, + server->path); server_free(server); } @@ -1384,10 +1371,10 @@ server->conn = NULL; if (!g_dbus_register_interface(connection, path, SAP_SERVER_INTERFACE, - server_methods, server_signals, NULL, - server, destroy_sap_interface)) { + server_methods, server_signals, NULL, + server, destroy_sap_interface)) { error("D-Bus failed to register %s interface", - SAP_SERVER_INTERFACE); + SAP_SERVER_INTERFACE); goto server_err; } diff -Nru bluez-4.91/sbc/sbcinfo.c bluez-4.96/sbc/sbcinfo.c --- bluez-4.91/sbc/sbcinfo.c 2010-01-09 20:52:17.000000000 +0000 +++ bluez-4.96/sbc/sbcinfo.c 2011-05-31 02:39:53.000000000 +0000 @@ -174,7 +174,7 @@ unsigned char buf[64]; double rate; int bitpool[SIZE], frame_len[SIZE]; - int subbands, blocks, freq, mode, method; + int subbands, blocks, freq, method; int n, p1, p2, fd, size, num; ssize_t len; unsigned int count; @@ -199,7 +199,6 @@ subbands = (hdr.subbands + 1) * 4; blocks = (hdr.blocks + 1) * 4; freq = hdr.sampling_frequency; - mode = hdr.channel_mode; method = hdr.allocation_method; count = calc_frame_len(&hdr); diff -Nru bluez-4.91/sbc/sbctester.c bluez-4.96/sbc/sbctester.c --- bluez-4.91/sbc/sbctester.c 2010-01-09 20:52:17.000000000 +0000 +++ bluez-4.96/sbc/sbctester.c 2011-05-31 02:39:53.000000000 +0000 @@ -245,7 +245,7 @@ return verdict; } -static void usage() +static void usage(void) { printf("SBC conformance test ver %s\n", VERSION); printf("Copyright (c) 2007-2010 Marcel Holtmann\n"); diff -Nru bluez-4.91/scripts/bluetooth-hid2hci.rules bluez-4.96/scripts/bluetooth-hid2hci.rules --- bluez-4.91/scripts/bluetooth-hid2hci.rules 2009-05-19 09:04:10.000000000 +0000 +++ bluez-4.96/scripts/bluetooth-hid2hci.rules 2011-07-04 04:59:05.000000000 +0000 @@ -1,36 +1,28 @@ -# Variety of Dell Bluetooth devices -# -# it looks like a bit of an odd rule, because it is matching -# on a mouse device that is self powered, but that is where -# a HID report needs to be sent to switch modes. -# -# Known supported devices: -# 413c:8154 -# 413c:8158 -# 413c:8162 -ACTION=="add", ENV{ID_VENDOR}=="413c", ENV{ID_CLASS}=="mouse", ATTRS{bmAttributes}=="e0", KERNEL=="mouse*", RUN+="/usr/sbin/hid2hci --method dell -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hci" +# do not edit this file, it will be overwritten on update + +ACTION=="remove", GOTO="hid2hci_end" +SUBSYSTEM!="usb", GOTO="hid2hci_end" + +# Variety of Dell Bluetooth devices - match on a mouse device that is +# self powered and where a HID report needs to be sent to switch modes +# Known supported devices: 413c:8154, 413c:8158, 413c:8162 +ATTR{bInterfaceClass}=="03", ATTR{bInterfaceSubClass}=="01", ATTR{bInterfaceProtocol}=="02", \ + ATTRS{bDeviceClass}=="00", ATTRS{idVendor}=="413c", ATTRS{bmAttributes}=="e0", \ + RUN+="hid2hci --method=dell --devpath=%p", ENV{HID2HCI_SWITCH}="1" # Logitech devices -ACTION=="add", ENV{ID_VENDOR}=="046d", ENV{ID_MODEL}=="c703" RUN+="/usr/sbin/hid2hci --method logitech -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hci" -ACTION=="add", ENV{ID_VENDOR}=="046d", ENV{ID_MODEL}=="c704" RUN+="/usr/sbin/hid2hci --method logitech -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hci" -ACTION=="add", ENV{ID_VENDOR}=="046d", ENV{ID_MODEL}=="c705" RUN+="/usr/sbin/hid2hci --method logitech -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hci" -ACTION=="add", ENV{ID_VENDOR}=="046d", ENV{ID_MODEL}=="c70a" RUN+="/usr/sbin/hid2hci --method logitech -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hci" -ACTION=="add", ENV{ID_VENDOR}=="046d", ENV{ID_MODEL}=="c70b" RUN+="/usr/sbin/hid2hci --method logitech -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hci" -ACTION=="add", ENV{ID_VENDOR}=="046d", ENV{ID_MODEL}=="c70c" RUN+="/usr/sbin/hid2hci --method logitech -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hci" -ACTION=="add", ENV{ID_VENDOR}=="046d", ENV{ID_MODEL}=="c70e" RUN+="/usr/sbin/hid2hci --method logitech -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hci" -ACTION=="add", ENV{ID_VENDOR}=="046d", ENV{ID_MODEL}=="c713" RUN+="/usr/sbin/hid2hci --method logitech -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hci" -ACTION=="add", ENV{ID_VENDOR}=="046d", ENV{ID_MODEL}=="c714" RUN+="/usr/sbin/hid2hci --method logitech -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hci" -ACTION=="add", ENV{ID_VENDOR}=="046d", ENV{ID_MODEL}=="c71b" RUN+="/usr/sbin/hid2hci --method logitech -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hci" -ACTION=="add", ENV{ID_VENDOR}=="046d", ENV{ID_MODEL}=="c71c" RUN+="/usr/sbin/hid2hci --method logitech -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hci" - -# CSR devices (in HID mode) -ACTION=="add", ENV{ID_VENDOR}=="0a12", ENV{ID_MODEL}=="1000" RUN+="/usr/sbin/hid2hci --method csr -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hci" -ACTION=="add", ENV{ID_VENDOR}=="0458", ENV{ID_MODEL}=="1000" RUN+="/usr/sbin/hid2hci --method csr -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hci" -ACTION=="add", ENV{ID_VENDOR}=="05ac", ENV{ID_MODEL}=="1000" RUN+="/usr/sbin/hid2hci --method csr -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hci" - -# CSR devices (in HCI mode) -#ACTION=="add", ENV{ID_VENDOR}=="0a12", ENV{ID_MODEL}=="0001" RUN+="/usr/sbin/hid2hci --method csr -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hid" -#ACTION=="add", ENV{ID_VENDOR}=="0458", ENV{ID_MODEL}=="003f" RUN+="/usr/sbin/hid2hci --method csr -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hid" -#ACTION=="add", ENV{ID_VENDOR}=="05ac", ENV{ID_MODEL}=="8203" RUN+="/usr/sbin/hid2hci --method csr -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hid" -#ACTION=="add", ENV{ID_VENDOR}=="05ac", ENV{ID_MODEL}=="8204" RUN+="/usr/sbin/hid2hci --method csr -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hid" -#ACTION=="add", ENV{ID_VENDOR}=="05ac", ENV{ID_MODEL}=="8207" RUN+="/usr/sbin/hid2hci --method csr -v $env{ID_VENDOR} -p $env{ID_MODEL} --mode hid" +KERNEL=="hiddev*", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c70[345abce]|c71[34bc]", \ + RUN+="hid2hci --method=logitech-hid --devpath=%p" + +ENV{DEVTYPE}!="usb_device", GOTO="hid2hci_end" + +# When a Dell device recovers from S3, the mouse child needs to be repoked +# Unfortunately the only event seen is the BT device disappearing, so the mouse +# device needs to be chased down on the USB bus. +ATTR{bDeviceClass}=="e0", ATTR{bDeviceSubClass}=="01", ATTR{bDeviceProtocol}=="01", ATTR{idVendor}=="413c", \ + ENV{REMOVE_CMD}="/sbin/udevadm trigger --action=change --subsystem-match=usb --property-match=HID2HCI_SWITCH=1" + +# CSR devices +ATTR{idVendor}=="0a12|0458|05ac", ATTR{idProduct}=="1000", RUN+="hid2hci --method=csr --devpath=%p" + +LABEL="hid2hci_end" diff -Nru bluez-4.91/serial/port.c bluez-4.96/serial/port.c --- bluez-4.91/serial/port.c 2010-12-26 17:20:48.000000000 +0000 +++ bluez-4.96/serial/port.c 2011-07-04 04:59:05.000000000 +0000 @@ -189,8 +189,9 @@ return -err; } -static void serial_port_free(struct serial_port *port) +static void serial_port_free(void *data) { + struct serial_port *port = data; struct serial_device *device = port->device; if (device && port->listener_id > 0) @@ -202,8 +203,10 @@ g_free(port); } -static void serial_device_free(struct serial_device *device) +static void serial_device_free(void *data) { + struct serial_device *device = data; + g_free(device->path); if (device->conn) dbus_connection_unref(device->conn); @@ -232,8 +235,7 @@ void port_release_all(void) { - g_slist_foreach(devices, (GFunc) serial_device_free, NULL); - g_slist_free(devices); + g_slist_free_full(devices, serial_device_free); } static void open_notify(int fd, int err, struct serial_port *port) @@ -613,8 +615,7 @@ if (!device) return -ENOENT; - g_slist_foreach(device->ports, (GFunc) serial_port_free, NULL); - g_slist_free(device->ports); + g_slist_free_full(device->ports, serial_port_free); g_dbus_unregister_interface(device->conn, path, SERIAL_PORT_INTERFACE); diff -Nru bluez-4.91/serial/proxy.c bluez-4.96/serial/proxy.c --- bluez-4.91/serial/proxy.c 2011-01-20 07:49:26.000000000 +0000 +++ bluez-4.96/serial/proxy.c 2011-07-04 04:59:05.000000000 +0000 @@ -208,11 +208,10 @@ fd = g_io_channel_unix_get_fd(chan); - wbytes = written = 0; + wbytes = 0; while (wbytes < size) { written = write(fd, buf + wbytes, size - wbytes); - - if (written) + if (written < 0) return -errno; wbytes += written; @@ -312,8 +311,7 @@ static int tcp_socket_connect(const char *address) { struct sockaddr_in addr; - int err, sk; - unsigned short int port; + int err, sk, port; memset(&addr, 0, sizeof(addr)); @@ -812,7 +810,7 @@ sk = open(address, O_RDONLY | O_NOCTTY); if (sk < 0) { - error("Cant open TTY: %s(%d)", strerror(errno), errno); + error("Can't open TTY: %s(%d)", strerror(errno), errno); return -EINVAL; } @@ -1147,10 +1145,8 @@ static struct serial_adapter *find_adapter(GSList *list, struct btd_adapter *btd_adapter) { - GSList *l; - - for (l = list; l; l = l->next) { - struct serial_adapter *adapter = l->data; + for (; list; list = list->next) { + struct serial_adapter *adapter = list->data; if (adapter->btd_adapter == btd_adapter) return adapter; diff -Nru bluez-4.91/src/adapter.c bluez-4.96/src/adapter.c --- bluez-4.91/src/adapter.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/src/adapter.c 2011-07-31 06:52:19.000000000 +0000 @@ -58,6 +58,7 @@ #include "storage.h" #include "attrib-server.h" #include "att.h" +#include "eir.h" /* Flags Descriptions */ #define EIR_LIM_DISC 0x01 /* LE Limited Discoverable Mode */ @@ -68,9 +69,6 @@ #define EIR_SIM_HOST 0x10 /* Simultaneous LE and BR/EDR to Same Device Capable (Host) */ -#define ADV_TYPE_IND 0x00 -#define ADV_TYPE_DIRECT_IND 0x01 - #define IO_CAPABILITY_DISPLAYONLY 0x00 #define IO_CAPABILITY_DISPLAYYESNO 0x01 #define IO_CAPABILITY_KEYBOARDONLY 0x02 @@ -79,6 +77,8 @@ #define check_address(address) bachk(address) +#define OFF_TIMER 3 + static DBusConnection *connection = NULL; static GSList *adapter_drivers = NULL; @@ -110,6 +110,8 @@ char *path; /* adapter object path */ bdaddr_t bdaddr; /* adapter Bluetooth Address */ uint32_t dev_class; /* Class of Device */ + char name[MAX_NAME_LENGTH + 1]; /* adapter name */ + gboolean allow_name_changes; /* whether the adapter name can be changed */ guint discov_timeout_id; /* discoverable timeout id */ guint stop_discov_id; /* stop inquiry/scanning id */ uint32_t discov_timeout; /* discoverable time(sec) */ @@ -134,7 +136,6 @@ guint scheduler_id; /* Scheduler handle */ sdp_list_t *services; /* Services associated to adapter */ - struct hci_dev dev; /* hci info */ gboolean pairable; /* pairable state */ gboolean initialized; @@ -142,9 +143,10 @@ gint ref; - GSList *powered_callbacks; + guint off_timer; - gboolean name_stored; + GSList *powered_callbacks; + GSList *pin_callbacks; GSList *loaded_drivers; }; @@ -172,74 +174,17 @@ return 0; } -static void dev_info_free(struct remote_dev_info *dev) +static void dev_info_free(void *data) { + struct remote_dev_info *dev = data; + g_free(dev->name); g_free(dev->alias); - g_slist_foreach(dev->services, (GFunc) g_free, NULL); - g_slist_free(dev->services); + g_slist_free_full(dev->services, g_free); g_strfreev(dev->uuids); g_free(dev); } -/* - * Device name expansion - * %d - device id - */ -static char *expand_name(char *dst, int size, char *str, int dev_id) -{ - register int sp, np, olen; - char *opt, buf[10]; - - if (!str || !dst) - return NULL; - - sp = np = 0; - while (np < size - 1 && str[sp]) { - switch (str[sp]) { - case '%': - opt = NULL; - - switch (str[sp+1]) { - case 'd': - sprintf(buf, "%d", dev_id); - opt = buf; - break; - - case 'h': - opt = main_opts.host_name; - break; - - case '%': - dst[np++] = str[sp++]; - /* fall through */ - default: - sp++; - continue; - } - - if (opt) { - /* substitute */ - olen = strlen(opt); - if (np + olen < size - 1) - memcpy(dst + np, opt, olen); - np += olen; - } - sp += 2; - continue; - - case '\\': - sp++; - /* fall through */ - default: - dst[np++] = str[sp++]; - break; - } - } - dst[np] = '\0'; - return dst; -} - int btd_adapter_set_class(struct btd_adapter *adapter, uint8_t major, uint8_t minor) { @@ -260,11 +205,13 @@ if (!dev) /* no pending request */ return -ENODATA; - adapter->state &= ~STATE_RESOLVNAME; err = adapter_ops->cancel_resolve_name(adapter->dev_id, &dev->bdaddr); if (err < 0) error("Remote name cancel failed: %s(%d)", strerror(errno), errno); + + adapter_set_state(adapter, STATE_IDLE); + return err; } @@ -274,7 +221,7 @@ int err; /* Do not attempt to resolve more names if on suspended state */ - if (adapter->state & STATE_SUSPENDED) + if (adapter->state == STATE_SUSPENDED) return 0; memset(&match, 0, sizeof(struct remote_dev_info)); @@ -458,10 +405,8 @@ static struct session_req *find_session_by_msg(GSList *list, const DBusMessage *msg) { - GSList *l; - - for (l = list; l; l = l->next) { - struct session_req *req = l->data; + for (; list; list = list->next) { + struct session_req *req = list->data; if (req->msg == msg) return req; @@ -475,13 +420,10 @@ { int err; const char *modestr; - gboolean discoverable; if (adapter->pending_mode != NULL) return -EALREADY; - discoverable = new_mode == MODE_DISCOVERABLE; - if (!adapter->up && new_mode != MODE_OFF) { err = adapter_ops->set_powered(adapter->dev_id, TRUE); if (err < 0) @@ -647,10 +589,8 @@ static struct session_req *find_session(GSList *list, const char *sender) { - GSList *l; - - for (l = list; l; l = l->next) { - struct session_req *req = l->data; + for (; list; list = list->next) { + struct session_req *req = list->data; if (g_str_equal(req->owner, sender)) return req; @@ -695,12 +635,11 @@ return le; } -static void stop_discovery(struct btd_adapter *adapter, gboolean suspend) +static void stop_discovery(struct btd_adapter *adapter) { pending_remote_name_cancel(adapter); - if (suspend == FALSE) - adapter->found_devices = remove_bredr(adapter->found_devices); + adapter->found_devices = remove_bredr(adapter->found_devices); if (adapter->oor_devices) { g_slist_free(adapter->oor_devices); @@ -709,8 +648,8 @@ /* Reset if suspended, otherwise remove timer (software scheduler) or request inquiry to stop */ - if (adapter->state & STATE_SUSPENDED) { - adapter->state &= ~STATE_SUSPENDED; + if (adapter->state == STATE_SUSPENDED) { + adapter_set_state(adapter, STATE_IDLE); return; } @@ -720,10 +659,7 @@ return; } - if (adapter->state & STATE_LE_SCAN) - adapter_ops->stop_scanning(adapter->dev_id); - else - adapter_ops->stop_inquiry(adapter->dev_id); + adapter_ops->stop_discovery(adapter->dev_id); } static void session_remove(struct session_req *req) @@ -760,12 +696,14 @@ DBG("Stopping discovery"); - stop_discovery(adapter, FALSE); + stop_discovery(adapter); } } -static void session_free(struct session_req *req) +static void session_free(void *data) { + struct session_req *req = data; + if (req->id) g_dbus_remove_watch(req->conn, req->id); @@ -921,63 +859,57 @@ DBUS_TYPE_UINT32, &new_class); } -void adapter_update_local_name(struct btd_adapter *adapter, const char *name) +int adapter_update_local_name(struct btd_adapter *adapter, const char *name) { - struct hci_dev *dev = &adapter->dev; + char *name_ptr; - if (strncmp(name, dev->name, MAX_NAME_LENGTH) == 0) - return; + if (adapter->allow_name_changes == FALSE) + return -EPERM; - strncpy(dev->name, name, MAX_NAME_LENGTH); + if (strncmp(name, adapter->name, MAX_NAME_LENGTH) == 0) + return 0; + + if (!g_utf8_validate(name, -1, NULL)) { + error("Name change failed: supplied name isn't valid UTF-8"); + return -EINVAL; + } + + strncpy(adapter->name, name, MAX_NAME_LENGTH); if (main_opts.attrib_server) attrib_gap_set(GATT_CHARAC_DEVICE_NAME, - (const uint8_t *) dev->name, strlen(dev->name)); + (const uint8_t *) adapter->name, strlen(adapter->name)); + + name_ptr = adapter->name; - if (!adapter->name_stored) { - char *name_ptr = dev->name; + write_local_name(&adapter->bdaddr, adapter->name); - write_local_name(&adapter->bdaddr, dev->name); + if (connection) + emit_property_changed(connection, adapter->path, + ADAPTER_INTERFACE, "Name", + DBUS_TYPE_STRING, &name_ptr); - if (connection) - emit_property_changed(connection, adapter->path, - ADAPTER_INTERFACE, "Name", - DBUS_TYPE_STRING, &name_ptr); + if (adapter->up) { + int err = adapter_ops->set_name(adapter->dev_id, name); + if (err < 0) + return err; } - adapter->name_stored = FALSE; + return 0; } static DBusMessage *set_name(DBusConnection *conn, DBusMessage *msg, const char *name, void *data) { struct btd_adapter *adapter = data; - struct hci_dev *dev = &adapter->dev; - char *name_ptr = dev->name; + int ret; - if (!g_utf8_validate(name, -1, NULL)) { - error("Name change failed: supplied name isn't valid UTF-8"); + ret = adapter_update_local_name(adapter, name); + if (ret == -EINVAL) return btd_error_invalid_args(msg); - } - - if (strncmp(name, dev->name, MAX_NAME_LENGTH) == 0) - goto done; - - strncpy(dev->name, name, MAX_NAME_LENGTH); - write_local_name(&adapter->bdaddr, name); - emit_property_changed(connection, adapter->path, - ADAPTER_INTERFACE, "Name", - DBUS_TYPE_STRING, &name_ptr); - - if (adapter->up) { - int err = adapter_ops->set_name(adapter->dev_id, name); - if (err < 0) - return btd_error_failed(msg, strerror(-err)); + else if (ret < 0) + return btd_error_failed(msg, strerror(-ret)); - adapter->name_stored = TRUE; - } - -done: return dbus_message_new_method_return(msg); } @@ -1204,49 +1136,33 @@ DEVICE_TYPE_BREDR); } -static gboolean stop_scanning(gpointer user_data) -{ - struct btd_adapter *adapter = user_data; - - adapter_ops->stop_scanning(adapter->dev_id); - - return FALSE; -} - static int start_discovery(struct btd_adapter *adapter) { - int err, type; - /* Do not start if suspended */ - if (adapter->state & STATE_SUSPENDED) + if (adapter->state == STATE_SUSPENDED) return 0; /* Postpone discovery if still resolving names */ - if (adapter->state & STATE_RESOLVNAME) - return 1; + if (adapter->state == STATE_RESOLVNAME) + return -EINPROGRESS; pending_remote_name_cancel(adapter); - type = adapter_get_discover_type(adapter) & ~DISC_RESOLVNAME; + return adapter_ops->start_discovery(adapter->dev_id); +} - switch (type) { - case DISC_STDINQ: - case DISC_INTERLEAVE: - err = adapter_ops->start_inquiry(adapter->dev_id, - 0x08, FALSE); - break; - case DISC_PINQ: - err = adapter_ops->start_inquiry(adapter->dev_id, - 0x08, TRUE); - break; - case DISC_LE: - err = adapter_ops->start_scanning(adapter->dev_id); - break; - default: - err = -EINVAL; - } +static gboolean discovery_cb(gpointer user_data) +{ + struct btd_adapter *adapter = user_data; + int err; - return err; + err = start_discovery(adapter); + if (err == -EINPROGRESS) + return TRUE; + else if (err < 0) + error("start_discovery: %s (%d)", strerror(-err), -err); + + return FALSE; } static DBusMessage *adapter_start_discovery(DBusConnection *conn, @@ -1269,15 +1185,14 @@ if (adapter->disc_sessions) goto done; - g_slist_foreach(adapter->found_devices, (GFunc) dev_info_free, NULL); - g_slist_free(adapter->found_devices); + g_slist_free_full(adapter->found_devices, dev_info_free); adapter->found_devices = NULL; g_slist_free(adapter->oor_devices); adapter->oor_devices = NULL; err = start_discovery(adapter); - if (err < 0) + if (err < 0 && err != -EINPROGRESS) return btd_error_failed(msg, strerror(-err)); done: @@ -1308,11 +1223,6 @@ return dbus_message_new_method_return(msg); } -struct remote_device_list_t { - GSList *list; - time_t time; -}; - static DBusMessage *get_properties(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -1350,7 +1260,7 @@ /* Name */ memset(str, 0, sizeof(str)); - strncpy(str, (char *) adapter->dev.name, MAX_NAME_LENGTH); + strncpy(str, (char *) adapter->name, MAX_NAME_LENGTH); property = str; dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &property); @@ -1380,7 +1290,7 @@ DBUS_TYPE_UINT32, &adapter->pairable_timeout); - if (adapter->state & (STATE_PINQ | STATE_STDINQ | STATE_LE_SCAN)) + if (adapter->state == STATE_DISCOV) value = TRUE; else value = FALSE; @@ -1627,39 +1537,9 @@ return dbus_message_new_method_return(msg); } -static device_type_t flags2type(uint8_t flags) -{ - /* Inferring the remote type based on the EIR Flags field */ - - /* For LE only and dual mode the following flags must be zero */ - if (flags & (EIR_SIM_CONTROLLER | EIR_SIM_HOST)) - return DEVICE_TYPE_UNKNOWN; - - /* Limited or General discoverable mode bit must be enabled */ - if (!(flags & (EIR_LIM_DISC | EIR_GEN_DISC))) - return DEVICE_TYPE_UNKNOWN; - - if (flags & EIR_BREDR_UNSUP) - return DEVICE_TYPE_LE; - else - return DEVICE_TYPE_DUALMODE; -} - -static gboolean event_is_connectable(uint8_t type) -{ - switch (type) { - case ADV_TYPE_IND: - case ADV_TYPE_DIRECT_IND: - return TRUE; - default: - return FALSE; - } -} - static struct btd_device *create_device_internal(DBusConnection *conn, struct btd_adapter *adapter, - const gchar *address, - gboolean force, int *err) + const gchar *address, int *err) { struct remote_dev_info *dev, match; struct btd_device *device; @@ -1670,19 +1550,11 @@ match.name_status = NAME_ANY; dev = adapter_search_found_devices(adapter, &match); - if (dev && dev->flags) - type = flags2type(dev->flags); + if (dev && dev->le) + type = DEVICE_TYPE_LE; else type = DEVICE_TYPE_BREDR; - if (!force && type == DEVICE_TYPE_LE && - !event_is_connectable(dev->evt_type)) { - if (err) - *err = -ENOTCONN; - - return NULL; - } - device = adapter_create_device(conn, adapter, address, type); if (!device && err) *err = -ENOMEM; @@ -1714,7 +1586,7 @@ DBG("%s", address); - device = create_device_internal(conn, adapter, address, TRUE, &err); + device = create_device_internal(conn, adapter, address, &err); if (!device) goto failed; @@ -1795,8 +1667,7 @@ device = adapter_find_device(adapter, address); if (!device) { - device = create_device_internal(conn, adapter, address, - FALSE, &err); + device = create_device_internal(conn, adapter, address, &err); if (!device) return btd_error_failed(msg, strerror(-err)); } @@ -1992,7 +1863,7 @@ void *user_data) { struct btd_adapter *adapter = user_data; - GSList *uuids = bt_string2list(value); + GSList *list, *uuids = bt_string2list(value); struct btd_device *device; if (g_slist_find_custom(adapter->devices, @@ -2006,10 +1877,13 @@ device_set_temporary(device, FALSE); adapter->devices = g_slist_append(adapter->devices, device); + list = device_services_from_record(device, uuids); + if (list) + device_register_services(connection, device, list, ATT_PSM); + device_probe_drivers(device, uuids); - g_slist_foreach(uuids, (GFunc) g_free, NULL); - g_slist_free(uuids); + g_slist_free_full(uuids, g_free); } struct adapter_keys { @@ -2159,18 +2033,16 @@ struct btd_device *device; GSList *services, *uuids, *l; - l = g_slist_find_custom(adapter->devices, - key, (GCompareFunc) device_address_cmp); - if (l) - device = l->data; - else { - device = device_create(connection, adapter, key, DEVICE_TYPE_BREDR); - if (!device) - return; + if (g_slist_find_custom(adapter->devices, + key, (GCompareFunc) device_address_cmp)) + return; - device_set_temporary(device, FALSE); - adapter->devices = g_slist_append(adapter->devices, device); - } + device = device_create(connection, adapter, key, DEVICE_TYPE_LE); + if (!device) + return; + + device_set_temporary(device, FALSE); + adapter->devices = g_slist_append(adapter->devices, device); services = string_to_primary_list(value); if (services == NULL) @@ -2179,13 +2051,12 @@ for (l = services, uuids = NULL; l; l = l->next) { struct att_primary *prim = l->data; uuids = g_slist_append(uuids, prim->uuid); - - device_add_primary(device, prim); } + device_register_services(connection, device, services, -1); + device_probe_drivers(device, uuids); - g_slist_free(services); g_slist_free(uuids); } @@ -2214,8 +2085,7 @@ if (err < 0) { error("Unable to load keys to adapter_ops: %s (%d)", strerror(-err), -err); - g_slist_foreach(keys.keys, (GFunc) g_free, NULL); - g_slist_free(keys.keys); + g_slist_free_full(keys.keys, g_free); } create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "blocked"); @@ -2299,8 +2169,7 @@ adapter_add_connection(adapter, device); } - g_slist_foreach(conns, (GFunc) g_free, NULL); - g_slist_free(conns); + g_slist_free_full(conns, g_free); } static int get_discoverable_timeout(const char *src) @@ -2355,46 +2224,10 @@ static void update_oor_devices(struct btd_adapter *adapter) { g_slist_foreach(adapter->oor_devices, emit_device_disappeared, adapter); - g_slist_foreach(adapter->oor_devices, (GFunc) dev_info_free, NULL); - g_slist_free(adapter->oor_devices); + g_slist_free_full(adapter->oor_devices, dev_info_free); adapter->oor_devices = g_slist_copy(adapter->found_devices); } -static gboolean bredr_capable(struct btd_adapter *adapter) -{ - struct hci_dev *dev = &adapter->dev; - - return (dev->features[4] & LMP_NO_BREDR) == 0 ? TRUE : FALSE; -} - -static gboolean le_capable(struct btd_adapter *adapter) -{ - struct hci_dev *dev = &adapter->dev; - - return (dev->features[4] & LMP_LE && - dev->extfeatures[0] & LMP_HOST_LE) ? TRUE : FALSE; -} - -int adapter_get_discover_type(struct btd_adapter *adapter) -{ - gboolean le, bredr; - int type; - - le = le_capable(adapter); - bredr = bredr_capable(adapter); - - if (le) - type = bredr ? DISC_INTERLEAVE : DISC_LE; - else - type = main_opts.discov_interval ? DISC_STDINQ : - DISC_PINQ; - - if (main_opts.name_resolv) - type |= DISC_RESOLVNAME; - - return type; -} - void btd_adapter_get_mode(struct btd_adapter *adapter, uint8_t *mode, uint8_t *on_mode, gboolean *pairable) { @@ -2439,11 +2272,12 @@ adapter->pairable_timeout = get_pairable_timeout(address); adapter->state = STATE_IDLE; adapter->mode = MODE_CONNECTABLE; + adapter->off_timer = 0; if (main_opts.le) adapter_ops->enable_le(adapter->dev_id); - adapter_ops->set_name(adapter->dev_id, adapter->dev.name); + adapter_ops->set_name(adapter->dev_id, adapter->name); if (read_local_class(&adapter->bdaddr, cls) < 0) { uint32_t class = htobl(main_opts.class); @@ -2564,12 +2398,10 @@ /* check pending requests */ reply_pending_requests(adapter); - stop_discovery(adapter, FALSE); + stop_discovery(adapter); if (adapter->disc_sessions) { - g_slist_foreach(adapter->disc_sessions, (GFunc) session_free, - NULL); - g_slist_free(adapter->disc_sessions); + g_slist_free_full(adapter->disc_sessions, session_free); adapter->disc_sessions = NULL; } @@ -2601,7 +2433,6 @@ adapter->mode = MODE_OFF; adapter->state = STATE_IDLE; adapter->off_requested = FALSE; - adapter->name_stored = FALSE; call_adapter_powered_callbacks(adapter, FALSE); @@ -2612,13 +2443,10 @@ return 0; } -int adapter_update_ssp_mode(struct btd_adapter *adapter, uint8_t mode) +static void off_timer_remove(struct btd_adapter *adapter) { - struct hci_dev *dev = &adapter->dev; - - dev->ssp_mode = mode; - - return 0; + g_source_remove(adapter->off_timer); + adapter->off_timer = 0; } static void adapter_free(gpointer user_data) @@ -2633,10 +2461,12 @@ if (adapter->auth_idle_id) g_source_remove(adapter->auth_idle_id); + if (adapter->off_timer) + off_timer_remove(adapter); + sdp_list_free(adapter->services, NULL); - g_slist_foreach(adapter->found_devices, (GFunc) dev_info_free, NULL); - g_slist_free(adapter->found_devices); + g_slist_free_full(adapter->found_devices, dev_info_free); g_slist_free(adapter->oor_devices); @@ -2673,14 +2503,12 @@ gboolean adapter_init(struct btd_adapter *adapter) { - struct hci_version ver; - struct hci_dev *dev; - int err; - /* adapter_ops makes sure that newly registered adapters always * start off as powered */ adapter->up = TRUE; + adapter->allow_name_changes = TRUE; + adapter_ops->read_bdaddr(adapter->dev_id, &adapter->bdaddr); if (bacmp(&adapter->bdaddr, BDADDR_ANY) == 0) { @@ -2688,35 +2516,6 @@ return FALSE; } - err = adapter_ops->read_local_version(adapter->dev_id, &ver); - if (err < 0) { - error("Can't read version info for hci%d: %s (%d)", - adapter->dev_id, strerror(-err), -err); - return FALSE; - } - - dev = &adapter->dev; - - dev->hci_rev = ver.hci_rev; - dev->lmp_ver = ver.lmp_ver; - dev->lmp_subver = ver.lmp_subver; - dev->manufacturer = ver.manufacturer; - - err = adapter_ops->read_local_features(adapter->dev_id, dev->features); - if (err < 0) { - error("Can't read features for hci%d: %s (%d)", - adapter->dev_id, strerror(-err), -err); - return FALSE; - } - - if (read_local_name(&adapter->bdaddr, adapter->dev.name) < 0) - expand_name(adapter->dev.name, MAX_NAME_LENGTH, main_opts.name, - adapter->dev_id); - - if (main_opts.attrib_server) - attrib_gap_set(GATT_CHARAC_DEVICE_NAME, - (const uint8_t *) dev->name, strlen(dev->name)); - sdp_init_services_list(&adapter->bdaddr); load_drivers(adapter); clear_blocked(adapter); @@ -2777,11 +2576,10 @@ g_slist_free(adapter->devices); unload_drivers(adapter); + g_slist_free(adapter->pin_callbacks); /* Return adapter to down state if it was not up on init */ adapter_ops->restore_powered(adapter->dev_id); - - btd_adapter_unref(adapter); } uint16_t adapter_get_dev_id(struct btd_adapter *adapter) @@ -2802,81 +2600,82 @@ bacpy(bdaddr, &adapter->bdaddr); } +void adapter_set_allow_name_changes(struct btd_adapter *adapter, + gboolean allow_name_changes) +{ + adapter->allow_name_changes = allow_name_changes; +} + +static inline void suspend_discovery(struct btd_adapter *adapter) +{ + if (adapter->state != STATE_SUSPENDED) + return; + + if (adapter->oor_devices) { + g_slist_free(adapter->oor_devices); + adapter->oor_devices = NULL; + } + + if (adapter->scheduler_id) { + g_source_remove(adapter->scheduler_id); + adapter->scheduler_id = 0; + } + + adapter_ops->stop_discovery(adapter->dev_id); +} + +static inline void resolve_names(struct btd_adapter *adapter) +{ + int err; + + if (adapter->state != STATE_RESOLVNAME) + return; + + err = adapter_resolve_names(adapter); + if (err < 0) + adapter_set_state(adapter, STATE_IDLE); +} + void adapter_set_state(struct btd_adapter *adapter, int state) { const char *path = adapter->path; gboolean discov_active; - int previous, type; if (adapter->state == state) return; - previous = adapter->state; adapter->state = state; - type = adapter_get_discover_type(adapter); + DBG("hci%d: new state %d", adapter->dev_id, adapter->state); - switch (state) { - case STATE_STDINQ: - case STATE_PINQ: - discov_active = TRUE; + switch (adapter->state) { + case STATE_IDLE: + update_oor_devices(adapter); - /* Started a new session while resolving names ? */ - if (previous & STATE_RESOLVNAME) - return; - break; - case STATE_LE_SCAN: - /* Scanning enabled */ - if (adapter->disc_sessions) { - adapter->stop_discov_id = g_timeout_add(5120, - stop_scanning, - adapter); + discov_active = FALSE; + emit_property_changed(connection, path, + ADAPTER_INTERFACE, "Discovering", + DBUS_TYPE_BOOLEAN, &discov_active); - /* For dual mode: don't send "Discovering = TRUE" */ - if (bredr_capable(adapter) == TRUE) - return; + if (adapter_has_discov_sessions(adapter)) { + adapter->scheduler_id = g_timeout_add_seconds( + main_opts.discov_interval, + discovery_cb, adapter); } - - /* LE only */ + break; + case STATE_DISCOV: discov_active = TRUE; - + emit_property_changed(connection, path, + ADAPTER_INTERFACE, "Discovering", + DBUS_TYPE_BOOLEAN, &discov_active); break; - case STATE_IDLE: - /* - * Interleave: from inquiry to scanning. Interleave is not - * applicable to requests triggered by external applications. - */ - if (adapter->disc_sessions && (type & DISC_INTERLEAVE) && - (previous & STATE_STDINQ)) { - adapter_ops->start_scanning(adapter->dev_id); - return; - } - /* BR/EDR only: inquiry finished */ - discov_active = FALSE; + case STATE_RESOLVNAME: + resolve_names(adapter); break; - default: - discov_active = FALSE; + case STATE_SUSPENDED: + suspend_discovery(adapter); break; } - - if (discov_active == FALSE) { - if (type & DISC_RESOLVNAME) { - if (adapter_resolve_names(adapter) == 0) { - adapter->state |= STATE_RESOLVNAME; - return; - } - } - - update_oor_devices(adapter); - } else if (adapter->disc_sessions && main_opts.discov_interval) - adapter->scheduler_id = g_timeout_add_seconds( - main_opts.discov_interval, - (GSourceFunc) start_discovery, - adapter); - - emit_property_changed(connection, path, - ADAPTER_INTERFACE, "Discovering", - DBUS_TYPE_BOOLEAN, &discov_active); } int adapter_get_state(struct btd_adapter *adapter) @@ -2965,7 +2764,6 @@ static char **strlist2array(GSList *list) { - GSList *l; unsigned int i, n; char **array; @@ -2975,8 +2773,8 @@ n = g_slist_length(list); array = g_new0(char *, n + 1); - for (l = list, i = 0; l; l = l->next, i++) - array[i] = g_strdup((const gchar *) l->data); + for (i = 0; list; list = list->next, i++) + array[i] = g_strdup((const gchar *) list->data); return array; } @@ -3052,29 +2850,24 @@ g_free(alias); } -static struct remote_dev_info *get_found_dev(struct btd_adapter *adapter, - const bdaddr_t *bdaddr, - gboolean *new_dev) +static struct remote_dev_info *found_device_new(const bdaddr_t *bdaddr, + gboolean le, const char *name, + const char *alias, uint32_t class, + gboolean legacy, name_status_t status, + int flags) { - struct remote_dev_info *dev, match; - - memset(&match, 0, sizeof(struct remote_dev_info)); - bacpy(&match.bdaddr, bdaddr); - match.name_status = NAME_ANY; + struct remote_dev_info *dev; - dev = adapter_search_found_devices(adapter, &match); - if (dev) { - *new_dev = FALSE; - /* Out of range list update */ - adapter->oor_devices = g_slist_remove(adapter->oor_devices, - dev); - } else { - *new_dev = TRUE; - dev = g_new0(struct remote_dev_info, 1); - bacpy(&dev->bdaddr, bdaddr); - adapter->found_devices = g_slist_prepend(adapter->found_devices, - dev); - } + dev = g_new0(struct remote_dev_info, 1); + bacpy(&dev->bdaddr, bdaddr); + dev->le = le; + dev->name = g_strdup(name); + dev->alias = g_strdup(alias); + dev->class = class; + dev->legacy = legacy; + dev->name_status = status; + if (flags >= 0) + dev->flags = flags; return dev; } @@ -3104,76 +2897,118 @@ dev->services = g_slist_prepend(dev->services, g_strdup(new_uuid)); } -void adapter_update_device_from_info(struct btd_adapter *adapter, - bdaddr_t bdaddr, int8_t rssi, - uint8_t evt_type, const char *name, - GSList *services, int flags) +static gboolean pairing_is_legacy(bdaddr_t *local, bdaddr_t *peer, + const uint8_t *eir, const char *name) { - struct remote_dev_info *dev; - gboolean new_dev; + unsigned char features[8]; - dev = get_found_dev(adapter, &bdaddr, &new_dev); + if (eir) + return FALSE; - if (new_dev) { - dev->le = TRUE; - dev->evt_type = evt_type; - } else if (dev->rssi == rssi) - return; + if (name == NULL) + return TRUE; - dev->rssi = rssi; + if (read_remote_features(local, peer, NULL, features) < 0) + return TRUE; - adapter->found_devices = g_slist_sort(adapter->found_devices, - (GCompareFunc) dev_rssi_cmp); + if (features[0] & 0x01) + return FALSE; + else + return TRUE; +} - g_slist_foreach(services, remove_same_uuid, dev); - g_slist_foreach(services, dev_prepend_uuid, dev); +static char *read_stored_data(bdaddr_t *local, bdaddr_t *peer, const char *file) +{ + char local_addr[18], peer_addr[18], filename[PATH_MAX + 1]; - if (flags >= 0) - dev->flags = flags; + ba2str(local, local_addr); + ba2str(peer, peer_addr); - if (name) { - g_free(dev->name); - dev->name = g_strdup(name); - } + create_name(filename, PATH_MAX, STORAGEDIR, local_addr, file); - /* FIXME: check if other information was changed before emitting the - * signal */ - adapter_emit_device_found(adapter, dev); + return textfile_get(filename, peer_addr); } void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr, - int8_t rssi, uint32_t class, const char *name, - const char *alias, gboolean legacy, - GSList *services, name_status_t name_status) + uint32_t class, int8_t rssi, + uint8_t *data) { - struct remote_dev_info *dev; - gboolean new_dev; + struct remote_dev_info *dev, match; + struct eir_data eir_data; + char *alias, *name; + gboolean legacy, le; + name_status_t name_status; + int err; + + memset(&eir_data, 0, sizeof(eir_data)); + err = eir_parse(&eir_data, data); + if (err < 0) { + error("Error parsing EIR data: %s (%d)", strerror(-err), -err); + return; + } - dev = get_found_dev(adapter, bdaddr, &new_dev); + if (eir_data.name != NULL && eir_data.name_complete) + write_device_name(&adapter->bdaddr, bdaddr, eir_data.name); + + /* Device already seen in the discovery session ? */ + memset(&match, 0, sizeof(struct remote_dev_info)); + bacpy(&match.bdaddr, bdaddr); + match.name_status = NAME_ANY; + + dev = adapter_search_found_devices(adapter, &match); + if (dev) { + adapter->oor_devices = g_slist_remove(adapter->oor_devices, + dev); + if (dev->rssi != rssi) + goto done; + + eir_data_free(&eir_data); - if (new_dev) { - if (name) - dev->name = g_strdup(name); - - if (alias) - dev->alias = g_strdup(alias); - - dev->le = FALSE; - dev->class = class; - dev->legacy = legacy; - dev->name_status = name_status; - } else if (dev->rssi == rssi) return; + } + + /* New device in the discovery session */ + + name = read_stored_data(&adapter->bdaddr, bdaddr, "names"); + if (eir_data.flags < 0) { + le = FALSE; + + legacy = pairing_is_legacy(&adapter->bdaddr, bdaddr, data, + name); + + if (!name && main_opts.name_resolv && + adapter_has_discov_sessions(adapter)) + name_status = NAME_REQUIRED; + else + name_status = NAME_NOT_REQUIRED; + } else { + le = TRUE; + legacy = FALSE; + name_status = NAME_NOT_REQUIRED; + } + + alias = read_stored_data(&adapter->bdaddr, bdaddr, "aliases"); + + dev = found_device_new(bdaddr, le, name, alias, class, legacy, + name_status, eir_data.flags); + free(name); + free(alias); + + adapter->found_devices = g_slist_prepend(adapter->found_devices, dev); + +done: dev->rssi = rssi; adapter->found_devices = g_slist_sort(adapter->found_devices, (GCompareFunc) dev_rssi_cmp); - g_slist_foreach(services, remove_same_uuid, dev); - g_slist_foreach(services, dev_prepend_uuid, dev); + g_slist_foreach(eir_data.services, remove_same_uuid, dev); + g_slist_foreach(eir_data.services, dev_prepend_uuid, dev); adapter_emit_device_found(adapter, dev); + + eir_data_free(&eir_data); } int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr) @@ -3256,7 +3091,7 @@ struct agent *adapter_get_agent(struct btd_adapter *adapter) { - if (!adapter || !adapter->agent) + if (!adapter) return NULL; return adapter->agent; @@ -3278,8 +3113,6 @@ void adapter_remove_connection(struct btd_adapter *adapter, struct btd_device *device) { - bdaddr_t bdaddr; - DBG(""); if (!g_slist_find(adapter->connections, device)) { @@ -3291,9 +3124,6 @@ adapter->connections = g_slist_remove(adapter->connections, device); - /* clean pending HCI cmds */ - device_get_address(device, &bdaddr); - if (device_is_authenticating(device)) device_cancel_authentication(device, TRUE); @@ -3316,24 +3146,19 @@ void adapter_suspend_discovery(struct btd_adapter *adapter) { if (adapter->disc_sessions == NULL || - adapter->state & STATE_SUSPENDED) + adapter->state == STATE_SUSPENDED) return; DBG("Suspending discovery"); - stop_discovery(adapter, TRUE); - adapter->state |= STATE_SUSPENDED; + adapter_set_state(adapter, STATE_SUSPENDED); } void adapter_resume_discovery(struct btd_adapter *adapter) { - if (adapter->disc_sessions == NULL) - return; - DBG("Resuming discovery"); - adapter->state &= ~STATE_SUSPENDED; - start_discovery(adapter); + adapter_set_state(adapter, STATE_IDLE); } int btd_register_adapter_driver(struct btd_adapter_driver *driver) @@ -3547,7 +3372,6 @@ int btd_adapter_restore_powered(struct btd_adapter *adapter) { char mode[14], address[18]; - gboolean discoverable; if (!adapter_ops) return -EINVAL; @@ -3563,11 +3387,19 @@ g_str_equal(mode, "off")) return 0; - discoverable = get_mode(&adapter->bdaddr, mode) == MODE_DISCOVERABLE; - return adapter_ops->set_powered(adapter->dev_id, TRUE); } +static gboolean switch_off_timeout(gpointer user_data) +{ + struct btd_adapter *adapter = user_data; + + adapter_ops->set_powered(adapter->dev_id, FALSE); + adapter->off_timer = 0; + + return FALSE; +} + int btd_adapter_switch_online(struct btd_adapter *adapter) { if (!adapter_ops) @@ -3576,6 +3408,9 @@ if (adapter->up) return 0; + if (adapter->off_timer) + off_timer_remove(adapter); + return adapter_ops->set_powered(adapter->dev_id, TRUE); } @@ -3587,7 +3422,54 @@ if (!adapter->up) return 0; - return adapter_ops->set_powered(adapter->dev_id, FALSE); + if (adapter->off_timer) + return 0; + + adapter->global_mode = MODE_OFF; + + if (adapter->connections == NULL) + return adapter_ops->set_powered(adapter->dev_id, FALSE); + + g_slist_foreach(adapter->connections, + (GFunc) device_request_disconnect, NULL); + + adapter->off_timer = g_timeout_add_seconds(OFF_TIMER, + switch_off_timeout, adapter); + + return 0; +} + +void btd_adapter_register_pin_cb(struct btd_adapter *adapter, + btd_adapter_pin_cb_t cb) +{ + adapter->pin_callbacks = g_slist_prepend(adapter->pin_callbacks, cb); +} + +void btd_adapter_unregister_pin_cb(struct btd_adapter *adapter, + btd_adapter_pin_cb_t cb) +{ + adapter->pin_callbacks = g_slist_remove(adapter->pin_callbacks, cb); +} + +ssize_t btd_adapter_get_pin(struct btd_adapter *adapter, struct btd_device *dev, + char *pin_buf) +{ + GSList *l; + btd_adapter_pin_cb_t cb; + bdaddr_t sba, dba; + ssize_t ret; + + for (l = adapter->pin_callbacks; l != NULL; l = g_slist_next(l)) { + cb = l->data; + ret = cb(adapter, dev, pin_buf); + if (ret > 0) + return ret; + } + + adapter_get_address(adapter, &sba); + device_get_address(dev, &dba); + + return read_pin_code(&sba, &dba, pin_buf); } int btd_register_adapter_ops(struct btd_adapter_ops *ops, gboolean priority) @@ -3685,9 +3567,10 @@ } int btd_adapter_pincode_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr, - const char *pin) + const char *pin, size_t pin_len) { - return adapter_ops->pincode_reply(adapter->dev_id, bdaddr, pin); + return adapter_ops->pincode_reply(adapter->dev_id, bdaddr, pin, + pin_len); } int btd_adapter_confirm_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr, @@ -3702,14 +3585,6 @@ return adapter_ops->passkey_reply(adapter->dev_id, bdaddr, passkey); } -void btd_adapter_update_local_ext_features(struct btd_adapter *adapter, - const uint8_t *features) -{ - struct hci_dev *dev = &adapter->dev; - - memcpy(dev->extfeatures, features, 8); -} - int btd_adapter_encrypt_link(struct btd_adapter *adapter, bdaddr_t *bdaddr, bt_hci_result_t cb, gpointer user_data) { diff -Nru bluez-4.91/src/adapter.h bluez-4.96/src/adapter.h --- bluez-4.91/src/adapter.h 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/src/adapter.h 2011-07-31 06:52:19.000000000 +0000 @@ -37,19 +37,10 @@ #define MODE_UNKNOWN 0xff /* Discover states */ -#define STATE_IDLE 0x00 -#define STATE_LE_SCAN 0x01 -#define STATE_STDINQ 0x02 -#define STATE_PINQ 0x04 -#define STATE_RESOLVNAME 0x08 -#define STATE_SUSPENDED 0x10 - -/* Supported host/controller discover type */ -#define DISC_LE 0x01 -#define DISC_STDINQ 0x02 -#define DISC_INTERLEAVE 0x04 -#define DISC_PINQ 0x08 -#define DISC_RESOLVNAME 0x10 +#define STATE_IDLE 0 +#define STATE_DISCOV 1 +#define STATE_RESOLVNAME 2 +#define STATE_SUSPENDED 3 #define MAX_NAME_LENGTH 248 @@ -84,23 +75,10 @@ char **uuids; size_t uuid_count; GSList *services; - uint8_t evt_type; uint8_t bdaddr_type; uint8_t flags; }; -struct hci_dev { - uint8_t features[8]; - uint8_t extfeatures[8]; - uint8_t lmp_ver; - uint16_t lmp_subver; - uint16_t hci_rev; - uint16_t manufacturer; - - uint8_t ssp_mode; - char name[MAX_NAME_LENGTH + 1]; -}; - void btd_adapter_start(struct btd_adapter *adapter); int btd_adapter_stop(struct btd_adapter *adapter); @@ -108,8 +86,6 @@ void btd_adapter_get_mode(struct btd_adapter *adapter, uint8_t *mode, uint8_t *on_mode, gboolean *pairable); -int adapter_update_ssp_mode(struct btd_adapter *adapter, uint8_t mode); - struct btd_device *adapter_get_device(DBusConnection *conn, struct btd_adapter *adapter, const char *address); @@ -124,6 +100,8 @@ struct btd_adapter *adapter_create(DBusConnection *conn, int id); gboolean adapter_init(struct btd_adapter *adapter); void adapter_remove(struct btd_adapter *adapter); +void adapter_set_allow_name_changes(struct btd_adapter *adapter, + gboolean allow_name_changes); uint16_t adapter_get_dev_id(struct btd_adapter *adapter); const gchar *adapter_get_path(struct btd_adapter *adapter); void adapter_get_address(struct btd_adapter *adapter, bdaddr_t *bdaddr); @@ -132,19 +110,14 @@ int adapter_get_discover_type(struct btd_adapter *adapter); struct remote_dev_info *adapter_search_found_devices(struct btd_adapter *adapter, struct remote_dev_info *match); -void adapter_update_device_from_info(struct btd_adapter *adapter, - bdaddr_t bdaddr, int8_t rssi, - uint8_t evt_type, const char *name, - GSList *services, int flags); void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr, - int8_t rssi, uint32_t class, const char *name, - const char *alias, gboolean legacy, - GSList *services, name_status_t name_status); + uint32_t class, int8_t rssi, + uint8_t *data); int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr); void adapter_emit_device_found(struct btd_adapter *adapter, struct remote_dev_info *dev); void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode); -void adapter_update_local_name(struct btd_adapter *adapter, const char *name); +int adapter_update_local_name(struct btd_adapter *adapter, const char *name); void adapter_service_insert(struct btd_adapter *adapter, void *rec); void adapter_service_remove(struct btd_adapter *adapter, void *rec); void btd_adapter_class_changed(struct btd_adapter *adapter, @@ -192,6 +165,15 @@ int btd_adapter_switch_online(struct btd_adapter *adapter); int btd_adapter_switch_offline(struct btd_adapter *adapter); +typedef ssize_t (*btd_adapter_pin_cb_t) (struct btd_adapter *adapter, + struct btd_device *dev, char *out); +void btd_adapter_register_pin_cb(struct btd_adapter *adapter, + btd_adapter_pin_cb_t cb); +void btd_adapter_unregister_pin_cb(struct btd_adapter *adapter, + btd_adapter_pin_cb_t cb); +ssize_t btd_adapter_get_pin(struct btd_adapter *adapter, struct btd_device *dev, + char *pin_buf); + typedef void (*bt_hci_result_t) (uint8_t status, gpointer user_data); struct btd_adapter_ops { @@ -201,10 +183,8 @@ int (*set_discoverable) (int index, gboolean discoverable); int (*set_pairable) (int index, gboolean pairable); int (*set_limited_discoverable) (int index, gboolean limited); - int (*start_inquiry) (int index, uint8_t length, gboolean periodic); - int (*stop_inquiry) (int index); - int (*start_scanning) (int index); - int (*stop_scanning) (int index); + int (*start_discovery) (int index); + int (*stop_discovery) (int index); int (*resolve_name) (int index, bdaddr_t *bdaddr); int (*cancel_resolve_name) (int index, bdaddr_t *bdaddr); @@ -217,11 +197,10 @@ int (*block_device) (int index, bdaddr_t *bdaddr); int (*unblock_device) (int index, bdaddr_t *bdaddr); int (*get_conn_list) (int index, GSList **conns); - int (*read_local_version) (int index, struct hci_version *ver); - int (*read_local_features) (int index, uint8_t *features); int (*disconnect) (int index, bdaddr_t *bdaddr); int (*remove_bonding) (int index, bdaddr_t *bdaddr); - int (*pincode_reply) (int index, bdaddr_t *bdaddr, const char *pin); + int (*pincode_reply) (int index, bdaddr_t *bdaddr, const char *pin, + size_t pin_len); int (*confirm_reply) (int index, bdaddr_t *bdaddr, gboolean success); int (*passkey_reply) (int index, bdaddr_t *bdaddr, uint32_t passkey); int (*enable_le) (int index); @@ -273,15 +252,12 @@ int btd_adapter_remove_bonding(struct btd_adapter *adapter, bdaddr_t *bdaddr); int btd_adapter_pincode_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr, - const char *pin); + const char *pin, size_t pin_len); int btd_adapter_confirm_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr, gboolean success); int btd_adapter_passkey_reply(struct btd_adapter *adapter, bdaddr_t *bdaddr, uint32_t passkey); -void btd_adapter_update_local_ext_features(struct btd_adapter *adapter, - const uint8_t *features); - int btd_adapter_encrypt_link(struct btd_adapter *adapter, bdaddr_t *bdaddr, bt_hci_result_t cb, gpointer user_data); diff -Nru bluez-4.91/src/agent.c bluez-4.96/src/agent.c --- bluez-4.91/src/agent.c 2011-02-13 20:40:34.000000000 +0000 +++ bluez-4.96/src/agent.c 2011-07-31 06:52:19.000000000 +0000 @@ -41,7 +41,6 @@ #include "log.h" -#include "hcid.h" #include "adapter.h" #include "device.h" #include "agent.h" @@ -424,10 +423,13 @@ } static int pincode_request_new(struct agent_request *req, const char *device_path, - dbus_bool_t numeric) + dbus_bool_t secure) { struct agent *agent = req->agent; + /* TODO: Add a new method or a new param to Agent interface to request + secure pin. */ + req->msg = dbus_message_new_method_call(agent->name, agent->path, "org.bluez.Agent", "RequestPinCode"); if (req->msg == NULL) { @@ -449,8 +451,8 @@ } int agent_request_pincode(struct agent *agent, struct btd_device *device, - agent_pincode_cb cb, void *user_data, - GDestroyNotify destroy) + agent_pincode_cb cb, gboolean secure, + void *user_data, GDestroyNotify destroy) { struct agent_request *req; const gchar *dev_path = device_get_path(device); @@ -462,7 +464,7 @@ req = agent_request_new(agent, AGENT_REQUEST_PINCODE, cb, user_data, destroy); - err = pincode_request_new(req, dev_path, FALSE); + err = pincode_request_new(req, dev_path, secure); if (err < 0) goto failed; diff -Nru bluez-4.91/src/agent.h bluez-4.96/src/agent.h --- bluez-4.91/src/agent.h 2010-01-09 20:52:17.000000000 +0000 +++ bluez-4.96/src/agent.h 2011-07-04 04:59:05.000000000 +0000 @@ -46,8 +46,8 @@ GDestroyNotify destroy); int agent_request_pincode(struct agent *agent, struct btd_device *device, - agent_pincode_cb cb, void *user_data, - GDestroyNotify destroy); + agent_pincode_cb cb, gboolean secure, + void *user_data, GDestroyNotify destroy); int agent_confirm_mode_change(struct agent *agent, const char *new_mode, agent_cb cb, void *user_data, diff -Nru bluez-4.91/src/attio.h bluez-4.96/src/attio.h --- bluez-4.91/src/attio.h 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/src/attio.h 2011-07-31 06:52:19.000000000 +0000 @@ -0,0 +1,33 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 Nokia Corporation + * Copyright (C) 2011 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +typedef void (*attio_connect_cb) (GAttrib *attrib, gpointer user_data); +typedef void (*attio_disconnect_cb) (gpointer user_data); + +guint btd_device_add_attio_callback(struct btd_device *device, + attio_connect_cb cfunc, + attio_disconnect_cb dcfunc, + gpointer user_data); + +gboolean btd_device_remove_attio_callback(struct btd_device *device, guint id); diff -Nru bluez-4.91/src/attrib-server.c bluez-4.96/src/attrib-server.c --- bluez-4.91/src/attrib-server.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/src/attrib-server.c 2011-07-04 04:59:05.000000000 +0000 @@ -47,9 +47,6 @@ #include "attrib-server.h" -#define GATT_PSM 0x1f -#define GATT_CID 4 - static GSList *database = NULL; struct gatt_channel { @@ -97,7 +94,7 @@ uuid_t root_uuid, proto_uuid, l2cap; sdp_record_t *record; sdp_data_t *psm, *sh, *eh; - uint16_t lp = GATT_PSM; + uint16_t lp = ATT_PSM; if (uuid == NULL) return NULL; @@ -172,9 +169,9 @@ if (!channel->encrypted) channel->encrypted = g_attrib_is_encrypted(channel->attrib); if (reqs == ATT_AUTHENTICATION && !channel->encrypted) - return ATT_ECODE_INSUFF_AUTHEN; + return ATT_ECODE_AUTHENTICATION; else if (reqs == ATT_AUTHORIZATION) - return ATT_ECODE_INSUFF_AUTHO; + return ATT_ECODE_AUTHORIZATION; switch (opcode) { case ATT_OP_READ_BY_GROUP_REQ: @@ -354,8 +351,7 @@ status = a->read_cb(a, a->cb_user_data); if (status) { - g_slist_foreach(groups, (GFunc) g_free, NULL); - g_slist_free(groups); + g_slist_free_full(groups, g_free); return enc_error_resp(ATT_OP_READ_BY_GROUP_REQ, a->handle, status, pdu, len); } @@ -402,8 +398,7 @@ length = enc_read_by_grp_resp(adl, pdu, len); att_data_list_free(adl); - g_slist_foreach(groups, (GFunc) g_free, NULL); - g_slist_free(groups); + g_slist_free_full(groups, g_free); return length; } @@ -431,7 +426,7 @@ if (a->handle < start) continue; - if (a->handle >= end) + if (a->handle > end) break; if (bt_uuid_cmp(&a->uuid, uuid) != 0) @@ -617,8 +612,7 @@ len = enc_find_by_type_resp(matches, opdu, mtu); - g_slist_foreach(matches, (GFunc) g_free, NULL); - g_slist_free(matches); + g_slist_free_full(matches, g_free); return len; } @@ -789,8 +783,7 @@ g_slist_free(channel->notify); g_slist_free(channel->indicate); - g_slist_foreach(channel->configs, (GFunc) g_free, NULL); - g_slist_free(channel->configs); + g_slist_free_full(channel->configs, g_free); g_free(channel); } @@ -949,7 +942,7 @@ if (channel->mtu > ATT_MAX_MTU) channel->mtu = ATT_MAX_MTU; - if (cid != GATT_CID) + if (cid != ATT_CID) channel->le = FALSE; else channel->le = TRUE; @@ -1089,7 +1082,7 @@ l2cap_io = bt_io_listen(BT_IO_L2CAP, NULL, confirm_event, NULL, NULL, &gerr, BT_IO_OPT_SOURCE_BDADDR, BDADDR_ANY, - BT_IO_OPT_PSM, GATT_PSM, + BT_IO_OPT_PSM, ATT_PSM, BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, BT_IO_OPT_INVALID); if (l2cap_io == NULL) { @@ -1108,7 +1101,7 @@ le_io = bt_io_listen(BT_IO_L2CAP, NULL, confirm_event, &le_io, NULL, &gerr, BT_IO_OPT_SOURCE_BDADDR, BDADDR_ANY, - BT_IO_OPT_CID, GATT_CID, + BT_IO_OPT_CID, ATT_CID, BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, BT_IO_OPT_INVALID); if (le_io == NULL) { @@ -1135,8 +1128,7 @@ { GSList *l; - g_slist_foreach(database, (GFunc) g_free, NULL); - g_slist_free(database); + g_slist_free_full(database, g_free); if (l2cap_io) { g_io_channel_unref(l2cap_io); @@ -1153,8 +1145,7 @@ g_slist_free(channel->notify); g_slist_free(channel->indicate); - g_slist_foreach(channel->configs, (GFunc) g_free, NULL); - g_slist_free(channel->configs); + g_slist_free_full(channel->configs, g_free); g_attrib_unref(channel->attrib); g_free(channel); @@ -1215,6 +1206,34 @@ remove_record_from_server(sdp_handle); } +uint16_t attrib_db_find_avail(uint16_t nitems) +{ + uint16_t handle; + GSList *l; + + g_assert(nitems > 0); + + for (l = database, handle = 0; l; l = l->next) { + struct attribute *a = l->data; + + if (handle && (bt_uuid_cmp(&a->uuid, &prim_uuid) == 0 || + bt_uuid_cmp(&a->uuid, &snd_uuid) == 0) && + a->handle - handle >= nitems) + /* Note: the range above excludes the current handle */ + return handle; + + if (a->handle == 0xffff) + return 0; + + handle = a->handle + 1; + } + + if (0xffff - handle + 1 >= nitems) + return handle; + + return 0; +} + struct attribute *attrib_db_add(uint16_t handle, bt_uuid_t *uuid, int read_reqs, int write_reqs, const uint8_t *value, int len) { diff -Nru bluez-4.91/src/attrib-server.h bluez-4.96/src/attrib-server.h --- bluez-4.91/src/attrib-server.h 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/src/attrib-server.h 2011-07-31 06:52:19.000000000 +0000 @@ -22,9 +22,7 @@ * */ -int attrib_server_init(void); -void attrib_server_exit(void); - +uint16_t attrib_db_find_avail(uint16_t nitems); struct attribute *attrib_db_add(uint16_t handle, bt_uuid_t *uuid, int read_reqs, int write_reqs, const uint8_t *value, int len); int attrib_db_update(uint16_t handle, bt_uuid_t *uuid, const uint8_t *value, diff -Nru bluez-4.91/src/bluetooth.service.in bluez-4.96/src/bluetooth.service.in --- bluez-4.91/src/bluetooth.service.in 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/src/bluetooth.service.in 2011-07-04 04:59:05.000000000 +0000 @@ -0,0 +1,12 @@ +[Unit] +Description=Bluetooth service +After=syslog.target + +[Service] +Type=dbus +BusName=org.bluez +ExecStart=@prefix@/sbin/bluetoothd -n +StandardOutput=syslog + +[Install] +WantedBy=bluetooth.target diff -Nru bluez-4.91/src/device.c bluez-4.96/src/device.c --- bluez-4.91/src/device.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/src/device.c 2011-07-31 06:52:19.000000000 +0000 @@ -49,20 +49,23 @@ #include "att.h" #include "hcid.h" #include "adapter.h" +#include "gattrib.h" +#include "attio.h" #include "device.h" #include "dbus-common.h" #include "event.h" #include "error.h" #include "glib-helper.h" -#include "gattrib.h" #include "gatt.h" #include "agent.h" #include "sdp-xml.h" #include "storage.h" #include "btio.h" +#include "attrib/client.h" #define DISCONNECT_TIMER 2 #define DISCOVERY_TIMER 2 +#define AUTOCONNECT_INTERVAL 45 /* When all services should trust a remote device */ #define GLOBAL_TRUST "[all]" @@ -92,8 +95,8 @@ struct browse_req { DBusConnection *conn; DBusMessage *msg; - GAttrib *attrib; GIOChannel *io; + GAttrib *attrib; struct btd_device *device; GSList *match_uuids; GSList *profiles_added; @@ -104,6 +107,13 @@ guint listener_id; }; +struct attio_data { + guint id; + attio_connect_cb cfunc; + attio_disconnect_cb dcfunc; + gpointer user_data; +}; + struct btd_device { bdaddr_t bdaddr; device_type_t type; @@ -124,17 +134,19 @@ struct bonding_req *bonding; struct authentication_req *authr; /* authentication request */ GSList *disconnects; /* disconnects message */ + GAttrib *attrib; + GSList *attios; + GSList *attios_offline; + guint attioid; gboolean connected; - /* Whether were creating a security mode 3 connection */ - gboolean secmode3; - sdp_list_t *tmp_records; gboolean trusted; gboolean paired; gboolean blocked; + gboolean bonded; gboolean authorizing; gint ref; @@ -149,28 +161,28 @@ static GSList *device_drivers = NULL; -static void browse_request_free(struct browse_req *req) +static void browse_request_free(struct browse_req *req, gboolean shutdown) { if (req->listener_id) g_dbus_remove_watch(req->conn, req->listener_id); + if (req->attrib) + g_attrib_unref(req->attrib); + if (req->io) { + if (shutdown) + g_io_channel_shutdown(req->io, FALSE, NULL); + g_io_channel_unref(req->io); + } if (req->msg) dbus_message_unref(req->msg); if (req->conn) dbus_connection_unref(req->conn); if (req->device) btd_device_unref(req->device); - g_slist_foreach(req->profiles_added, (GFunc) g_free, NULL); - g_slist_free(req->profiles_added); + g_slist_free_full(req->profiles_added, g_free); g_slist_free(req->profiles_removed); if (req->records) sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free); - if (req->io) { - g_attrib_unref(req->attrib); - g_io_channel_unref(req->io); - g_io_channel_shutdown(req->io, FALSE, NULL); - } - g_free(req); } @@ -188,7 +200,7 @@ bt_cancel_discovery(&src, &device->bdaddr); device->browse = NULL; - browse_request_free(req); + browse_request_free(req, TRUE); } static void device_free(gpointer user_data) @@ -204,14 +216,13 @@ agent_is_busy(agent, device->authr))) agent_cancel(agent); - g_slist_foreach(device->services, (GFunc) g_free, NULL); - g_slist_free(device->services); - - g_slist_foreach(device->uuids, (GFunc) g_free, NULL); - g_slist_free(device->uuids); + g_slist_free_full(device->services, g_free); + g_slist_free_full(device->uuids, g_free); + g_slist_free_full(device->primaries, g_free); + g_slist_free_full(device->attios, g_free); + g_slist_free_full(device->attios_offline, g_free); - g_slist_foreach(device->primaries, (GFunc) g_free, NULL); - g_slist_free(device->primaries); + g_attrib_unref(device->attrib); if (device->tmp_records) sdp_list_free(device->tmp_records, @@ -223,6 +234,9 @@ if (device->discov_timer) g_source_remove(device->discov_timer); + if (device->attioid) + g_source_remove(device->attioid); + DBG("%p", device); g_free(device->authr); @@ -236,6 +250,11 @@ return device->paired; } +gboolean device_is_bonded(struct btd_device *device) +{ + return device->bonded; +} + gboolean device_is_trusted(struct btd_device *device) { return device->trusted; @@ -836,6 +855,9 @@ device->disconnects = g_slist_remove(device->disconnects, msg); } + if (device_is_paired(device) && !device_is_bonded(device)) + device_set_paired(device, FALSE); + emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Connected", DBUS_TYPE_BOOLEAN, &device->connected); @@ -918,8 +940,10 @@ if (read_blocked(&src, &device->bdaddr)) device_block(conn, device); - if (read_link_key(&src, &device->bdaddr, NULL, NULL) == 0) - device->paired = TRUE; + if (read_link_key(&src, &device->bdaddr, NULL, NULL) == 0) { + device_set_paired(device, TRUE); + device_set_bonded(device, TRUE); + } return btd_device_ref(device); } @@ -955,25 +979,6 @@ return device->type; } -void device_remove_bonding(struct btd_device *device) -{ - char filename[PATH_MAX + 1]; - char srcaddr[18], dstaddr[18]; - bdaddr_t bdaddr; - - adapter_get_address(device->adapter, &bdaddr); - ba2str(&bdaddr, srcaddr); - ba2str(&device->bdaddr, dstaddr); - - create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, - "linkkeys"); - - /* Delete the link key from storage */ - textfile_casedel(filename, dstaddr); - - btd_adapter_remove_bonding(device->adapter, &device->bdaddr); -} - static void device_remove_stored(struct btd_device *device) { bdaddr_t src; @@ -983,8 +988,13 @@ adapter_get_address(device->adapter, &src); ba2str(&device->bdaddr, addr); - if (device->paired) - device_remove_bonding(device); + if (device_is_bonded(device)) { + delete_entry(&src, "linkkeys", addr); + delete_entry(&src, "aliases", addr); + device_set_bonded(device, FALSE); + device_set_paired(device, FALSE); + btd_adapter_remove_bonding(device->adapter, &device->bdaddr); + } delete_entry(&src, "profiles", addr); delete_entry(&src, "trusts", addr); delete_entry(&src, "types", addr); @@ -1030,6 +1040,8 @@ g_slist_free(device->drivers); device->drivers = NULL; + attrib_client_unregister(device->services); + btd_device_unref(device); } @@ -1368,6 +1380,45 @@ g_dbus_send_message(req->conn, reply); } +GSList *device_services_from_record(struct btd_device *device, GSList *profiles) +{ + GSList *l, *prim_list = NULL; + char *att_uuid; + uuid_t proto_uuid; + + sdp_uuid16_create(&proto_uuid, ATT_UUID); + att_uuid = bt_uuid2string(&proto_uuid); + + for (l = profiles; l; l = l->next) { + const char *profile_uuid = l->data; + const sdp_record_t *rec; + struct att_primary *prim; + uint16_t start = 0, end = 0, psm = 0; + uuid_t prim_uuid; + + rec = btd_device_get_record(device, profile_uuid); + if (!rec) + continue; + + if (!record_has_uuid(rec, att_uuid)) + continue; + + if (!gatt_parse_record(rec, &prim_uuid, &psm, &start, &end)) + continue; + + prim = g_new0(struct att_primary, 1); + prim->start = start; + prim->end = end; + sdp_uuid2strn(&prim_uuid, prim->uuid, sizeof(prim->uuid)); + + prim_list = g_slist_append(prim_list, prim); + } + + g_free(att_uuid); + + return prim_list; +} + static void search_cb(sdp_list_t *recs, int err, gpointer user_data) { struct browse_req *req = user_data; @@ -1397,8 +1448,16 @@ } /* Probe matching drivers for services added */ - if (req->profiles_added) + if (req->profiles_added) { + GSList *list; + + list = device_services_from_record(device, req->profiles_added); + if (list) + device_register_services(req->conn, device, list, + ATT_PSM); + device_probe_drivers(device, req->profiles_added); + } /* Remove drivers for services removed */ if (req->profiles_removed) @@ -1442,7 +1501,7 @@ } device->browse = NULL; - browse_request_free(req); + browse_request_free(req, FALSE); } static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) @@ -1517,19 +1576,67 @@ return g_string_free(services, FALSE); } +static void store_services(struct btd_device *device) +{ + struct btd_adapter *adapter = device->adapter; + bdaddr_t dba, sba; + char *str = primary_list_to_string(device->primaries); + + adapter_get_address(adapter, &sba); + device_get_address(device, &dba); + + write_device_type(&sba, &dba, device->type); + write_device_services(&sba, &dba, str); + + g_free(str); +} + +static void attio_connected(gpointer data, gpointer user_data) +{ + struct attio_data *attio = data; + GAttrib *attrib = user_data; + + if (attio->cfunc) + attio->cfunc(attrib, attio->user_data); +} + +static void attio_disconnected(gpointer data, gpointer user_data) +{ + struct attio_data *attio = data; + + if (attio->dcfunc) + attio->dcfunc(attio->user_data); +} + +static gboolean att_auto_connect(gpointer user_data); + +static void attrib_disconnected(gpointer user_data) +{ + struct btd_device *device = user_data; + + g_slist_foreach(device->attios, attio_disconnected, NULL); + + if ((device->attios || device->attios_offline) && device->attioid == 0) + device->attioid = g_timeout_add_seconds(AUTOCONNECT_INTERVAL, + att_auto_connect, + device); + + g_attrib_unref(device->attrib); + device->attrib = NULL; +} + static void primary_cb(GSList *services, guint8 status, gpointer user_data) { struct browse_req *req = user_data; struct btd_device *device = req->device; - struct btd_adapter *adapter = device->adapter; GSList *l, *uuids = NULL; - bdaddr_t dba, sba; - char *str; + gboolean shutdown; if (status) { DBusMessage *reply; reply = btd_error_failed(req->msg, att_ecode2str(status)); g_dbus_send_message(req->conn, reply); + shutdown = TRUE; goto done; } @@ -1539,49 +1646,114 @@ for (l = services; l; l = l->next) { struct att_primary *prim = l->data; uuids = g_slist_append(uuids, prim->uuid); - device_add_primary(device, prim); } + /* + * Profiles may register attio callbacks in the probing callback. + * GAttrib reference can be released if the registered callbacks + * list is emtpy. + */ + device->attrib = g_attrib_ref(req->attrib); + + device_register_services(req->conn, device, g_slist_copy(services), -1); device_probe_drivers(device, uuids); - g_slist_free(uuids); - create_device_reply(device, req); + if (device->attios == NULL && device->attios_offline == NULL) { + g_attrib_unref(device->attrib); + device->attrib = NULL; + } - str = primary_list_to_string(services); + g_slist_free(uuids); - adapter_get_address(adapter, &sba); - device_get_address(device, &dba); + create_device_reply(device, req); - write_device_type(&sba, &dba, device->type); - write_device_services(&sba, &dba, str); - g_free(str); + store_services(device); + shutdown = FALSE; done: device->browse = NULL; - browse_request_free(req); + browse_request_free(req, shutdown); } -static void gatt_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data) +static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data) { - struct browse_req *req = user_data; - struct btd_device *device = req->device; + struct btd_device *device = user_data; + struct browse_req *req = device->browse; if (gerr) { DBusMessage *reply; DBG("%s", gerr->message); - reply = btd_error_failed(req->msg, gerr->message); - g_dbus_send_message(req->conn, reply); + if (req) { + reply = btd_error_failed(req->msg, gerr->message); + g_dbus_send_message(req->conn, reply); - device->browse = NULL; - browse_request_free(req); + device->browse = NULL; + browse_request_free(req, TRUE); + } return; } - req->attrib = g_attrib_new(io); - gatt_discover_primary(req->attrib, NULL, primary_cb, req); + if (device->attioid) { + g_source_remove(device->attioid); + device->attioid = 0; + } + + if (req) { + req->attrib = g_attrib_new(io); + gatt_discover_primary(req->attrib, NULL, primary_cb, req); + } else if (device->attios) { + device->attrib = g_attrib_new(io); + g_attrib_set_disconnect_function(device->attrib, + attrib_disconnected, device); + g_slist_foreach(device->attios, attio_connected, + device->attrib); + } +} + +static gboolean att_auto_connect(gpointer user_data) +{ + struct btd_device *device = user_data; + struct btd_adapter *adapter = device->adapter; + GIOChannel *io; + GError *gerr = NULL; + char addr[18]; + bdaddr_t sba; + + adapter_get_address(adapter, &sba); + ba2str(&device->bdaddr, addr); + + DBG("Connection attempt to: %s", addr); + + if (device->type != DEVICE_TYPE_LE) { + io = bt_io_connect(BT_IO_L2CAP, att_connect_cb, + device, NULL, &gerr, + BT_IO_OPT_SOURCE_BDADDR, &sba, + BT_IO_OPT_DEST_BDADDR, &device->bdaddr, + BT_IO_OPT_PSM, ATT_PSM, + BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, + BT_IO_OPT_INVALID); + } else { + io = bt_io_connect(BT_IO_L2CAP, att_connect_cb, + device, NULL, &gerr, + BT_IO_OPT_SOURCE_BDADDR, &sba, + BT_IO_OPT_DEST_BDADDR, &device->bdaddr, + BT_IO_OPT_CID, ATT_CID, + BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW, + BT_IO_OPT_INVALID); + } + + if (io == NULL) { + error("ATT bt_io_connect(%s): %s", addr, gerr->message); + g_error_free(gerr); + return TRUE; + } + + g_io_channel_unref(io); + + return TRUE; } int device_browse_primary(struct btd_device *device, DBusConnection *conn, @@ -1602,21 +1774,19 @@ sec_level = secure ? BT_IO_SEC_HIGH : BT_IO_SEC_LOW; - req->io = bt_io_connect(BT_IO_L2CAP, gatt_connect_cb, req, NULL, NULL, + req->io = bt_io_connect(BT_IO_L2CAP, att_connect_cb, + device, NULL, NULL, BT_IO_OPT_SOURCE_BDADDR, &src, BT_IO_OPT_DEST_BDADDR, &device->bdaddr, - BT_IO_OPT_CID, GATT_CID, + BT_IO_OPT_CID, ATT_CID, BT_IO_OPT_SEC_LEVEL, sec_level, BT_IO_OPT_INVALID); - if (req->io == NULL ) { - browse_request_free(req); + if (req->io == NULL) { + browse_request_free(req, FALSE); return -EIO; } - if (conn == NULL) - conn = get_dbus_connection(); - req->conn = dbus_connection_ref(conn); device->browse = req; @@ -1663,7 +1833,7 @@ err = bt_search_service(&src, &device->bdaddr, &uuid, cb, req, NULL); if (err < 0) { - browse_request_free(req); + browse_request_free(req, FALSE); return err; } @@ -1740,6 +1910,16 @@ device->temporary = temporary; } +void device_set_bonded(struct btd_device *device, gboolean bonded) +{ + if (!device) + return; + + DBG("bonded %d", bonded); + + device->bonded = bonded; +} + void device_set_type(struct btd_device *device, device_type_t type) { if (!device) @@ -2161,7 +2341,7 @@ } int device_request_authentication(struct btd_device *device, auth_type_t type, - uint32_t passkey, void *cb) + uint32_t passkey, gboolean secure, void *cb) { struct authentication_req *auth; struct agent *agent; @@ -2191,7 +2371,7 @@ switch (type) { case AUTH_TYPE_PINCODE: - err = agent_request_pincode(agent, device, pincode_cb, + err = agent_request_pincode(agent, device, pincode_cb, secure, auth, NULL); break; case AUTH_TYPE_PASSKEY: @@ -2286,17 +2466,12 @@ device->authorizing = auth; } -void btd_device_add_service(struct btd_device *device, const char *path) -{ - if (g_slist_find_custom(device->services, path, (GCompareFunc) strcmp)) - return; - - device->services = g_slist_append(device->services, g_strdup(path)); -} - -void device_add_primary(struct btd_device *device, struct att_primary *prim) +void device_register_services(DBusConnection *conn, struct btd_device *device, + GSList *prim_list, int psm) { - device->primaries = g_slist_append(device->primaries, prim); + device->primaries = g_slist_concat(device->primaries, prim_list); + device->services = attrib_client_register(conn, device, psm, NULL, + prim_list); } GSList *btd_device_get_primaries(struct btd_device *device) @@ -2386,3 +2561,103 @@ g_free(path); } + +void device_set_class(struct btd_device *device, uint32_t value) +{ + DBusConnection *conn = get_dbus_connection(); + + emit_property_changed(conn, device->path, DEVICE_INTERFACE, "Class", + DBUS_TYPE_UINT32, &value); +} + +static gboolean notify_attios(gpointer user_data) +{ + struct btd_device *device = user_data; + + if (device->attrib == NULL) + return FALSE; + + g_slist_foreach(device->attios_offline, attio_connected, device->attrib); + device->attios = g_slist_concat(device->attios, device->attios_offline); + device->attios_offline = NULL; + + return FALSE; +} + +guint btd_device_add_attio_callback(struct btd_device *device, + attio_connect_cb cfunc, + attio_disconnect_cb dcfunc, + gpointer user_data) +{ + struct attio_data *attio; + static guint attio_id = 0; + + DBG("%p registered ATT connection callback", device); + + attio = g_new0(struct attio_data, 1); + attio->id = ++attio_id; + attio->cfunc = cfunc; + attio->dcfunc = dcfunc; + attio->user_data = user_data; + + if (device->attrib && cfunc) { + device->attios_offline = g_slist_append(device->attios_offline, + attio); + g_idle_add(notify_attios, device); + } else if (device->attioid == 0) { + att_auto_connect(device); + device->attioid = g_timeout_add_seconds(AUTOCONNECT_INTERVAL, + att_auto_connect, + device); + device->attios = g_slist_append(device->attios, attio); + } + + return attio->id; +} + +static int attio_id_cmp(gconstpointer a, gconstpointer b) +{ + const struct attio_data *attio = a; + guint id = GPOINTER_TO_UINT(b); + + return attio->id - id; +} + +gboolean btd_device_remove_attio_callback(struct btd_device *device, guint id) +{ + struct attio_data *attio; + GSList *l; + + l = g_slist_find_custom(device->attios, GUINT_TO_POINTER(id), + attio_id_cmp); + if (l) { + attio = l->data; + device->attios = g_slist_remove(device->attios, attio); + } else { + l = g_slist_find_custom(device->attios_offline, + GUINT_TO_POINTER(id), attio_id_cmp); + if (!l) + return FALSE; + + attio = l->data; + device->attios_offline = g_slist_remove(device->attios_offline, + attio); + } + + g_free(attio); + + if (device->attios != NULL || device->attios_offline != NULL) + return TRUE; + + if (device->attioid) { + g_source_remove(device->attioid); + device->attioid = 0; + } + + if (device->attrib) { + g_attrib_unref(device->attrib); + device->attrib = NULL; + } + + return TRUE; +} diff -Nru bluez-4.91/src/device.h bluez-4.96/src/device.h --- bluez-4.91/src/device.h 2011-02-20 14:49:06.000000000 +0000 +++ bluez-4.96/src/device.h 2011-07-31 06:52:19.000000000 +0000 @@ -25,7 +25,6 @@ #define DEVICE_INTERFACE "org.bluez.Device" struct btd_device; -struct att_primary; typedef enum { AUTH_TYPE_PINCODE, @@ -57,8 +56,10 @@ const sdp_record_t *btd_device_get_record(struct btd_device *device, const char *uuid); GSList *btd_device_get_primaries(struct btd_device *device); -void btd_device_add_service(struct btd_device *device, const char *path); -void device_add_primary(struct btd_device *device, struct att_primary *prim); +void device_register_services(DBusConnection *conn, struct btd_device *device, + GSList *prim_list, int psm); +GSList *device_services_from_record(struct btd_device *device, + GSList *profiles); void btd_device_add_uuid(struct btd_device *device, const char *uuid); struct btd_adapter *device_get_adapter(struct btd_device *device); void device_get_address(struct btd_device *device, bdaddr_t *bdaddr); @@ -67,26 +68,23 @@ gboolean device_is_busy(struct btd_device *device); gboolean device_is_temporary(struct btd_device *device); gboolean device_is_paired(struct btd_device *device); +gboolean device_is_bonded(struct btd_device *device); gboolean device_is_trusted(struct btd_device *device); void device_set_paired(struct btd_device *device, gboolean paired); void device_set_temporary(struct btd_device *device, gboolean temporary); -void device_set_cap(struct btd_device *device, uint8_t cap); void device_set_type(struct btd_device *device, device_type_t type); -uint8_t device_get_cap(struct btd_device *device); -void device_set_auth(struct btd_device *device, uint8_t auth); -uint8_t device_get_auth(struct btd_device *device); +void device_set_bonded(struct btd_device *device, gboolean bonded); gboolean device_is_connected(struct btd_device *device); DBusMessage *device_create_bonding(struct btd_device *device, DBusConnection *conn, DBusMessage *msg, const char *agent_path, uint8_t capability); -void device_remove_bonding(struct btd_device *device); void device_bonding_complete(struct btd_device *device, uint8_t status); void device_simple_pairing_complete(struct btd_device *device, uint8_t status); gboolean device_is_creating(struct btd_device *device, const char *sender); gboolean device_is_bonding(struct btd_device *device, const char *sender); void device_cancel_bonding(struct btd_device *device, uint8_t status); int device_request_authentication(struct btd_device *device, auth_type_t type, - uint32_t passkey, void *cb); + uint32_t passkey, gboolean secure, void *cb); void device_cancel_authentication(struct btd_device *device, gboolean aborted); gboolean device_is_authenticating(struct btd_device *device); gboolean device_is_authorizing(struct btd_device *device); @@ -102,6 +100,7 @@ disconnect_watch watch, void *user_data, GDestroyNotify destroy); void device_remove_disconnect_watch(struct btd_device *device, guint id); +void device_set_class(struct btd_device *device, uint32_t value); #define BTD_UUIDS(args...) ((const char *[]) { args, NULL } ) diff -Nru bluez-4.91/src/eir.c bluez-4.96/src/eir.c --- bluez-4.91/src/eir.c 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/src/eir.c 2011-07-04 04:59:05.000000000 +0000 @@ -0,0 +1,332 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 Nokia Corporation + * Copyright (C) 2011 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include +#include +#include + +#include "glib-helper.h" +#include "eir.h" + +#define EIR_FLAGS 0x01 /* flags */ +#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */ +#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */ +#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */ +#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */ +#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */ +#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */ +#define EIR_NAME_SHORT 0x08 /* shortened local name */ +#define EIR_NAME_COMPLETE 0x09 /* complete local name */ +#define EIR_TX_POWER 0x0A /* transmit power level */ +#define EIR_DEVICE_ID 0x10 /* device ID */ + +void eir_data_free(struct eir_data *eir) +{ + g_slist_free_full(eir->services, g_free); + g_free(eir->name); +} + +int eir_parse(struct eir_data *eir, uint8_t *eir_data) +{ + uint16_t len = 0; + size_t total; + size_t uuid16_count = 0; + size_t uuid32_count = 0; + size_t uuid128_count = 0; + uint8_t *uuid16 = NULL; + uint8_t *uuid32 = NULL; + uint8_t *uuid128 = NULL; + uuid_t service; + char *uuid_str; + unsigned int i; + + eir->flags = -1; + + /* No EIR data to parse */ + if (eir_data == NULL) + return 0; + + while (len < HCI_MAX_EIR_LENGTH - 1) { + uint8_t field_len = eir_data[0]; + + /* Check for the end of EIR */ + if (field_len == 0) + break; + + switch (eir_data[1]) { + case EIR_UUID16_SOME: + case EIR_UUID16_ALL: + uuid16_count = field_len / 2; + uuid16 = &eir_data[2]; + break; + case EIR_UUID32_SOME: + case EIR_UUID32_ALL: + uuid32_count = field_len / 4; + uuid32 = &eir_data[2]; + break; + case EIR_UUID128_SOME: + case EIR_UUID128_ALL: + uuid128_count = field_len / 16; + uuid128 = &eir_data[2]; + break; + case EIR_FLAGS: + eir->flags = eir_data[2]; + break; + case EIR_NAME_SHORT: + case EIR_NAME_COMPLETE: + if (g_utf8_validate((char *) &eir_data[2], + field_len - 1, NULL)) + eir->name = g_strndup((char *) &eir_data[2], + field_len - 1); + else + eir->name = g_strdup(""); + eir->name_complete = eir_data[1] == EIR_NAME_COMPLETE; + break; + } + + len += field_len + 1; + eir_data += field_len + 1; + } + + /* Bail out if got incorrect length */ + if (len > HCI_MAX_EIR_LENGTH) + return -EINVAL; + + total = uuid16_count + uuid32_count + uuid128_count; + + /* No UUIDs were parsed, so skip code below */ + if (!total) + return 0; + + /* Generate uuids in SDP format (EIR data is Little Endian) */ + service.type = SDP_UUID16; + for (i = 0; i < uuid16_count; i++) { + uint16_t val16 = uuid16[1]; + + val16 = (val16 << 8) + uuid16[0]; + service.value.uuid16 = val16; + uuid_str = bt_uuid2string(&service); + eir->services = g_slist_append(eir->services, uuid_str); + uuid16 += 2; + } + + service.type = SDP_UUID32; + for (i = uuid16_count; i < uuid32_count + uuid16_count; i++) { + uint32_t val32 = uuid32[3]; + int k; + + for (k = 2; k >= 0; k--) + val32 = (val32 << 8) + uuid32[k]; + + service.value.uuid32 = val32; + uuid_str = bt_uuid2string(&service); + eir->services = g_slist_append(eir->services, uuid_str); + uuid32 += 4; + } + + service.type = SDP_UUID128; + for (i = uuid32_count + uuid16_count; i < total; i++) { + int k; + + for (k = 0; k < 16; k++) + service.value.uuid128.data[k] = uuid128[16 - k - 1]; + + uuid_str = bt_uuid2string(&service); + eir->services = g_slist_append(eir->services, uuid_str); + uuid128 += 16; + } + + return 0; +} + +#define SIZEOF_UUID128 16 + +static void eir_generate_uuid128(GSList *list, uint8_t *ptr, uint16_t *eir_len) +{ + int i, k, uuid_count = 0; + uint16_t len = *eir_len; + uint8_t *uuid128; + gboolean truncated = FALSE; + + /* Store UUIDs in place, skip 2 bytes to write type and length later */ + uuid128 = ptr + 2; + + for (; list; list = list->next) { + struct uuid_info *uuid = list->data; + uint8_t *uuid128_data = uuid->uuid.value.uuid128.data; + + if (uuid->uuid.type != SDP_UUID128) + continue; + + /* Stop if not enough space to put next UUID128 */ + if ((len + 2 + SIZEOF_UUID128) > HCI_MAX_EIR_LENGTH) { + truncated = TRUE; + break; + } + + /* Check for duplicates, EIR data is Little Endian */ + for (i = 0; i < uuid_count; i++) { + for (k = 0; k < SIZEOF_UUID128; k++) { + if (uuid128[i * SIZEOF_UUID128 + k] != + uuid128_data[SIZEOF_UUID128 - 1 - k]) + break; + } + if (k == SIZEOF_UUID128) + break; + } + + if (i < uuid_count) + continue; + + /* EIR data is Little Endian */ + for (k = 0; k < SIZEOF_UUID128; k++) + uuid128[uuid_count * SIZEOF_UUID128 + k] = + uuid128_data[SIZEOF_UUID128 - 1 - k]; + + len += SIZEOF_UUID128; + uuid_count++; + } + + if (uuid_count > 0 || truncated) { + /* EIR Data length */ + ptr[0] = (uuid_count * SIZEOF_UUID128) + 1; + /* EIR Data type */ + ptr[1] = truncated ? EIR_UUID128_SOME : EIR_UUID128_ALL; + len += 2; + *eir_len = len; + } +} + +void eir_create(const char *name, int8_t tx_power, uint16_t did_vendor, + uint16_t did_product, uint16_t did_version, + GSList *uuids, uint8_t *data) +{ + GSList *l; + uint8_t *ptr = data; + uint16_t eir_len = 0; + uint16_t uuid16[HCI_MAX_EIR_LENGTH / 2]; + int i, uuid_count = 0; + gboolean truncated = FALSE; + size_t name_len; + + name_len = strlen(name); + + if (name_len > 0) { + /* EIR Data type */ + if (name_len > 48) { + name_len = 48; + ptr[1] = EIR_NAME_SHORT; + } else + ptr[1] = EIR_NAME_COMPLETE; + + /* EIR Data length */ + ptr[0] = name_len + 1; + + memcpy(ptr + 2, name, name_len); + + eir_len += (name_len + 2); + ptr += (name_len + 2); + } + + if (tx_power != 0) { + *ptr++ = 2; + *ptr++ = EIR_TX_POWER; + *ptr++ = (uint8_t) tx_power; + eir_len += 3; + } + + if (did_vendor != 0x0000) { + uint16_t source = 0x0002; + *ptr++ = 9; + *ptr++ = EIR_DEVICE_ID; + *ptr++ = (source & 0x00ff); + *ptr++ = (source & 0xff00) >> 8; + *ptr++ = (did_vendor & 0x00ff); + *ptr++ = (did_vendor & 0xff00) >> 8; + *ptr++ = (did_product & 0x00ff); + *ptr++ = (did_product & 0xff00) >> 8; + *ptr++ = (did_version & 0x00ff); + *ptr++ = (did_version & 0xff00) >> 8; + eir_len += 10; + } + + /* Group all UUID16 types */ + for (l = uuids; l != NULL; l = g_slist_next(l)) { + struct uuid_info *uuid = l->data; + + if (uuid->uuid.type != SDP_UUID16) + continue; + + if (uuid->uuid.value.uuid16 < 0x1100) + continue; + + if (uuid->uuid.value.uuid16 == PNP_INFO_SVCLASS_ID) + continue; + + /* Stop if not enough space to put next UUID16 */ + if ((eir_len + 2 + sizeof(uint16_t)) > HCI_MAX_EIR_LENGTH) { + truncated = TRUE; + break; + } + + /* Check for duplicates */ + for (i = 0; i < uuid_count; i++) + if (uuid16[i] == uuid->uuid.value.uuid16) + break; + + if (i < uuid_count) + continue; + + uuid16[uuid_count++] = uuid->uuid.value.uuid16; + eir_len += sizeof(uint16_t); + } + + if (uuid_count > 0) { + /* EIR Data length */ + ptr[0] = (uuid_count * sizeof(uint16_t)) + 1; + /* EIR Data type */ + ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL; + + ptr += 2; + eir_len += 2; + + for (i = 0; i < uuid_count; i++) { + *ptr++ = (uuid16[i] & 0x00ff); + *ptr++ = (uuid16[i] & 0xff00) >> 8; + } + } + + /* Group all UUID128 types */ + if (eir_len <= HCI_MAX_EIR_LENGTH - 2) + eir_generate_uuid128(uuids, ptr, &eir_len); +} diff -Nru bluez-4.91/src/eir.h bluez-4.96/src/eir.h --- bluez-4.91/src/eir.h 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/src/eir.h 2011-05-31 02:39:53.000000000 +0000 @@ -0,0 +1,41 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 Nokia Corporation + * Copyright (C) 2011 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +struct uuid_info { + uuid_t uuid; + uint8_t svc_hint; +}; + +struct eir_data { + GSList *services; + int flags; + char *name; + gboolean name_complete; +}; + +void eir_data_free(struct eir_data *eir); +int eir_parse(struct eir_data *eir, uint8_t *eir_data); +void eir_create(const char *name, int8_t tx_power, uint16_t did_vendor, + uint16_t did_product, uint16_t did_version, + GSList *uuids, uint8_t *data); diff -Nru bluez-4.91/src/event.c bluez-4.96/src/event.c --- bluez-4.91/src/event.c 2011-02-20 14:49:06.000000000 +0000 +++ bluez-4.96/src/event.c 2011-07-31 06:52:19.000000000 +0000 @@ -28,6 +28,7 @@ #define _GNU_SOURCE #include +#include #include #include #include @@ -46,7 +47,6 @@ #include "log.h" #include "textfile.h" -#include "hcid.h" #include "adapter.h" #include "manager.h" #include "device.h" @@ -57,13 +57,7 @@ #include "storage.h" #include "event.h" #include "sdpd.h" - -struct eir_data { - GSList *services; - int flags; - char *name; - gboolean name_complete; -}; +#include "eir.h" static gboolean get_adapter_and_device(bdaddr_t *src, bdaddr_t *dst, struct btd_adapter **adapter, @@ -105,49 +99,48 @@ const char *pincode, struct btd_device *device) { struct btd_adapter *adapter = device_get_adapter(device); - bdaddr_t sba, dba; + bdaddr_t dba; int err; device_get_address(device, &dba); if (derr) { - err = btd_adapter_pincode_reply(adapter, &dba, NULL); + err = btd_adapter_pincode_reply(adapter, &dba, NULL, 0); if (err < 0) goto fail; return; } - err = btd_adapter_pincode_reply(adapter, &dba, pincode); + err = btd_adapter_pincode_reply(adapter, &dba, pincode, + pincode ? strlen(pincode) : 0); if (err < 0) goto fail; - adapter_get_address(adapter, &sba); - return; fail: error("Sending PIN code reply failed: %s (%d)", strerror(-err), -err); } -int btd_event_request_pin(bdaddr_t *sba, bdaddr_t *dba) +int btd_event_request_pin(bdaddr_t *sba, bdaddr_t *dba, gboolean secure) { struct btd_adapter *adapter; struct btd_device *device; char pin[17]; - int pinlen; + ssize_t pinlen; if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE)) return -ENODEV; memset(pin, 0, sizeof(pin)); - pinlen = read_pin_code(sba, dba, pin); - if (pinlen > 0) { - btd_adapter_pincode_reply(adapter, dba, pin); + pinlen = btd_adapter_get_pin(adapter, device, pin); + if (pinlen > 0 && (!secure || pinlen == 16)) { + btd_adapter_pincode_reply(adapter, dba, pin, pinlen); return 0; } return device_request_authentication(device, AUTH_TYPE_PINCODE, 0, - pincode_cb); + secure, pincode_cb); } static int confirm_reply(struct btd_adapter *adapter, @@ -193,7 +186,7 @@ return -ENODEV; return device_request_authentication(device, AUTH_TYPE_CONFIRM, - passkey, confirm_cb); + passkey, FALSE, confirm_cb); } int btd_event_user_passkey(bdaddr_t *sba, bdaddr_t *dba) @@ -205,7 +198,7 @@ return -ENODEV; return device_request_authentication(device, AUTH_TYPE_PASSKEY, 0, - passkey_cb); + FALSE, passkey_cb); } int btd_event_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey) @@ -216,8 +209,8 @@ if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE)) return -ENODEV; - return device_request_authentication(device, AUTH_TYPE_NOTIFY, - passkey, NULL); + return device_request_authentication(device, AUTH_TYPE_NOTIFY, passkey, + FALSE, NULL); } void btd_event_bonding_complete(bdaddr_t *local, bdaddr_t *peer, @@ -258,155 +251,6 @@ device_simple_pairing_complete(device, status); } -static int parse_eir_data(struct eir_data *eir, uint8_t *eir_data, - size_t eir_length) -{ - uint16_t len = 0; - size_t total; - size_t uuid16_count = 0; - size_t uuid32_count = 0; - size_t uuid128_count = 0; - uint8_t *uuid16 = NULL; - uint8_t *uuid32 = NULL; - uint8_t *uuid128 = NULL; - uuid_t service; - char *uuid_str; - unsigned int i; - - eir->flags = -1; - - /* No EIR data to parse */ - if (eir_data == NULL || eir_length == 0) - return 0; - - while (len < eir_length - 1) { - uint8_t field_len = eir_data[0]; - - /* Check for the end of EIR */ - if (field_len == 0) - break; - - switch (eir_data[1]) { - case EIR_UUID16_SOME: - case EIR_UUID16_ALL: - uuid16_count = field_len / 2; - uuid16 = &eir_data[2]; - break; - case EIR_UUID32_SOME: - case EIR_UUID32_ALL: - uuid32_count = field_len / 4; - uuid32 = &eir_data[2]; - break; - case EIR_UUID128_SOME: - case EIR_UUID128_ALL: - uuid128_count = field_len / 16; - uuid128 = &eir_data[2]; - break; - case EIR_FLAGS: - eir->flags = eir_data[2]; - break; - case EIR_NAME_SHORT: - case EIR_NAME_COMPLETE: - if (g_utf8_validate((char *) &eir_data[2], - field_len - 1, NULL)) - eir->name = g_strndup((char *) &eir_data[2], - field_len - 1); - else - eir->name = g_strdup(""); - eir->name_complete = eir_data[1] == EIR_NAME_COMPLETE; - break; - } - - len += field_len + 1; - eir_data += field_len + 1; - } - - /* Bail out if got incorrect length */ - if (len > eir_length) - return -EINVAL; - - total = uuid16_count + uuid32_count + uuid128_count; - - /* No UUIDs were parsed, so skip code below */ - if (!total) - return 0; - - /* Generate uuids in SDP format (EIR data is Little Endian) */ - service.type = SDP_UUID16; - for (i = 0; i < uuid16_count; i++) { - uint16_t val16 = uuid16[1]; - - val16 = (val16 << 8) + uuid16[0]; - service.value.uuid16 = val16; - uuid_str = bt_uuid2string(&service); - eir->services = g_slist_append(eir->services, uuid_str); - uuid16 += 2; - } - - service.type = SDP_UUID32; - for (i = uuid16_count; i < uuid32_count + uuid16_count; i++) { - uint32_t val32 = uuid32[3]; - int k; - - for (k = 2; k >= 0; k--) - val32 = (val32 << 8) + uuid32[k]; - - service.value.uuid32 = val32; - uuid_str = bt_uuid2string(&service); - eir->services = g_slist_append(eir->services, uuid_str); - uuid32 += 4; - } - - service.type = SDP_UUID128; - for (i = uuid32_count + uuid16_count; i < total; i++) { - int k; - - for (k = 0; k < 16; k++) - service.value.uuid128.data[k] = uuid128[16 - k - 1]; - - uuid_str = bt_uuid2string(&service); - eir->services = g_slist_append(eir->services, uuid_str); - uuid128 += 16; - } - - return 0; -} - -static void free_eir_data(struct eir_data *eir) -{ - g_slist_foreach(eir->services, (GFunc) g_free, NULL); - g_slist_free(eir->services); - g_free(eir->name); -} - -void btd_event_advertising_report(bdaddr_t *local, le_advertising_info *info) -{ - struct btd_adapter *adapter; - struct eir_data eir_data; - int8_t rssi; - int err; - - adapter = manager_find_adapter(local); - if (adapter == NULL) { - error("No matching adapter found"); - return; - } - - memset(&eir_data, 0, sizeof(eir_data)); - err = parse_eir_data(&eir_data, info->data, info->length); - if (err < 0) - error("Error parsing advertising data: %s (%d)", - strerror(-err), -err); - - rssi = *(info->data + info->length); - - adapter_update_device_from_info(adapter, info->bdaddr, rssi, - info->evt_type, eir_data.name, - eir_data.services, eir_data.flags); - - free_eir_data(&eir_data); -} - static void update_lastseen(bdaddr_t *sba, bdaddr_t *dba) { time_t t; @@ -432,18 +276,7 @@ void btd_event_device_found(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi, uint8_t *data) { - char filename[PATH_MAX + 1]; struct btd_adapter *adapter; - char local_addr[18], peer_addr[18], *alias, *name; - name_status_t name_status; - struct eir_data eir_data; - int state, err; - dbus_bool_t legacy; - unsigned char features[8]; - const char *dev_name; - - ba2str(local, local_addr); - ba2str(peer, peer_addr); adapter = manager_find_adapter(local); if (!adapter) { @@ -457,66 +290,7 @@ if (data) write_remote_eir(local, peer, data); - /* - * Workaround to identify periodic inquiry: inquiry complete event is - * sent after each window, however there isn't an event to indicate the - * beginning of a new periodic inquiry window. - */ - state = adapter_get_state(adapter); - if (!(state & (STATE_STDINQ | STATE_LE_SCAN | STATE_PINQ))) { - state |= STATE_PINQ; - adapter_set_state(adapter, state); - } - - /* the inquiry result can be triggered by NON D-Bus client */ - if (adapter_get_discover_type(adapter) & DISC_RESOLVNAME && - adapter_has_discov_sessions(adapter)) - name_status = NAME_REQUIRED; - else - name_status = NAME_NOT_REQUIRED; - - create_name(filename, PATH_MAX, STORAGEDIR, local_addr, "aliases"); - alias = textfile_get(filename, peer_addr); - - create_name(filename, PATH_MAX, STORAGEDIR, local_addr, "names"); - name = textfile_get(filename, peer_addr); - - if (data) - legacy = FALSE; - else if (name == NULL) - legacy = TRUE; - else if (read_remote_features(local, peer, NULL, features) == 0) { - if (features[0] & 0x01) - legacy = FALSE; - else - legacy = TRUE; - } else - legacy = TRUE; - - memset(&eir_data, 0, sizeof(eir_data)); - err = parse_eir_data(&eir_data, data, EIR_DATA_LENGTH); - if (err < 0) - error("Error parsing EIR data: %s (%d)", strerror(-err), -err); - - /* Complete EIR names are always used. Shortened EIR names are only - * used if there is no name already in storage. */ - dev_name = name; - if (eir_data.name != NULL) { - if (eir_data.name_complete) { - write_device_name(local, peer, eir_data.name); - name_status = NAME_NOT_REQUIRED; - dev_name = eir_data.name; - } else if (name == NULL) - dev_name = eir_data.name; - } - - adapter_update_found_devices(adapter, peer, rssi, class, dev_name, - alias, legacy, eir_data.services, - name_status); - - free_eir_data(&eir_data); - free(name); - free(alias); + adapter_update_found_devices(adapter, peer, class, rssi, data); } void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer, @@ -542,11 +316,9 @@ void btd_event_remote_class(bdaddr_t *local, bdaddr_t *peer, uint32_t class) { - uint32_t old_class = 0; struct btd_adapter *adapter; struct btd_device *device; - const gchar *dev_path; - DBusConnection *conn = get_dbus_connection(); + uint32_t old_class = 0; read_remote_class(local, peer, &old_class); @@ -561,10 +333,7 @@ if (!device) return; - dev_path = device_get_path(device); - - emit_property_changed(conn, dev_path, DEVICE_INTERFACE, "Class", - DBUS_TYPE_UINT32, &class); + device_set_class(device, class); } void btd_event_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status, @@ -572,17 +341,22 @@ { struct btd_adapter *adapter; char srcaddr[18], dstaddr[18]; - int state; struct btd_device *device; struct remote_dev_info match, *dev_info; if (status == 0) { - char *end; + if (!g_utf8_validate(name, -1, NULL)) { + int i; - /* It's ok to cast end between const and non-const since - * we know it points to inside of name which is non-const */ - if (!g_utf8_validate(name, -1, (const char **) &end)) - *end = '\0'; + /* Assume ASCII, and replace all non-ASCII with + * spaces */ + for (i = 0; name[i] != '\0'; i++) { + if (!isascii(name[i])) + name[i] = ' '; + } + /* Remove leading and trailing whitespace characters */ + g_strstrip(name); + } write_device_name(local, peer, name); } @@ -617,9 +391,7 @@ if (adapter_resolve_names(adapter) == 0) return; - state = adapter_get_state(adapter); - state &= ~STATE_RESOLVNAME; - adapter_set_state(adapter, state); + adapter_set_state(adapter, STATE_IDLE); } int btd_event_link_key_notify(bdaddr_t *local, bdaddr_t *peer, @@ -637,8 +409,12 @@ ret = write_link_key(local, peer, key, key_type, pin_length); - if (ret == 0 && device_is_temporary(device)) - device_set_temporary(device, FALSE); + if (ret == 0) { + device_set_bonded(device, TRUE); + + if (device_is_temporary(device)) + device_set_temporary(device, FALSE); + } return ret; } @@ -670,6 +446,9 @@ if (!device) return; + if (device_is_bonding(device, NULL)) + device_cancel_bonding(device, status); + if (device_is_temporary(device)) adapter_remove_device(conn, adapter, device, TRUE); } @@ -692,33 +471,6 @@ /* Section reserved to device HCI callbacks */ -void btd_event_le_set_scan_enable_complete(bdaddr_t *local, uint8_t status) -{ - struct btd_adapter *adapter; - int state; - - adapter = manager_find_adapter(local); - if (!adapter) { - error("No matching adapter found"); - return; - } - - if (status) { - error("Can't enable/disable LE scan"); - return; - } - - state = adapter_get_state(adapter); - - /* Enabling or disabling ? */ - if (state & STATE_LE_SCAN) - state &= ~STATE_LE_SCAN; - else - state |= STATE_LE_SCAN; - - adapter_set_state(adapter, state); -} - void btd_event_returned_link_key(bdaddr_t *local, bdaddr_t *peer) { struct btd_adapter *adapter; diff -Nru bluez-4.91/src/event.h bluez-4.96/src/event.h --- bluez-4.91/src/event.h 2011-02-20 14:49:06.000000000 +0000 +++ bluez-4.96/src/event.h 2011-07-04 04:59:05.000000000 +0000 @@ -22,8 +22,7 @@ * */ -int btd_event_request_pin(bdaddr_t *sba, bdaddr_t *dba); -void btd_event_advertising_report(bdaddr_t *local, le_advertising_info *info); +int btd_event_request_pin(bdaddr_t *sba, bdaddr_t *dba, gboolean secure); void btd_event_device_found(bdaddr_t *local, bdaddr_t *peer, uint32_t class, int8_t rssi, uint8_t *data); void btd_event_set_legacy_pairing(bdaddr_t *local, bdaddr_t *peer, gboolean legacy); @@ -35,7 +34,6 @@ void btd_event_bonding_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t status); void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t status); -void btd_event_le_set_scan_enable_complete(bdaddr_t *local, uint8_t status); void btd_event_returned_link_key(bdaddr_t *local, bdaddr_t *peer); int btd_event_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey); int btd_event_user_passkey(bdaddr_t *sba, bdaddr_t *dba); diff -Nru bluez-4.91/src/glib-helper.h bluez-4.96/src/glib-helper.h --- bluez-4.91/src/glib-helper.h 2011-01-11 14:51:27.000000000 +0000 +++ bluez-4.96/src/glib-helper.h 2011-07-04 04:59:05.000000000 +0000 @@ -34,3 +34,11 @@ int bt_string2uuid(uuid_t *uuid, const char *string); gchar *bt_list2string(GSList *list); GSList *bt_string2list(const gchar *str); + +#ifdef NEED_G_SLIST_FREE_FULL +static inline void g_slist_free_full(GSList *list, GDestroyNotify free_func) +{ + g_slist_foreach(list, (GFunc) free_func, NULL); + g_slist_free(list); +} +#endif diff -Nru bluez-4.91/src/hcid.h bluez-4.96/src/hcid.h --- bluez-4.91/src/hcid.h 2010-12-26 17:20:48.000000000 +0000 +++ bluez-4.96/src/hcid.h 2011-07-31 06:52:19.000000000 +0000 @@ -40,7 +40,6 @@ gboolean attrib_server; gboolean le; - uint8_t scan; uint8_t mode; uint8_t discov_interval; char deviceid[15]; /* FIXME: */ @@ -64,3 +63,6 @@ void rfkill_init(void); void rfkill_exit(void); + +int attrib_server_init(void); +void attrib_server_exit(void); diff -Nru bluez-4.91/src/log.c bluez-4.96/src/log.c --- bluez-4.91/src/log.c 2010-07-02 19:40:38.000000000 +0000 +++ bluez-4.96/src/log.c 2011-07-04 04:59:05.000000000 +0000 @@ -78,19 +78,15 @@ if (enabled == NULL) return 0; - for (i = 0; enabled[i] != NULL; i++) { - if (desc->name != NULL && g_pattern_match_simple(enabled[i], - desc->name) == TRUE) - return 1; + for (i = 0; enabled[i] != NULL; i++) if (desc->file != NULL && g_pattern_match_simple(enabled[i], desc->file) == TRUE) return 1; - } return 0; } -void __btd_toggle_debug() +void __btd_toggle_debug(void) { struct btd_debug_desc *desc; @@ -102,30 +98,20 @@ { int option = LOG_NDELAY | LOG_PID; struct btd_debug_desc *desc; - const char *name = NULL, *file = NULL; if (debug != NULL) enabled = g_strsplit_set(debug, ":, ", 0); - for (desc = __start___debug; desc < __stop___debug; desc++) { - if (file != NULL || name != NULL) { - if (g_strcmp0(desc->file, file) == 0) { - if (desc->name == NULL) - desc->name = name; - } else - file = NULL; - } - + for (desc = __start___debug; desc < __stop___debug; desc++) if (is_enabled(desc)) desc->flags |= BTD_DEBUG_FLAG_PRINT; - } if (!detach) option |= LOG_PERROR; openlog("bluetoothd", option, LOG_DAEMON); - syslog(LOG_INFO, "Bluetooth deamon %s", VERSION); + syslog(LOG_INFO, "Bluetooth daemon %s", VERSION); } void __btd_log_cleanup(void) diff -Nru bluez-4.91/src/log.h bluez-4.96/src/log.h --- bluez-4.91/src/log.h 2010-07-02 19:40:38.000000000 +0000 +++ bluez-4.96/src/log.h 2011-05-31 02:39:53.000000000 +0000 @@ -28,10 +28,9 @@ void __btd_log_init(const char *debug, int detach); void __btd_log_cleanup(void); -void __btd_toggle_debug(); +void __btd_toggle_debug(void); struct btd_debug_desc { - const char *name; const char *file; #define BTD_DEBUG_FLAG_DEFAULT (0) #define BTD_DEBUG_FLAG_PRINT (1 << 0) diff -Nru bluez-4.91/src/main.c bluez-4.96/src/main.c --- bluez-4.91/src/main.c 2011-03-16 00:34:27.000000000 +0000 +++ bluez-4.96/src/main.c 2011-07-31 06:52:19.000000000 +0000 @@ -33,10 +33,8 @@ #include #include #include -#include -#include -#include #include +#include #include #include @@ -51,9 +49,7 @@ #include "hcid.h" #include "sdpd.h" -#include "attrib-server.h" #include "adapter.h" -#include "event.h" #include "dbus-common.h" #include "agent.h" #include "manager.h" @@ -238,7 +234,6 @@ { /* Default HCId settings */ memset(&main_opts, 0, sizeof(main_opts)); - main_opts.scan = SCAN_PAGE; main_opts.mode = MODE_CONNECTABLE; main_opts.name = g_strdup("BlueZ"); main_opts.discovto = DEFAULT_DISCOVERABLE_TIMEOUT; diff -Nru bluez-4.91/src/main.conf bluez-4.96/src/main.conf --- bluez-4.91/src/main.conf 2010-11-20 20:25:14.000000000 +0000 +++ bluez-4.96/src/main.conf 2011-05-31 02:39:53.000000000 +0000 @@ -27,8 +27,8 @@ PageTimeout = 8192 # Discover scheduler interval used in Adapter.DiscoverDevices -# The value is in seconds. Defaults is 0 to use controller scheduler. -DiscoverSchedulerInterval = 0 +# The value is in seconds. Defaults is 30. +DiscoverSchedulerInterval = 30 # What value should be assumed for the adapter Powered property when # SetProperty(Powered, ...) hasn't been called yet. Defaults to true diff -Nru bluez-4.91/src/manager.c bluez-4.96/src/manager.c --- bluez-4.91/src/manager.c 2010-12-26 17:20:48.000000000 +0000 +++ bluez-4.96/src/manager.c 2011-07-31 06:52:19.000000000 +0000 @@ -34,6 +34,8 @@ #include #include +#include +#include #include @@ -41,6 +43,7 @@ #include +#include "glib-helper.h" #include "hcid.h" #include "dbus-common.h" #include "log.h" @@ -262,6 +265,11 @@ DBUS_TYPE_INVALID); } +struct btd_adapter *manager_get_default_adapter(void) +{ + return manager_find_adapter_by_id(default_adapter_id); +} + static void manager_remove_adapter(struct btd_adapter *adapter) { uint16_t dev_id = adapter_get_dev_id(adapter); @@ -283,6 +291,7 @@ DBUS_TYPE_INVALID); adapter_remove(adapter); + btd_adapter_unref(adapter); if (adapters == NULL) btd_start_exit_timer(); @@ -290,8 +299,15 @@ void manager_cleanup(DBusConnection *conn, const char *path) { - g_slist_foreach(adapters, (GFunc) manager_remove_adapter, NULL); - g_slist_free(adapters); + while (adapters) { + struct btd_adapter *adapter = adapters->data; + + adapters = g_slist_remove(adapters, adapter); + adapter_remove(adapter); + btd_adapter_unref(adapter); + } + + btd_start_exit_timer(); g_dbus_unregister_interface(conn, "/", MANAGER_INTERFACE); } diff -Nru bluez-4.91/src/manager.h bluez-4.96/src/manager.h --- bluez-4.91/src/manager.h 2010-12-26 17:20:48.000000000 +0000 +++ bluez-4.96/src/manager.h 2011-07-04 04:59:05.000000000 +0000 @@ -35,6 +35,7 @@ const char *manager_get_base_path(void); struct btd_adapter *manager_find_adapter(const bdaddr_t *sba); struct btd_adapter *manager_find_adapter_by_id(int id); +struct btd_adapter *manager_get_default_adapter(void); void manager_foreach_adapter(adapter_cb func, gpointer user_data); GSList *manager_get_adapters(void); struct btd_adapter *btd_manager_register_adapter(int id); diff -Nru bluez-4.91/src/sdpd-database.c bluez-4.96/src/sdpd-database.c --- bluez-4.91/src/sdpd-database.c 2010-12-26 17:20:48.000000000 +0000 +++ bluez-4.96/src/sdpd-database.c 2011-05-31 02:39:53.000000000 +0000 @@ -90,7 +90,7 @@ /* * Reset the service repository by deleting its contents */ -void sdp_svcdb_reset() +void sdp_svcdb_reset(void) { sdp_list_free(service_db, (sdp_free_func_t) sdp_record_free); sdp_list_free(access_db, access_free); diff -Nru bluez-4.91/src/sdpd.h bluez-4.96/src/sdpd.h --- bluez-4.91/src/sdpd.h 2010-12-26 17:20:48.000000000 +0000 +++ bluez-4.96/src/sdpd.h 2011-05-31 02:39:53.000000000 +0000 @@ -34,20 +34,6 @@ #define SDPDBG(fmt...) #endif -#define EIR_DATA_LENGTH 240 - -#define EIR_FLAGS 0x01 /* flags */ -#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */ -#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */ -#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */ -#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */ -#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */ -#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */ -#define EIR_NAME_SHORT 0x08 /* shortened local name */ -#define EIR_NAME_COMPLETE 0x09 /* complete local name */ -#define EIR_TX_POWER 0x0A /* transmit power level */ -#define EIR_DEVICE_ID 0x10 /* device ID */ - typedef struct request { bdaddr_t device; bdaddr_t bdaddr; @@ -83,7 +69,7 @@ int sdp_check_access(uint32_t handle, bdaddr_t *device); uint32_t sdp_next_handle(void); -uint32_t sdp_get_time(); +uint32_t sdp_get_time(void); #define SDP_SERVER_COMPAT (1 << 0) #define SDP_SERVER_MASTER (1 << 1) diff -Nru bluez-4.91/src/sdpd-request.c bluez-4.96/src/sdpd-request.c --- bluez-4.91/src/sdpd-request.c 2011-03-16 00:34:27.000000000 +0000 +++ bluez-4.96/src/sdpd-request.c 2011-07-04 04:59:05.000000000 +0000 @@ -67,7 +67,7 @@ static sdp_cstate_list_t *cstates; -// FIXME: should probably remove it when it's found +/* FIXME: should probably remove it when it's found */ static sdp_buf_t *sdp_get_cached_rsp(sdp_cont_state_t *cstate) { sdp_cstate_list_t *p; @@ -256,15 +256,14 @@ if (cstate) { SDPDBG("Non null sdp_cstate_t id : 0x%x", cstate->timestamp); - *(uint8_t *)pdata = sizeof(sdp_cont_state_t); + *pdata = sizeof(sdp_cont_state_t); pdata += sizeof(uint8_t); length += sizeof(uint8_t); memcpy(pdata, cstate, sizeof(sdp_cont_state_t)); length += sizeof(sdp_cont_state_t); } else { - // set "null" continuation state - *(uint8_t *)pdata = 0; - pdata += sizeof(uint8_t); + /* set "null" continuation state */ + *pdata = 0; length += sizeof(uint8_t); } buf->data_size += length; @@ -335,7 +334,7 @@ if (data == NULL) return -1; - // create 128-bit form of the search UUID + /* create 128-bit form of the search UUID */ uuid128 = sdp_uuid_to_uuid128((uuid_t *)data); list = sdp_list_find(pattern, uuid128, sdp_uuid128_cmp); bt_free(uuid128); @@ -375,7 +374,7 @@ plen = ntohs(((sdp_pdu_hdr_t *)(req->buf))->plen); mlen = scanned + sizeof(uint16_t) + 1; - // ensure we don't read past buffer + /* ensure we don't read past buffer */ if (plen < mlen || plen != mlen + *(uint8_t *)(pdata+sizeof(uint16_t))) { status = SDP_INVALID_SYNTAX; goto done; @@ -671,7 +670,7 @@ plen = ntohs(((sdp_pdu_hdr_t *)(req->buf))->plen); mlen = scanned + sizeof(uint32_t) + sizeof(uint16_t) + 1; - // ensure we don't read past buffer + /* ensure we don't read past buffer */ if (plen < mlen || plen != mlen + *(uint8_t *)pdata) { status = SDP_INVALID_PDU_SIZE; goto done; @@ -699,7 +698,7 @@ } /* - * Calculate Attribute size acording to MTU + * Calculate Attribute size according to MTU * We can send only (MTU - sizeof(sdp_pdu_hdr_t) - sizeof(sdp_cont_state_t)) */ max_rsp_size = MIN(max_rsp_size, req->mtu - sizeof(sdp_pdu_hdr_t) - @@ -754,7 +753,7 @@ } } - // push header + /* push header */ buf->data -= sizeof(uint16_t); buf->buf_size += sizeof(uint16_t); @@ -785,7 +784,7 @@ short cstate_size = 0; uint8_t dtd = 0; sdp_buf_t tmpbuf; - size_t data_left = req->len; + size_t data_left; tmpbuf.data = NULL; pdata = req->buf + sizeof(sdp_pdu_hdr_t); @@ -854,7 +853,7 @@ memset(tmpbuf.data, 0, USHRT_MAX); /* - * Calculate Attribute size acording to MTU + * Calculate Attribute size according to MTU * We can send only (MTU - sizeof(sdp_pdu_hdr_t) - sizeof(sdp_cont_state_t)) */ max = MIN(max, req->mtu - sizeof(sdp_pdu_hdr_t) - SDP_CONT_STATE_SIZE - sizeof(uint16_t)); @@ -880,7 +879,7 @@ break; } if (buf->data_size + tmpbuf.data_size < buf->buf_size) { - // to be sure no relocations + /* to be sure no relocations */ sdp_append_to_buf(buf, tmpbuf.data, tmpbuf.data_size); tmpbuf.data_size = 0; memset(tmpbuf.data, 0, USHRT_MAX); @@ -925,13 +924,13 @@ } if (!rsp_count && !cstate) { - // found nothing + /* found nothing */ buf->data_size = 0; sdp_append_to_buf(buf, tmpbuf.data, tmpbuf.data_size); sdp_set_cstate_pdu(buf, NULL); } - // push header + /* push header */ buf->data -= sizeof(uint16_t); buf->buf_size += sizeof(uint16_t); @@ -962,7 +961,6 @@ sdp_pdu_hdr_t *rsphdr; sdp_buf_t rsp; uint8_t *buf = malloc(USHRT_MAX); - int sent = 0; int status = SDP_INVALID_SYNTAX; memset(buf, 0, USHRT_MAX); @@ -1036,7 +1034,8 @@ rsp.data = buf; /* stream the rsp PDU */ - sent = send(req->sock, rsp.data, rsp.data_size, 0); + if (send(req->sock, rsp.data, rsp.data_size, 0) < 0) + error("send: %s (%d)", strerror(errno), errno); SDPDBG("Bytes Sent : %d", sent); diff -Nru bluez-4.91/src/sdpd-service.c bluez-4.96/src/sdpd-service.c --- bluez-4.91/src/sdpd-service.c 2011-01-11 14:51:27.000000000 +0000 +++ bluez-4.96/src/sdpd-service.c 2011-05-31 02:39:53.000000000 +0000 @@ -65,7 +65,7 @@ * seconds. Used for updating the service db state * attribute of the service record of the SDP server */ -uint32_t sdp_get_time() +uint32_t sdp_get_time(void) { /* * To handle failure in gettimeofday, so an old @@ -411,7 +411,7 @@ bufsize -= sizeof(bdaddr_t); } - // save image of PDU: we need it when clients request this attribute + /* save image of PDU: we need it when clients request this attribute */ rec = extract_pdu_server(&req->device, p, bufsize, 0xffffffff, &scanned); if (!rec) goto invalid; @@ -515,7 +515,6 @@ int status = 0; /* extract service record handle */ - p += sizeof(uint32_t); rec = sdp_record_find(handle); if (rec) { diff -Nru bluez-4.91/src/sdp-xml.c bluez-4.96/src/sdp-xml.c --- bluez-4.91/src/sdp-xml.c 2010-11-05 13:57:33.000000000 +0000 +++ bluez-4.96/src/sdp-xml.c 2011-05-31 02:39:53.000000000 +0000 @@ -47,7 +47,6 @@ int i, hex; char buf[STRBUFSIZE]; char indent[MAXINDENT]; - char next_indent[MAXINDENT]; if (!value) return; @@ -55,15 +54,10 @@ if (indent_level >= MAXINDENT) indent_level = MAXINDENT - 2; - for (i = 0; i < indent_level; i++) { + for (i = 0; i < indent_level; i++) indent[i] = '\t'; - next_indent[i] = '\t'; - } indent[i] = '\0'; - next_indent[i] = '\t'; - next_indent[i + 1] = '\0'; - buf[STRBUFSIZE - 1] = '\0'; switch (value->dtd) { @@ -704,7 +698,7 @@ #define DEFAULT_XML_DATA_SIZE 1024 -struct sdp_xml_data *sdp_xml_data_alloc() +struct sdp_xml_data *sdp_xml_data_alloc(void) { struct sdp_xml_data *elem; diff -Nru bluez-4.91/src/sdp-xml.h bluez-4.96/src/sdp-xml.h --- bluez-4.91/src/sdp-xml.h 2010-01-09 20:52:17.000000000 +0000 +++ bluez-4.96/src/sdp-xml.h 2011-05-31 02:39:53.000000000 +0000 @@ -49,7 +49,7 @@ /* TODO: What is it used for? */ }; -struct sdp_xml_data *sdp_xml_data_alloc(); +struct sdp_xml_data *sdp_xml_data_alloc(void); void sdp_xml_data_free(struct sdp_xml_data *elem); struct sdp_xml_data *sdp_xml_data_expand(struct sdp_xml_data *elem); diff -Nru bluez-4.91/src/storage.c bluez-4.96/src/storage.c --- bluez-4.91/src/storage.c 2011-01-25 17:07:54.000000000 +0000 +++ bluez-4.96/src/storage.c 2011-07-31 06:52:19.000000000 +0000 @@ -368,7 +368,7 @@ int i; memset(str, 0, sizeof(str)); - for (i = 0; i < 240; i++) + for (i = 0; i < HCI_MAX_EIR_LENGTH; i++) sprintf(str + (i * 2), "%2.2X", data[i]); create_filename(filename, PATH_MAX, local, "eir"); @@ -402,7 +402,7 @@ return -EIO; } - for (i = 0; i < 240; i++) + for (i = 0; i < HCI_MAX_EIR_LENGTH; i++) sscanf(str + (i * 2), "%02hhX", &data[i]); free(str); @@ -594,10 +594,10 @@ return 0; } -int read_pin_code(bdaddr_t *local, bdaddr_t *peer, char *pin) +ssize_t read_pin_code(bdaddr_t *local, bdaddr_t *peer, char *pin) { char filename[PATH_MAX + 1], addr[18], *str; - int len; + ssize_t len; create_filename(filename, PATH_MAX, local, "pincodes"); @@ -1211,8 +1211,7 @@ textfile_del(filename, key); } - g_slist_foreach(match.keys, (GFunc) g_free, NULL); - g_slist_free(match.keys); + g_slist_free_full(match.keys, g_free); /* Deleting all attributes values of a given address */ memset(&match, 0, sizeof(match)); @@ -1228,8 +1227,7 @@ textfile_del(filename, key); } - g_slist_foreach(match.keys, (GFunc) g_free, NULL); - g_slist_free(match.keys); + g_slist_free_full(match.keys, g_free); return 0; } diff -Nru bluez-4.91/src/storage.h bluez-4.96/src/storage.h --- bluez-4.91/src/storage.h 2011-01-25 17:07:54.000000000 +0000 +++ bluez-4.96/src/storage.h 2011-07-31 06:52:19.000000000 +0000 @@ -49,7 +49,7 @@ int write_lastused_info(bdaddr_t *local, bdaddr_t *peer, struct tm *tm); int write_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key, uint8_t type, int length); int read_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key, uint8_t *type); -int read_pin_code(bdaddr_t *local, bdaddr_t *peer, char *pin); +ssize_t read_pin_code(bdaddr_t *local, bdaddr_t *peer, char *pin); gboolean read_trust(const bdaddr_t *local, const char *addr, const char *service); int write_trust(const char *src, const char *addr, const char *service, gboolean trust); GSList *list_trusts(bdaddr_t *local, const char *service); diff -Nru bluez-4.91/src/textfile.c bluez-4.96/src/textfile.c --- bluez-4.91/src/textfile.c 2010-12-18 19:12:17.000000000 +0000 +++ bluez-4.96/src/textfile.c 2011-05-31 02:39:53.000000000 +0000 @@ -182,7 +182,8 @@ { struct stat st; char *map, *off, *end, *str; - off_t size, pos; size_t base; + off_t size; + size_t base; int fd, len, err = 0; fd = open(pathname, O_RDWR); @@ -203,7 +204,7 @@ if (!size) { if (value) { - pos = lseek(fd, size, SEEK_SET); + lseek(fd, size, SEEK_SET); err = write_key_value(fd, key, value); } goto unlock; @@ -221,7 +222,7 @@ if (!off) { if (value) { munmap(map, size); - pos = lseek(fd, size, SEEK_SET); + lseek(fd, size, SEEK_SET); err = write_key_value(fd, key, value); } goto unlock; @@ -249,7 +250,7 @@ err = errno; goto unlock; } - pos = lseek(fd, base, SEEK_SET); + lseek(fd, base, SEEK_SET); if (value) err = write_key_value(fd, key, value); @@ -275,7 +276,7 @@ free(str); goto unlock; } - pos = lseek(fd, base, SEEK_SET); + lseek(fd, base, SEEK_SET); if (value) err = write_key_value(fd, key, value); diff -Nru bluez-4.91/test/agent.c bluez-4.96/test/agent.c --- bluez-4.91/test/agent.c 2010-01-09 20:52:17.000000000 +0000 +++ bluez-4.96/test/agent.c 2011-07-04 04:59:05.000000000 +0000 @@ -41,6 +41,7 @@ static volatile sig_atomic_t __io_canceled = 0; static volatile sig_atomic_t __io_terminated = 0; +static volatile sig_atomic_t exit_on_release = 1; static void sig_term(int sig) { @@ -286,7 +287,8 @@ if (!__io_canceled) fprintf(stderr, "Agent has been released\n"); - __io_terminated = 1; + if (exit_on_release) + __io_terminated = 1; reply = dbus_message_new_method_return(msg); if (!reply) { @@ -414,6 +416,13 @@ return 0; } +static void create_paired_device_reply(DBusPendingCall *pending, + void *user_data) +{ + __io_terminated = 1; + return; +} + static int create_paired_device(DBusConnection *conn, const char *adapter_path, const char *agent_path, const char *capabilities, @@ -421,6 +430,7 @@ { dbus_bool_t success; DBusMessage *msg; + DBusPendingCall *pending; msg = dbus_message_new_method_call("org.bluez", adapter_path, "org.bluez.Adapter", @@ -435,7 +445,12 @@ DBUS_TYPE_STRING, &capabilities, DBUS_TYPE_INVALID); - success = dbus_connection_send(conn, msg, NULL); + exit_on_release = 0; + success = dbus_connection_send_with_reply(conn, msg, &pending, -1); + if (pending) + dbus_pending_call_set_notify(pending, + create_paired_device_reply, + NULL, NULL); dbus_message_unref(msg); diff -Nru bluez-4.91/test/apitest bluez-4.96/test/apitest --- bluez-4.91/test/apitest 2008-08-05 21:14:56.000000000 +0000 +++ bluez-4.96/test/apitest 2011-07-04 04:59:05.000000000 +0000 @@ -403,7 +403,7 @@ print 'Usage: %s -i ListRecentRemoteDevices date' % self.name else: # FIXME: remove at future version - print 'Script Error: Method %s not found. Maybe a mispelled word.' % (self.cmd_args) + print 'Script Error: Method %s not found. Maybe a misspelled word.' % (self.cmd_args) except dbus.DBusException, e: print '%s failed: %s' % (self.cmd, e) sys.exit(1) diff -Nru bluez-4.91/test/avtest.c bluez-4.96/test/avtest.c --- bluez-4.91/test/avtest.c 2010-01-09 20:52:17.000000000 +0000 +++ bluez-4.96/test/avtest.c 2011-05-31 02:39:53.000000000 +0000 @@ -714,7 +714,7 @@ dump_avctp_header(hdr); } -static void usage() +static void usage(void) { printf("avtest - Audio/Video testing ver %s\n", VERSION); printf("Usage:\n" diff -Nru bluez-4.91/test/bdaddr.c bluez-4.96/test/bdaddr.c --- bluez-4.91/test/bdaddr.c 2010-01-09 20:52:17.000000000 +0000 +++ bluez-4.96/test/bdaddr.c 2011-07-04 04:59:05.000000000 +0000 @@ -437,7 +437,7 @@ printf("Reset device manually\n"); } else { ioctl(dd, HCIDEVRESET, dev); - printf("Device reset successully\n"); + printf("Device reset successfully\n"); } } else { printf("Reset device now\n"); diff -Nru bluez-4.91/test/hciemu.c bluez-4.96/test/hciemu.c --- bluez-4.91/test/hciemu.c 2011-03-16 00:34:27.000000000 +0000 +++ bluez-4.96/test/hciemu.c 2011-05-31 02:39:53.000000000 +0000 @@ -68,7 +68,7 @@ uint8_t dev_class[3]; uint8_t inq_mode; uint8_t eir_fec; - uint8_t eir_data[240]; + uint8_t eir_data[HCI_MAX_EIR_LENGTH]; uint16_t acl_cnt; bdaddr_t bdaddr; int fd; @@ -203,7 +203,6 @@ struct timeval tv; uint32_t size = len; uint64_t ts; - int err; if (fd < 0) return -1; @@ -221,8 +220,11 @@ if (type == HCI_COMMAND_PKT || type == HCI_EVENT_PKT) pkt.flags |= ntohl(0x02); - err = write(fd, &pkt, BTSNOOP_PKT_SIZE); - err = write(fd, buf, size); + if (write(fd, &pkt, BTSNOOP_PKT_SIZE) < 0) + return -errno; + + if (write(fd, buf, size) < 0) + return -errno; return 0; } @@ -714,14 +716,14 @@ case OCF_READ_EXT_INQUIRY_RESPONSE: ir.status = 0x00; ir.fec = vdev.eir_fec; - memcpy(ir.data, vdev.eir_data, 240); + memcpy(ir.data, vdev.eir_data, HCI_MAX_EIR_LENGTH); command_complete(ogf, ocf, sizeof(ir), &ir); break; case OCF_WRITE_EXT_INQUIRY_RESPONSE: status = 0x00; vdev.eir_fec = data[0]; - memcpy(vdev.eir_data, data + 1, 240); + memcpy(vdev.eir_data, data + 1, HCI_MAX_EIR_LENGTH); command_complete(ogf, ocf, 1, &status); break; @@ -861,7 +863,7 @@ unsigned char buf[HCI_MAX_FRAME_SIZE], *ptr; hci_acl_hdr *ah; uint16_t flags; - int fd, err, len; + int fd, len; if (cond & G_IO_NVAL) { g_io_channel_unref(chan); @@ -898,7 +900,8 @@ write_snoop(vdev.dd, HCI_ACLDATA_PKT, 1, buf, len); - err = write(vdev.fd, buf, len); + if (write(vdev.fd, buf, len) < 0) + return FALSE; return TRUE; } diff -Nru bluez-4.91/test/hstest.c bluez-4.96/test/hstest.c --- bluez-4.91/test/hstest.c 2010-05-23 12:47:19.000000000 +0000 +++ bluez-4.96/test/hstest.c 2011-05-31 02:39:53.000000000 +0000 @@ -159,7 +159,7 @@ char *filename; mode_t filemode; - int err, mode = 0; + int mode = 0; int dd, rd, sd, fd; uint16_t sco_handle, sco_mtu, vs; @@ -244,8 +244,10 @@ fprintf(stderr, "SCO audio channel connected (handle %d, mtu %d)\n", sco_handle, sco_mtu); - if (mode == RECORD) - err = write(rd, "RING\r\n", 6); + if (mode == RECORD) { + if (write(rd, "RING\r\n", 6) < 0) + return -errno; + } maxfd = (rd > sd) ? rd : sd; diff -Nru bluez-4.91/test/l2test.c bluez-4.96/test/l2test.c --- bluez-4.91/test/l2test.c 2011-02-13 20:40:34.000000000 +0000 +++ bluez-4.96/test/l2test.c 2011-07-31 06:52:19.000000000 +0000 @@ -112,6 +112,30 @@ static int timestamp = 0; static int defer_setup = 0; +static struct { + char *name; + int flag; +} l2cap_modes[] = { + { "basic", L2CAP_MODE_BASIC }, + /* Not implemented + { "flowctl", L2CAP_MODE_FLOWCTL }, + { "retrans", L2CAP_MODE_RETRANS }, + */ + { "ertm", L2CAP_MODE_ERTM }, + { "streaming", L2CAP_MODE_STREAMING }, + { 0 } +}; + +static void list_l2cap_modes(void) +{ + int i; + + printf("l2test - L2CAP testing\n" + "List L2CAP modes:\n"); + for (i=0; l2cap_modes[i].name; i++) + printf("\t%s\n", l2cap_modes[i].name); +} + static float tv2fl(struct timeval tv) { return (float)tv.tv_sec + (float)(tv.tv_usec/1000000.0); @@ -948,25 +972,25 @@ case 0x0000: memcpy(&mask, rsp->data, sizeof(mask)); printf("Extended feature mask is 0x%04x\n", btohl(mask)); - if (mask & 0x01) + if (mask & L2CAP_FEAT_FLOWCTL) printf(" Flow control mode\n"); - if (mask & 0x02) + if (mask & L2CAP_FEAT_RETRANS) printf(" Retransmission mode\n"); - if (mask & 0x04) + if (mask & L2CAP_FEAT_BIDIR_QOS) printf(" Bi-directional QoS\n"); - if (mask & 0x08) + if (mask & L2CAP_FEAT_ERTM) printf(" Enhanced Retransmission mode\n"); - if (mask & 0x10) + if (mask & L2CAP_FEAT_STREAMING) printf(" Streaming mode\n"); - if (mask & 0x20) + if (mask & L2CAP_FEAT_FCS) printf(" FCS Option\n"); - if (mask & 0x40) + if (mask & L2CAP_FEAT_EXT_FLOW) printf(" Extended Flow Specification\n"); - if (mask & 0x80) + if (mask & L2CAP_FEAT_FIXED_CHAN) printf(" Fixed Channels\n"); - if (mask & 0x0100) + if (mask & L2CAP_FEAT_EXT_WINDOW) printf(" Extended Window Size\n"); - if (mask & 0x0200) + if (mask & L2CAP_FEAT_UCD) printf(" Unicast Connectionless Data Reception\n"); break; case 0x0001: @@ -1083,7 +1107,7 @@ "\t[-N num] send num frames (default = infinite)\n" "\t[-C num] send num frames before delay (default = 1)\n" "\t[-D milliseconds] delay after sending num frames (default = 0)\n" - "\t[-X mode] select retransmission/flow-control mode\n" + "\t[-X mode] l2cap mode (help for list, default = basic)\n" "\t[-F fcs] use CRC16 check (default = 1)\n" "\t[-Q num] Max Transmit value (default = 3)\n" "\t[-Z size] Transmission Window size (default = 63)\n" @@ -1100,7 +1124,7 @@ int main(int argc, char *argv[]) { struct sigaction sa; - int opt, sk, mode = RECV, need_addr = 0; + int opt, sk, i, mode = RECV, need_addr = 0; bacpy(&bdaddr, BDADDR_ANY); @@ -1218,10 +1242,17 @@ break; case 'X': - if (strcasecmp(optarg, "ertm") == 0) - rfcmode = L2CAP_MODE_ERTM; - else - rfcmode = atoi(optarg); + rfcmode = -1; + + for (i = 0; l2cap_modes[i].name; i++) + if (!strcasecmp(l2cap_modes[i].name, optarg)) + rfcmode = l2cap_modes[i].flag; + + if (!strcasecmp(optarg, "help") || rfcmode == -1) { + list_l2cap_modes(); + exit(1); + } + break; case 'F': diff -Nru bluez-4.91/test/rctest.c bluez-4.96/test/rctest.c --- bluez-4.91/test/rctest.c 2010-05-23 12:47:19.000000000 +0000 +++ bluez-4.96/test/rctest.c 2011-05-31 02:39:53.000000000 +0000 @@ -417,13 +417,11 @@ struct timeval tv_beg, tv_end, tv_diff; char ts[30]; long total; - uint32_t seq; syslog(LOG_INFO, "Receiving ..."); memset(ts, 0, sizeof(ts)); - seq = 0; while (1) { gettimeofday(&tv_beg,NULL); total = 0; diff -Nru bluez-4.91/test/sap-client bluez-4.96/test/sap-client --- bluez-4.91/test/sap-client 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/test/sap-client 2011-07-04 04:59:05.000000000 +0000 @@ -829,7 +829,7 @@ try: params = self.__rcvMsg(SAPMessage_DISCONNECT_IND()).getParams() - """gracefull""" + """graceful""" if params[0].getValue() == 0x00: if not self.proc_transferAPDU(): return False diff -Nru bluez-4.91/test/scotest.c bluez-4.96/test/scotest.c --- bluez-4.91/test/scotest.c 2010-05-23 12:47:19.000000000 +0000 +++ bluez-4.96/test/scotest.c 2011-05-31 02:39:53.000000000 +0000 @@ -216,11 +216,9 @@ { struct timeval tv_beg,tv_end,tv_diff; long total; - uint32_t seq; syslog(LOG_INFO, "Receiving ..."); - seq = 0; while (1) { gettimeofday(&tv_beg, NULL); total = 0; diff -Nru bluez-4.91/test/simple-agent bluez-4.96/test/simple-agent --- bluez-4.91/test/simple-agent 2010-09-08 15:27:53.000000000 +0000 +++ bluez-4.96/test/simple-agent 2011-07-04 04:59:05.000000000 +0000 @@ -6,6 +6,7 @@ import dbus import dbus.service import dbus.mainloop.glib +from optparse import OptionParser class Rejected(dbus.DBusException): _dbus_error_name = "org.bluez.Error.Rejected" @@ -88,8 +89,17 @@ manager = dbus.Interface(bus.get_object("org.bluez", "/"), "org.bluez.Manager") - if len(sys.argv) > 1: - path = manager.FindAdapter(sys.argv[1]) + capability = "DisplayYesNo" + + parser = OptionParser() + parser.add_option("-c", "--capability", action="store", + type="string", dest="capability") + (options, args) = parser.parse_args() + if options.capability: + capability = options.capability + + if len(args) > 0: + path = manager.FindAdapter(args[0]) else: path = manager.DefaultAdapter() @@ -101,17 +111,17 @@ mainloop = gobject.MainLoop() - if len(sys.argv) > 2: - if len(sys.argv) > 3: - device = adapter.FindDevice(sys.argv[2]) + if len(args) > 1: + if len(args) > 2: + device = adapter.FindDevice(args[1]) adapter.RemoveDevice(device) agent.set_exit_on_release(False) - adapter.CreatePairedDevice(sys.argv[2], path, "DisplayYesNo", + adapter.CreatePairedDevice(args[1], path, capability, reply_handler=create_device_reply, error_handler=create_device_error) else: - adapter.RegisterAgent(path, "DisplayYesNo") + adapter.RegisterAgent(path, capability) print "Agent registered" mainloop.run() diff -Nru bluez-4.91/test/test-oob bluez-4.96/test/test-oob --- bluez-4.91/test/test-oob 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/test/test-oob 2011-04-25 09:44:21.000000000 +0000 @@ -0,0 +1,80 @@ +#!/usr/bin/python + +import gobject + +import dbus.mainloop.glib + +def create_device_reply(device): + print "Pairing succeed!" + mainloop.quit() + +def create_device_error(error): + print "Pairing failed." + mainloop.quit() + +if __name__ == '__main__': + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + + mainloop = gobject.MainLoop() + + bus = dbus.SystemBus() + manager = dbus.Interface(bus.get_object("org.bluez", "/"), + "org.bluez.Manager") + + adapter0_path = manager.FindAdapter("hci0") + adapter1_path = manager.FindAdapter("hci1") + + adapter0 = dbus.Interface(bus.get_object("org.bluez", adapter0_path), + "org.bluez.Adapter") + adapter1 = dbus.Interface(bus.get_object("org.bluez", adapter1_path), + "org.bluez.Adapter") + + adapter0_address = adapter0.GetProperties()["Address"] + adapter1_address = adapter1.GetProperties()["Address"] + print "Adapters:" + print " hci0: " + adapter0_address + print " hci1: " + adapter1_address + print + + print "Removing any existing bond..." + + try: + device = adapter0.FindDevice(adapter1_address) + adapter0.RemoveDevice(device) + except: + pass + + try: + device = adapter1.FindDevice(adapter0_address) + adapter1.RemoveDevice(device) + except: + pass + + print "Done." + print + print "Reading local Out of Band data..." + + oob_adapter0 = dbus.Interface(bus.get_object("org.bluez", + adapter0_path), "org.bluez.OutOfBand") + oob_adapter1 = dbus.Interface(bus.get_object("org.bluez", + adapter1_path), "org.bluez.OutOfBand") + + oob0 = oob_adapter0.ReadLocalData() + oob1 = oob_adapter1.ReadLocalData() + + print "Done." + print + print "Exchanging Out of Band data..." + + oob_adapter0.AddRemoteData(adapter1_address, oob1[0], oob1[1]) + oob_adapter1.AddRemoteData(adapter0_address, oob0[0], oob0[1]) + + print "Done." + print + print "Starting to pair." + adapter1.CreatePairedDevice(adapter0_address, "/test/agent_oob", + "DisplayYesNo", + reply_handler=create_device_reply, + error_handler=create_device_error) + + mainloop.run() diff -Nru bluez-4.91/test/test-textfile.c bluez-4.96/test/test-textfile.c --- bluez-4.91/test/test-textfile.c 2010-05-23 12:47:19.000000000 +0000 +++ bluez-4.96/test/test-textfile.c 2011-05-31 02:39:53.000000000 +0000 @@ -44,25 +44,28 @@ char filename[] = "/tmp/textfile"; char key[18], value[512], *str; unsigned int i, j, size, max = 10; - int fd, err; + int fd; size = getpagesize(); printf("System uses a page size of %d bytes\n\n", size); fd = creat(filename, 0644); - err = ftruncate(fd, 0); + if (ftruncate(fd, 0) < 0) + return -errno; memset(value, 0, sizeof(value)); - for (i = 0; i < (size / sizeof(value)); i++) - err = write(fd, value, sizeof(value)); + for (i = 0; i < (size / sizeof(value)); i++) { + if (write(fd, value, sizeof(value)) < 0) + return -errno; + } close(fd); sprintf(key, "11:11:11:11:11:11"); str = textfile_get(filename, key); - err = truncate(filename, 0); - + if (truncate(filename, 0) < 0) + return -errno; sprintf(key, "00:00:00:00:00:00"); if (textfile_del(filename, key) < 0) diff -Nru bluez-4.91/thermometer/main.c bluez-4.96/thermometer/main.c --- bluez-4.91/thermometer/main.c 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/thermometer/main.c 2011-07-31 06:52:19.000000000 +0000 @@ -0,0 +1,59 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 GSyC/LibreSoft, Universidad Rey Juan Carlos. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include "plugin.h" +#include "manager.h" + +static DBusConnection *connection = NULL; + +static int thermometer_init(void) +{ + connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (connection == NULL) + return -EIO; + + if (thermometer_manager_init(connection) < 0) { + dbus_connection_unref(connection); + return -EIO; + } + + return 0; +} + +static void thermometer_exit(void) +{ + thermometer_manager_exit(); + + dbus_connection_unref(connection); + connection = NULL; +} + +BLUETOOTH_PLUGIN_DEFINE(thermometer, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, + thermometer_init, thermometer_exit) diff -Nru bluez-4.91/thermometer/manager.c bluez-4.96/thermometer/manager.c --- bluez-4.91/thermometer/manager.c 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/thermometer/manager.c 2011-07-31 06:52:19.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 GSyC/LibreSoft, Universidad Rey Juan Carlos. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +#include "adapter.h" +#include "device.h" +#include "thermometer.h" +#include "manager.h" + +#define HEALTH_THERMOMETER_UUID "00001809-0000-1000-8000-00805f9b34fb" + +static DBusConnection *connection = NULL; + +static int thermometer_driver_probe(struct btd_device *device, GSList *uuids) +{ + return thermometer_register(connection, device); +} + +static void thermometer_driver_remove(struct btd_device *device) +{ + thermometer_unregister(device); +} + +static struct btd_device_driver thermometer_device_driver = { + .name = "thermometer-device-driver", + .uuids = BTD_UUIDS(HEALTH_THERMOMETER_UUID), + .probe = thermometer_driver_probe, + .remove = thermometer_driver_remove +}; + +int thermometer_manager_init(DBusConnection *conn) +{ + int ret; + + ret = btd_register_device_driver(&thermometer_device_driver); + if (ret < 0) + return ret; + + connection = dbus_connection_ref(conn); + return 0; +} + +void thermometer_manager_exit(void) +{ + btd_unregister_device_driver(&thermometer_device_driver); + + dbus_connection_unref(connection); + connection = NULL; +} diff -Nru bluez-4.91/thermometer/manager.h bluez-4.96/thermometer/manager.h --- bluez-4.91/thermometer/manager.h 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/thermometer/manager.h 2011-07-31 06:52:19.000000000 +0000 @@ -0,0 +1,24 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 GSyC/LibreSoft, Universidad Rey Juan Carlos. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +int thermometer_manager_init(DBusConnection *conn); +void thermometer_manager_exit(void); diff -Nru bluez-4.91/thermometer/thermometer.c bluez-4.96/thermometer/thermometer.c --- bluez-4.91/thermometer/thermometer.c 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/thermometer/thermometer.c 2011-07-31 06:52:19.000000000 +0000 @@ -0,0 +1,38 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 GSyC/LibreSoft, Universidad Rey Juan Carlos. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include + +#include "adapter.h" +#include "device.h" +#include "thermometer.h" + +int thermometer_register(DBusConnection *connection, struct btd_device *device) +{ + /* TODO: Register Health Thermometer Interface */ + return 0; +} + +void thermometer_unregister(struct btd_device *device) +{ + /* TODO: Unregister Health Thermometer Interface */ +} diff -Nru bluez-4.91/thermometer/thermometer.h bluez-4.96/thermometer/thermometer.h --- bluez-4.91/thermometer/thermometer.h 1970-01-01 00:00:00.000000000 +0000 +++ bluez-4.96/thermometer/thermometer.h 2011-07-31 06:52:19.000000000 +0000 @@ -0,0 +1,24 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011 GSyC/LibreSoft, Universidad Rey Juan Carlos. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +int thermometer_register(DBusConnection *connection, struct btd_device *device); +void thermometer_unregister(struct btd_device *device); diff -Nru bluez-4.91/TODO bluez-4.96/TODO --- bluez-4.91/TODO 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/TODO 2011-04-25 09:44:21.000000000 +0000 @@ -114,16 +114,6 @@ ATT/GATT ======== -- For BR/EDR, primary services can be registered based on the information - extracted from the service records. UUIDs, start and end handles information - are available in the record, Discover All Primary Services procedure is not - necessary. If a GATT service doesn't export a service record means that - it should not be used over BR/EDR. Don't start this task before to move the - attribute client code to the bluetoothd core. - - Priority: Medium - Complexity: C1 - - At the moment authentication and authorization is not supported at the same time, read/write requirements in the attribute server needs to be extended. According to Bluetooth Specification a server shall check @@ -146,6 +136,11 @@ Priority: Medium Complexity: C1 +- Fix hard-coded PSM for GATT services over basic rate. + + Priority: Low + Complexity: C1 + - Refactor read_by_group() and read_by_type() in src/attrib-server.c (they've grown simply too big). First step could be to move out the long for-loops to new functions called e.g. get_groups() and get_types(). @@ -232,11 +227,6 @@ Priority: High Complexity: C3 -- EIR generation support - - Priority: High - Complexity: C2 - - Blacklist support Priority: Medium diff -Nru bluez-4.91/tools/avinfo.c bluez-4.96/tools/avinfo.c --- bluez-4.91/tools/avinfo.c 2010-01-09 20:52:17.000000000 +0000 +++ bluez-4.96/tools/avinfo.c 2011-05-31 02:39:53.000000000 +0000 @@ -604,7 +604,7 @@ return sk; } -static void usage() +static void usage(void) { printf("avinfo - Audio/Video Info Tool ver %s\n", VERSION); printf("Usage:\n" diff -Nru bluez-4.91/tools/bccmd.c bluez-4.96/tools/bccmd.c --- bluez-4.91/tools/bccmd.c 2010-11-30 14:50:48.000000000 +0000 +++ bluez-4.96/tools/bccmd.c 2011-05-31 02:39:53.000000000 +0000 @@ -1226,8 +1226,7 @@ if (transport_open(transport, device, bcsp_rate) < 0) exit(1); - if (device) - free(device); + free(device); for (i = 0; commands[i].str; i++) { if (strcasecmp(commands[i].str, argv[0])) diff -Nru bluez-4.91/tools/hciattach_ath3k.c bluez-4.96/tools/hciattach_ath3k.c --- bluez-4.91/tools/hciattach_ath3k.c 2010-11-30 14:50:48.000000000 +0000 +++ bluez-4.96/tools/hciattach_ath3k.c 2011-05-31 02:39:53.000000000 +0000 @@ -148,8 +148,8 @@ return err; err = read_ps_event(event, HCI_PS_CMD_OCF); - if (event) - free(event); + + free(event); return err; } @@ -493,8 +493,7 @@ err = read_ps_event(event, HCI_PS_CMD_OCF); - if (event) - free(event); + free(event); return err; } @@ -623,8 +622,7 @@ if (read_ps_event(event, HCI_PS_CMD_OCF) >= 0) err = -EILSEQ; - if (!event) - free(event); + free(event); return err; } @@ -667,8 +665,7 @@ *code = reg; cleanup: - if (event) - free(event); + free(event); return err; } @@ -709,8 +706,7 @@ *build_version = status; cleanup: - if (event) - free(event); + free(event); return err; } @@ -768,8 +764,7 @@ err = read_ps_event(event, HCI_PS_CMD_OCF); - if (event) - free(event); + free(event); return err; } diff -Nru bluez-4.91/tools/hciattach.c bluez-4.96/tools/hciattach.c --- bluez-4.91/tools/hciattach.c 2010-11-30 14:50:48.000000000 +0000 +++ bluez-4.96/tools/hciattach.c 2011-07-04 04:59:05.000000000 +0000 @@ -351,12 +351,12 @@ static void bcsp_tshy_sig_alarm(int sig) { unsigned char bcsp_sync_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xda,0xdc,0xed,0xed,0xc0}; - int len; static int retries = 0; if (retries < bcsp_max_retries) { retries++; - len = write(serial_fd, &bcsp_sync_pkt, 10); + if (write(serial_fd, &bcsp_sync_pkt, 10) < 0) + return; alarm(1); return; } @@ -369,12 +369,12 @@ static void bcsp_tconf_sig_alarm(int sig) { unsigned char bcsp_conf_pkt[10] = {0xc0,0x00,0x41,0x00,0xbe,0xad,0xef,0xac,0xed,0xc0}; - int len; static int retries = 0; if (retries < bcsp_max_retries){ retries++; - len = write(serial_fd, &bcsp_conf_pkt, 10); + if (write(serial_fd, &bcsp_conf_pkt, 10) < 0) + return; alarm(1); return; } @@ -451,7 +451,8 @@ } if (!memcmp(bcspp, bcspsync, 4)) { - len = write(fd, &bcsp_sync_resp_pkt,10); + if (write(fd, &bcsp_sync_resp_pkt,10) < 0) + return -1; } else if (!memcmp(bcspp, bcspsyncresp, 4)) break; } @@ -500,6 +501,11 @@ len = write(fd, &bcsp_conf_resp_pkt, 10); else if (!memcmp(bcspp, bcspconfresp, 4)) break; + else + continue; + + if (len < 0) + return -errno; } /* State = garrulous */ @@ -774,12 +780,12 @@ nanosleep(&tm, NULL); // now the uart baud rate on the silicon wave module is set and effective. - // change our own baud rate as well. Then there is a reset event comming in + // change our own baud rate as well. Then there is a reset event coming in // on the *new* baud rate. This is *undocumented*! The packet looks like this: // 04 FF 01 0B (which would make that a confirmation of 0x0B = "Param // subcommand class". So: change to new baud rate, read with timeout, parse // data, error handling. BTW: all param access in Silicon Wave is done this way. - // Maybe this code would belong in a seperate file, or at least code reuse... + // Maybe this code would belong in a separate file, or at least code reuse... return 0; } diff -Nru bluez-4.91/tools/hciattach_ti.c bluez-4.96/tools/hciattach_ti.c --- bluez-4.91/tools/hciattach_ti.c 2010-11-20 20:25:14.000000000 +0000 +++ bluez-4.96/tools/hciattach_ti.c 2011-07-04 04:59:05.000000000 +0000 @@ -119,7 +119,7 @@ fp = fopen(file_name, "rb"); if (!fp) { perror("can't open firmware file"); - goto out; + return NULL; } if (1 != fread(&header, sizeof(struct bts_header), 1, fp)) { @@ -135,13 +135,12 @@ if (NULL != version) *version = header.version; - goto out; + return fp; errclose: fclose(fp); - fp = NULL; -out: - return fp; + + return NULL; } static unsigned long bts_fetch_action(FILE* fp, unsigned char* action_buf, diff -Nru bluez-4.91/tools/hciconfig.c bluez-4.96/tools/hciconfig.c --- bluez-4.91/tools/hciconfig.c 2011-03-29 08:53:53.000000000 +0000 +++ bluez-4.96/tools/hciconfig.c 2011-05-03 08:20:36.000000000 +0000 @@ -1252,7 +1252,7 @@ } if (opt) { - uint8_t fec = 0, data[240]; + uint8_t fec = 0, data[HCI_MAX_EIR_LENGTH]; char tmp[3]; int i, size; @@ -1260,8 +1260,8 @@ memset(tmp, 0, sizeof(tmp)); size = (strlen(opt) + 1) / 2; - if (size > 240) - size = 240; + if (size > HCI_MAX_EIR_LENGTH) + size = HCI_MAX_EIR_LENGTH; for (i = 0; i < size; i++) { memcpy(tmp, opt + (i * 2), 2); @@ -1274,7 +1274,7 @@ exit(1); } } else { - uint8_t fec, data[240], len, type, *ptr; + uint8_t fec, data[HCI_MAX_EIR_LENGTH], len, type, *ptr; char *str; if (hci_read_ext_inquiry_response(dd, &fec, data, 1000) < 0) { @@ -1285,7 +1285,7 @@ print_dev_hdr(&di); printf("\tFEC %s\n\t\t", fec ? "enabled" : "disabled"); - for (i = 0; i < 240; i++) + for (i = 0; i < HCI_MAX_EIR_LENGTH; i++) printf("%02x%s%s", data[i], (i + 1) % 8 ? "" : " ", (i + 1) % 16 ? " " : (i < 239 ? "\n\t\t" : "\n")); diff -Nru bluez-4.91/tools/hcitool.c bluez-4.96/tools/hcitool.c --- bluez-4.91/tools/hcitool.c 2011-03-16 00:34:28.000000000 +0000 +++ bluez-4.96/tools/hcitool.c 2011-05-31 02:39:53.000000000 +0000 @@ -2351,7 +2351,6 @@ unsigned char buf[HCI_MAX_EVENT_SIZE], *ptr; struct hci_filter nf, of; socklen_t olen; - hci_event_hdr *hdr; int num, len; olen = sizeof(of); @@ -2382,7 +2381,6 @@ goto done; } - hdr = (void *) (buf + 1); ptr = buf + (1 + HCI_EVENT_HDR_SIZE); len -= (1 + HCI_EVENT_HDR_SIZE); diff -Nru bluez-4.91/tools/hid2hci.8 bluez-4.96/tools/hid2hci.8 --- bluez-4.91/tools/hid2hci.8 2009-05-19 09:04:10.000000000 +0000 +++ bluez-4.96/tools/hid2hci.8 2011-05-03 08:20:36.000000000 +0000 @@ -29,23 +29,18 @@ mode and back. .SH OPTIONS .TP -.BI -h -Gives a list of possible options. -.TP -.BI -q -Don't display any messages. -.TP -.BI -r [hid,hci] +.B --mode= [hid, hci] Sets the mode to switch the device into .TP -.BI -v -Specifies the 4 digit vendor ID assigned to the device being switched +.B --method= [csr, logitech-hid, dell] +Which vendor method to use for switching the device. .TP -.BI -p -Specifies the 4 digit product ID assigned to the device being switched +.B --devpath= +Specifies the device path in /sys +.TP +.B --help +Gives a list of possible options. .TP -.BI -m [csr, logitech, dell] -Which vendor method to use for switching the device. .SH AUTHOR Written by Marcel Holtmann . .br diff -Nru bluez-4.91/tools/hid2hci.c bluez-4.96/tools/hid2hci.c --- bluez-4.91/tools/hid2hci.c 2010-01-09 20:52:18.000000000 +0000 +++ bluez-4.96/tools/hid2hci.c 2011-05-03 08:20:36.000000000 +0000 @@ -1,9 +1,10 @@ /* - * - * BlueZ - Bluetooth protocol stack for Linux + * hid2hci : switch the radio on devices that support + * it from HID to HCI and back * * Copyright (C) 2003-2010 Marcel Holtmann - * + * Copyright (C) 2008-2009 Mario Limonciello + * Copyright (C) 2009-2011 Kay Sievers * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,93 +33,34 @@ #include #include #include - +#include +#include #include -#ifdef NEED_USB_GET_BUSSES -static inline struct usb_bus *usb_get_busses(void) -{ - return usb_busses; -} -#endif - -#ifndef USB_DIR_OUT -#define USB_DIR_OUT 0x00 -#endif - -static char devpath[PATH_MAX + 1] = "/dev"; - -struct hiddev_devinfo { - unsigned int bustype; - unsigned int busnum; - unsigned int devnum; - unsigned int ifnum; - short vendor; - short product; - short version; - unsigned num_applications; -}; - -struct hiddev_report_info { - unsigned report_type; - unsigned report_id; - unsigned num_fields; -}; - -typedef __signed__ int __s32; - -struct hiddev_usage_ref { - unsigned report_type; - unsigned report_id; - unsigned field_index; - unsigned usage_index; - unsigned usage_code; - __s32 value; -}; - -#define HIDIOCGDEVINFO _IOR('H', 0x03, struct hiddev_devinfo) -#define HIDIOCINITREPORT _IO('H', 0x05) -#define HIDIOCSREPORT _IOW('H', 0x08, struct hiddev_report_info) -#define HIDIOCSUSAGE _IOW('H', 0x0C, struct hiddev_usage_ref) - -#define HID_REPORT_TYPE_OUTPUT 2 +#include "libudev.h" -#define HCI 0 -#define HID 1 - -struct device_info { - struct usb_device *dev; - int mode; - uint16_t vendor; - uint16_t product; +enum mode { + HCI = 0, + HID = 1, }; -static int switch_csr(struct device_info *devinfo) +static int usb_switch_csr(struct usb_dev_handle *dev, enum mode mode) { - struct usb_dev_handle *udev; int err; - udev = usb_open(devinfo->dev); - if (!udev) - return -errno; - - err = usb_control_msg(udev, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0, devinfo->mode, 0, NULL, 0, 10000); - + err = usb_control_msg(dev, + USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, mode, 0, NULL, 0, 10000); if (err == 0) { err = -1; errno = EALREADY; - } else { - if (errno == ETIMEDOUT) - err = 0; - } - - usb_close(udev); + } else if (errno == ETIMEDOUT) + err = 0; return err; } -static int send_report(int fd, const char *buf, size_t size) +static int hid_logitech_send_report(int fd, const char *buf, size_t size) { struct hiddev_report_info rinfo; struct hiddev_usage_ref uref; @@ -147,72 +89,42 @@ return err; } -static int switch_logitech(struct device_info *devinfo) +static int hid_switch_logitech(const char *filename) { - char devname[PATH_MAX + 1]; - int i, fd, err = -1; - - for (i = 0; i < 16; i++) { - struct hiddev_devinfo dinfo; - char rep1[] = { 0xff, 0x80, 0x80, 0x01, 0x00, 0x00 }; - char rep2[] = { 0xff, 0x80, 0x00, 0x00, 0x30, 0x00 }; - char rep3[] = { 0xff, 0x81, 0x80, 0x00, 0x00, 0x00 }; - - sprintf(devname, "%s/hiddev%d", devpath, i); - fd = open(devname, O_RDWR); - if (fd < 0) { - sprintf(devname, "%s/usb/hiddev%d", devpath, i); - fd = open(devname, O_RDWR); - if (fd < 0) { - sprintf(devname, "%s/usb/hid/hiddev%d", devpath, i); - fd = open(devname, O_RDWR); - if (fd < 0) - continue; - } - } - - memset(&dinfo, 0, sizeof(dinfo)); - err = ioctl(fd, HIDIOCGDEVINFO, &dinfo); - if (err < 0 || (int) dinfo.busnum != atoi(devinfo->dev->bus->dirname) || - (int) dinfo.devnum != atoi(devinfo->dev->filename)) { - close(fd); - continue; - } - - err = ioctl(fd, HIDIOCINITREPORT, 0); - if (err < 0) { - close(fd); - break; - } - - err = send_report(fd, rep1, sizeof(rep1)); - if (err < 0) { - close(fd); - break; - } - - err = send_report(fd, rep2, sizeof(rep2)); - if (err < 0) { - close(fd); - break; - } - - err = send_report(fd, rep3, sizeof(rep3)); - close(fd); - break; - } - + char rep1[] = { 0xff, 0x80, 0x80, 0x01, 0x00, 0x00 }; + char rep2[] = { 0xff, 0x80, 0x00, 0x00, 0x30, 0x00 }; + char rep3[] = { 0xff, 0x81, 0x80, 0x00, 0x00, 0x00 }; + int fd; + int err = -1; + + fd = open(filename, O_RDWR); + if (fd < 0) + return err; + + err = ioctl(fd, HIDIOCINITREPORT, 0); + if (err < 0) + goto out; + + err = hid_logitech_send_report(fd, rep1, sizeof(rep1)); + if (err < 0) + goto out; + + err = hid_logitech_send_report(fd, rep2, sizeof(rep2)); + if (err < 0) + goto out; + + err = hid_logitech_send_report(fd, rep3, sizeof(rep3)); +out: + close(fd); return err; } -static int switch_dell(struct device_info *devinfo) +static int usb_switch_dell(struct usb_dev_handle *dev, enum mode mode) { char report[] = { 0x7f, 0x00, 0x00, 0x00 }; - - struct usb_dev_handle *handle; int err; - switch (devinfo->mode) { + switch (mode) { case HCI: report[1] = 0x13; break; @@ -221,22 +133,16 @@ break; } - handle = usb_open(devinfo->dev); - if (!handle) - return -EIO; - /* Don't need to check return, as might not be in use */ - usb_detach_kernel_driver_np(handle, 0); + usb_detach_kernel_driver_np(dev, 0); - if (usb_claim_interface(handle, 0) < 0) { - usb_close(handle); + if (usb_claim_interface(dev, 0) < 0) return -EIO; - } - err = usb_control_msg(handle, - USB_ENDPOINT_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, + err = usb_control_msg(dev, + USB_ENDPOINT_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, USB_REQ_SET_CONFIGURATION, 0x7f | (0x03 << 8), 0, - report, sizeof(report), 5000); + report, sizeof(report), 5000); if (err == 0) { err = -1; @@ -245,131 +151,200 @@ if (errno == ETIMEDOUT) err = 0; } - - usb_close(handle); - return err; } -static int find_device(struct device_info* devinfo) +/* + * libusb needs to scan and open all devices, just to to find the + * device we already have. This should be fixed in libusb. + */ +static struct usb_device *usb_device_open_from_udev(struct udev_device *usb_dev) { struct usb_bus *bus; - struct usb_device *dev; + const char *str; + int busnum; + int devnum; + + str = udev_device_get_sysattr_value(usb_dev, "busnum"); + if (str == NULL) + return NULL; + busnum = strtol(str, NULL, 0); + + str = udev_device_get_sysattr_value(usb_dev, "devnum"); + if (str == NULL) + return NULL; + devnum = strtol(str, NULL, 0); + usb_init(); usb_find_busses(); usb_find_devices(); - for (bus = usb_get_busses(); bus; bus = bus->next) + for (bus = usb_get_busses(); bus; bus = bus->next) { + struct usb_device *dev; + + if (strtol(bus->dirname, NULL, 10) != busnum) + continue; + for (dev = bus->devices; dev; dev = dev->next) { - if (dev->descriptor.idVendor == devinfo->vendor && - dev->descriptor.idProduct == devinfo->product) { - devinfo->dev=dev; - return 1; - } + if (dev->devnum == devnum) + return dev; } - return 0; + } + + return NULL; } -static void usage(char* error) +static struct usb_dev_handle *find_device(struct udev_device *udev_dev) +{ + struct usb_device *dev; + + dev = usb_device_open_from_udev(udev_dev); + if (dev == NULL) + return NULL; + return usb_open(dev); +} + +static void usage(const char *error) { if (error) fprintf(stderr,"\n%s\n", error); else printf("hid2hci - Bluetooth HID to HCI mode switching utility\n\n"); - printf("Usage:\n" - "\thid2hci [options]\n" - "\n"); - - printf("Options:\n" - "\t-h, --help Display help\n" - "\t-q, --quiet Don't display any messages\n" - "\t-r, --mode= Mode to switch to [hid, hci]\n" - "\t-v, --vendor= Vendor ID to act upon\n" - "\t-p, --product= Product ID to act upon\n" - "\t-m, --method= Method to use to switch [csr, logitech, dell]\n" - "\n"); - if (error) - exit(1); + printf("Usage: hid2hci [options]\n" + " --mode= mode to switch to [hid|hci] (default hci)\n" + " --devpath= sys device path\n" + " --method= method to use to switch [csr|logitech-hid|dell]\n" + " --help\n\n"); } -static struct option main_options[] = { - { "help", no_argument, 0, 'h' }, - { "quiet", no_argument, 0, 'q' }, - { "mode", required_argument, 0, 'r' }, - { "vendor", required_argument, 0, 'v' }, - { "product", required_argument, 0, 'p' }, - { "method", required_argument, 0, 'm' }, - { 0, 0, 0, 0 } -}; - int main(int argc, char *argv[]) { - struct device_info dev = { NULL, HCI, 0, 0 }; - int opt, quiet = 0; - int (*method)(struct device_info *dev) = NULL; - - while ((opt = getopt_long(argc, argv, "+r:v:p:m:qh", main_options, NULL)) != -1) { - switch (opt) { - case 'r': - if (optarg && !strcmp(optarg, "hid")) - dev.mode = HID; - else if (optarg && !strcmp(optarg, "hci")) - dev.mode = HCI; - else - usage("ERROR: Undefined radio mode\n"); + static const struct option options[] = { + { "help", no_argument, NULL, 'h' }, + { "mode", required_argument, NULL, 'm' }, + { "devpath", required_argument, NULL, 'p' }, + { "method", required_argument, NULL, 'M' }, + { } + }; + enum method { + METHOD_UNDEF, + METHOD_CSR, + METHOD_LOGITECH_HID, + METHOD_DELL, + } method = METHOD_UNDEF; + struct udev *udev; + struct udev_device *udev_dev = NULL; + char syspath[PATH_MAX]; + int (*usb_switch)(struct usb_dev_handle *dev, enum mode mode) = NULL; + enum mode mode = HCI; + const char *devpath = NULL; + int err = -1; + int rc = 1; + + for (;;) { + int option; + + option = getopt_long(argc, argv, "m:p:M:h", options, NULL); + if (option == -1) break; - case 'v': - sscanf(optarg, "%4hx", &dev.vendor); + + switch (option) { + case 'm': + if (!strcmp(optarg, "hid")) { + mode = HID; + } else if (!strcmp(optarg, "hci")) { + mode = HCI; + } else { + usage("error: undefined radio mode\n"); + exit(1); + } break; case 'p': - sscanf(optarg, "%4hx", &dev.product); + devpath = optarg; break; - case 'm': - if (optarg && !strcmp(optarg, "csr")) - method = switch_csr; - else if (optarg && !strcmp(optarg, "logitech")) - method = switch_logitech; - else if (optarg && !strcmp(optarg, "dell")) - method = switch_dell; - else - usage("ERROR: Undefined switching method\n"); - break; - case 'q': - quiet = 1; + case 'M': + if (!strcmp(optarg, "csr")) { + method = METHOD_CSR; + usb_switch = usb_switch_csr; + } else if (!strcmp(optarg, "logitech-hid")) { + method = METHOD_LOGITECH_HID; + } else if (!strcmp(optarg, "dell")) { + method = METHOD_DELL; + usb_switch = usb_switch_dell; + } else { + usage("error: undefined switching method\n"); + exit(1); + } break; case 'h': usage(NULL); - default: - exit(0); } } - if (!quiet && (!dev.vendor || !dev.product || !method)) - usage("ERROR: Vendor ID, Product ID, and Switching Method must all be defined.\n"); + if (!devpath || method == METHOD_UNDEF) { + usage("error: --devpath= and --method= must be defined\n"); + exit(1); + } - argc -= optind; - argv += optind; - optind = 0; + udev = udev_new(); + if (udev == NULL) + goto exit; + + snprintf(syspath, sizeof(syspath), "%s/%s", udev_get_sys_path(udev), devpath); + udev_dev = udev_device_new_from_syspath(udev, syspath); + if (udev_dev == NULL) { + fprintf(stderr, "error: could not find '%s'\n", devpath); + goto exit; + } - usb_init(); + switch (method) { + case METHOD_CSR: + case METHOD_DELL: { + struct udev_device *dev; + struct usb_dev_handle *handle; + const char *type; + + /* get the parent usb_device if needed */ + dev = udev_dev; + type = udev_device_get_devtype(dev); + if (type == NULL || strcmp(type, "usb_device") != 0) { + dev = udev_device_get_parent_with_subsystem_devtype(dev, "usb", "usb_device"); + if (dev == NULL) { + fprintf(stderr, "error: could not find usb_device for '%s'\n", devpath); + goto exit; + } + } - if (!find_device(&dev)) { - if (!quiet) - fprintf(stderr, "Device %04x:%04x not found on USB bus.\n", - dev.vendor, dev.product); - exit(1); + handle = find_device(dev); + if (handle == NULL) { + fprintf(stderr, "error: unable to handle '%s'\n", + udev_device_get_syspath(dev)); + goto exit; + } + err = usb_switch(handle, mode); + break; } + case METHOD_LOGITECH_HID: { + const char *device; - if (!quiet) - printf("Attempting to switch device %04x:%04x to %s mode ", - dev.vendor, dev.product, dev.mode ? "HID" : "HCI"); - fflush(stdout); - - if (method(&dev) < 0 && !quiet) - printf("failed (%s)\n", strerror(errno)); - else if (!quiet) - printf("was successful\n"); + device = udev_device_get_devnode(udev_dev); + if (device == NULL) { + fprintf(stderr, "error: could not find hiddev device node\n"); + goto exit; + } + err = hid_switch_logitech(device); + break; + } + default: + break; + } - return errno; + if (err < 0) + fprintf(stderr, "error: switching device '%s' failed.\n", + udev_device_get_syspath(udev_dev)); +exit: + udev_device_unref(udev_dev); + udev_unref(udev); + return rc; } diff -Nru bluez-4.91/tools/rfcomm.1 bluez-4.96/tools/rfcomm.1 --- bluez-4.91/tools/rfcomm.1 2009-09-03 03:58:36.000000000 +0000 +++ bluez-4.96/tools/rfcomm.1 2011-07-04 04:59:05.000000000 +0000 @@ -99,7 +99,7 @@ a channel must be specified before cmd. If cmd is given, it will be executed as soon as a client connects. When the child process terminates or the client disconnect, the command will terminate. -Occurences of {} in cmd will be replaced by the name of the device +Occurrences of {} in cmd will be replaced by the name of the device used by the connection. This command can be terminated with the key sequence CTRL-C. .TP diff -Nru bluez-4.91/tools/sdptool.c bluez-4.96/tools/sdptool.c --- bluez-4.91/tools/sdptool.c 2010-09-21 16:41:10.000000000 +0000 +++ bluez-4.96/tools/sdptool.c 2011-07-04 04:59:05.000000000 +0000 @@ -4116,10 +4116,9 @@ context.handle = base[i] + n; err = get_service(&bdaddr, &context, 1); if (err < 0) - goto done; + return 0; } -done: return 0; } diff -Nru bluez-4.91/tools/ubcsp.c bluez-4.96/tools/ubcsp.c --- bluez-4.91/tools/ubcsp.c 2008-12-24 19:41:48.000000000 +0000 +++ bluez-4.96/tools/ubcsp.c 2011-07-04 04:59:05.000000000 +0000 @@ -720,13 +720,13 @@ activity |= UBCSP_PACKET_RECEIVED; } - } - } - - /* Just return any activity that occured */ - - return activity; -} + } + } + + /* Just return any activity that occurred */ + + return activity; +} /*****************************************************************************/ /** **/ @@ -1143,13 +1143,13 @@ ubcsp_config.receive_index ++; } - else if (ubcsp_config.receive_index < ubcsp_config.receive_packet->length) - { - /* We are receiving the payload */ - /* We might stop comming here if we are receiving a - packet which is longer than the receive_packet->length - given by the host */ - + else if (ubcsp_config.receive_index < ubcsp_config.receive_packet->length) + { + /* We are receiving the payload */ + /* We might stop coming here if we are receiving a + packet which is longer than the receive_packet->length + given by the host */ + ubcsp_config.receive_packet->payload[ubcsp_config.receive_index] = value; ubcsp_config.receive_index ++; diff -Nru bluez-4.91/tracer/main.c bluez-4.96/tracer/main.c --- bluez-4.91/tracer/main.c 2010-05-23 12:47:19.000000000 +0000 +++ bluez-4.96/tracer/main.c 2011-07-04 04:59:05.000000000 +0000 @@ -118,7 +118,7 @@ openlog("hcitrace", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON); - syslog(LOG_INFO, "HCI trace deamon %s", VERSION); + syslog(LOG_INFO, "HCI trace daemon %s", VERSION); memset(&sa, 0, sizeof(sa)); sa.sa_flags = SA_NOCLDSTOP;