1. 05 Apr, 2021 2 commits
    • James Bottomley's avatar
      bluetooth: add wideband audio codec negotiation to HFP · 4444ecad
      James Bottomley authored
      The HFP protocol supports the ability to negotiate codecs if that is
      supported by both AG and HF.  This patch adds advertising of codec
      negotiation support and the ability to negotiate a codec change.  The
      only currently supported extra codec (as of HF 1.7.1) is mSBC.  mSBC
      requires that the transmission be done over an eSCO link with
      Transparent Data.  The linux kernel ensures the former, but we have to
      manually set the socket to transparent data.
      Signed-off-by: James Bottomley's avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
      Part-of: <!507>
    • James Bottomley's avatar
      bluetooth: add support for mSBC codec · f22cfa8f
      James Bottomley authored
      Adding processing support for the mSBC codec is somewhat problematic,
      because, although it is a SBC codec, the a2dp handling can't simply be
      reused because the codec is used on an eSCO link with transparent
      data, meaning the transmission unit has to be 48 bytes (fragmenting
      the codec packets) and reassembly and boundary detection is required
      to be done by the implementation.  Therefore we have to implement
      separate render and push routines for msbc that do this fragmentation.
      Fragmentation is done by emulating circular buffers.  The receive
      (push) buffer is easy, since the mSBC packet size is 60, simply have a
      buffer of this size in the sbc_info area where the fragments are
      reassembled.  Once we have a full 60 bytes, decode and restart from
      zero.  The send (render) buffer is more problematic, since the
      transmit must be done from contiguous memory.  This means that the
      buffer must be the lowest common multiple of the transmission unit and
      the packet size.  This value is 240 since 240/48 == 5 and 240/60 == 4.
      So the buffer pointers are reset at 240 which is a whole number of
      both rendered packets and eSCO transmission units.
      Signed-off-by: James Bottomley's avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
      Part-of: <!507>
  2. 03 Apr, 2021 1 commit
    • Igor Kovalenko's avatar
      bluetooth: prioritize native backend HFP HF connection · 1f204a13
      Igor Kovalenko authored
      Bluez prepends newly registered profile to a list of supported profiles,
      and new peer profile connections are attempted in reverse order of profile
      Currently native backend would register HFP AG profile before HSP AG profile.
      When peer supports both HFP HF and HSP HS profiles, this registration order
      causes extra HSP HS connection attempt before native backend would reject it
      to make sure peer is reconnected with HFP HF profile.
      Reorder HSP AG profile registration before HFP AG to make sure peer supporting
      both profiles connects with HFP HF profile first.
      Part-of: <!534>
  3. 17 Mar, 2021 1 commit
    • Marijn Suijten's avatar
      bluetooth: Set up hardware gain control if init volume is received late · 8db4dff2
      Marijn Suijten authored
      Originally written for A2DP this rework of that patch enables late-bound
      hardware volume control on HFP and HSP.  As per the specification the
      headphones (where gain control for both speaker and microphone could
      happen in hardware on the peer) are supposed to send initial values for
      these before the SCO connection is created; these `AT+VG[MS]` commands
      are also used to determine support for it.  PA uses this information in
      `add_{sink,source}` to attach hardware volume callbacks, _if_ it is
      supported.  Otherwise PA performs the attenuation in software.
      Unfortunately headphones like the WH-1000XM3's connect to A2DP
      initially and only send `AT+VGS` (microphone hardware gain is not
      supported) _during_ SCO connection when the user switches to the HFP
      profile afterwards; the callbacks set up dynamically in
      `rfcomm_io_callback` are written after the sink and source have been
      created (`add_{sink,source}`), leaving them without hardware volume
      callbacks and with software volume when adjusted on the PA side.  (The
      headphones can still send volume updates resulting in abrupt changes if
      software and peer volume differ.  Furthermore the same attenuation is
      applied twice - once in PA software, once on the peer).
      To solve this problem we simply check whether the callbacks have been
      attached whenever the peer sends a volume change, and if not attach the
      callbacks to the sink/source and reset software volume.
      Fixes: d510ddc7 ("bluetooth: Perform software attenuation until HF/HS reports gain control")
      Part-of: <!528>
  4. 16 Mar, 2021 2 commits
    • Marijn Suijten's avatar
      bluetooth: Perform software attenuation until HF/HS reports gain control · d510ddc7
      Marijn Suijten authored
      HF/HS hardware attenuation is optional on HFP: the peer indicates
      support with the AT+BRSF command, when bit 4 is set.  That does not
      explicitly mandate speaker or microphone gain control; either is
      dynamically detected as soon as `AT+VG[MS]=` is received.  Otherwise
      software attenuation is performed.
      It is also optional on HSP but nothing is mentioned about feature
      detection, assume it is the same as HFP: perform software attenuation
      until the HF/HS peer sends an `AT+VG[MS]=` command.
      When PA is a HS/HF (and the peer the AG) we attenuate both channels in
      software and unconditionally keep the peer up to date with
      `AT+VGM/AT+VGS` commands.
      Part-of: <!521>
    • Marijn Suijten's avatar
      bluetooth: Move attenuation decision to shared function · 9c847b16
      Marijn Suijten authored
      Generalize the distinction between local and peer-attenuated volumes
      into a function, paving the way for future changes where this needs to
      be checked in more places and when A2DP Absolute Volume support is
      Part-of: <!521>
  5. 23 Feb, 2021 2 commits
    • Igor Kovalenko's avatar
      bluetooth: prefer headset HFP HF connection with native backend · 815dd2d6
      Igor Kovalenko authored
      When HFP HF support is enabled in native backend, peer HFP HF profile connection
      is preferred over same peer HSP HS profile connection if peer supports both
      Enforce the preference by rejecting HSP HS profile connections from such peer.
      Part-of: <!491>
    • James Bottomley's avatar
      bluetooth: separate HSP and HFP · 66ed99a1
      James Bottomley authored
      When all headsets supported both HSP and HFP, life was good and we
      only needed to implement HSP in the native backend.  Unfortunately
      some headsets have started supporting HFP only.  Unfortuantely, we
      can't simply switch to HFP only because that might break older HSP
      only headsets meaning we need to support both HSP and HFP separately.
      This patch separates them from a joint profile to being two separate
      ones.  The older one retains the headset_head_unit name, meaning any
      saved parameters will still select this (keeping us backward
      compatible).  It also introduces a new headset_handsfree.
      For headsets that support both HSP and HFP, the two profiles will
      become separately visible and selectable.  This will only matter once
      we start adding features to HFP that HSP can't support (like wideband
      Signed-off-by: <James.Bottomley@HansenPartnership.com>
      - merge profile switching fixes patch from Rodrigo Araujo
      - rename option to enable_native_hfp_hf
      - don't call profile_done for HFP_HF unless it was initialised
      - Update for PA 11.0
      - fold in review feedback
      - add global disable option for not registering HFP
      - change parameter to enable_profile_hfp
      - update device_supports_profile to be aware of hfp/hsp exclusivity
      - change parameter to enable_profile_hfp_hf
      bluetooth: separate HSP and HFP (to me merged with this patch)
      First, just to say that your patches are going great. Finally I can use
      the microphone of my HFP only headset (a version of a Bluedio T2+).
      So far, I've only encontered one problem: the auto_switch option of
      module_bluetooth_policy stops working. Dug through the code and I think
      you missed a few spots were you have to hangle the new headset_handsfree
      profile in module_bluetooth_policy.c
      Applying the following after applying your v5 patches fixed the issue
      for me, now when I start making a VOIP call the profile switches to
      headset_handsfree and the mic works automatically, and when the call
      finishes it reverts back to a2dp.
      Thanks and best regards.
      Part-of: <!491>
  6. 01 Feb, 2021 1 commit
  7. 22 Jan, 2021 1 commit
    • Sanchayan Maity's avatar
      bluetooth: ldac: Use format as FLOAT32LE · c6862152
      Sanchayan Maity authored
      LDAC encoder already supports S16, S24, S32 and F32LE. Using FLOAT32LE
      for the sample format would avoid the additional call for conversion to
      pa_sconv_s32le_from_float32ne. perf tool shows this as being the function
      called frequently after encode. So, just avoid this by using sample format
      as F32LE.
      Part-of: <!486>
  8. 21 Jan, 2021 2 commits
  9. 19 Jan, 2021 10 commits
    • Sanchayan Maity's avatar
      bluetooth: Register an endpoint according to encode or decode support · ed44fa18
      Sanchayan Maity authored
      As we now support codecs other than SBC, we might have codec which does
      not have an encode or a decode capability. Specifically, in the case of
      LDAC there isn't a known decoder implementation available. For such a
      case, we should not register the corresponding endpoint.
      In case of LDAC, as decoding cannot be supported, we should not register
      a sink endpoint or vice versa in the other scenario.
      To do this, we check if encode_buffer or decode_buffer entry for a codec
      has been set in pa_a2dp_codec and accordingly prevent or allow it's
      Part-of: <!440>
    • Sanchayan Maity's avatar
      bluetooth: Prevent registration of an unavailable codec at runtime · 8289bdb7
      Sanchayan Maity authored
      When it comes to codecs provided via GStreamer, we register all codecs
      if GStreamer option is enabled for bluez5 via meson. However, the
      GStreamer plugin required for the codec might not be present on the
      system. This results in the codec being available for registration with
      the bluez stack or selection by the user, but, trying to use the said
      codec then fails.
      To prevent the above, we now use the can_be_supported codec API to check
      if the codec is usable and if not, we do not register the said codec and
      also prevent users from switching to it.
      Part-of: <!440>
    • Sanchayan Maity's avatar
      bluetooth: Introduce a can_be_supported API for A2DP codecs · d6149364
      Sanchayan Maity authored
      This API internally checks if a requested codec can be supported on the
      system. This is especially required for codecs supported via GStreamer
      where the availability of a plugin decides if the said codec can be
      This will be used to prevent registration of a codec which the remote
      endpoint device might be able to support, but, PulseAudio can't as the
      codec is not available on the system due to the absence of a plugin.
      We can also prevent listing or switching to an unavailable codec.
      Note that the codec negotiation happens with the bluez stack even before
      a device is connected. Because of this, we need to make sure that gst_init
      is called before checking for the availability of a plugin. Since
      module-bluez5-device gets loaded only after a connection to the device
      has been established, doing the gst_init in that or one of the bluetooth
      modules is not feasible.
      Part-of: <!440>
    • Sanchayan Maity's avatar
      bluetooth: Add support for getting current active codec · 60441697
      Sanchayan Maity authored
      For example, using the following on the command line will return the
      current codec for a bluetooth device
      pacmd send-message /card/bluez_card.4C_BC_98_80_01_9B/bluez get-codec
      where 4C_BC_98_80_01_9B is the bluetooth device.
      Part-of: <!440>
    • Sanchayan Maity's avatar
      bluetooth: Add support for getting list of negotiated codecs · 2fea838e
      Sanchayan Maity authored
      For example, using the following on the command line will return the
      list of possible codecs for a bluetooth device
      pacmd send-message /card/bluez_card.4C_BC_98_80_01_9B/bluez list-codecs
      where 4C_BC_98_80_01_9B is the bluetooth device.
      Part-of: <!440>
    • Sanchayan Maity's avatar
      bluetooth: Add aptX support via GStreamer · 33779648
      Sanchayan Maity authored
      Part-of: <!440>
    • Sanchayan Maity's avatar
      bluetooth: Add LDAC support via GStreamer · ef4762a4
      Sanchayan Maity authored
      Part-of: <!440>
    • Sanchayan Maity's avatar
      bluetooth: Add a generic GStreamer codec module · a407e9aa
      Sanchayan Maity authored
      This adds a generic gstreamer codec module based on which other
      bluetooth codecs viz. aptX, aptX-HD, LDAC and AAC can be supported.
      The GStreamer codec plugins used here themselves depend on the native
      codec implementation.
      aptX/aptX-HD -> libopenaptx
      LDAC         -> libldac
      AAC          -> Fraunhofer FDK AAC
      Part-of: <!440>
    • Sanchayan Maity's avatar
      bluetooth: Support A2DP codec switching via messaging API · 3447335d
      Sanchayan Maity authored
      This uses the messaging API to initiate a codec switch.
      While a particular codec might be applicable only for a particular
      profile, for eg. aptX can only be applicable for A2DP sink or source
      and not for let's say HSP, the codec switching logic has not been
      tied to the logic for switching profiles.
      Codec can be switched by running the following on the command line.
      pacmd send-message /card/bluez_card.XX_XX_XX_XX_XX_XX/bluez switch-codec{"ldac_hq"}
      pacmd send-message /card/bluez_card.XX_XX_XX_XX_XX_XX/bluez switch-codec {"ldac_mq"}
      pacmd send-message /card/bluez_card.XX_XX_XX_XX_XX_XX/bluez switch-codec {"ldac_sq"}
      pacmd send-message /card/bluez_card.XX_XX_XX_XX_XX_XX/bluez switch-codec {"aptx_hd"}
      pacmd send-message /card/bluez_card.XX_XX_XX_XX_XX_XX/bluez switch-codec {"aptx"}
      pacmd send-message /card/bluez_card.XX_XX_XX_XX_XX_XX/bluez switch-codec {"sbc"}
      Codec name passed above is matched against pa_a2dp_codec->name. Note that
      the match is case sensitive. XX_XX_XX_XX_XX_XX needs to be substituted with
      the actual bluetooth device id.
      Part-of: <!440>
    • Sanchayan Maity's avatar
      bluez5-util: Add support for using RegisterApplication D-Bus API · 5284b450
      Sanchayan Maity authored
      A2DP codec switching needs new version of bluez as older version does not
      provide needed org.freedesktop.DBus.ObjectManager and RegisterApplication
      DBus APIs. As a preparation for the next step of adding codecs and then
      codec switching, add support for using the new API.
      Getting list of supported codecs by remote device is supported only by new
      version of bluez daemon. If the RegisterApplication API fails, we
      fallback to the older RegisterEndpoint API and only register the SBC
      For more information, see
      This changeset has been taken from Pali Rohár's A2DP codec patch
      series but separated out to only include the D-Bus specific changes.
      Part-of: <!440>
  10. 19 Mar, 2020 1 commit
  11. 24 Jul, 2019 1 commit
    • pali's avatar
      bluetooth: Fix usage of RTP structures in SBC codec · 9e70d052
      pali authored
      Rename struct rtp_payload to rtp_sbc_payload as it is specific for SBC
      codec payload.
      Add proper checks for endianity in rtp.h header and use uint8_t type
      where appropriated.
      Field frame_count is only 4 bit number, so add checks to prevent overflow.
      And because is_fragmented field is not parsed by decoder there is no
      support for decoding fragmented SBC frames. So throw an error in this case.
  12. 12 Apr, 2019 2 commits
    • pali's avatar
      bluetooth: Set correct endianity of audio samples for SBC codec · 1b6e5b85
      pali authored
      Pulseaudio SBC codec defines that audio samples are in PA_SAMPLE_S16LE
      format which is little endian. But libsbc library expects audio samples by
      default in host endianity which is big endian on big endian system. So SBC
      support on big endian system is broken. To fix this problem tell libsbc
      library that audio samples are in little endian to match PA_SIMPLE_S16LE
      sample format.
      Bug: https://bugs.freedesktop.org/show_bug.cgi?id=91359
    • pali's avatar
      bluetooth: Modular API for A2DP codecs · 106aa914
      pali authored
      This patch introduce new modular API for bluetooth A2DP codecs. Its
      benefits are:
      * bluez5-util and module-bluez5-device does not contain any codec specific
        code, they are codec independent.
      * For adding new A2DP codec it is needed just to adjust one table in
        a2dp-codec-util.c file. All codec specific functions are in separate
        codec file.
      * Support for backchannel (microphone voice). Some A2DP codecs (like
        FastStream or aptX Low Latency) are bi-directional and can be used for
        both music playback and audio call.
      * Support for more configurations per codec. This allows to implement low
        quality mode of some codec together with high quality.
      Current SBC codec implementation was moved from bluez5-util and
      module-bluez5-device to its own file and converted to this new A2DP API.
  13. 27 Jul, 2018 1 commit
  14. 21 Jun, 2018 1 commit
  15. 05 Sep, 2017 1 commit
    • Colin Leroy's avatar
      cli-command: don't exit on "module already loaded" errors · f0dfddea
      Colin Leroy authored
      Some modules may only be loaded once, and trying to load them
      twice from default.pa makes PulseAudio startup fail. While that could
      be considered a user error, it's nicer to not be so strict. It's not
      necessarily easy to figure what went wrong, if for example the user
      plays with RAOP and adds module-raop-discover to default.pa, which first
      works fine, but suddenly stops working when the user at some point
      enables RAOP support in paprefs. Enabling RAOP in paprefs makes
      module-gconf load the module too, so the module gets loaded twice.
      This patch adds a way to differentiate module load errors, and
      make cli-command ignore the error when the module is already
  16. 28 Mar, 2017 1 commit
    • Tanu Kaskinen's avatar
      bluez5-util: fix profile waiting logic · cb78d6f5
      Tanu Kaskinen authored
      There were two bugs in the old logic. The first one:
      If a device has two profiles, the old code would start the wait timer
      when the first profile connects, but when the second profile connects,
      the timer would not get stopped and the CONNECTION_CHANGED hook would
      not get fired, because the code for that was inside an if block that
      only gets executed when the first profile connects. As a result,
      module-bluez5-device loading would always be delayed until the wait
      timeout expires.
      The second bug:
      A crash was observed in device_start_waiting_for_profiles(). That
      function is called whenever the connected profile count changes from 0
      to 1. The function also has an assertion that checks that the timer is
      not running when the function is called. That assertion crashed in the
      following scenario with a headset that supports HSP and A2DP:
      1. First HSP gets connected. The timer is started.
      2. Then HSP gets disconnected for some reason. The timer is still
      3. Then A2DP gets connected. device_start_waiting_for_profiles() is
      called, because the connected profile count changed from 0 to 1 again.
      The timer is already running, so the assertion fails.
      First I thought I'd remove the assertion from
      device_start_waiting_for_profiles() and just restart the timer on the
      second call, but then I figured that when the device returns to the
      "everything disconnected" state in step 2, it would be better to stop
      the timer. The purpose of the timer is to delay the notification of the
      device becoming connected, but if the device becomes disconnected during
      the waiting period, the notification doesn't make sense any more, and
      therefore the timer doesn't make sense either.
      BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=100237
  17. 11 Mar, 2017 1 commit
    • Georg Chini's avatar
      bluetooth: use native and ofono backends in parallel with headset=auto · adc2e8cd
      Georg Chini authored
      This patch changes the behavior of the headset=auto switch for module-bluez5-discover.
      With headset=auto now both backends will be active at the same time for the AG role and
      the switching between the backends is only done for the HS role.
      headset=ofono and headset=native remain unchanged.
      This allows to use old HSP only headsets while running ofono and to have headset support
      via pulseaudio if ofono is started with the --noplugin=hfp_ag_bluez5 option.
  18. 07 Mar, 2017 1 commit
    • Wim Taymans's avatar
      backend-native: add support for the HSP Headset role · e1dc75da
      Wim Taymans authored
      This is a rebase of Wim Taymans patch to support the HSP headset role that has
      somehow been forgotten. Original patch can be found at
      Rebase and minor changes by Georg Chini.
      In addition to the HSP Audio Gateway, also add support for the headset
      role in the native bluetooth backend. In this role, pulseaudio is used as
      In the headset role, we create source and sink to receive and send the samples
      from the gateway, respectively. Module-bluetooth-policy will automatically load
      loopback modules to link these to a sink and source for playback. Because this
      makes the source the speaker and the sink the microphone, we need to reverse the
      roles of source and sink compared to the gateway role.
      In the gateway role, adjusting the sink volume generates a +VGS command to set
      the volume on the headset. Likewise, receiving AT+VGS updates the sink volume.
      In the headset role, receiving a +VGS should set the source volume and any
      source volume changes should be reported back to the gateway with AT+VGS.
  19. 23 Sep, 2016 1 commit
  20. 10 Aug, 2016 1 commit
    • Tanu Kaskinen's avatar
      bluetooth: don't create the HSP/HFP profile twice · 32c2a6d6
      Tanu Kaskinen authored
      create_card_profile() used to get called separately for HSP and HFP,
      so if a headset supports both profiles, a profile named
      "headset_head_unit" would get created twice. The second instance would
      get immediately freed, so that wasn't a particularly serious problem.
      However, I think it makes more sense to create the profile only once.
      This patch makes things so that before a profile is created, we check
      what name that profile would have, and if a profile with that name
      already exists, we don't create the profile.
      A couple of Yocto releases (jethro and krogoth) have non-upstream
      patches that suffer from this double creation. The patches add
      associations between profiles and ports, and those associations use
      the profile name as the key. When the second profile gets freed, the
      associations between the profile and its ports get removed, and since
      the profile name is used as the key, this erroneously affects the
      first profile too. Crashing ensues.
      BugLink: https://bugzilla.yoctoproject.org/show_bug.cgi?id=10018
  21. 22 Jul, 2016 1 commit
    • pali's avatar
      bluetooth: Add support for automatic switch between hsp and a2dp profiles · bde2ff87
      pali authored
      With this patch module-bluetooth-policy automatically switch from a2dp profile
      to hsp profile if some VOIP application with media.role=phone wants to start
      recording audio.
      By default a2dp profile is used for listening music, but for VOIP calls is
      needed profile with microphone support (hsp). So this patch will switch to
      hsp profile if some application want to use microphone (and specify it in
      media.role as "phone). After recording is stopped profile is switched back
      to a2dp. So this patch allows to use bluetooth microphone for VOIP applications
      with media.role=phone automatically without need of user interaction.
      Signed-off-by: pali's avatarPali Rohár <pali.rohar@gmail.com>
  22. 31 Oct, 2014 1 commit
    • Wim Taymans's avatar
      backend-native: add a new native headset backend · 7d4a497b
      Wim Taymans authored
      Add a simple native headset backend that implements support for the
      blutooth HSP profile.
      This allows pulseaudio to output audio to a Headset using the HSP profile.
      Make the native backend the default.
  23. 22 Aug, 2014 1 commit
  24. 29 Sep, 2013 3 commits
    • João Paulo Rechi Vita's avatar
      bluetooth: Revive module-bluetooth-discover · 8753b8c1
      João Paulo Rechi Vita authored
      Create a wrapper module called module-bluetooth-discover to avoid
      breaking backward-compatibility of default.pa. This wrapper may
      eventually be dropped altoghether with BlueZ 4 support.
    • João Paulo Rechi Vita's avatar
      bluetooth: Fail to load driver if discovery module is not loaded · dc4be17e
      João Paulo Rechi Vita authored
      For quite some time now the device driver module doesn't work well
      without the discovery module, so for the BlueZ 5 support we'll prevent
      the device driver module to be loaded if the discovery module is not
    • João Paulo Rechi Vita's avatar
      bluetooth: Create pa_bluetooth_transport for BlueZ 5 support · e78e7e69
      João Paulo Rechi Vita authored
      Create the pa_bluetooth_transport structure to store information about
      the bluetooth transport and utility functions to manipulate this
      structure. The acquire() and release() operations are function pointers
      in the pa_bluetooth_transport structure to make possible for different
      transport backends to provide different implementations of these
      operations. Thre is also a userdata field for the transport backend
      provide data for the acquire/release functions.
      This commit also creates a new function
      pa_bluetooth_device_any_transport_connected() to check if there is any
      audio connection between the host and a remote device.