* [RFC] android/tester: Fix valgrind memory warnings
From: Andrei Emeltchenko @ 2013-12-20 9:49 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Make device structure static, fixes valgrind memory leak warnings in
android-tester and haltest.
==26231== 80 bytes in 1 blocks are definitely lost in loss record 25 of
31
==26231== at 0x4C2A2DB: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26231== by 0x40F153: open_bluetooth (hal-bluetooth.c:800)
==26231== by 0x40C8D8: setup (android-tester.c:835)
==26231== by 0x40CB20: setup_socket_interface_enabled
(android-tester.c:1166)
==26231== by 0x409C15: setup_callback (tester.c:373)
==26231== by 0x4E7C3B5: g_main_context_dispatch (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
==26231== by 0x4E7C707: ??? (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
==26231== by 0x4E7CB09: g_main_loop_run (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
==26231== by 0x40A83C: tester_run (tester.c:784)
==26231== by 0x40362A: main (android-tester.c:1643)
---
android/hal-bluetooth.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 7cac15c..738c189 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -797,18 +797,17 @@ static int close_bluetooth(struct hw_device_t *device)
static int open_bluetooth(const struct hw_module_t *module, char const *name,
struct hw_device_t **device)
{
- bluetooth_device_t *dev = malloc(sizeof(bluetooth_device_t));
+ static bluetooth_device_t dev;
DBG("");
- memset(dev, 0, sizeof(bluetooth_device_t));
- dev->common.tag = HARDWARE_DEVICE_TAG;
- dev->common.version = 0;
- dev->common.module = (struct hw_module_t *) module;
- dev->common.close = close_bluetooth;
- dev->get_bluetooth_interface = get_bluetooth_interface;
+ dev.common.tag = HARDWARE_DEVICE_TAG;
+ dev.common.version = 0;
+ dev.common.module = (struct hw_module_t *) module;
+ dev.common.close = close_bluetooth;
+ dev.get_bluetooth_interface = get_bluetooth_interface;
- *device = (struct hw_device_t *) dev;
+ *device = (struct hw_device_t *) &dev;
return 0;
}
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH] android/tester: Fix valgrind memory warnings
From: Johan Hedberg @ 2013-12-20 9:30 UTC (permalink / raw)
To: Szymon Janc; +Cc: Andrei Emeltchenko, linux-bluetooth
In-Reply-To: <2739769.kltLLfnETe@uw000953>
Hi Szymon,
On Fri, Dec 20, 2013, Szymon Janc wrote:
> > Free device structure allocated during open_bluetooth().
> > ---
> > android/android-tester.c | 6 ++++++
> > 1 file changed, 6 insertions(+)
> >
> > diff --git a/android/android-tester.c b/android/android-tester.c
> > index 7d7ed88..6007797 100644
> > --- a/android/android-tester.c
> > +++ b/android/android-tester.c
> > @@ -109,6 +109,7 @@ struct test_data {
> > const void *test_data;
> > pid_t bluetoothd_pid;
> >
> > + hw_device_t *device;
> > const bt_interface_t *if_bluetooth;
> > const btsock_interface_t *if_sock;
> >
> > @@ -838,6 +839,8 @@ static void setup(struct test_data *data)
> > return;
> > }
> >
> > + data->device = device;
> > +
> > data->if_bluetooth = ((bluetooth_device_t *)
> > device)->get_bluetooth_interface();
> > if (!data->if_bluetooth) {
> > @@ -882,6 +885,9 @@ static void teardown(const void *test_data)
> > data->if_bluetooth = NULL;
> > }
> >
> > + if (data->device)
> > + free(data->device);
>
> There is no need to check pointer before passing it to free().
The bigger issue here is that the ->open() caller shouldn't know how the
memory was allocated (or if it was allocated at all for that matter - it
might just be a static variable).
This is really a failure of the API since it doesn't provide a ->close()
callback that could do the right thing.
Johan
^ permalink raw reply
* [PATCHv2] tools/l2cap-tester: Fix memory leak
From: Marcin Kraglak @ 2013-12-20 9:30 UTC (permalink / raw)
To: linux-bluetooth
Set close_on_unref on new created GIOChannel and don't close
its file descriptor.
126 (120 direct, 6 indirect) bytes in 1 blocks aredefinitely
lost in loss record 24 of 28
at 0x4A06409: malloc (in/usr/lib64/valgrind/vgpreload_memcheck
-amd64-linux.so)
by 0x3C9564D88E: g_malloc (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3C956881F4: g_io_channel_unix_new (in/usr/lib64/libglib-
2.0.so.0.3600.3)
by 0x402A5A: l2cap_listen_cb (l2cap-tester.c:774)
by 0x3C95647DF5: g_main_context_dispatch (in/usr/lib64/
libglib-2.0.so.0.3600.3)
by 0x3C95648147: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3C95648549: g_main_loop_run
(in/usr/lib64/libglib-2.0.so.0.3600.3)
by 0x40A67C: tester_run (tester.c:784)
by 0x4026A9: main (l2cap-tester.c:991)
---
tools/l2cap-tester.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index 7c50f26..a5028a3 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -535,7 +535,6 @@ static gboolean server_received_data(GIOChannel *io, GIOCondition cond,
if (read(sk, buf, l2data->data_len) != l2data->data_len) {
tester_warn("Unable to read %u bytes", l2data->data_len);
tester_test_failed();
- close(sk);
return FALSE;
}
@@ -544,8 +543,6 @@ static gboolean server_received_data(GIOChannel *io, GIOCondition cond,
else
tester_test_passed();
- close(sk);
-
return FALSE;
}
@@ -785,12 +782,15 @@ static gboolean l2cap_listen_cb(GIOChannel *io, GIOCondition cond,
GIOChannel *new_io;
new_io = g_io_channel_unix_new(new_sk);
+ g_io_channel_set_close_on_unref(new_io, TRUE);
bthost = hciemu_client_get_host(data->hciemu);
g_io_add_watch(new_io, G_IO_IN, server_received_data, NULL);
bthost_send_cid(bthost, data->handle, data->dcid,
l2data->read_data, l2data->data_len);
+ g_io_channel_unref(new_io);
+
return FALSE;
} else if (l2data->write_data) {
struct bthost *bthost;
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH] android/tester: Fix valgrind memory warnings
From: Szymon Janc @ 2013-12-20 9:12 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth
In-Reply-To: <1387529782-26462-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> Free device structure allocated during open_bluetooth().
> ---
> android/android-tester.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/android/android-tester.c b/android/android-tester.c
> index 7d7ed88..6007797 100644
> --- a/android/android-tester.c
> +++ b/android/android-tester.c
> @@ -109,6 +109,7 @@ struct test_data {
> const void *test_data;
> pid_t bluetoothd_pid;
>
> + hw_device_t *device;
> const bt_interface_t *if_bluetooth;
> const btsock_interface_t *if_sock;
>
> @@ -838,6 +839,8 @@ static void setup(struct test_data *data)
> return;
> }
>
> + data->device = device;
> +
> data->if_bluetooth = ((bluetooth_device_t *)
> device)->get_bluetooth_interface();
> if (!data->if_bluetooth) {
> @@ -882,6 +885,9 @@ static void teardown(const void *test_data)
> data->if_bluetooth = NULL;
> }
>
> + if (data->device)
> + free(data->device);
There is no need to check pointer before passing it to free().
> +
> if (data->bluetoothd_pid)
> waitpid(data->bluetoothd_pid, NULL, 0);
>
>
--
BR
Szymon Janc
^ permalink raw reply
* [PATCH] tools/l2cap-tester: Fix memory leak
From: Marcin Kraglak @ 2013-12-20 9:10 UTC (permalink / raw)
To: linux-bluetooth
Set close_on_unref on new created GIOChannel and don't close
its file descriptor.
126 (120 direct, 6 indirect) bytes in 1 blocks aredefinitely
lost in loss record 24 of 28
at 0x4A06409: malloc (in/usr/lib64/valgrind/vgpreload_memcheck
-amd64-linux.so)
by 0x3C9564D88E: g_malloc (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3C956881F4: g_io_channel_unix_new (in/usr/lib64/libglib-
2.0.so.0.3600.3)
by 0x402A5A: l2cap_listen_cb (l2cap-tester.c:774)
by 0x3C95647DF5: g_main_context_dispatch (in/usr/lib64/
libglib-2.0.so.0.3600.3)
by 0x3C95648147: ??? (in /usr/lib64/libglib-2.0.so.0.3600.3)
by 0x3C95648549: g_main_loop_run
(in/usr/lib64/libglib-2.0.so.0.3600.3)
by 0x40A67C: tester_run (tester.c:784)
by 0x4026A9: main (l2cap-tester.c:991)
---
tools/l2cap-tester.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index 7c50f26..e4ebe7b 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -544,8 +544,6 @@ static gboolean server_received_data(GIOChannel *io, GIOCondition cond,
else
tester_test_passed();
- close(sk);
-
return FALSE;
}
@@ -785,12 +783,15 @@ static gboolean l2cap_listen_cb(GIOChannel *io, GIOCondition cond,
GIOChannel *new_io;
new_io = g_io_channel_unix_new(new_sk);
+ g_io_channel_set_close_on_unref(new_io, TRUE);
bthost = hciemu_client_get_host(data->hciemu);
g_io_add_watch(new_io, G_IO_IN, server_received_data, NULL);
bthost_send_cid(bthost, data->handle, data->dcid,
l2data->read_data, l2data->data_len);
+ g_io_channel_unref(new_io);
+
return FALSE;
} else if (l2data->write_data) {
struct bthost *bthost;
--
1.8.3.1
^ permalink raw reply related
* [PATCH] android/tester: Fix valgrind memory warnings
From: Andrei Emeltchenko @ 2013-12-20 9:00 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1387529782-26462-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Free device structure allocated during open_bluetooth().
==26231== 80 bytes in 1 blocks are definitely lost in loss record 25 of
31
==26231== at 0x4C2A2DB: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26231== by 0x40F153: open_bluetooth (hal-bluetooth.c:800)
==26231== by 0x40C8D8: setup (android-tester.c:835)
==26231== by 0x40CB20: setup_socket_interface_enabled
(android-tester.c:1166)
==26231== by 0x409C15: setup_callback (tester.c:373)
==26231== by 0x4E7C3B5: g_main_context_dispatch (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
==26231== by 0x4E7C707: ??? (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
==26231== by 0x4E7CB09: g_main_loop_run (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3800.1)
==26231== by 0x40A83C: tester_run (tester.c:784)
==26231== by 0x40362A: main (android-tester.c:1643)
---
android/android-tester.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 7d7ed88..6007797 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -109,6 +109,7 @@ struct test_data {
const void *test_data;
pid_t bluetoothd_pid;
+ hw_device_t *device;
const bt_interface_t *if_bluetooth;
const btsock_interface_t *if_sock;
@@ -838,6 +839,8 @@ static void setup(struct test_data *data)
return;
}
+ data->device = device;
+
data->if_bluetooth = ((bluetooth_device_t *)
device)->get_bluetooth_interface();
if (!data->if_bluetooth) {
@@ -882,6 +885,9 @@ static void teardown(const void *test_data)
data->if_bluetooth = NULL;
}
+ if (data->device)
+ free(data->device);
+
if (data->bluetoothd_pid)
waitpid(data->bluetoothd_pid, NULL, 0);
--
1.8.3.2
^ permalink raw reply related
* [PATCH] android/tester: Fix valgrind memory warnings
From: Andrei Emeltchenko @ 2013-12-20 8:56 UTC (permalink / raw)
To: linux-bluetooth
From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Free device structure allocated during open_bluetooth().
---
android/android-tester.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/android/android-tester.c b/android/android-tester.c
index 7d7ed88..6007797 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -109,6 +109,7 @@ struct test_data {
const void *test_data;
pid_t bluetoothd_pid;
+ hw_device_t *device;
const bt_interface_t *if_bluetooth;
const btsock_interface_t *if_sock;
@@ -838,6 +839,8 @@ static void setup(struct test_data *data)
return;
}
+ data->device = device;
+
data->if_bluetooth = ((bluetooth_device_t *)
device)->get_bluetooth_interface();
if (!data->if_bluetooth) {
@@ -882,6 +885,9 @@ static void teardown(const void *test_data)
data->if_bluetooth = NULL;
}
+ if (data->device)
+ free(data->device);
+
if (data->bluetoothd_pid)
waitpid(data->bluetoothd_pid, NULL, 0);
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCHv2 6/6] emulator: Remove not necessary bthost_set_server_psm
From: Johan Hedberg @ 2013-12-20 7:44 UTC (permalink / raw)
To: Marcin Kraglak; +Cc: linux-bluetooth
In-Reply-To: <1387463345-26406-6-git-send-email-marcin.kraglak@tieto.com>
Hi Marcin,
On Thu, Dec 19, 2013, Marcin Kraglak wrote:
> Remove not necessary function and replace all uses with new one,
> bthost_add_l2cap_server().
> ---
> android/android-tester.c | 2 +-
> emulator/bthost.c | 5 -----
> emulator/bthost.h | 2 --
> tools/l2cap-tester.c | 3 ++-
> 4 files changed, 3 insertions(+), 9 deletions(-)
Correction to my previous "all patches applied email": this patch hasn't
been applied. Please split it into three separate ones. Two patches to
convert the last users in l2cap-tester and android-tester and a third
patch to remove the old function.
Johan
^ permalink raw reply
* Re: [PATCHv2 1/6] emulator: Add new method for adding l2cap server
From: Johan Hedberg @ 2013-12-20 7:42 UTC (permalink / raw)
To: Marcin Kraglak; +Cc: linux-bluetooth
In-Reply-To: <1387463345-26406-1-git-send-email-marcin.kraglak@tieto.com>
Hi Marcin,
On Thu, Dec 19, 2013, Marcin Kraglak wrote:
> This method allow user to add l2cap server and register
> connect callback. If no callback is specified, it will behave
> like bthost_set_server_psm() method.
> ---
> emulator/bthost.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++----
> emulator/bthost.h | 5 +++++
> 2 files changed, 63 insertions(+), 4 deletions(-)
All patches in this set have been applied. Thanks.
I also applied two cleanup patches to bthost to remove some redundant
function calls.
Johan
^ permalink raw reply
* Re: [PATCH BlueZ 1/4] android/AVDTP: Add avdtp_add_disconnect_cb and avdtp_remove_disconnect_cb
From: Johan Hedberg @ 2013-12-20 7:28 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1387466156-14100-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On Thu, Dec 19, 2013, Luiz Augusto von Dentz wrote:
> With these functions the user application can detect when the AVDTP has
> been disconnected and cleanup properly.
> ---
> android/avdtp.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
> android/avdtp.h | 6 ++++++
> 2 files changed, 64 insertions(+), 3 deletions(-)
All four patches have been applied. Thanks.
Johan
^ permalink raw reply
* Re: [RFC v4 05/12] Bluetooth: Stop scanning on LE connection
From: Andre Guedes @ 2013-12-19 21:07 UTC (permalink / raw)
To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <20131218111116.GA25848@x220.p-661hnu-f1>
Hi Johan,
On Wed, 2013-12-18 at 13:11 +0200, Johan Hedberg wrote:
> Hi Andre,
>
> On Tue, Dec 17, 2013, Andre Guedes wrote:
> > > > @@ -518,8 +518,17 @@ static void create_le_conn_complete(struct hci_dev *hdev, u8 status)
> > > > {
> > > > struct hci_conn *conn;
> > > >
> > > > - if (status == 0)
> > > > + if (status == 0) {
> > > > + /* If the discovery procedure was running, we prematurely
> > > > + * stopped it. So we have to change the discovery state.
> > > > + */
> > > > + if (hdev->discovery.state == DISCOVERY_FINDING) {
> > > > + cancel_delayed_work(&hdev->le_scan_disable);
> > > > + hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
> > > > + }
> > > > +
> > > > return;
> > > > + }
> > > >
> > > > BT_ERR("HCI request failed to create LE connection: status 0x%2.2x",
> > > > status);
> > > > @@ -552,6 +561,18 @@ static int hci_create_le_conn(struct hci_conn *conn)
> > > >
> > > > hci_req_init(&req, hdev);
> > > >
> > > > + /* If controller is scanning, we stop it since some controllers are
> > > > + * not able to scan and connect at the same time.
> > > > + */
> > > > + if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
> > > > + struct hci_cp_le_set_scan_enable enable_cp;
> > > > +
> > > > + memset(&enable_cp, 0, sizeof(enable_cp));
> > > > + enable_cp.enable = LE_SCAN_DISABLE;
> > > > + hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
> > > > + &enable_cp);
> > > > + }
> > > > +
> > > > memset(&cp, 0, sizeof(cp));
> > > > cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
> > > > cp.scan_window = cpu_to_le16(hdev->le_scan_window);
> > >
> > > The way this all hangs together with a discovery process started through
> > > mgmt_start_discovery feels a bit flimsy to me. Particularly, have you
> > > ensured that everything is fine if you've got inquiry ongoing when you
> > > do hci_discovery_set_state(hdev, DISCOVERY_STOPPED). Also, are there any
> > > risks of race conditions here, e.g. is it fine to let the
> > > cancel_delayed_work() call be in create_le_conn_complete() instead of
> > > doing it in hci_create_le_conn()?
> >
> > Yes, I did lots of testing, including the inquiry test you mentioned,
> > and I didn't find any issues.
> >
> > I failed to see any race conditons since cancel_delayed_work() does not
> > block. So it is fine to call cancel_delayed_work() in
> > create_le_conn_complete() as well as in hci_create_le_conn().
>
> I presume you'd want to prevent the delayed work from getting called as
> soon as you've entered the if (test_bit(HCI_LE_SCAN)) section in
> hci_create_le_conn? In theory it might get called before
> create_le_conn_complete. In such a scenario
> le_scan_disable_work_complete could e.g. trigger inquiry before
> create_le_conn_complete is called, couldn't it?
Yes, this scenario can indeed happen in a very short window. However, it
doesn't seem to be a big issue. If that happen then the discovery
procedure keeps running normally and the connection attempt fails. If it
is a auto connection then the kernel will retry in a near future. If it
a user connection, it will get a busy error.
> > > What also makes this hard to track is that the condition you're testing
> > > for first is the HCI_LE_SCAN bit, but then later you look at
> > > discovery.state == DISCOVERY_FINDING. For the casual reader there's no
> > > direct indication of how these two are releated for the various types of
> > > discovery that are possible (LE-only, BR/EDR-only and interleaved).
> >
> > Yes, I see your point. However, we can't check HCI_LE_SCAN in
> > create_le_conn_complete() because the flag was already cleared in
> > hci_cc_le_set_scan_enable().
>
> Understood.
>
> > > I don't mean to say that this is a nack for the patch, but I'd like to
> > > know that you've considered and tested this kind of cases. I had to
> > > spend quite some time looking through the existing code and this patch
> > > and still couldn't arrive at absolute confidence of its correctness,
> > > meaning there should hopefully be some room for simplification.
> >
> > So I think we can do some simplification by moving this discovery
> > handling from create_le_conn_complete() to hci_create_le_conn(), at
> > least I think this code will become a bit easier to follow. What do you
> > think?
>
> I think it would at least close the potential race I described above,
> i.e. the delayed work getting triggered before create_le_conn_complete.
I realized this approach is not good enough since we'll be changing
discovery state before being sure the HCI command executed successfully.
This could let the discovery state inconsistent.
So after spending some time thinking about this issue, I believe the
better way to handle this is taking it in two steps. First, we simply
stop scanning and handle the discovery state. Then we create the LE
connection.
I'm already working on this "two steps" approach and I should send the
v5 patch set very soon.
Regards,
Andre
^ permalink raw reply
* Re: [PATCH_v6 4/5] bnep: Refactored bnep connect and disconnect calls
From: Luiz Augusto von Dentz @ 2013-12-19 15:43 UTC (permalink / raw)
To: Ravi kumar Veeramally; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1387463983-6373-4-git-send-email-ravikumar.veeramally@linux.intel.com>
Hi Ravi,
On Thu, Dec 19, 2013 at 4:39 PM, Ravi kumar Veeramally
<ravikumar.veeramally@linux.intel.com> wrote:
> Refactored bnep connect and disconnect calls to simplify and
> keeping bnep related functionality behind curtains.
> Provided bnep struct globally. bnep_connect calls takes
> care of bnep_setup until interface up then connect callback
> will be called. Provided bnep_set_disconnect. Set disconnect
> when connect call succeeds. bnep_disconnect should be
> called only when iface is up/connected.
> ---
> android/pan.c | 60 +++++++++++++-----------
> profiles/network/bnep.c | 105 ++++++++++++++++++++++++++++--------------
> profiles/network/bnep.h | 8 ++--
> profiles/network/connection.c | 60 ++++++++++++++++--------
> 4 files changed, 152 insertions(+), 81 deletions(-)
>
> diff --git a/android/pan.c b/android/pan.c
> index 187953b..51a11dd 100644
> --- a/android/pan.c
> +++ b/android/pan.c
> @@ -55,6 +55,7 @@ struct pan_device {
> uint8_t role;
> GIOChannel *io;
> guint watch;
> + struct bnep *session;
> };
>
> static int device_cmp(gconstpointer s, gconstpointer user_data)
> @@ -77,6 +78,7 @@ static void pan_device_free(struct pan_device *dev)
> dev->io = NULL;
> }
>
> + bnep_free(dev->session);
> devices = g_slist_remove(devices, dev);
> g_free(dev);
>
> @@ -104,8 +106,10 @@ static void bt_pan_notify_conn_state(struct pan_device *dev, uint8_t state)
>
> ipc_send_notif(HAL_SERVICE_ID_PAN, HAL_EV_PAN_CONN_STATE, sizeof(ev),
> &ev);
> - if (dev->conn_state == HAL_PAN_STATE_DISCONNECTED)
> - pan_device_free(dev);
> + if (state != HAL_PAN_STATE_DISCONNECTED)
> + return;
> +
> + pan_device_free(dev);
> }
This change is completely unrelated and probably doesn't make much sense.
> static void bt_pan_notify_ctrl_state(struct pan_device *dev, uint8_t state)
> @@ -124,21 +128,27 @@ static void bt_pan_notify_ctrl_state(struct pan_device *dev, uint8_t state)
> &ev);
> }
>
> -static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
> - gpointer data)
> +static gboolean watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
> {
> struct pan_device *dev = data;
>
> - DBG("%s disconnected", dev->iface);
> + DBG("disconnected");
>
> - bnep_if_down(dev->iface);
> - bnep_conndel(&dev->dst);
> bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
>
> return FALSE;
> }
>
> -static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
> +static void bnep_disconn_cb(void *data)
> +{
> + struct pan_device *dev = data;
> +
> + DBG("%s disconnected", dev->iface);
> +
> + bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
> +}
There does seems to have 2 watches for the exact same thing.
> +static void bnep_conn_cb(char *iface, int err, void *data)
> {
> struct pan_device *dev = data;
>
> @@ -146,28 +156,21 @@ static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
>
> if (err < 0) {
> error("bnep connect req failed: %s", strerror(-err));
> - bnep_conndel(&dev->dst);
> bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
> return;
> }
>
> - memcpy(dev->iface, iface, sizeof(dev->iface));
> -
> - DBG("%s connected", dev->iface);
> + DBG("%s connected", iface);
>
> + memcpy(dev->iface, iface, sizeof(dev->iface));
> bt_pan_notify_ctrl_state(dev, HAL_PAN_CTRL_ENABLED);
> bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTED);
> -
> - dev->watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
> - bnep_watchdog_cb, dev);
> - g_io_channel_unref(dev->io);
> - dev->io = NULL;
> }
>
> static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
> {
> struct pan_device *dev = data;
> - uint16_t src, dst;
> + uint16_t l_role, r_role;
> int perr, sk;
>
> DBG("");
> @@ -177,16 +180,23 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
> goto fail;
> }
>
> - src = (local_role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
> - dst = (dev->role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
> + l_role = (local_role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP :
> + BNEP_SVC_PANU;
> + r_role = (dev->role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
> sk = g_io_channel_unix_get_fd(dev->io);
> -
> - perr = bnep_connect(sk, src, dst, bnep_conn_cb, dev);
> + dev->session = bnep_new(sk, l_role, r_role);
> + perr = bnep_connect(dev->session, bnep_conn_cb, dev);
> if (perr < 0) {
> error("bnep connect req failed: %s", strerror(-perr));
> goto fail;
> }
>
> + bnep_set_disconnect(dev->session, bnep_disconn_cb, dev);
> + dev->watch = g_io_add_watch(dev->io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
> + watch_cb, dev);
> + g_io_channel_unref(dev->io);
> + dev->io = NULL;
You probably don't need the dev->watch anymore.
> return;
>
> fail:
> @@ -288,10 +298,8 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
> if (dev->io)
> g_io_channel_shutdown(dev->io, TRUE, NULL);
>
> - if (dev->conn_state == HAL_PAN_STATE_CONNECTED) {
> - bnep_if_down(dev->iface);
> - bnep_conndel(&dst);
> - }
> + if (dev->conn_state == HAL_PAN_STATE_CONNECTED)
> + bnep_disconnect(dev->session);
>
> bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTING);
> status = HAL_STATUS_SUCCESS;
> diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
> index d09f369..a4b1670 100644
> --- a/profiles/network/bnep.c
> +++ b/profiles/network/bnep.c
> @@ -39,6 +39,7 @@
> #include <bluetooth/bluetooth.h>
> #include <bluetooth/l2cap.h>
> #include <bluetooth/bnep.h>
> +#include <btio/btio.h>
>
> #include <glib.h>
>
> @@ -71,26 +72,18 @@ struct bnep {
> GIOChannel *io;
> uint16_t src;
> uint16_t dst;
> + bdaddr_t dst_addr;
> + char iface[16];
> guint attempts;
> guint setup_to;
> guint watch;
> void *data;
> bnep_connect_cb conn_cb;
> + void *conn_data;
> + bnep_disconnect_cb disconn_cb;
> + void *disconn_data;
> };
>
> -static void free_bnep_connect(struct bnep *b)
> -{
> - if (!b)
> - return;
> -
> - if (b->io) {
> - g_io_channel_unref(b->io);
> - b->io = NULL;
> - }
> -
> - g_free(b);
> -}
> -
> uint16_t bnep_service_id(const char *svc)
> {
> int i;
> @@ -247,6 +240,17 @@ int bnep_if_down(const char *devname)
> return 0;
> }
>
> +static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
> + gpointer data)
> +{
> + struct bnep *b = data;
> +
> + if (b->disconn_cb)
> + b->disconn_cb(b->disconn_data);
> +
> + return FALSE;
> +}
> +
> static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
> gpointer data)
> {
> @@ -254,7 +258,6 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
> struct bnep_control_rsp *rsp;
> struct timeval timeo;
> char pkt[BNEP_MTU];
> - char iface[16];
> ssize_t r;
> int sk;
>
> @@ -311,24 +314,27 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
> setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
>
> sk = g_io_channel_unix_get_fd(b->io);
> - if (bnep_connadd(sk, b->src, iface)) {
> + if (bnep_connadd(sk, b->src, b->iface)) {
> error("bnep conn could not be added");
> goto failed;
> }
>
> - if (bnep_if_up(iface)) {
> - error("could not up %s", iface);
> + if (bnep_if_up(b->iface)) {
> + error("could not up %s", b->iface);
> + bnep_conndel(&b->dst_addr);
> goto failed;
> }
>
> - b->conn_cb(chan, iface, 0, b->data);
> - free_bnep_connect(b);
> + b->conn_cb(b->iface, 0, b->conn_data);
> + b->watch = g_io_add_watch(b->io, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
> + (GIOFunc) bnep_watchdog_cb, b);
> + g_io_channel_unref(b->io);
> + b->io = NULL;
>
> return FALSE;
>
> failed:
> - b->conn_cb(NULL, NULL, -EIO, b->data);
> - free_bnep_connect(b);
> + b->conn_cb(NULL, -EIO, b->conn_data);
>
> return FALSE;
> }
> @@ -372,8 +378,7 @@ static gboolean bnep_conn_req_to(gpointer user_data)
> return TRUE;
> }
>
> - b->conn_cb(NULL, NULL, -ETIMEDOUT, b->data);
> - free_bnep_connect(b);
> + b->conn_cb(NULL, -ETIMEDOUT, b->conn_data);
>
> return FALSE;
> }
> @@ -412,22 +417,25 @@ void bnep_free(struct bnep *b)
> g_free(b);
> }
>
> -int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
> - void *data)
> +int bnep_connect(struct bnep *b, bnep_connect_cb conn_cb, void *data)
> {
> - struct bnep *b;
> + GError *gerr = NULL;
> int err;
>
> - if (!conn_cb)
> + if (!b || !conn_cb)
> return -EINVAL;
>
> - b = g_new0(struct bnep, 1);
> - b->io = g_io_channel_unix_new(sk);
> b->attempts = 0;
> - b->src = src;
> - b->dst = dst;
> b->conn_cb = conn_cb;
> - b->data = data;
> + b->conn_data = data;
> +
> + bt_io_get(b->io, &gerr, BT_IO_OPT_DEST_BDADDR, &b->dst_addr,
> + BT_IO_OPT_INVALID);
> + if (gerr) {
> + error("%s", gerr->message);
> + g_error_free(gerr);
> + return -EINVAL;
> + }
>
> err = bnep_setup_conn_req(b);
> if (err < 0)
> @@ -435,11 +443,40 @@ int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
>
> b->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
> bnep_conn_req_to, b);
> - g_io_add_watch(b->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
> - bnep_setup_cb, b);
> return 0;
> }
>
> +void bnep_disconnect(struct bnep *b)
> +{
> + if (!b)
> + return;
> +
> + if (b->watch > 0) {
> + g_source_remove(b->watch);
> + b->watch = 0;
> + }
> +
> + if (b->io) {
> + g_io_channel_unref(b->io);
> + b->io = NULL;
> + }
> +
> + bnep_if_down(b->iface);
> + bnep_conndel(&b->dst_addr);
> +}
> +
> +void bnep_set_disconnect(struct bnep *b, bnep_disconnect_cb disconn_cb,
> + void *data)
> +{
> + if (!b || !disconn_cb)
> + return;
> +
> + if (!b->disconn_cb && !b->disconn_data) {
> + b->disconn_cb = disconn_cb;
> + b->disconn_data = data;
> + }
> +}
> +
> int bnep_add_to_bridge(const char *devname, const char *bridge)
> {
> int ifindex;
> diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
> index 091a7f2..cff5c78 100644
> --- a/profiles/network/bnep.h
> +++ b/profiles/network/bnep.h
> @@ -39,10 +39,12 @@ int bnep_if_down(const char *devname);
> int bnep_add_to_bridge(const char *devname, const char *bridge);
> int bnep_del_from_bridge(const char *devname, const char *bridge);
>
> -typedef void (*bnep_connect_cb) (GIOChannel *chan, char *iface, int err,
> - void *data);
> -int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
> +typedef void (*bnep_connect_cb) (char *iface, int err, void *data);
> +typedef void (*bnep_disconnect_cb) (void *data);
> +int bnep_connect(struct bnep *b, bnep_connect_cb conn_cb, void *data);
> +void bnep_set_disconnect(struct bnep *b, bnep_disconnect_cb disconn_cb,
> void *data);
> +void bnep_disconnect(struct bnep *b);
>
> ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp);
> uint16_t bnep_setup_chk(uint16_t dst_role, uint16_t src_role);
> diff --git a/profiles/network/connection.c b/profiles/network/connection.c
> index fb3e1ce..4539972 100644
> --- a/profiles/network/connection.c
> +++ b/profiles/network/connection.c
> @@ -70,8 +70,10 @@ struct network_conn {
> conn_state state;
> GIOChannel *io;
> guint dc_id;
> + guint watch;
> struct network_peer *peer;
> DBusMessage *connect;
> + struct bnep *session;
> };
>
> static GSList *peers = NULL;
> @@ -106,8 +108,7 @@ static struct network_conn *find_connection_by_state(GSList *list,
> return NULL;
> }
>
> -static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
> - gpointer data)
> +static void bnep_disconn_cb(gpointer data)
> {
> struct network_conn *nc = data;
> DBusConnection *conn = btd_get_dbus_connection();
> @@ -126,11 +127,23 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
>
> info("%s disconnected", nc->dev);
>
> - bnep_if_down(nc->dev);
> nc->state = DISCONNECTED;
> memset(nc->dev, 0, sizeof(nc->dev));
> strcpy(nc->dev, "bnep%d");
>
> + bnep_free(nc->session);
> + nc->session = NULL;
> +
> + if (nc->io) {
> + g_io_channel_unref(nc->io);
> + nc->io = NULL;
> + }
> +}
> +
> +static gboolean watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
> +{
> + bnep_disconn_cb(data);
> +
> return FALSE;
> }
>
> @@ -155,12 +168,25 @@ static void local_connect_cb(struct network_conn *nc, int err)
> static void cancel_connection(struct network_conn *nc, int err)
> {
> btd_service_connecting_complete(nc->service, err);
> +
> if (nc->connect)
> local_connect_cb(nc, err);
>
> - g_io_channel_shutdown(nc->io, TRUE, NULL);
> - g_io_channel_unref(nc->io);
> - nc->io = NULL;
> + if (nc->watch > 0) {
> + g_source_remove(nc->watch);
> + nc->watch = 0;
> + }
> +
> + if (nc->io) {
> + g_io_channel_unref(nc->io);
> + nc->io = NULL;
> + }
> +
> + if (nc->state == CONNECTED)
> + bnep_disconnect(nc->session);
> +
> + bnep_free(nc->session);
> + nc->session = NULL;
>
> nc->state = DISCONNECTED;
> }
> @@ -169,11 +195,7 @@ static void connection_destroy(DBusConnection *conn, void *user_data)
> {
> struct network_conn *nc = user_data;
>
> - if (nc->state == CONNECTED) {
> - bnep_if_down(nc->dev);
> - bnep_conndel(device_get_address(nc->peer->device));
> - } else if (nc->io)
> - cancel_connection(nc, -EIO);
> + cancel_connection(nc, -EIO);
> }
>
> static void disconnect_cb(struct btd_device *device, gboolean removal,
> @@ -186,7 +208,7 @@ static void disconnect_cb(struct btd_device *device, gboolean removal,
> connection_destroy(NULL, user_data);
> }
>
> -static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
> +static void bnep_conn_cb(char *iface, int err, void *data)
> {
> struct network_conn *nc = data;
> const char *path;
> @@ -220,11 +242,6 @@ static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
> nc->state = CONNECTED;
> nc->dc_id = device_add_disconnect_watch(nc->peer->device, disconnect_cb,
> nc, NULL);
> - g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
> - bnep_watchdog_cb, nc);
> - g_io_channel_unref(nc->io);
> - nc->io = NULL;
> -
> return;
>
> failed:
> @@ -242,12 +259,19 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
> }
>
> sk = g_io_channel_unix_get_fd(nc->io);
> - perr = bnep_connect(sk, BNEP_SVC_PANU, nc->id, bnep_conn_cb, nc);
> + nc->session = bnep_new(sk, BNEP_SVC_PANU, nc->id);
> + perr = bnep_connect(nc->session, bnep_conn_cb, nc);
> if (perr < 0) {
> error("bnep connect(): %s (%d)", strerror(-perr), -perr);
> goto failed;
> }
>
> + bnep_set_disconnect(nc->session, bnep_disconn_cb, nc);
> + nc->watch = g_io_add_watch(nc->io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
> + watch_cb, nc);
> + g_io_channel_unref(nc->io);
> + nc->io = NULL;
> +
> return;
>
> failed:
> --
> 1.8.3.2
This patch is packing a lot of changes perhaps you should consider splitting.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH_v6 2/5] bnep: Rename struct bnep_conn to struct bnep for better readability
From: Luiz Augusto von Dentz @ 2013-12-19 15:33 UTC (permalink / raw)
To: Ravi kumar Veeramally; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1387463983-6373-2-git-send-email-ravikumar.veeramally@linux.intel.com>
Hi Ravi,
On Thu, Dec 19, 2013 at 4:39 PM, Ravi kumar Veeramally
<ravikumar.veeramally@linux.intel.com> wrote:
> ---
> profiles/network/bnep.c | 80 ++++++++++++++++++++++++-------------------------
> 1 file changed, 40 insertions(+), 40 deletions(-)
>
> diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
> index 08037e6..02e2647 100644
> --- a/profiles/network/bnep.c
> +++ b/profiles/network/bnep.c
> @@ -67,7 +67,7 @@ struct __service_16 {
> uint16_t src;
> } __attribute__ ((packed));
>
> -struct bnep_conn {
> +struct bnep {
> GIOChannel *io;
> uint16_t src;
> uint16_t dst;
> @@ -77,17 +77,17 @@ struct bnep_conn {
> bnep_connect_cb conn_cb;
> };
>
> -static void free_bnep_connect(struct bnep_conn *bc)
> +static void free_bnep_connect(struct bnep *b)
I guess if you want to be consist you should name the var session here as well.
--
Luiz Augusto von Dentz
^ permalink raw reply
* [PATCH BlueZ 4/4] android/A2DP: Fix disconnecting after AVDTP session creation
From: Luiz Augusto von Dentz @ 2013-12-19 15:15 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1387466156-14100-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Once the connection is handover to AVDTP code the GIOChannel can be
unref but it should not close the connection.
---
android/a2dp.c | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/android/a2dp.c b/android/a2dp.c
index 2de2f66..9087c62 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -73,8 +73,10 @@ static void a2dp_device_free(struct a2dp_device *dev)
if (dev->session)
avdtp_unref(dev->session);
- if (dev->io)
+ if (dev->io) {
+ g_io_channel_shutdown(dev->io, FALSE, NULL);
g_io_channel_unref(dev->io);
+ }
devices = g_slist_remove(devices, dev);
g_free(dev);
@@ -148,11 +150,18 @@ static void signaling_connect_cb(GIOChannel *chan, GError *err,
return;
}
- /* FIXME: Add proper version */
+ g_io_channel_set_close_on_unref(chan, FALSE);
fd = g_io_channel_unix_get_fd(chan);
+
+ /* FIXME: Add proper version */
dev->session = avdtp_new(fd, imtu, omtu, 0x0100);
avdtp_add_disconnect_cb(dev->session, disconnect_cb, dev);
+ if (dev->io) {
+ g_io_channel_unref(dev->io);
+ dev->io = NULL;
+ }
+
bt_a2dp_notify_state(dev, HAL_A2DP_STATE_CONNECTED);
}
@@ -221,15 +230,17 @@ static void bt_a2dp_disconnect(const void *buf, uint16_t len)
}
dev = l->data;
+ status = HAL_STATUS_SUCCESS;
- /* Wait signaling channel to HUP */
- if (dev->io)
- g_io_channel_shutdown(dev->io, TRUE, NULL);
+ if (dev->io) {
+ bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
+ goto failed;
+ }
+ /* Wait AVDTP session to shutdown */
+ avdtp_shutdown(dev->session);
bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTING);
- status = HAL_STATUS_SUCCESS;
-
failed:
ipc_send_rsp(HAL_SERVICE_ID_A2DP, HAL_OP_A2DP_DISCONNECT, status);
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 3/4] android/AVDTP: Add avdtp_shutdown
From: Luiz Augusto von Dentz @ 2013-12-19 15:15 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1387466156-14100-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
avdtp_shutdown can be used to disconnect closing all existing stream
properly.
---
android/avdtp.c | 19 +++++++++++++++++++
android/avdtp.h | 2 ++
2 files changed, 21 insertions(+)
diff --git a/android/avdtp.c b/android/avdtp.c
index b2d77a4..7d3cb18 100644
--- a/android/avdtp.c
+++ b/android/avdtp.c
@@ -2102,6 +2102,25 @@ gboolean avdtp_remove_disconnect_cb(struct avdtp *session, unsigned int id)
return FALSE;
}
+void avdtp_shutdown(struct avdtp *session)
+{
+ GSList *l;
+ int sock;
+
+ if (!session->io)
+ return;
+
+ for (l = session->streams; l; l = g_slist_next(l)) {
+ struct avdtp_stream *stream = l->data;
+
+ avdtp_close(session, stream, TRUE);
+ }
+
+ sock = g_io_channel_unix_get_fd(session->io);
+
+ shutdown(sock, SHUT_RDWR);
+}
+
static void queue_request(struct avdtp *session, struct pending_req *req,
gboolean priority)
{
diff --git a/android/avdtp.h b/android/avdtp.h
index 1619029..d371653 100644
--- a/android/avdtp.h
+++ b/android/avdtp.h
@@ -209,6 +209,8 @@ unsigned int avdtp_add_disconnect_cb(struct avdtp *session,
void *user_data);
gboolean avdtp_remove_disconnect_cb(struct avdtp *session, unsigned int id);
+void avdtp_shutdown(struct avdtp *session);
+
void avdtp_unref(struct avdtp *session);
struct avdtp *avdtp_ref(struct avdtp *session);
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 2/4] android/A2DP: Use avdtp_add_disconnect_cb to cleanup on disconnect
From: Luiz Augusto von Dentz @ 2013-12-19 15:15 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1387466156-14100-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This replaces the use of g_io_add_watch with avdtp_add_disconnect_cb so
connection tracking stay within AVDTP code.
---
android/a2dp.c | 14 +++-----------
1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/android/a2dp.c b/android/a2dp.c
index 107cbb8..2de2f66 100644
--- a/android/a2dp.c
+++ b/android/a2dp.c
@@ -57,7 +57,6 @@ struct a2dp_device {
bdaddr_t dst;
uint8_t state;
GIOChannel *io;
- guint watch;
struct avdtp *session;
};
@@ -74,9 +73,6 @@ static void a2dp_device_free(struct a2dp_device *dev)
if (dev->session)
avdtp_unref(dev->session);
- if (dev->watch > 0)
- g_source_remove(dev->watch);
-
if (dev->io)
g_io_channel_unref(dev->io);
@@ -120,13 +116,11 @@ static void bt_a2dp_notify_state(struct a2dp_device *dev, uint8_t state)
a2dp_device_free(dev);
}
-static gboolean watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
+static void disconnect_cb(void *user_data)
{
- struct a2dp_device *dev = data;
+ struct a2dp_device *dev = user_data;
bt_a2dp_notify_state(dev, HAL_A2DP_STATE_DISCONNECTED);
-
- return FALSE;
}
static void signaling_connect_cb(GIOChannel *chan, GError *err,
@@ -157,9 +151,7 @@ static void signaling_connect_cb(GIOChannel *chan, GError *err,
/* FIXME: Add proper version */
fd = g_io_channel_unix_get_fd(chan);
dev->session = avdtp_new(fd, imtu, omtu, 0x0100);
-
- dev->watch = g_io_add_watch(dev->io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- watch_cb, dev);
+ avdtp_add_disconnect_cb(dev->session, disconnect_cb, dev);
bt_a2dp_notify_state(dev, HAL_A2DP_STATE_CONNECTED);
}
--
1.8.3.1
^ permalink raw reply related
* [PATCH BlueZ 1/4] android/AVDTP: Add avdtp_add_disconnect_cb and avdtp_remove_disconnect_cb
From: Luiz Augusto von Dentz @ 2013-12-19 15:15 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
With these functions the user application can detect when the AVDTP has
been disconnected and cleanup properly.
---
android/avdtp.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---
android/avdtp.h | 6 ++++++
2 files changed, 64 insertions(+), 3 deletions(-)
diff --git a/android/avdtp.c b/android/avdtp.c
index 3a3380a..b2d77a4 100644
--- a/android/avdtp.c
+++ b/android/avdtp.c
@@ -336,6 +336,12 @@ struct discover_callback {
void *user_data;
};
+struct disconnect_callback {
+ unsigned int id;
+ avdtp_disconnect_cb_t cb;
+ void *user_data;
+};
+
struct avdtp_stream {
GIOChannel *io;
uint16_t imtu;
@@ -390,6 +396,8 @@ struct avdtp {
struct discover_callback *discover;
struct pending_req *req;
+
+ GSList *disconnect;
};
static GSList *lseps = NULL;
@@ -970,12 +978,22 @@ static void avdtp_free(void *data)
g_slist_free_full(session->req_queue, pending_req_free);
g_slist_free_full(session->prio_queue, pending_req_free);
g_slist_free_full(session->seps, sep_free);
+ g_slist_free_full(session->disconnect, g_free);
g_free(session->buf);
g_free(session);
}
+static void process_disconnect(void *data)
+{
+ struct disconnect_callback *callback = data;
+
+ callback->cb(callback->user_data);
+
+ g_free(callback);
+}
+
static void connection_lost(struct avdtp *session, int err)
{
DBG("Disconnected: %s (%d)", strerror(err), err);
@@ -983,12 +1001,14 @@ static void connection_lost(struct avdtp *session, int err)
g_slist_foreach(session->streams, (GFunc) release_stream, session);
session->streams = NULL;
+ avdtp_ref(session);
+
finalize_discovery(session, err);
- if (session->ref > 0)
- return;
+ g_slist_free_full(session->disconnect, process_disconnect);
+ session->disconnect = NULL;
- avdtp_free(session);
+ avdtp_unref(session);
}
void avdtp_unref(struct avdtp *session)
@@ -2047,6 +2067,41 @@ struct avdtp *avdtp_new(int fd, size_t imtu, size_t omtu, uint16_t version)
return avdtp_ref(session);
}
+unsigned int avdtp_add_disconnect_cb(struct avdtp *session,
+ avdtp_disconnect_cb_t cb,
+ void *user_data)
+{
+ struct disconnect_callback *callback;
+ static unsigned int id = 0;
+
+ callback = g_new0(struct disconnect_callback, 1);
+ callback->id = ++id;
+ callback->cb = cb;
+ callback->user_data = user_data;
+ session->disconnect = g_slist_append(session->disconnect, callback);
+
+ return id;
+}
+
+gboolean avdtp_remove_disconnect_cb(struct avdtp *session, unsigned int id)
+{
+ GSList *l;
+
+ for (l = session->disconnect; l; l = g_slist_next(l)) {
+ struct disconnect_callback *callback = l->data;
+
+ if (callback->id != id)
+ continue;
+
+ session->disconnect = g_slist_remove(session->disconnect,
+ callback);
+ g_free(callback);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static void queue_request(struct avdtp *session, struct pending_req *req,
gboolean priority)
{
diff --git a/android/avdtp.h b/android/avdtp.h
index 9760875..1619029 100644
--- a/android/avdtp.h
+++ b/android/avdtp.h
@@ -200,9 +200,15 @@ struct avdtp_sep_ind {
typedef void (*avdtp_discover_cb_t) (struct avdtp *session, GSList *seps,
struct avdtp_error *err, void *user_data);
+typedef void (*avdtp_disconnect_cb_t) (void *user_data);
struct avdtp *avdtp_new(int fd, size_t imtu, size_t omtu, uint16_t version);
+unsigned int avdtp_add_disconnect_cb(struct avdtp *session,
+ avdtp_disconnect_cb_t cb,
+ void *user_data);
+gboolean avdtp_remove_disconnect_cb(struct avdtp *session, unsigned int id);
+
void avdtp_unref(struct avdtp *session);
struct avdtp *avdtp_ref(struct avdtp *session);
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH 1/6] android/tester: Fix for not checking for BT_STATUS_SUCCESS
From: Johan Hedberg @ 2013-12-19 14:42 UTC (permalink / raw)
To: Jakub Tyszkowski, linux-bluetooth
In-Reply-To: <20131219134224.GA23417@x220.p-661hnu-f1>
Hi,
On Thu, Dec 19, 2013, Johan Hedberg wrote:
> On Thu, Dec 19, 2013, Jakub Tyszkowski wrote:
> > For BT_STATUS_SUCCESS no checks were done as it is 0 in bt_status_t
> > enum. Valid status for no status expected should be STATUS_NOT_EXPECTED.
> >
> > ---
> > android/android-tester.c | 6 ++++--
> > 1 file changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/android/android-tester.c b/android/android-tester.c
> > index c24f5a6..5549dcb 100644
> > --- a/android/android-tester.c
> > +++ b/android/android-tester.c
> > @@ -72,7 +72,7 @@ enum hal_bluetooth_callbacks_id {
> > };
> >
> > struct generic_data {
> > - uint8_t expected_adapter_status;
> > + int expected_adapter_status;
> > uint32_t expect_settings_set;
> > bt_property_t expected_property;
> > uint8_t expected_hal_callbacks[];
> > @@ -92,6 +92,8 @@ struct socket_data {
> > #define WAIT_FOR_SIGNAL_TIME 2 /* in seconds */
> > #define EMULATOR_SIGNAL "emulator_started"
> >
> > +#define BT_STATUS_NOT_EXPECTED -1
> > +
> > struct test_data {
> > struct mgmt *mgmt;
> > uint16_t mgmt_index;
> > @@ -199,7 +201,7 @@ static void expected_status_init(struct test_data *data)
> > {
> > const struct generic_data *test_data = data->test_data;
> >
> > - if (!(test_data->expected_adapter_status))
> > + if (test_data->expected_adapter_status == BT_STATUS_NOT_EXPECTED)
> > data->status_checked = true;
> > }
>
> I suppose it does make sense to have such a special value, but I can't
> see you use it anywhere in your patch set. So I'd postpone this patch
> until you've got some actual code that needs it.
Nevermind. I now see that even though you don't add any tests that would
use this new value the change of the if-statement that this patch
introduces is already enough of a justification.
All patches in the set have now been applied.
Johan
^ permalink raw reply
* Re: [PATCH 1/6] android/tester: Fix for not checking for BT_STATUS_SUCCESS
From: Tyszkowski Jakub @ 2013-12-19 14:41 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <20131219134224.GA23417@x220.p-661hnu-f1>
On 12/19/2013 02:42 PM, Johan Hedberg wrote:
> Hi Jakub,
>
> On Thu, Dec 19, 2013, Jakub Tyszkowski wrote:
>> For BT_STATUS_SUCCESS no checks were done as it is 0 in bt_status_t
>> enum. Valid status for no status expected should be STATUS_NOT_EXPECTED.
>>
>> ---
>> android/android-tester.c | 6 ++++--
>> 1 file changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/android/android-tester.c b/android/android-tester.c
>> index c24f5a6..5549dcb 100644
>> --- a/android/android-tester.c
>> +++ b/android/android-tester.c
>> @@ -72,7 +72,7 @@ enum hal_bluetooth_callbacks_id {
>> };
>>
>> struct generic_data {
>> - uint8_t expected_adapter_status;
>> + int expected_adapter_status;
>> uint32_t expect_settings_set;
>> bt_property_t expected_property;
>> uint8_t expected_hal_callbacks[];
>> @@ -92,6 +92,8 @@ struct socket_data {
>> #define WAIT_FOR_SIGNAL_TIME 2 /* in seconds */
>> #define EMULATOR_SIGNAL "emulator_started"
>>
>> +#define BT_STATUS_NOT_EXPECTED -1
>> +
>> struct test_data {
>> struct mgmt *mgmt;
>> uint16_t mgmt_index;
>> @@ -199,7 +201,7 @@ static void expected_status_init(struct test_data *data)
>> {
>> const struct generic_data *test_data = data->test_data;
>>
>> - if (!(test_data->expected_adapter_status))
>> + if (test_data->expected_adapter_status == BT_STATUS_NOT_EXPECTED)
>> data->status_checked = true;
>> }
>
> I suppose it does make sense to have such a special value, but I can't
> see you use it anywhere in your patch set. So I'd postpone this patch
> until you've got some actual code that needs it.
>
> Johan
>
But this will actually leave the tester not checking for
BT_STATUS_SUCCESS (0 in enum) at all during real tests, as it is already
being set as checked during the expected_status_init() call.
^ permalink raw reply
* [PATCH_v6 5/5] bnep: Refactored bnep server apis for bridge addition and deletion
From: Ravi kumar Veeramally @ 2013-12-19 14:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1387463983-6373-1-git-send-email-ravikumar.veeramally@linux.intel.com>
To simplify bnep server realted bridge creation and deletion calls
provided extra apis and moved existing apis to static.
---
profiles/network/bnep.c | 50 +++++++++++++++++++++++++++++++++++++++++------
profiles/network/bnep.h | 11 ++++-------
profiles/network/server.c | 37 +++--------------------------------
3 files changed, 51 insertions(+), 47 deletions(-)
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index a4b1670..9e93949 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -154,7 +154,7 @@ int bnep_cleanup(void)
return 0;
}
-int bnep_conndel(const bdaddr_t *dst)
+static int bnep_conndel(const bdaddr_t *dst)
{
struct bnep_conndel_req req;
@@ -170,7 +170,7 @@ int bnep_conndel(const bdaddr_t *dst)
return 0;
}
-int bnep_connadd(int sk, uint16_t role, char *dev)
+static int bnep_connadd(int sk, uint16_t role, char *dev)
{
struct bnep_connadd_req req;
@@ -190,7 +190,7 @@ int bnep_connadd(int sk, uint16_t role, char *dev)
return 0;
}
-int bnep_if_up(const char *devname)
+static int bnep_if_up(const char *devname)
{
struct ifreq ifr;
int sk, err;
@@ -215,7 +215,7 @@ int bnep_if_up(const char *devname)
return 0;
}
-int bnep_if_down(const char *devname)
+static int bnep_if_down(const char *devname)
{
struct ifreq ifr;
int sk, err;
@@ -477,7 +477,7 @@ void bnep_set_disconnect(struct bnep *b, bnep_disconnect_cb disconn_cb,
}
}
-int bnep_add_to_bridge(const char *devname, const char *bridge)
+static int bnep_add_to_bridge(const char *devname, const char *bridge)
{
int ifindex;
struct ifreq ifr;
@@ -508,7 +508,7 @@ int bnep_add_to_bridge(const char *devname, const char *bridge)
return 0;
}
-int bnep_del_from_bridge(const char *devname, const char *bridge)
+static int bnep_del_from_bridge(const char *devname, const char *bridge)
{
int ifindex = if_nametoindex(devname);
struct ifreq ifr;
@@ -537,6 +537,44 @@ int bnep_del_from_bridge(const char *devname, const char *bridge)
return 0;
}
+int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
+ const bdaddr_t *addr)
+{
+ if (!bridge || !bridge || !iface || !addr)
+ return -EINVAL;
+
+ if (bnep_connadd(sk, dst, iface) < 0) {
+ error("Can't add connection to the bridge %s: %s(%d)",
+ bridge, strerror(errno), errno);
+ return -errno;
+ }
+
+ if (bnep_add_to_bridge(iface, bridge) < 0) {
+ error("Can't add %s to the bridge %s: %s(%d)",
+ iface, bridge, strerror(errno), errno);
+ bnep_conndel(addr);
+ return -errno;
+ }
+
+ if (bnep_if_up(iface) < 0) {
+ error("Can't up the interface %s: %s(%d)",
+ iface, strerror(errno), errno);
+ return -errno;
+ }
+
+ return 0;
+}
+
+void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr)
+{
+ if (!bridge || !iface || !addr)
+ return;
+
+ bnep_del_from_bridge(iface, bridge);
+ bnep_if_down(iface);
+ bnep_conndel(addr);
+}
+
ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp)
{
struct bnep_control_rsp rsp;
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index cff5c78..ea28c2f 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -32,13 +32,6 @@ const char *bnep_name(uint16_t id);
struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role);
void bnep_free(struct bnep *b);
-int bnep_connadd(int sk, uint16_t role, char *dev);
-int bnep_conndel(const bdaddr_t *dst);
-int bnep_if_up(const char *devname);
-int bnep_if_down(const char *devname);
-int bnep_add_to_bridge(const char *devname, const char *bridge);
-int bnep_del_from_bridge(const char *devname, const char *bridge);
-
typedef void (*bnep_connect_cb) (char *iface, int err, void *data);
typedef void (*bnep_disconnect_cb) (void *data);
int bnep_connect(struct bnep *b, bnep_connect_cb conn_cb, void *data);
@@ -46,6 +39,10 @@ void bnep_set_disconnect(struct bnep *b, bnep_disconnect_cb disconn_cb,
void *data);
void bnep_disconnect(struct bnep *b);
+int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
+ const bdaddr_t *addr);
+void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr);
+
ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp);
uint16_t bnep_setup_chk(uint16_t dst_role, uint16_t src_role);
uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
diff --git a/profiles/network/server.c b/profiles/network/server.c
index 73741ec..7cb5a1e 100644
--- a/profiles/network/server.c
+++ b/profiles/network/server.c
@@ -251,35 +251,6 @@ static sdp_record_t *server_record_new(const char *name, uint16_t id)
return record;
}
-static int server_connadd(struct network_server *ns,
- struct network_session *session,
- uint16_t dst_role)
-{
- char devname[16];
- int err, nsk;
-
- nsk = g_io_channel_unix_get_fd(session->io);
- err = bnep_connadd(nsk, dst_role, devname);
- if (err < 0)
- return err;
-
- info("Added new connection: %s", devname);
-
- if (bnep_add_to_bridge(devname, ns->bridge) < 0) {
- error("Can't add %s to the bridge %s: %s(%d)",
- devname, ns->bridge, strerror(errno), errno);
- return -EPERM;
- }
-
- bnep_if_up(devname);
-
- strncpy(session->dev, devname, sizeof(devname));
-
- ns->sessions = g_slist_append(ns->sessions, session);
-
- return 0;
-}
-
static void session_free(void *data)
{
struct network_session *session = data;
@@ -377,7 +348,8 @@ static gboolean bnep_setup(GIOChannel *chan,
goto reply;
}
- if (server_connadd(ns, na->setup, dst_role) < 0)
+ if (bnep_server_add(sk, dst_role, ns->bridge, na->setup->dev,
+ &na->setup->dst) < 0)
goto reply;
na->setup = NULL;
@@ -524,10 +496,7 @@ static void server_remove_sessions(struct network_server *ns)
if (*session->dev == '\0')
continue;
- bnep_del_from_bridge(session->dev, ns->bridge);
- bnep_if_down(session->dev);
-
- bnep_conndel(&session->dst);
+ bnep_server_delete(ns->bridge, session->dev, &session->dst);
}
g_slist_free_full(ns->sessions, session_free);
--
1.8.3.2
^ permalink raw reply related
* [PATCH_v6 4/5] bnep: Refactored bnep connect and disconnect calls
From: Ravi kumar Veeramally @ 2013-12-19 14:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1387463983-6373-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Refactored bnep connect and disconnect calls to simplify and
keeping bnep related functionality behind curtains.
Provided bnep struct globally. bnep_connect calls takes
care of bnep_setup until interface up then connect callback
will be called. Provided bnep_set_disconnect. Set disconnect
when connect call succeeds. bnep_disconnect should be
called only when iface is up/connected.
---
android/pan.c | 60 +++++++++++++-----------
profiles/network/bnep.c | 105 ++++++++++++++++++++++++++++--------------
profiles/network/bnep.h | 8 ++--
profiles/network/connection.c | 60 ++++++++++++++++--------
4 files changed, 152 insertions(+), 81 deletions(-)
diff --git a/android/pan.c b/android/pan.c
index 187953b..51a11dd 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -55,6 +55,7 @@ struct pan_device {
uint8_t role;
GIOChannel *io;
guint watch;
+ struct bnep *session;
};
static int device_cmp(gconstpointer s, gconstpointer user_data)
@@ -77,6 +78,7 @@ static void pan_device_free(struct pan_device *dev)
dev->io = NULL;
}
+ bnep_free(dev->session);
devices = g_slist_remove(devices, dev);
g_free(dev);
@@ -104,8 +106,10 @@ static void bt_pan_notify_conn_state(struct pan_device *dev, uint8_t state)
ipc_send_notif(HAL_SERVICE_ID_PAN, HAL_EV_PAN_CONN_STATE, sizeof(ev),
&ev);
- if (dev->conn_state == HAL_PAN_STATE_DISCONNECTED)
- pan_device_free(dev);
+ if (state != HAL_PAN_STATE_DISCONNECTED)
+ return;
+
+ pan_device_free(dev);
}
static void bt_pan_notify_ctrl_state(struct pan_device *dev, uint8_t state)
@@ -124,21 +128,27 @@ static void bt_pan_notify_ctrl_state(struct pan_device *dev, uint8_t state)
&ev);
}
-static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
- gpointer data)
+static gboolean watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
{
struct pan_device *dev = data;
- DBG("%s disconnected", dev->iface);
+ DBG("disconnected");
- bnep_if_down(dev->iface);
- bnep_conndel(&dev->dst);
bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
return FALSE;
}
-static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
+static void bnep_disconn_cb(void *data)
+{
+ struct pan_device *dev = data;
+
+ DBG("%s disconnected", dev->iface);
+
+ bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+}
+
+static void bnep_conn_cb(char *iface, int err, void *data)
{
struct pan_device *dev = data;
@@ -146,28 +156,21 @@ static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
if (err < 0) {
error("bnep connect req failed: %s", strerror(-err));
- bnep_conndel(&dev->dst);
bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
return;
}
- memcpy(dev->iface, iface, sizeof(dev->iface));
-
- DBG("%s connected", dev->iface);
+ DBG("%s connected", iface);
+ memcpy(dev->iface, iface, sizeof(dev->iface));
bt_pan_notify_ctrl_state(dev, HAL_PAN_CTRL_ENABLED);
bt_pan_notify_conn_state(dev, HAL_PAN_STATE_CONNECTED);
-
- dev->watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
- bnep_watchdog_cb, dev);
- g_io_channel_unref(dev->io);
- dev->io = NULL;
}
static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
{
struct pan_device *dev = data;
- uint16_t src, dst;
+ uint16_t l_role, r_role;
int perr, sk;
DBG("");
@@ -177,16 +180,23 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
goto fail;
}
- src = (local_role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
- dst = (dev->role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
+ l_role = (local_role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP :
+ BNEP_SVC_PANU;
+ r_role = (dev->role == HAL_PAN_ROLE_NAP) ? BNEP_SVC_NAP : BNEP_SVC_PANU;
sk = g_io_channel_unix_get_fd(dev->io);
-
- perr = bnep_connect(sk, src, dst, bnep_conn_cb, dev);
+ dev->session = bnep_new(sk, l_role, r_role);
+ perr = bnep_connect(dev->session, bnep_conn_cb, dev);
if (perr < 0) {
error("bnep connect req failed: %s", strerror(-perr));
goto fail;
}
+ bnep_set_disconnect(dev->session, bnep_disconn_cb, dev);
+ dev->watch = g_io_add_watch(dev->io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ watch_cb, dev);
+ g_io_channel_unref(dev->io);
+ dev->io = NULL;
+
return;
fail:
@@ -288,10 +298,8 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
if (dev->io)
g_io_channel_shutdown(dev->io, TRUE, NULL);
- if (dev->conn_state == HAL_PAN_STATE_CONNECTED) {
- bnep_if_down(dev->iface);
- bnep_conndel(&dst);
- }
+ if (dev->conn_state == HAL_PAN_STATE_CONNECTED)
+ bnep_disconnect(dev->session);
bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTING);
status = HAL_STATUS_SUCCESS;
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index d09f369..a4b1670 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -39,6 +39,7 @@
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
#include <bluetooth/bnep.h>
+#include <btio/btio.h>
#include <glib.h>
@@ -71,26 +72,18 @@ struct bnep {
GIOChannel *io;
uint16_t src;
uint16_t dst;
+ bdaddr_t dst_addr;
+ char iface[16];
guint attempts;
guint setup_to;
guint watch;
void *data;
bnep_connect_cb conn_cb;
+ void *conn_data;
+ bnep_disconnect_cb disconn_cb;
+ void *disconn_data;
};
-static void free_bnep_connect(struct bnep *b)
-{
- if (!b)
- return;
-
- if (b->io) {
- g_io_channel_unref(b->io);
- b->io = NULL;
- }
-
- g_free(b);
-}
-
uint16_t bnep_service_id(const char *svc)
{
int i;
@@ -247,6 +240,17 @@ int bnep_if_down(const char *devname)
return 0;
}
+static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
+ gpointer data)
+{
+ struct bnep *b = data;
+
+ if (b->disconn_cb)
+ b->disconn_cb(b->disconn_data);
+
+ return FALSE;
+}
+
static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
gpointer data)
{
@@ -254,7 +258,6 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
struct bnep_control_rsp *rsp;
struct timeval timeo;
char pkt[BNEP_MTU];
- char iface[16];
ssize_t r;
int sk;
@@ -311,24 +314,27 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
sk = g_io_channel_unix_get_fd(b->io);
- if (bnep_connadd(sk, b->src, iface)) {
+ if (bnep_connadd(sk, b->src, b->iface)) {
error("bnep conn could not be added");
goto failed;
}
- if (bnep_if_up(iface)) {
- error("could not up %s", iface);
+ if (bnep_if_up(b->iface)) {
+ error("could not up %s", b->iface);
+ bnep_conndel(&b->dst_addr);
goto failed;
}
- b->conn_cb(chan, iface, 0, b->data);
- free_bnep_connect(b);
+ b->conn_cb(b->iface, 0, b->conn_data);
+ b->watch = g_io_add_watch(b->io, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ (GIOFunc) bnep_watchdog_cb, b);
+ g_io_channel_unref(b->io);
+ b->io = NULL;
return FALSE;
failed:
- b->conn_cb(NULL, NULL, -EIO, b->data);
- free_bnep_connect(b);
+ b->conn_cb(NULL, -EIO, b->conn_data);
return FALSE;
}
@@ -372,8 +378,7 @@ static gboolean bnep_conn_req_to(gpointer user_data)
return TRUE;
}
- b->conn_cb(NULL, NULL, -ETIMEDOUT, b->data);
- free_bnep_connect(b);
+ b->conn_cb(NULL, -ETIMEDOUT, b->conn_data);
return FALSE;
}
@@ -412,22 +417,25 @@ void bnep_free(struct bnep *b)
g_free(b);
}
-int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
- void *data)
+int bnep_connect(struct bnep *b, bnep_connect_cb conn_cb, void *data)
{
- struct bnep *b;
+ GError *gerr = NULL;
int err;
- if (!conn_cb)
+ if (!b || !conn_cb)
return -EINVAL;
- b = g_new0(struct bnep, 1);
- b->io = g_io_channel_unix_new(sk);
b->attempts = 0;
- b->src = src;
- b->dst = dst;
b->conn_cb = conn_cb;
- b->data = data;
+ b->conn_data = data;
+
+ bt_io_get(b->io, &gerr, BT_IO_OPT_DEST_BDADDR, &b->dst_addr,
+ BT_IO_OPT_INVALID);
+ if (gerr) {
+ error("%s", gerr->message);
+ g_error_free(gerr);
+ return -EINVAL;
+ }
err = bnep_setup_conn_req(b);
if (err < 0)
@@ -435,11 +443,40 @@ int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
b->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
bnep_conn_req_to, b);
- g_io_add_watch(b->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
- bnep_setup_cb, b);
return 0;
}
+void bnep_disconnect(struct bnep *b)
+{
+ if (!b)
+ return;
+
+ if (b->watch > 0) {
+ g_source_remove(b->watch);
+ b->watch = 0;
+ }
+
+ if (b->io) {
+ g_io_channel_unref(b->io);
+ b->io = NULL;
+ }
+
+ bnep_if_down(b->iface);
+ bnep_conndel(&b->dst_addr);
+}
+
+void bnep_set_disconnect(struct bnep *b, bnep_disconnect_cb disconn_cb,
+ void *data)
+{
+ if (!b || !disconn_cb)
+ return;
+
+ if (!b->disconn_cb && !b->disconn_data) {
+ b->disconn_cb = disconn_cb;
+ b->disconn_data = data;
+ }
+}
+
int bnep_add_to_bridge(const char *devname, const char *bridge)
{
int ifindex;
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index 091a7f2..cff5c78 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -39,10 +39,12 @@ int bnep_if_down(const char *devname);
int bnep_add_to_bridge(const char *devname, const char *bridge);
int bnep_del_from_bridge(const char *devname, const char *bridge);
-typedef void (*bnep_connect_cb) (GIOChannel *chan, char *iface, int err,
- void *data);
-int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
+typedef void (*bnep_connect_cb) (char *iface, int err, void *data);
+typedef void (*bnep_disconnect_cb) (void *data);
+int bnep_connect(struct bnep *b, bnep_connect_cb conn_cb, void *data);
+void bnep_set_disconnect(struct bnep *b, bnep_disconnect_cb disconn_cb,
void *data);
+void bnep_disconnect(struct bnep *b);
ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp);
uint16_t bnep_setup_chk(uint16_t dst_role, uint16_t src_role);
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index fb3e1ce..4539972 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -70,8 +70,10 @@ struct network_conn {
conn_state state;
GIOChannel *io;
guint dc_id;
+ guint watch;
struct network_peer *peer;
DBusMessage *connect;
+ struct bnep *session;
};
static GSList *peers = NULL;
@@ -106,8 +108,7 @@ static struct network_conn *find_connection_by_state(GSList *list,
return NULL;
}
-static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
- gpointer data)
+static void bnep_disconn_cb(gpointer data)
{
struct network_conn *nc = data;
DBusConnection *conn = btd_get_dbus_connection();
@@ -126,11 +127,23 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
info("%s disconnected", nc->dev);
- bnep_if_down(nc->dev);
nc->state = DISCONNECTED;
memset(nc->dev, 0, sizeof(nc->dev));
strcpy(nc->dev, "bnep%d");
+ bnep_free(nc->session);
+ nc->session = NULL;
+
+ if (nc->io) {
+ g_io_channel_unref(nc->io);
+ nc->io = NULL;
+ }
+}
+
+static gboolean watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
+{
+ bnep_disconn_cb(data);
+
return FALSE;
}
@@ -155,12 +168,25 @@ static void local_connect_cb(struct network_conn *nc, int err)
static void cancel_connection(struct network_conn *nc, int err)
{
btd_service_connecting_complete(nc->service, err);
+
if (nc->connect)
local_connect_cb(nc, err);
- g_io_channel_shutdown(nc->io, TRUE, NULL);
- g_io_channel_unref(nc->io);
- nc->io = NULL;
+ if (nc->watch > 0) {
+ g_source_remove(nc->watch);
+ nc->watch = 0;
+ }
+
+ if (nc->io) {
+ g_io_channel_unref(nc->io);
+ nc->io = NULL;
+ }
+
+ if (nc->state == CONNECTED)
+ bnep_disconnect(nc->session);
+
+ bnep_free(nc->session);
+ nc->session = NULL;
nc->state = DISCONNECTED;
}
@@ -169,11 +195,7 @@ static void connection_destroy(DBusConnection *conn, void *user_data)
{
struct network_conn *nc = user_data;
- if (nc->state == CONNECTED) {
- bnep_if_down(nc->dev);
- bnep_conndel(device_get_address(nc->peer->device));
- } else if (nc->io)
- cancel_connection(nc, -EIO);
+ cancel_connection(nc, -EIO);
}
static void disconnect_cb(struct btd_device *device, gboolean removal,
@@ -186,7 +208,7 @@ static void disconnect_cb(struct btd_device *device, gboolean removal,
connection_destroy(NULL, user_data);
}
-static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
+static void bnep_conn_cb(char *iface, int err, void *data)
{
struct network_conn *nc = data;
const char *path;
@@ -220,11 +242,6 @@ static void bnep_conn_cb(GIOChannel *chan, char *iface, int err, void *data)
nc->state = CONNECTED;
nc->dc_id = device_add_disconnect_watch(nc->peer->device, disconnect_cb,
nc, NULL);
- g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
- bnep_watchdog_cb, nc);
- g_io_channel_unref(nc->io);
- nc->io = NULL;
-
return;
failed:
@@ -242,12 +259,19 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
}
sk = g_io_channel_unix_get_fd(nc->io);
- perr = bnep_connect(sk, BNEP_SVC_PANU, nc->id, bnep_conn_cb, nc);
+ nc->session = bnep_new(sk, BNEP_SVC_PANU, nc->id);
+ perr = bnep_connect(nc->session, bnep_conn_cb, nc);
if (perr < 0) {
error("bnep connect(): %s (%d)", strerror(-perr), -perr);
goto failed;
}
+ bnep_set_disconnect(nc->session, bnep_disconn_cb, nc);
+ nc->watch = g_io_add_watch(nc->io, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ watch_cb, nc);
+ g_io_channel_unref(nc->io);
+ nc->io = NULL;
+
return;
failed:
--
1.8.3.2
^ permalink raw reply related
* [PATCH_v6 3/5] bnep: Add bnep_new and bnep_free api's
From: Ravi kumar Veeramally @ 2013-12-19 14:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1387463983-6373-1-git-send-email-ravikumar.veeramally@linux.intel.com>
Refacoring connect and disconnect mechanisms. It would be more
convinient for caller to maintain just bnep connection reference
and delete whenever it is not required.
---
profiles/network/bnep.c | 35 +++++++++++++++++++++++++++++++++++
profiles/network/bnep.h | 4 ++++
2 files changed, 39 insertions(+)
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 02e2647..d09f369 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -73,6 +73,7 @@ struct bnep {
uint16_t dst;
guint attempts;
guint setup_to;
+ guint watch;
void *data;
bnep_connect_cb conn_cb;
};
@@ -377,6 +378,40 @@ static gboolean bnep_conn_req_to(gpointer user_data)
return FALSE;
}
+struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role)
+{
+ struct bnep *b;
+
+ b = g_new0(struct bnep, 1);
+ b->io = g_io_channel_unix_new(sk);
+ b->src = local_role;
+ b->dst = remote_role;
+
+ b->watch = g_io_add_watch_full(b->io, G_PRIORITY_LOW,
+ G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ (GIOFunc) bnep_setup_cb, b, NULL);
+
+ return b;
+}
+
+void bnep_free(struct bnep *b)
+{
+ if (!b)
+ return;
+
+ if (b->io) {
+ g_io_channel_unref(b->io);
+ b->io = NULL;
+ }
+
+ if (b->watch > 0) {
+ g_source_remove(b->watch);
+ b->watch = 0;
+ }
+
+ g_free(b);
+}
+
int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
void *data)
{
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index dd22c40..091a7f2 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -21,6 +21,8 @@
*
*/
+struct bnep;
+
int bnep_init(void);
int bnep_cleanup(void);
@@ -28,6 +30,8 @@ uint16_t bnep_service_id(const char *svc);
const char *bnep_uuid(uint16_t id);
const char *bnep_name(uint16_t id);
+struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role);
+void bnep_free(struct bnep *b);
int bnep_connadd(int sk, uint16_t role, char *dev);
int bnep_conndel(const bdaddr_t *dst);
int bnep_if_up(const char *devname);
--
1.8.3.2
^ permalink raw reply related
* [PATCH_v6 2/5] bnep: Rename struct bnep_conn to struct bnep for better readability
From: Ravi kumar Veeramally @ 2013-12-19 14:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
In-Reply-To: <1387463983-6373-1-git-send-email-ravikumar.veeramally@linux.intel.com>
---
profiles/network/bnep.c | 80 ++++++++++++++++++++++++-------------------------
1 file changed, 40 insertions(+), 40 deletions(-)
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 08037e6..02e2647 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -67,7 +67,7 @@ struct __service_16 {
uint16_t src;
} __attribute__ ((packed));
-struct bnep_conn {
+struct bnep {
GIOChannel *io;
uint16_t src;
uint16_t dst;
@@ -77,17 +77,17 @@ struct bnep_conn {
bnep_connect_cb conn_cb;
};
-static void free_bnep_connect(struct bnep_conn *bc)
+static void free_bnep_connect(struct bnep *b)
{
- if (!bc)
+ if (!b)
return;
- if (bc->io) {
- g_io_channel_unref(bc->io);
- bc->io = NULL;
+ if (b->io) {
+ g_io_channel_unref(b->io);
+ b->io = NULL;
}
- g_free(bc);
+ g_free(b);
}
uint16_t bnep_service_id(const char *svc)
@@ -249,7 +249,7 @@ int bnep_if_down(const char *devname)
static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
gpointer data)
{
- struct bnep_conn *bc = data;
+ struct bnep *b = data;
struct bnep_control_rsp *rsp;
struct timeval timeo;
char pkt[BNEP_MTU];
@@ -260,9 +260,9 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
if (cond & G_IO_NVAL)
goto failed;
- if (bc->setup_to > 0) {
- g_source_remove(bc->setup_to);
- bc->setup_to = 0;
+ if (b->setup_to > 0) {
+ g_source_remove(b->setup_to);
+ b->setup_to = 0;
}
if (cond & (G_IO_HUP | G_IO_ERR)) {
@@ -309,8 +309,8 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
timeo.tv_sec = 0;
setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
- sk = g_io_channel_unix_get_fd(bc->io);
- if (bnep_connadd(sk, bc->src, iface)) {
+ sk = g_io_channel_unix_get_fd(b->io);
+ if (bnep_connadd(sk, b->src, iface)) {
error("bnep conn could not be added");
goto failed;
}
@@ -320,19 +320,19 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
goto failed;
}
- bc->conn_cb(chan, iface, 0, bc->data);
- free_bnep_connect(bc);
+ b->conn_cb(chan, iface, 0, b->data);
+ free_bnep_connect(b);
return FALSE;
failed:
- bc->conn_cb(NULL, NULL, -EIO, bc->data);
- free_bnep_connect(bc);
+ b->conn_cb(NULL, NULL, -EIO, b->data);
+ free_bnep_connect(b);
return FALSE;
}
-static int bnep_setup_conn_req(struct bnep_conn *bc)
+static int bnep_setup_conn_req(struct bnep *b)
{
struct bnep_setup_conn_req *req;
struct __service_16 *s;
@@ -345,34 +345,34 @@ static int bnep_setup_conn_req(struct bnep_conn *bc)
req->ctrl = BNEP_SETUP_CONN_REQ;
req->uuid_size = 2; /* 16bit UUID */
s = (void *) req->service;
- s->src = htons(bc->src);
- s->dst = htons(bc->dst);
+ s->src = htons(b->src);
+ s->dst = htons(b->dst);
- fd = g_io_channel_unix_get_fd(bc->io);
+ fd = g_io_channel_unix_get_fd(b->io);
if (write(fd, pkt, sizeof(*req) + sizeof(*s)) < 0) {
error("bnep connection req send failed: %s", strerror(errno));
return -errno;
}
- bc->attempts++;
+ b->attempts++;
return 0;
}
static gboolean bnep_conn_req_to(gpointer user_data)
{
- struct bnep_conn *bc = user_data;
+ struct bnep *b = user_data;
- if (bc->attempts == CON_SETUP_RETRIES) {
+ if (b->attempts == CON_SETUP_RETRIES) {
error("Too many bnep connection attempts");
} else {
error("bnep connection setup TO, retrying...");
- if (bnep_setup_conn_req(bc) == 0)
+ if (bnep_setup_conn_req(b) == 0)
return TRUE;
}
- bc->conn_cb(NULL, NULL, -ETIMEDOUT, bc->data);
- free_bnep_connect(bc);
+ b->conn_cb(NULL, NULL, -ETIMEDOUT, b->data);
+ free_bnep_connect(b);
return FALSE;
}
@@ -380,28 +380,28 @@ static gboolean bnep_conn_req_to(gpointer user_data)
int bnep_connect(int sk, uint16_t src, uint16_t dst, bnep_connect_cb conn_cb,
void *data)
{
- struct bnep_conn *bc;
+ struct bnep *b;
int err;
if (!conn_cb)
return -EINVAL;
- bc = g_new0(struct bnep_conn, 1);
- bc->io = g_io_channel_unix_new(sk);
- bc->attempts = 0;
- bc->src = src;
- bc->dst = dst;
- bc->conn_cb = conn_cb;
- bc->data = data;
+ b = g_new0(struct bnep, 1);
+ b->io = g_io_channel_unix_new(sk);
+ b->attempts = 0;
+ b->src = src;
+ b->dst = dst;
+ b->conn_cb = conn_cb;
+ b->data = data;
- err = bnep_setup_conn_req(bc);
+ err = bnep_setup_conn_req(b);
if (err < 0)
return err;
- bc->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
- bnep_conn_req_to, bc);
- g_io_add_watch(bc->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
- bnep_setup_cb, bc);
+ b->setup_to = g_timeout_add_seconds(CON_SETUP_TO,
+ bnep_conn_req_to, b);
+ g_io_add_watch(b->io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+ bnep_setup_cb, b);
return 0;
}
--
1.8.3.2
^ permalink raw reply related
* [PATCH_v6 1/5] android/pan: shutdown io channel on disconnect call
From: Ravi kumar Veeramally @ 2013-12-19 14:39 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ravi kumar Veeramally
Shutdown io channel and send DISCONNECTING notification and send
DISCONNECTED notification and free the device on callback.
---
android/pan.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/android/pan.c b/android/pan.c
index b83f534..187953b 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -284,14 +284,16 @@ static void bt_pan_disconnect(const void *buf, uint16_t len)
}
dev = l->data;
- if (dev->watch) {
- g_source_remove(dev->watch);
- dev->watch = 0;
+
+ if (dev->io)
+ g_io_channel_shutdown(dev->io, TRUE, NULL);
+
+ if (dev->conn_state == HAL_PAN_STATE_CONNECTED) {
+ bnep_if_down(dev->iface);
+ bnep_conndel(&dst);
}
- bnep_if_down(dev->iface);
- bnep_conndel(&dst);
- bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTED);
+ bt_pan_notify_conn_state(dev, HAL_PAN_STATE_DISCONNECTING);
status = HAL_STATUS_SUCCESS;
failed:
--
1.8.3.2
^ permalink raw reply related
* [PATCHv2 6/6] emulator: Remove not necessary bthost_set_server_psm
From: Marcin Kraglak @ 2013-12-19 14:29 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1387463345-26406-1-git-send-email-marcin.kraglak@tieto.com>
Remove not necessary function and replace all uses with new one,
bthost_add_l2cap_server().
---
android/android-tester.c | 2 +-
emulator/bthost.c | 5 -----
emulator/bthost.h | 2 --
tools/l2cap-tester.c | 3 ++-
4 files changed, 3 insertions(+), 9 deletions(-)
diff --git a/android/android-tester.c b/android/android-tester.c
index c24f5a6..2d78646 100644
--- a/android/android-tester.c
+++ b/android/android-tester.c
@@ -1279,7 +1279,7 @@ static void test_socket_real_connect(const void *test_data)
bdaddr2android((bdaddr_t *) client_bdaddr, &emu_bdaddr);
- bthost_set_server_psm(bthost, 0x0003);
+ bthost_add_l2cap_server(bthost, 0x0003, NULL, NULL);
status = data->if_sock->connect(&emu_bdaddr, test->sock_type,
test->service_uuid, test->channel,
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 7ccef9c..28d0591 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -1303,11 +1303,6 @@ void bthost_add_l2cap_server(struct bthost *bthost, uint16_t psm,
bthost->new_l2cap_conn_data = data;
}
-void bthost_set_server_psm(struct bthost *bthost, uint16_t psm)
-{
- bthost_add_l2cap_server(bthost, psm, NULL, NULL);
-}
-
void bthost_start(struct bthost *bthost)
{
if (!bthost)
diff --git a/emulator/bthost.h b/emulator/bthost.h
index 2b8f212..97f011b 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
@@ -77,8 +77,6 @@ void bthost_le_start_encrypt(struct bthost *bthost, uint16_t handle,
typedef void (*bthost_l2cap_connect_cb) (uint16_t handle, uint16_t cid,
void *user_data);
-void bthost_set_server_psm(struct bthost *bthost, uint16_t psm);
-
void bthost_add_l2cap_server(struct bthost *bthost, uint16_t psm,
bthost_l2cap_connect_cb func, void *user_data);
diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index 55e8ac9..2a7a394 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -720,7 +720,8 @@ static void test_connect(const void *test_data)
struct bthost *bthost = hciemu_client_get_host(data->hciemu);
if (!l2data->data_len)
- bthost_set_server_psm(bthost, l2data->server_psm);
+ bthost_add_l2cap_server(bthost, l2data->server_psm,
+ NULL, NULL);
else
bthost_add_l2cap_server(bthost, l2data->server_psm,
client_l2cap_connect_cb, data);
--
1.8.3.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox