Receiving broadcast OSC messages on Linux

Post Reply
User avatar
kripton
Posts: 42
Joined: Tue Sep 29, 2015 7:01 pm
Real Name: Jannis

Hi, I'm currently developing an embedded device (Wireless Buzzer) that should control QLC+ (Linux in my case) via OSC messages. In QLC+, there is one OSC "Mapping" line in the Inputs/Outputs tab for each network address found (which makes sense). However, on Linux, there is currently no way to receive OSC messages that have been sent to the "global broadcast address" (255.255.255.255) or to the "network-local broadcast address" (for example 192.168.0.255).
This is because currently, QLC+ binds the input- and output sockets to the IP address (which makes sense to have the correct source address, and for broadcasting: the correct sender interface) but on Linux, this doesn't allow reception of broadcast packages (see https://stackoverflow.com/questions/543 ... -interface and https://stackoverflow.com/questions/120 ... 24#1215424). Windows seems to behave differently (didn't check, just found the info online) and I honestly don't know how macOS might react.

Online, one can find four approaches to fix this:
- SO_BINDTODEVICE. This allow reception of broadcasts when bound but only works when running as root => not a valid option
- binding to INADDR_ANY, setting IP_PKTINFO and filtering (see https://stackoverflow.com/questions/120 ... 24#1215424): Works but is quite some effort, especially since implementation will get OS-specific
- binding to INADDR_ANY and doing "manual" filtering of acceptable packages via source and destination address
- Using THREE input sockets. The first one will be bound to the "unicast" IPv4-address of the network card (as done now), the second one will be bound to the "network-local broadcast address" (to be calculated from the IPv4 address and the subnet mask) and the third will be bound to the global broadcast address. Packages incoming on any of the sockets will be handled. This behaviour could be made to be always applied automatically (only applied on affected platforms (Linux and/or macOS)) OR could be configurable by the user (checkbox "receive broadcast" in the OSC configuration dialog) (not my preferred choice since the user might not be aware of that the problem is)

Massimo, any chance that a PR implementing this will get merged? Which option would you prefer? I didn't do much coding or testing yet, wanted to get your opinion first.

Jannis
User avatar
mcallegari
Posts: 4482
Joined: Sun Apr 12, 2015 9:09 am
Location: Italy
Real Name: Massimo Callegari
Contact:

Hi Jannis, the first question is of course: why do you need to send broadcast packets?
User avatar
GGGss
Posts: 2732
Joined: Mon Sep 12, 2016 7:15 pm
Location: Belgium
Real Name: Fredje Gallon

A quick note to the OP: the 'embedded device (wireless buzzer)' won't be able to broadcast beyond the wifi-AP and surely not through the router. For this purpose you need unicast packets, so your wireless devices will have to be 'paired' with the host (being QLC+).
All electric machines work on smoke... when the smoke escapes... they don't work anymore
User avatar
kripton
Posts: 42
Joined: Tue Sep 29, 2015 7:01 pm
Real Name: Jannis

@mcallegari: Valid question. Answer: Configuration simplicity. The wireless buzzer might be used by people not so familiar or skilled in computer networks. As such, it's easier just to configure the global broadcast address "255.255.255.255" as the target for the OSC packages and it should "just work". Having to configure the IP address of the machine running QLC+ on (which might even change if DHCP is being used), is one more thing that could go wrong. In hectic show situations, I want to make things as easy as possible.
Reason two: In some cases, stage lighting and sound is controlled by two different machines on the same network (say one machine running QLC+ for the lighting, another machine with QLab or similar for sound effects). If you want to trigger both, one would either send two unicast packages or one machine forwards the OSC packages to the other machine. Sending just one OSC packet to "the network" is way more simpler.

@GGGss: If a router was involved, yes, then a unicast would be required. However, if it's a "generic" Wireless Access Point that bridges its wireless and wired network interfaces and both interfaces are as such "on the same network", then broadcasts (as well as multicasts if the groups have been joined properly) will be seen by devices on the Ethernet network if they are generated by a device on the wireless network. Tested just yesterday when debugging the problem why QLC+ doesn't react to the packets. Wireshark does see them, no matter if unicast or local-network broadcast or global broadcast.
User avatar
mcallegari
Posts: 4482
Joined: Sun Apr 12, 2015 9:09 am
Location: Italy
Real Name: Massimo Callegari
Contact:

Replace m_ipAddr in this line
https://github.com/mcallegari/qlcplus/b ... r.cpp#L130
with
QHostAddress::Any

That should be it.
User avatar
kripton
Posts: 42
Joined: Tue Sep 29, 2015 7:01 pm
Real Name: Jannis

Indeed, I thought about using "QHostAddress::Any" to bind the InputSocket as well. While the solution would by fine for me, it has the possibly unwanted side effect that if there are multiple network interfaces on the machine, it would mean that unicast-OSC-packages on other network interfaces than the one selected would also be accepted. In the proposals I did, this does not happen. And it would also mean that it does not matter which of the listed "OSC Input Mappings" available one chooses as input, it would only make a difference if one uses QLC+ to SEND OSC.
User avatar
kripton
Posts: 42
Joined: Tue Sep 29, 2015 7:01 pm
Real Name: Jannis

I created a PR that implements Massimo's proposal. It fixes my use case and reception of OSC broadcast packages now works properly. Sending OSC packages from QLC+ behaves the same as before (verified using wireshark). Thanks for considering it :)
Post Reply