Hi, It comes from actually use in our product. The scenario is that: 1. Pair a device named 'A'. Before agent give response for pairing device 'A': 2. Call pair method again to pair another device named 'B' . Device 'B' will never be paired until turn off/on Bluetooth. You can try it use bluetoothctl. The root cause is pair method will check device->bonding, return 'In progress' when it exists. Normally device will create bonding. If another device is in pairing status, It will fail to create bonding in 'adapter_create_bonding', because another pairing is in progress. It will never be paired that device by checking device->bonding if it don't free bonding. -----Original Message----- From: Luiz Augusto von Dentz [mailto:luiz.dentz@xxxxxxxxx] Sent: Sunday, October 2, 2016 12:56 AM To: Wu, Jiangbo <jiangbo.wu@xxxxxxxxx> Cc: Xu, Martin <martin.xu@xxxxxxxxx>; Johan Hedberg <johan.hedberg@xxxxxxxxx>; linux-bluetooth@xxxxxxxxxxxxxxx Subject: Re: [PATCH] src/device: Free bonding while failed to pair device Hi, On Fri, Sep 30, 2016 at 6:39 PM, <jiangbo.wu@xxxxxxxxx> wrote: > From: Jiangbo Wu <jiangbo.wu@xxxxxxxxx> It would be good to have something in the patch description, perhaps the backtrace if this is a crash fix or perhaps this comes from a static analyzer? > --- > src/device.c | 62 > +++++++++++++++++++++++++++++++----------------------------- > 1 file changed, 32 insertions(+), 30 deletions(-) > > diff --git a/src/device.c b/src/device.c index 25d2e22..fb6104f 100644 > --- a/src/device.c > +++ b/src/device.c > @@ -2314,6 +2314,35 @@ static void create_bond_req_exit(DBusConnection *conn, void *user_data) > } > } > > +static void bonding_request_free(struct bonding_req *bonding) { > + if (!bonding) > + return; > + > + if (bonding->listener_id) > + g_dbus_remove_watch(dbus_conn, bonding->listener_id); > + > + if (bonding->msg) > + dbus_message_unref(bonding->msg); > + > + if (bonding->cb_iter) > + g_free(bonding->cb_iter); > + > + if (bonding->agent) { > + agent_cancel(bonding->agent); > + agent_unref(bonding->agent); > + bonding->agent = NULL; > + } > + > + if (bonding->retry_timer) > + g_source_remove(bonding->retry_timer); > + > + if (bonding->device) > + bonding->device->bonding = NULL; > + > + g_free(bonding); > +} > + > static DBusMessage *pair_device(DBusConnection *conn, DBusMessage *msg, > void > *data) { @@ -2384,8 +2413,10 @@ static DBusMessage > *pair_device(DBusConnection *conn, DBusMessage *msg, > BDADDR_BREDR, io_cap); > } > > - if (err < 0) > + if (err < 0) { > + bonding_request_free(device->bonding); > return btd_error_failed(msg, strerror(-err)); > + } > > return NULL; > } > @@ -2426,35 +2457,6 @@ static DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status) > } > } > > -static void bonding_request_free(struct bonding_req *bonding) -{ > - if (!bonding) > - return; > - > - if (bonding->listener_id) > - g_dbus_remove_watch(dbus_conn, bonding->listener_id); > - > - if (bonding->msg) > - dbus_message_unref(bonding->msg); > - > - if (bonding->cb_iter) > - g_free(bonding->cb_iter); > - > - if (bonding->agent) { > - agent_cancel(bonding->agent); > - agent_unref(bonding->agent); > - bonding->agent = NULL; > - } > - > - if (bonding->retry_timer) > - g_source_remove(bonding->retry_timer); > - > - if (bonding->device) > - bonding->device->bonding = NULL; > - > - g_free(bonding); > -} > - > static void device_cancel_bonding(struct btd_device *device, uint8_t > status) { > struct bonding_req *bonding = device->bonding; > -- > 1.9.1 > > -- > To unsubscribe from this list: send the line "unsubscribe > linux-bluetooth" in the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Luiz Augusto von Dentz ��.n��������+%������w��{.n�����{����^n�r������&��z�ޗ�zf���h���~����������_��+v���)ߣ