Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please fake a SIP-Server #1159

Open
Mannshoch opened this issue Aug 23, 2021 · 22 comments
Open

Please fake a SIP-Server #1159

Mannshoch opened this issue Aug 23, 2021 · 22 comments
Labels
help wanted An issue that needs contributors maybe A feature or change that's not certain to be implemented

Comments

@Mannshoch
Copy link

Mannshoch commented Aug 23, 2021

Is your feature request related to a problem? Please describe.
If I'm on my desktop I would prefer to use my Desktop with it's headset for calls. I mostly use my Laptop together with my phone.

Describe the solution you'd like
Beside WLan also connect over Bluetooth and fake a headset profile or use USB-Audiorouting, so I could use my desktops headset to hear my calls on my phone.

Describe alternatives you've considered
Do it manually

System Details (please complete the following information):

  • Ubuntu 21.04
  • Android with Lineageos 17 and F-droid store

Additional context
I propose to:

  • either connect the Ubuntu desktop with Headset bluetooth Profil to the Phone or use USB audiorouting.
  • Connect the KDE-Connect on android

-> With audio routing and KDEconnect you have all you need. Put them together and Fake a lokalhost SIP-Server where you could connect normal SIP Software

  • Add a SIP-Server module to GSConnect
  • Allow inside this modul to assign either a Bluetooth or an USB Device to a connected KDE-Connect device
  • If a KDEconnect device appear check if it also could get accessed by bluetooth or USB and if successfully start the fake SIP server.
@rohmishra
Copy link
Contributor

You don't need SIP server.

Most phones dont allow any apps to hook into call audio so KDE Connect app cannot do anything.

With Bluetooth, you can theoretically have calls on your laptop/desktop (it works, just modify your pw conf to add HFP/HSP sink) but it would always mean the audio will switch to your laptop if its connected to bluetooth. KDEConnect can help setting up the bluetooth connection automatically for you.

Im also not sure if we can dynamically control availability of HSP profile (maybe someone who knows more about how BT works can chime in) but all of this depends on KDE connect implementing it as gsconnect's aim is to replicate KDE Connect and no more.

@rohmishra
Copy link
Contributor

rohmishra commented Nov 20, 2021

So i took a look at Your Phone and it can do calls over BT on any laptop. So we should be able to do it. Now the question is the implementation: https://support.microsoft.com/en-us/topic/setting-up-calls-in-the-your-phone-app-c7e75908-c65d-bd42-fcb2-ea4d5fb783f1

KDE Connect android app can simplify setup of bluetooth in future but apart from that it would need to be done on laptop/desktop. This WILL ABSOLUTELY REQUIRE bluetooth

Edit: So HSP/HFP is all we need for this. It would allow us to accept/reject calls, mute calls, and even switch between phone and laptop.

https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=158743 and https://www.bluetooth.com/specifications/specs/hands-free-profile-1-8/ are interesting read.

@andyholmes
Copy link
Collaborator

Just to avoid confusion, this use of bluetooth is orthogonal to the bluetooth connection backend. Both could operate at the same time, though.

I'd guess that the way to control the audio profile would be with WirePlumber (or potentially PulseAudio), rather than bluetooth directly. At least, I don't see any interface for controlling the audio profile on the org.bluez DBus interface.

Also worth noting is there are probably more options available for GNU/Linux based smartphones, such as Phosh and Plasma Mobile.

@rohmishra
Copy link
Contributor

rohmishra commented Nov 20, 2021

I did some digging and HSP seems to be all we need. I can already confirm that calls work just fine once you let your laptop be a HSP sink. The only thing thats missing is any way to control the call. Answer/decline/ etc. HSP seems to use AT commands to control this just like on a car infotainment system. Ill try to cook something akin to proof of concept but im still trying to wrap my brain around how the spec works. Next ill have to figure out if the desktop bluetooth stack actually supports sending these AT commands, If it does, it seems it might not be that difficult to connect the dots and have away to handle calls.I know hsphfpd exists but i dont knowof its capabilites outside of call audio handling.

If you are using pipewire (or even pulse ftm), edit the config file to enable hfp_hf this will allow you to talk on calls using your laptop. Next is controlling the call, for which i have no clue yet what to really do. To enable it only for your phone, in media-session.d, create a rule that matches your device.name, i.e your phone's bluetooth name

