How to join a Skype for Business meeting from Linux
Summary: use a Windows virtual machine
Another day at work, another customer books a Skype for Business meeting. And you're using Linux, which has no client to join the meeting. So, what are your options? Let's recount.
- The trivial option: use another computer that has Windows.
- Use a mobile phone. The mobile client has a couple of major problems.
- Use a Windows virtual machine. You will lack audio.
- Call the Skype for Business meeting using GSM phone. Due to the limitations of options 2 and 3 I've had to resort to using this option once. The quality was horrible and it was expensive. I am not even going to mention this option again. Avoid it.
If you have a dedicated Windows computer always at your disposal, option 1 is the easiest one. There is still the problem of your work material not always being at hand if you're using a different computer. And you need the other computer. Therefore it's not a real solution. Nevertheless, it has been my preferred option in the past.
Problems of option 2: using a mobile phone
There are a couple of major problems when using a mobile phone to join a meeting: one is sharing (and viewing, to some extent) content, the other is that you can't join all meetings from the mobile client - at least not on Android phones.
For some reason the Android mobile client can't join meetings booked by our customers. If I book a meeting it will show up in the Skype for Business calendar and there's a direct join link, which works from mobile and desktop clients. For meetings booked by our customers, there is no direct join link. Instead, I always have to join using the link from the original booking email. The link opens a browser, which in turn launches the Skype for Business client. This has never worked on my Android phones.
Problems of option 3: using a Windows virtual machine
The main problem with using a KVM virtual machine is the lack of working audio emulation for Windows 10. It might be worth checking out my previous article about KVM audio in general. Viewing and sharing content works perfectly. For meetings booked by me I have sometimes joined using both a mobile phone for audio, and a virtual machine for sharing or viewing content.
I also tried using the RDP audio protocol. There are a couple of problems with it. Unfortunately, microphone input using PulseAudio does not currently work with FreeRDP, crashing the remote connection if trying to use it. Using pure ALSA, RDP audio seems to work. However, if using ALSA you must get rid of PulseAudio first, which might be a bit of a hassle. First of all, nowadays PulseAudio is a requirement for some programs such as the regular Skype. Additionally you will miss the few nice PulseAudio features such as support for Bluetooth headsets. I haven't tried BlueALSA, but it looks like another few hours of configuration.
Using USB passthrough to get audio capability
My workplace has plenty of cheap Logitech USB headsets lying around. Obviously they are not high-fidelity, but with the mediocre sound quality of Skype for Business there's little difference anyway, so they'll do just fine. To a computer, plugging in a USB headset is like plugging in a sound card. The idea is to plug in an actual sound card, or the headset, to the virtual machine. Your system will need either Intel VT-d or AMD IOMMU support to be able to pass through devices to the virtual machine. Both the processor and motherboard must have this support.
Let's plug in a USB headset and see how it looks:
~ $ lsusb -t
/: Bus 06.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/2p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/8p, 480M
|__ Port 5: Dev 3, If 0, Class=Human Interface Device, Driver=usbhid, 12M
|__ Port 5: Dev 3, If 1, Class=Human Interface Device, Driver=usbhid, 12M
|__ Port 5: Dev 3, If 2, Class=Human Interface Device, Driver=usbhid, 12M
/: Bus 05.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 5000M
/: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/2p, 480M
|__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/6p, 480M
|__ Port 3: Dev 3, If 0, Class=Vendor Specific Class, Driver=ftdi_sio, 12M
/: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 480M
|__ Port 1: Dev 3, If 0, Class=Audio, Driver=snd-usb-audio, 12M
|__ Port 1: Dev 3, If 1, Class=Audio, Driver=snd-usb-audio, 12M
|__ Port 1: Dev 3, If 2, Class=Audio, Driver=snd-usb-audio, 12M
|__ Port 1: Dev 3, If 3, Class=Human Interface Device, Driver=usbhid, 12M
|__ Port 2: Dev 2, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
|__ Port 2: Dev 2, If 1, Class=Human Interface Device, Driver=usbhid, 1.5M
I have a mouse, a keyboard and an LCD display attached besides the headset. The headset is plugged in to USB bus 1, physical port 1. The device in port 2 is my keyboard. We want to pass through bus 1, port 1. To achieve this, we append the following options to the QEMU-KVM command:
qemu-system-x86_64 \
-device usb-host,hostbus=1,hostport=1 \
-device nec-usb-xhci,id=usb,bus=pcie.0,addr=0x4
The first device line is self-explanatory. The second line isn't actually needed, but without it you'd need to have the device plugged in before starting the virtual machine, QEMU would just complain about an unknown port. The bus and addr apparently are just details for the emulated device and as such are pretty much arbitrary if they only work - the syntax is strict. I wasn't able to get the USB passthrough working with an emulated USB 2.0 class device (usb-ehci), it worked only with USB 3.0 (nec-usb-xhci). Notice the prefix nec-. Therefore I'd say the passthrough functionality seems to depend also on the bus. If it doesn't work for you, try another bus.
Now when using the virtual machine we can't connect via RDP, as it disables all the local audio devices. The SPICE protocol might work, but I use VNC. To get better resolutions (bigger than the default 1024x768) with VNC, QEMU needs to emulate a better video card. This may be done using -vga std
, but it may not always work. A better solution is to use the paravirtualized QXL driver, available as part of the SPICE project: -vga qxl
. Just install the Windows driver and set the QEMU command line and you may use resolutions all the way up to at least 2560x1600 in the guest.
The solution is not always bombproof: when I was setting the thing up with my work laptop, audio playback on the guest Windows 10 Enterprise just stopped working after a few seconds every time I tried to listen to something. The following day everything worked like a champ, however, and still seem to be working. Knowing there are sometimes weird problems with Windows audio or Skype for Business anyway, I wouldn't worry too much about it. Now I can finally have at work a single computer, with which I'm able to join every meeting, as long as I have a USB headset with me.
The script I use for starting my virtual machines is available on GitHub.
2018-09-08 update
I just switched to a new work laptop. I made it dual-bootable to Windows. The only reason is Skype for Business. Some time after I originally wrote this article some critical software was probably updated. At some point I noticed the audio just wasn't working anymore most of the time. It was just way too unreliable to pass through the USB audio headset to really have a meeting.
I am going to try again with my new laptop, but at least I now have a backup plan with me. I've also noticed a lot more connection problems even among customers with meetings they've booked themselves. Why Skype for Business is still being used by anyone is beyond me. It's just a bad piece of software.