From: Marcel Holtmann <marcel@holtmann.org>
To: Johan Hedberg <johan.hedberg@gmail.com>
Cc: linux-bluetooth@vger.kernel.org
Subject: Re: [PATCH 1/7] Bluetooth: mgmt: Add support for switching to LE peripheral mode
Date: Tue, 23 Oct 2012 14:49:28 -0700 [thread overview]
Message-ID: <1351028968.1785.60.camel@aeonflux> (raw)
In-Reply-To: <20121023202626.GA12042@x220.ger.corp.intel.com>
Hi Johan,
> > > --- a/net/bluetooth/hci_event.c
> > > +++ b/net/bluetooth/hci_event.c
> > > @@ -786,6 +786,9 @@ static void hci_set_le_support(struct hci_dev *hdev)
> > > if (cp.le != !!(hdev->host_features[0] & LMP_HOST_LE))
> > > hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
> > > &cp);
> > > + else if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags))
> > > + hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_ENABLE, sizeof(cp.le),
> > > + &cp.le);
> >
> > What is this doing and why it is correct? I am failing to see this. We
> > need to enable LE host supported first anyway.
>
> The first if-statement checks if the host feature bits are what we want
> them to be, and if not send the WRITE_LE_HOST_SUPPORTED command. The
> else if part (if the host features are already correct and don't need
> updating) enables advertising if necessary. There's a similar check for
> HCI_LE_PERIPHERAL in the command complete handler for
> HCI_OP_WRITE_LE_HOST_SUPPORTED in case the first if statement was
> triggered. FWIW, I have actually tested this both with hciconfig and
> btmgmt and it works fine.
>
> > > +static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
> > > +{
> > > + __u8 *sent, status = *((__u8 *) skb->data);
> > > +
> > > + BT_DBG("%s status 0x%2.2x", hdev->name, status);
> > > +
> > > + sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
> > > + if (!sent)
> > > + return;
> > > +
> > > + hci_dev_lock(hdev);
> > > +
> > > + if (!status) {
> > > + if (*sent)
> > > + set_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
> > > + else
> > > + clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
> > > + } else {
> > > + if (*sent)
> > > + clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
> > > + else
> > > + set_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
> > > + }
> >
> > Are you sure we want to based LE peripheral enabling based on if we
> > advertise or not. I can see cases where we are a peripheral, but might
> > want to not always advertise.
>
> These set_bit/clear_bit calls are actually all no-op in the case that
> the mgmt interface is used (since the LE_PERIPHERAL flag is already
> modified when receiving the mgmt command). The only reason I put them
> here is so that the reported mgmt settings remain correct and we reject
> connection initiation and scanning if "hciconfig hci0 leadv" or similar
> is used.
>
> The simplistic way I thought we'd initially keep peripheral mode is
> that it always implies advertising (unless a connection exists).
> Otherwise the user would need to switch to LE-off or Central mode.
I am fine with this. However we can not merge this upstream until we
have this figured out and have a good grasp on this. So it would be nice
to have this patch last. Since some of the other patches could be
actually merged right now. They are useful fixes no matter what.
We might want to introduce a enable_peripheral module parameter as safe
guard for the time being. So that the features bit PERIPHERAL is not set
if this is disabled. Just an idea.
>
> > > @@ -1213,48 +1242,71 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
> > > goto unlock;
> > > }
> > >
> > > - val = !!cp->val;
> > > - enabled = !!(hdev->host_features[0] & LMP_HOST_LE);
> > > + if (!valid_le_mode(cp->val)) {
> > > + err = cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
> > > + MGMT_STATUS_INVALID_PARAMS);
> > > + goto unlock;
> > > + }
> > >
> > > - if (!hdev_is_powered(hdev) || val == enabled) {
> > > - bool changed = false;
> > > + if (mgmt_pending_find(MGMT_OP_SET_LE, hdev)) {
> > > + err = cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
> > > + MGMT_STATUS_BUSY);
> > > + goto unlock;
> > > + }
> > > +
> > > + new_mode = cp->val;
> > > + old_mode = get_le_mode(hdev);
> > > +
> > > + BT_DBG("%s old_mode %u new_mode %u", hdev->name, old_mode, new_mode);
> > > +
> > > + if (new_mode == old_mode) {
> > > + err = send_settings_rsp(sk, MGMT_OP_SET_LE, hdev);
> > > + goto unlock;
> > > + }
> > > +
> > > + if (old_mode == MGMT_LE_PERIPHERAL || new_mode == MGMT_LE_PERIPHERAL)
> > > + change_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags);
> > >
> > > - if (val != test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
> > > + if (!hdev_is_powered(hdev)) {
> > > + if (old_mode == MGMT_LE_OFF || new_mode == MGMT_LE_OFF)
> > > change_bit(HCI_LE_ENABLED, &hdev->dev_flags);
> > > - changed = true;
> > > - }
> > >
> > > err = send_settings_rsp(sk, MGMT_OP_SET_LE, hdev);
> > > if (err < 0)
> > > goto unlock;
> > >
> > > - if (changed)
> > > - err = new_settings(hdev, sk);
> > > + err = new_settings(hdev, sk);
> > >
> > > goto unlock;
> > > }
> > >
> > > - if (mgmt_pending_find(MGMT_OP_SET_LE, hdev)) {
> > > - err = cmd_status(sk, hdev->id, MGMT_OP_SET_LE,
> > > - MGMT_STATUS_BUSY);
> > > - goto unlock;
> > > - }
> > > -
> > > cmd = mgmt_pending_add(sk, MGMT_OP_SET_LE, hdev, data, len);
> > > if (!cmd) {
> > > err = -ENOMEM;
> > > goto unlock;
> > > }
> > >
> > > + if ((old_mode != MGMT_LE_OFF && new_mode == MGMT_LE_PERIPHERAL) ||
> > > + old_mode == MGMT_LE_PERIPHERAL) {
> > > + u8 adv_enable = (new_mode == MGMT_LE_PERIPHERAL);
> > > +
> > > + err = hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_ENABLE,
> > > + sizeof(adv_enable), &adv_enable);
> > > + if (err < 0)
> > > + mgmt_pending_remove(cmd);
> > > +
> > > + goto unlock;
> > > + }
> > > +
> >
> > this gets a bit complicated. We either need more comments or split this
> > out in separate helper functions.
>
> I actually spent over a half a day trying to figure out an easy way to
> simplify this, but the best I got was those two simple helper functions.
> So I think I'll opt for just adding good code comments.
Sounds good to me.
Regards
Marcel
next prev parent reply other threads:[~2012-10-23 21:49 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-10-23 16:53 [PATCH 0/7] Bluetooth: Improved single-mode and LE peripheral support Johan Hedberg
2012-10-23 16:53 ` [PATCH 1/7] Bluetooth: mgmt: Add support for switching to LE peripheral mode Johan Hedberg
2012-10-23 19:01 ` Marcel Holtmann
2012-10-23 20:26 ` Johan Hedberg
2012-10-23 21:49 ` Marcel Holtmann [this message]
2012-10-23 16:53 ` [PATCH 2/7] Bluetooth: mgmt: Restrict BR/EDR settings to BR/EDR-only adapters Johan Hedberg
2012-10-23 18:51 ` Anderson Lizardo
2012-10-23 19:03 ` Marcel Holtmann
2012-10-23 19:02 ` Marcel Holtmann
2012-10-23 19:31 ` Anderson Lizardo
2012-10-23 20:48 ` Johan Hedberg
2012-10-23 21:46 ` Marcel Holtmann
2012-10-24 12:11 ` Anderson Lizardo
2012-10-24 15:14 ` Marcel Holtmann
2012-10-23 16:53 ` [PATCH 3/7] Bluetooth: Disallow LE scanning and connecting in peripheral mode Johan Hedberg
2012-10-23 18:42 ` Anderson Lizardo
2012-10-23 20:59 ` Johan Hedberg
2012-10-23 21:37 ` Marcel Holtmann
2012-10-23 16:53 ` [PATCH 4/7] Bluetooth: Add support for setting LE advertising data Johan Hedberg
2012-10-23 18:30 ` Anderson Lizardo
2012-10-23 21:26 ` Johan Hedberg
2012-10-25 0:00 ` Anderson Lizardo
2012-10-23 16:53 ` [PATCH 5/7] Bluetooth: Fix updating host feature bits for LE Johan Hedberg
2012-10-23 19:04 ` Marcel Holtmann
2012-10-23 16:54 ` [PATCH 6/7] Bluetooth: Sort feature test macros by bitmask location Johan Hedberg
2012-10-23 19:06 ` Marcel Holtmann
2012-10-23 16:54 ` [PATCH 7/7] Bluetooth: Make use feature test macros Johan Hedberg
2012-10-23 19:06 ` Marcel Holtmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1351028968.1785.60.camel@aeonflux \
--to=marcel@holtmann.org \
--cc=johan.hedberg@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).