AFAIK wireplumber allows you to programatically control config for devices so we can use that to configure hfp_hs only for the connected device. (in future: pair it with patches to KDE Connect and we should have the ability to even provide seamless pairing like what Your PHone Companion does)

Pipewire (and pulseaudio) want nothing to do with handling hfp commands (which is why hsphfpd exists) which im gonna dive into next.

Edit: So wireplumber kinda freaks out about buffer being empty when you have a bluettoth headset connected for output and make a call. It cannot both do AG and HS at once it seems for some reason. But using a headset, Yup. Calls work just fine. It doesnt forward audio volume so you dont have "absolute" volume. switching to pipewire-media-session works beautifully after editing the config! It just wont switch from A2DP to HSP for you.

I have some notes on what AT+ commands is needed for accepting call and rejecting call. Tomorrow, im gonna try sniffing what is sent from phone when a call is initiated.The gnome/phosh/librem calls app seem to use some other functionalities of hsphfpd so that would be my next stop. Hopefully it has some clues.

I think i found the path exposed on dbus, so i will poke that and see what i can find tmrw

#define HSP_HS_UUID "00001108-0000-1000-8000-00805f9b34fb"

@andyholmes
Copy link
Collaborator

As far as I know, there is no GObject-based library for real bluetooth stuff. The gnome-bluetooth library only offers very high-level list/connect/disconnect functionality. The bluez DBus service is probably the best bet for an easy method, although you may end up having to rely on CLI utilities or some other method.

@rohmishra
Copy link
Contributor

rohmishra commented Nov 21, 2021

i was able to get https://github.com/pali/hsphfpd-prototype/blob/prototype/hsphfpd.txt working so this is indeed possible!

Now do we want to add this to gsconnect would be a different question.

You need to have hsphfpd running which exposes org.hsphfpd.Endpoint which can be used to send commands and read on call details.

This worked for me with pipewire-media-session but i somehow broke hsphfpd while switching to wireplumber and no longer get org.hsphfpd to show up anymore. this shouldnt happen but im working on getting it back working.

Anyways, it looks like we can listen to org.hsphfpd.HSPGatewayEndpoint.IncomingCall() for calls even without wifi connected. And we can just add a Answer/decline button to the call notification if we find the HSP/HFP endpoints.

Next question is matching your phone to the bluetooth device, this would have be an extra menu until we can have KDE Connect app on the phone send the details to automate it. Once thats done, it would go like this:

  • KDE Connect shares the device name
  • We ask KDE Connect to start bluetooth pairing with your laptop
  • We pair/connect with phone using gnome-bluetooth and use wireplumber APIs to enable HSP/HFP_AG for just this endpoint
  • Same the WifiDevice/BluetoothDevice pair.

As for the call audio, we don't really need to do anything it seems. pipewire would handle that part for us without doing anything!
More management can come later!

For now, wireplumber has been the hardest part to understand and has took most of my time today so any help with that would be appreciated. HFP_AG seems to be enabled out of the box with wireplumber (unlike pw-m-s) but how do i use hsphfpd instead of native backend?

Im gonna roll back to pw-m-s and get as much call management documented as possible.

And so that people understand whats happening: when i enable hsphfpd.service, pipewire will not get the SCO and only works for A2DP with bluetooth headset. This is expected as only one service can own the sockets

And herein lies the problem:

  • How do i get wireplumber to use hsphfpd backend with pipewire instead of native?
  • How do i configure wireplumber for HFP protocol? It seems to default to HSP which is not what we want. HFP provides more "rich" features.

Although it shouldn't really make any difference, i would want to just stick to wireplumber now and work with that since thats what everyone would use eventually.

@ferdnyc
Copy link
Member

ferdnyc commented Nov 21, 2021

@rohmishra

I assume you've seen this: https://gitlab.freedesktop.org/pipewire/pipewire/-/merge_requests/355 , the (merged) pipewire MR that added support for HFP_AG with bluez5? There's a bunch of useful-looking info in the comments as others discussed how it did and (even more importantly, maybe) how it DIDN'T work for them as they were testing the changes.

