1. 18 Apr, 2013 1 commit
    • Jaganath Kanakkassery's avatar
      Bluetooth: Fix incorrect SSP mode bit for non SSP devices · bbb0eada
      Jaganath Kanakkassery authored
      Some faulty non SSP devices send extended inquiry response
      during device discovery which is a violation of 2.1 specification.
      So for these devices we set SSP bit during acl connection
      initiation thinking that it is an SSP device. But for these
      devices, in remote host features event SSP supported bit
      will be off. But we are not clearing the SSP bit in that case
      and eventually SSP bit in conn flag will be incorrectly set for
      these devices.
      
      The software which has caused this issue is MecApp
      http://www.mecel.se/products/bluetooth/downloads/MecApp_download
      
      This patch does a workaround by clearing the SSP bit if it is
      not supported in remote host features event
      
      hcidump log
      ----------
      
      < HCI Command: Inquiry (0x01|0x0001) plen 5
          lap 0x9e8b33 len 4 num 0
      > HCI Event: Command Status (0x0f) plen 4
          Inquiry (0x01|0x0001) status 0x00 ncmd 1
      > HCI Event: Extended Inquiry Result (0x2f) plen 255
          bdaddr 00:1B:DC:05:B5:25 mode 1 clkoffset 0x3263 class 0x3c0000 rssi -77
          Unknown type 0x42 with 8 bytes data
          Unknown type 0x1e with 2 bytes data
      > HCI Event: Inquiry Complete (0x01) plen 1
          status 0x00
      
      < HCI Command: Create Connection (0x01|0x0005) plen 13
          bdaddr 00:1B:DC:05:B5:25 ptype 0xcc18 rswitch 0x01 clkoffset 0x0000
          Packet type: DM1 DM3 DM5 DH1 DH3 DH5
      > HCI Event: Command Status (0x0f) plen 4
          Create Connection (0x01|0x0005) status 0x00 ncmd 1
      > HCI Event: Connect Complete (0x03) plen 11
          status 0x00 handle 12 bdaddr 00:1B:DC:05:B5:25 type ACL encrypt 0x00
      < HCI Command: Read Remote Supported Features (0x01|0x001b) plen 2
          handle 12
      > HCI Event: Command Status (0x0f) plen 4
          Read Remote Supported Features (0x01|0x001b) status 0x00 ncmd 1
      > HCI Event: Read Remote Supported Features (0x0b) plen 11
          status 0x00 handle 12
          Features: 0xff 0xff 0x8f 0x7e 0xd8 0x1f 0x5b 0x87
      < HCI Command: Read Remote Extended Features (0x01|0x001c) plen 3
          handle 12 page 1
      > HCI Event: Command Status (0x0f) plen 4
          Read Remote Extended Features (0x01|0x001c) status 0x00 ncmd 1
      > HCI Event: Page Scan Repetition Mode Change (0x20) plen 7
          bdaddr 00:1B:DC:05:B5:25 mode 1
      > HCI Event: Max Slots Change (0x1b) plen 3
          handle 12 slots 5
      > HCI Event: Read Remote Extended Features (0x23) plen 13
          status 0x00 handle 12 page 1 max 0
          Features: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      < HCI Command: Remote Name Request (0x01|0x0019) plen 10
          bdaddr 00:1B:DC:05:B5:25 mode 2 clkoffset 0x0000
      > HCI Event: Command Status (0x0f) plen 4
          Remote Name Request (0x01|0x0019) status 0x00 ncmd 1
      > HCI Event: Remote Name Req Complete (0x07) plen 255
          status 0x00 bdaddr 00:1B:DC:05:B5:25 name 'Bluetooth PTS Radio v4'
      < HCI Command: Authentication Requested (0x01|0x0011) plen 2
          handle 12
      > HCI Event: Command Status (0x0f) plen 4
          Authentication Requested (0x01|0x0011) status 0x00 ncmd 1
      > HCI Event: Link Key Request (0x17) plen 6
          bdaddr 00:1B:DC:05:B5:25
      < HCI Command: Link Key Request Negative Reply (0x01|0x000c) plen 6
          bdaddr 00:1B:DC:05:B5:25
      > HCI Event: Command Complete (0x0e) plen 10
          Link Key Request Negative Reply (0x01|0x000c) ncmd 1
          status 0x00 bdaddr 00:1B:DC:05:B5:25
      > HCI Event: PIN Code Request (0x16) plen 6
          bdaddr 00:1B:DC:05:B5:25
      Signed-off-by: default avatarJaganath Kanakkassery <jaganath.k@samsung.com>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      bbb0eada
  2. 17 Apr, 2013 15 commits
    • David Herrmann's avatar
      Bluetooth: hidp: fix sending output reports on intr channel · e73dcfbf
      David Herrmann authored
      According to the specifications, data output reports must be sent on the
      interrupt channel. See also usbhid implementation.
      Sending these reports on the control channel breaks newer Wii Remotes.
      
      Note that this will make output reports asynchronous. However, that's how
      hid_output_raw_report() is supposed to work with HID_OUTPUT_REPORT as
      report type. There are no responses to output reports.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      e73dcfbf
    • David Herrmann's avatar
      Bluetooth: hidp: don't send boot-protocol messages as HID-reports · af87b3d0
      David Herrmann authored
      If a device is registered as HID device, it is always in Report-Mode.
      Therefore, we must not send Boot-Protocol messages on
      hidinput_input_event() callbacks. This confuses devices and may cause
      disconnects on protocol errors.
      
      We disable the hidinput_input_event() callback for now. We can implement
      it properly later, but lets first fix the current code by disabling it.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      af87b3d0
    • David Herrmann's avatar
      Bluetooth: hidp: merge 'send' functions into hidp_send_message() · 41edc0c0
      David Herrmann authored
      We handle skb buffers all over the place, even though we have
      hidp_send_*_message() helpers. This creates a more generic
      hidp_send_message() helper and uses it instead of dealing with transmit
      queues directly everywhere.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      41edc0c0
    • David Herrmann's avatar
      Bluetooth: hidp: merge hidp_process_{ctrl,intr}_transmit() · 7350e6cf
      David Herrmann authored
      Both hidp_process_ctrl_transmit() and hidp_process_intr_transmit() are
      exactly the same apart from the transmit-queue and socket pointers.
      Therefore, pass them as argument and merge both functions into one so we
      avoid 25 lines of code-duplication.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      7350e6cf
    • David Herrmann's avatar
      Bluetooth: hidp: handle kernel_sendmsg() errors correctly · 2df01200
      David Herrmann authored
      We shouldn't push back the skbs if kernel_sendmsg() fails. Instead, we
      terminate the connection and drop the skb. Only on EAGAIN we push it back
      and return.
      l2cap doesn't return EAGAIN, yet, but this guarantees we're safe if it
      will at some time in the future.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      2df01200
    • David Herrmann's avatar
      Bluetooth: hidp: remove old session-management · 5205185d
      David Herrmann authored
      We have the full new session-management now available so lets switch over
      and remove all the old code. Few semantics changed, so we need to adjust
      the sock.c callers a bit. But this mostly simplifies the logic.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      5205185d
    • David Herrmann's avatar
      Bluetooth: hidp: add new session-management helpers · b4f34d8d
      David Herrmann authored
      This is a rewrite of the HIDP session management. It implements HIDP as an
      l2cap_user sub-module so we get proper notification when the underlying
      connection goes away.
      
      The helpers are not yet used but only added in this commit. The old
      session management is still used and will be removed in a following patch.
      
      The old session-management was flawed. Hotplugging is horribly broken and
      we have no way of getting notified when the underlying connection goes
      down. The whole idea of removing the HID/input sub-devices from within the
      session itself is broken and suffers from major dead-locks. We never can
      guarantee that the session can unregister itself as long as we use
      synchronous shutdowns. This can only work with asynchronous shutdowns.
      However, in this case we _must_ be able to unregister the session from the
      outside as otherwise the l2cap_conn object might be unlinked before we
      are.
      
      The new session-management is based on l2cap_user. There is only one
      way how to add a session and how to delete a session: "probe" and "remove"
      callbacks from l2cap_user.
      This guarantees that the session can be registered and unregistered at
      _any_ time without any synchronous shutdown.
      On the other hand, much work has been put into proper session-refcounting.
      We can unregister/unlink the session only if we can guarantee that it will
      stay alive. But for asynchronous shutdowns we never know when the last
      user goes away so we must use proper ref-counting.
      
      The old ->conn field has been renamed to ->hconn so we can reuse ->conn in
      the new session management. No other existing HIDP code is modified.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      b4f34d8d
    • David Herrmann's avatar
      Bluetooth: l2cap: add l2cap_user sub-modules · 2c8e1411
      David Herrmann authored
      Several sub-modules like HIDP, rfcomm, ... need to track l2cap
      connections. The l2cap_conn->hcon->dev object is used as parent for sysfs
      devices so the sub-modules need to be notified when the hci_conn object is
      removed from sysfs.
      
      As submodules normally use the l2cap layer, the l2cap_user objects are
      registered there instead of on the underlying hci_conn object. This avoids
      any direct dependency on the HCI layer and lets the l2cap core handle any
      specifics.
      
      This patch introduces l2cap_user objects which contain a "probe" and
      "remove" callback. You can register them on any l2cap_conn object and if
      it is active, the "probe" callback will get called. Otherwise, an error is
      returned.
      
      The l2cap_conn object will call your "remove" callback directly before it
      is removed from user-space. This allows you to remove your submodules
      _before_ the parent l2cap_conn and hci_conn object is removed.
      
      At any time you can asynchronously unregister your l2cap_user object if
      your submodule vanishes before the l2cap_conn object does.
      
      There is no way around l2cap_user. If we want wire-protocols in the
      kernel, we always want the hci_conn object as parent in the sysfs tree. We
      cannot use a channel here since we might need multiple channels for a
      single protocol.
      But the problem is, we _must_ get notified when an l2cap_conn object is
      removed. We cannot use reference-counting for object-removal! This is not
      how it works. If a hardware is removed, we should immediately remove the
      object from sysfs. Any other behavior would be inconsistent with the rest
      of the system. Also note that device_del() might sleep, but it doesn't
      wait for user-space or block very long. It only _unlinks_ the object from
      sysfs and the whole device-tree. Everything else is handled by ref-counts!
      This is exactly what the other sub-modules must do: unlink their devices
      when the "remove" l2cap_user callback is called. They should not do any
      cleanup or synchronous shutdowns.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      2c8e1411
    • David Herrmann's avatar
      Bluetooth: l2cap: introduce l2cap_conn ref-counting · 9c903e37
      David Herrmann authored
      If we want to use l2cap_conn outside of l2cap_core.c, we need refcounting
      for these objects. Otherwise, we cannot synchronize l2cap locks with
      outside locks and end up with deadlocks.
      
      Hence, introduce ref-counting for l2cap_conn objects. This doesn't affect
      l2cap internals at all, as they use a direct synchronization.
      We also keep a reference to the parent hci_conn for locking purposes as
      l2cap_conn depends on this. This doesn't affect the connection itself but
      only the lifetime of the (dead) object.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      9c903e37
    • David Herrmann's avatar
      Bluetooth: hidp: move hidp_schedule() to core.c · 3764eaa9
      David Herrmann authored
      There is no reason to keep this helper in the header file. No other file
      depends on it so move it into hidp/core.c where it belongs.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      3764eaa9
    • David Herrmann's avatar
      Bluetooth: allow constant arguments for bacmp()/bacpy() · f53c20e9
      David Herrmann authored
      There is no reason to require the source arguments to be writeable so fix
      this to allow constant source addresses.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      f53c20e9
    • David Herrmann's avatar
      Bluetooth: hidp: test "terminate" before sleeping · e3492dc3
      David Herrmann authored
      The "terminate" flag is guaranteed to be set before the session terminates
      and the handlers are woken up. Hence, we need to add it to the
      sleep-condition.
      
      Note that testing the flags is not enough as nothing prevents us from
      setting the flags again after the session-handler terminated.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      e3492dc3
    • David Herrmann's avatar
      Bluetooth: hidp: remove unused session->state field · dcc07647
      David Herrmann authored
      This field is always BT_CONNECTED. Remove it and set it to BT_CONNECTED in
      hidp_copy_session() unconditionally.
      
      Also note that this field is totally bogus. Userspace can query an
      hidp-session for its state. However, whenever user-space queries us, this
      field should be BT_CONNECTED. If it wasn't BT_CONNECTED, then we would be
      currently cleaning up the session and the session itself would exit in the
      next few milliseconds. Hence, there is no reason to let user-space know
      that the session will exit now if they cannot make _any_ use of that.
      
      Thus, remove the field and let user-space think that a session is always
      BT_CONNECTED as long as they can query it.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      dcc07647
    • David Herrmann's avatar
      Bluetooth: introduce hci_conn ref-counting · 8d12356f
      David Herrmann authored
      We currently do not allow using hci_conn from outside of HCI-core.
      However, several other users could make great use of it. This includes
      HIDP, rfcomm and all other sub-protocols that rely on an active
      connection.
      
      Hence, we now introduce hci_conn ref-counting. We currently never call
      get_device(). put_device() is exclusively used in hci_conn_del_sysfs().
      Hence, we currently never have a greater device-refcnt than 1.
      Therefore, it is safe to move the put_device() call from
      hci_conn_del_sysfs() to hci_conn_del() (it's the only caller). In fact,
      this even fixes a "use-after-free" bug as we access hci_conn after calling
      hci_conn_del_sysfs() in hci_conn_del().
      
      From now on we can add references to hci_conn objects in other layers
      (like l2cap_sock, HIDP, rfcomm, ...) and grab a reference via
      hci_conn_get(). This does _not_ guarantee, that the connection is still
      alive. But, this isn't what we want. We can simply lock the hci_conn
      device and use "device_is_registered(hci_conn->dev)" to test that.
      However, this is hardly necessary as outside users should never rely on
      the HCI connection to be alive, anyway. Instead, they should solely rely
      on the device-object to be available.
      But if sub-devices want the hci_conn object as sysfs parent, they need to
      be notified when the connection drops. This will be introduced in later
      patches with l2cap_users.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      8d12356f
    • David Herrmann's avatar
      Bluetooth: remove unneeded hci_conn_hold/put_device() · fc225c3f
      David Herrmann authored
      hci_conn_hold/put_device() is used to control when hci_conn->dev is no
      longer needed and can be deleted from the system. Lets first look how they
      are currently used throughout the code (excluding HIDP!).
      
      All code that uses hci_conn_hold_device() looks like this:
          ...
          hci_conn_hold_device();
          hci_conn_add_sysfs();
          ...
      On the other side, hci_conn_put_device() is exclusively used in
      hci_conn_del().
      
      So, considering that hci_conn_del() must not be called twice (which would
      fail horribly), we know that hci_conn_put_device() is only called _once_
      (which is in hci_conn_del()).
      On the other hand, hci_conn_add_sysfs() must not be called twice, either
      (it would call device_add twice, which breaks the device, see
      drivers/base/core.c). So we know that hci_conn_hold_device() is also
      called only once (it's only called directly before hci_conn_add_sysfs()).
      
      So hold and put are known to be called only once. That means we can safely
      remove them and directly call hci_conn_del_sysfs() in hci_conn_del().
      
      But there is one issue left: HIDP also uses hci_conn_hold/put_device().
      However, this case can be ignored and simply removed as it is totally
      broken. The issue is, the only thing HIDP delays with
      hci_conn_hold_device() is the removal of the hci_conn->dev from sysfs.
      But, the hci_conn device has no mechanism to get notified when its own
      parent (hci_dev) gets removed from sysfs. hci_dev_hold/put() does _not_
      control when it is removed but only when the device object is created
      and destroyed.
      And hci_dev calls hci_conn_flush_*() when it removes itself from sysfs,
      which itself causes hci_conn_del() to be called, but it does _not_ cause
      hci_conn_del_sysfs() to be called, which is wrong.
      
      Hence, we fix it to call hci_conn_del_sysfs() in hci_conn_del(). This
      guarantees that a hci_conn object is removed from sysfs _before_ its
      parent hci_dev is removed.
      
      The changes to HIDP look scary, wrong and broken. However, if you look at
      the HIDP session management, you will notice they're already broken in the
      exact _same_ way (ever tried "unplugging" HIDP devices? Breaks _all_ the
      time).
      So this patch only makes HIDP look _scary_ and _obviously broken_. It does
      not break HIDP itself, it already is!
      
      See later patches in this series which fix HIDP to use proper
      session-management.
      Signed-off-by: default avatarDavid Herrmann <dh.herrmann@gmail.com>
      Acked-by: default avatarMarcel Holtmann <marcel@holtmann.org>
      Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
      fc225c3f
  3. 11 Apr, 2013 7 commits
  4. 06 Apr, 2013 2 commits
  5. 04 Apr, 2013 14 commits
  6. 03 Apr, 2013 1 commit