Wireplumber probably invalidates at least some of that, but if you're looking for info on using wireplumber to make it work, the author George Kiagiadakis did a Fedora Magazine interview about it a couple of weeks ago, and can probably be reached for input.

@rohmishra
Copy link
Contributor

@ferdnyc yes I think I saw that. I was able to force pipewire to use hsphfpd by adding bluez5.hfphsp-backend = hsphfpd in bluez-monitor.conf for pw-m-s. And that allowed me to access the org.hsphfpd dbus while pipewire handled the audio. I already knew about this option so this took no time. I could see the the daemon do its thing on dbus when I called voicemail on my phone, had 2-way audio working. Even got it working fine with my pixel buds connected to my laptop and streaming call to my buds over mSBC.

But I decided to switch to wireplumber as that's where most of the effort is going forward and I was planning to switch anyways. Trying to get wireplumber and hsphfpd to talk to each other and finding solutions took almost all my time today afternoon.

With wireplumber it is forcing use of the native backend which I couldn't find a way to switch. I tried enabling hsphfpd to see if it just falls back to that if it cannot establish a socket to the device directly. But that doesn't seem to be the case.

I also found out that that wireplumber will try to automatically reconnect to Bluetooth audio devices which I don't like since it disconnects my pixel buds from my phone. this was a simple fix in the pw-m-s config file. But I couldn't find a similar config file I could edit for wireplumber. I might just be blind and somehow missed it so not really sure.

Once I get wireplumber to get pw to talk to the hsphfpd daemon, I'm gonna see how we can accept and reject calls over dbus. HSP provides a method that can be called to replicate the button but I did not see a method to send commands in HFP_AG which is what we want to use to get all the advanced features.

I also took a look at how gnome calls work and that game me some insight but it was also using ofono instead.

@andyholmes
Copy link
Collaborator

Normally I'd recommend you'd pop onto the kdeconnect development channel, but since you've posted some research here I'm going to go ahead and CC @albertvaka and @nicolasfella. They may have some feeling of how/if this could be worked into the protocol or upstream projects in a reasonable way.

@nicolasfella
Copy link

I'm not sure KDE Connect/GSConnect is the right place to implement this. It requires setting up a completely separate communication channel and given how much trouble I usually have with manually pairing my phone and PC over bluetooth I don't see how we could possibly automate this in KDE Connect in a satisfying way.

I wonder if it would make more sense to add call handling to the desktop's native bluetooth integration (bluedevil for Plasma/gnome-bluetooth (?) for Gnome) instead of shoehorning it into KDE Connect. These already know how to deal with bluetooth devices etc. It requires an additional pairing step, but as I said earlier I'm not sure we can really automated that given how much of a clusterfuck bluetooth is

@rohmishra
Copy link
Contributor

rohmishra commented Nov 21, 2021

@nicolasfella Understandable.

gnome-bluetooth + shell might be a good place to handle calls which would allow any phone connected to the laptop/PC to handle calls albeit missing any advanced features that having KDE Connect on device may provide in future.

As for implementing it in gsc, we would have to interface with hsphfpd to listen to a. incoming calls/make outgoing calls in absence of WiFi connection and b. answer/decline/mute/hold/transfer a call regardless of if wifi is available.

The thing is this would be the method (over bluetooth) we need to use for call handling on android as apps are not allowed to interface with calls in any way outside of being aware of an incoming/ongoing call. This would be exactly how Microsoft's Your Phone and WearOS watches handle calls on android phones. Apple's implementation uses wifi too if im not wrong (i dont use an iphone and i didnt bother looking into the how when i did since calls only worked between my ipad and phone) but they have the advantage of owning the whole stack.

As for automating the process, we just need the bluetooth hardware address of the phone to initialize connection. So the process would look something like this:

  1. GSConnect: Your Laptop/PC requests KDE Connect to start pairing and maybe sends our BT details to phone.
  2. KDE Connect: prompts user for for Bluetooth to be enabled and visible and send the H/W identifier back to us over wifi (Android already has APIs for this, thats how it automates the process for other devices. Eg. see Your Phone setup processes)
  3. GSConnect: Check if device is not already paired and if not pair, then connect to the device using gnome-bluetooth/BlueZ APIs or wait for the phone to pair with us (we could reduce friction by approving the pairing req?). Selectively enable HSP_HS profile for device using wireplumber APIs if it is not enabled globally.
    At this point the audio is managed by pipewire. We just need to interact with hsphfpd over d-bus to manage calls and wire it to the call UI.

Relevant articles for android: https://developer.android.com/guide/topics/connectivity/bluetooth/connect-bluetooth-devices and https://developer.android.com/guide/topics/connectivity/companion-device-pairing

Outside of automating the pairing process and not asking the user to select the bluetooth device from a list, the app doesn't have to do anything on the phone (it cant tbh) we do all call management on our own. So we can go ahead and start working on this even if kde-connect-android doesnt do anything for us right now as we need manual pairing flow as fallback anyways. So just have that for now and then move it behind a "pair manually instead" option once/if KDE Connect gains ability to automate pairing.

Having this in KDE connect for now has one advantage that we can dual-source call notifications and try to connect to phone over bluetooth if we notice we have a incoming call but arent connected to bluetooth.

We really need bluetooth backend and it has been in talks for a long time. This could be good first feature to test waters with bluetooth features and would also add a brand new feature which means we arent messing with any current feature so we dont have to risk it stopping to work for someone.

Edit: And yes I'll pop in to the matrix chat to discuss further as this might be polluting the repository. I just wanted to document everything I found out so that in case someone decides to work on this further they could reference these notes.

@ferdnyc
Copy link
Member

ferdnyc commented Nov 22, 2021

Edit: And yes I'll pop in to the matrix chat to discuss further as this might be polluting the repository. I just wanted to document everything I found out so that in case someone decides to work on this further they could reference these notes.

I mean... work however you feel comfortable, and others may feel differently, but my personal preference is the same as your initial inclination: For things to be documented somewhere in the project, so they serve as a perpetual reference. I can't count the number of times I've linked to an old issue or PR comment I or someone else posted, by way of explanation of a known issue, a prior decision, or an implementation detail.

IMHO there's no such thing as "polluting the repo", short of maybe posting cat gifs. (And even then, i leave room for the possibility that they may be sufficiently relevant cat gifs. 😉 )

@rohmishra
Copy link
Contributor

To switch to hsphfpd,

rmishra: /usr/share/wireplumber/bluetooth.lua.d/50-bluez-config.lua: --["bluez5.hfphsp-backend"] = "native",

you would copy that file to /etc/wireplumber/bluetooth.lua.d/50-bluez-config.lua and then edit it to have ["bluez5.hfphsp-backend"] = "ofono"

This was suggested on pipewire matrix.

I looked at the file earlier but somehow completely ignored that somehow! I can be really dumb at times :P

I couldn't get to it but I'll try to do some more research after work this week if possible.

@egormanga
Copy link

@rohmishra,

apps are not allowed to interface with calls

I've just checked it, and Tasker somehow allows to make calls directly, without prompting the user. So even though it might require acquiring additional permissions via adb (such as android.permission.WRITE_SECURE_SETTINGS but I am not sure), this should be possible and is not something unfamiliar to a generic linux user.

@rohmishra
Copy link
Contributor

@egormanga There are several issues with that:

  • We need Bluetooth to carry audio anyways. Unless you are rooted. Grabbing the actual call audio or faking a microphone is impossible on android 9+
  • This might result in cases where your phone isnt actually connected to bluetooth, you accept the call but have no way to actually talk until you go and find your phone.
  • We want to avoid using permissions that are not meant for third party use as much as possible on android. Writing adb means installing adb-tools if you dont have it already, enabling developer settings, connecting via USB/network and modifying that permission using pm. Not a smooth experience. The goal is to provide an entirely graphic experience to the end user and automate as much as possible
  • We can actually automate almost everything on the linux system side. So doing as much as possible on pc/laptops is preferable
  • This would also require the KDE app to be updated from get go and more importantly to be installed and available (running).
  • Using bluetooth means we can provide the same experience even if user chooses not to install the app on phone or not to keep it running.
  • Having communication split between two networks (wifi and BT) means more chances of failures. Its nice to dual source information for increased robustness but in case of failure, one network should be able to handle everything.
  • I'm not against handling calls over wifi. It provides greater flexiblity, and we can probably do the entire call handling including audio over wifi on phones like pinephone and Librem 5 but for what most people use for now - android, it would not be possible.

@egormanga
Copy link

@rohmishra but that's no problem, I've got nothing against using bluetooth audio, in fact I'm using it myself (and I didn't say a word about routing it via Wi-Fi, just that we can initiate calls).

GSC should ensure that it is able to transfer audio before even advertising an ‘accept’ button to the user. But the notification should go anyway.

Again, I'm not sure if making calls needs any non-default permissions.

In case of IP failure, we'll still be able to use calls via AT commands, I guess. I have no idea if the direct calling (without prompting) is possible thus.

@rohmishra
Copy link
Contributor

Starting android 9 (or was it 8?) You can ask system to dial a number but it will just launch the dialer with the phone number displayed. Secondly, even if you start a call you'll still be stuck with audio only available on the device itself.

Without Bluetooth backend, we would just default to more or less the current notification. No changes there.

Yes, unlike a app triggering a call, you can trigger a call using Bluetooth which is how outgoing calls work in car infotainment systems.

More or less all features we'd want from remote call management is already provided by HFP which is what your car and windows' Your Phone currently uses to provide these features. Apple probably implements their own protocol but the call accept/decline, mute, hold, dial, end call, transfer call, call info are all provided by HFP over Bluetooth.

We just need a backend to consume these APIs on the laptop/desktop side. Your phone wouldn't even need a app installed and even a feature phone would work as long as it supports standard HFP.

@luisalvarado
Copy link

Main reason why I would want to use GSConnect for. To answer my calls from my computer. The clipboard and sharing options are amazing, just amazing. But the ability to answer calls on the computer would be the icing in this fabulous cake.

@rohmishra
Copy link
Contributor

rohmishra commented Mar 18, 2022

@luisalvarado you can already handle calls on your computer over Bluetooth. Managing calls is tricky. It requires some setup on most distributions and best i have are 5 different scripts that work sometimes to accept; decline and mute calls. Technically speaking, we just need to issue commands to your phone for handsfree commands and receive information like name, phone no, status, etc. That said, it is likely just my rusty brain writing poor code but handling these AT communication is difficult.

P.S. I would recommend starting at https://github.com/pali/hsphfpd-prototype if you are looking into trying it yourself. --

It works with pipewire as well, just be sure to set ["bluez5.hfphsp-backend"] = "any" or hsphfpd in bluez-config.lua for wireplumber or in pw-m-s config.

If you want just audio, enable hsp_hs and hfp_hf in config instead.

@luisalvarado
Copy link

@luisalvarado you can already handle calls on your computer over Bluetooth. Managing calls is tricky. It requires some setup on most distributions and best i have are 5 different scripts that work sometimes to accept; decline and mute calls. Technically speaking, we just need to issue commands to your phone for handsfree commands and receive information like name, phone no, status, etc. That said, it is likely just my rusty brain writing poor code but handling these AT communication is difficult.

P.S. I would recommend starting at https://github.com/pali/hsphfpd-prototype if you are looking into trying it yourself. --

It works with pipewire as well, just be sure to set ["bluez5.hfphsp-backend"] = "any" or hsphfpd in bluez-config.lua for wireplumber or in pw-m-s config.

If you want just audio, enable hsp_hs and hfp_hf in config instead.

Much appreciated buddy. Thank you I will.

@jash-maester
Copy link

Can Confirm! Audio routing works straight from GNOME's Bluetooth settings GUI, if you connect to your phone clicking on the menu items from the Bluetooth settings in the Settings App itself. But receiving and Ending calls, I have no idea. Someone should probably handle that I guess.

@rohmishra
Copy link
Contributor

@jash-maester Right now audio routing is handled directly by pipewire/pulseaudio. But they dont support AT commands for HSP/HFP.
You can get around that by using ofono or hsphfpd. Next you can use dbus to trigger the actions on your Endpoint/phone. I havent looked into ofono much but hsphfpd currently doesnt support all commands and has been abandoned.

@andyholmes andyholmes added help wanted An issue that needs contributors maybe A feature or change that's not certain to be implemented labels Aug 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted An issue that needs contributors maybe A feature or change that's not certain to be implemented
Projects
None yet
Development

No branches or pull requests

8 participants