albfan / miraclecast

Connect external monitors to your system via Wifi-Display specification also known as Miracast
Other
3.66k stars 407 forks source link

Configure wfd subelements #463

Open albfan opened 1 year ago

albfan commented 1 year ago

Right now this is set for source and target as a hardcoded value:

https://github.com/albfan/miraclecast/blob/master/src/ctl/sinkctl.c#L256

ctl_link_set_wfd_subelements(l, "000600111c4400c8");

but value might vary to reflect different config.

this value is documented on spec, but best human readable way I found (I cannot parse the spec) is to look at script write by @benzea on https://gitlab.gnome.org/GNOME/gnome-network-displays/-/issues/4#note_839104

#!/usr/bin/env python3

import dbus
import struct

class WFDSourceIEs:
    def __init__(self):
        self.rtsp_port = 7236
        # 802.11n is 300 Mbit/s
        self.throughput = 200 # Mbit/s
        self.coupled_sink = False
        self.available = True
        self.tdls_prefered = True
        self.content_protection = False
        self.time_synchronisation = False
        self.audio_only = False

    def to_bytes(self):
        hdr = struct.pack('>bh', 0, 6)

        # All other bits are always zero for one reason or another
        info_bitfield = 0
        info_bitfield |= int(self.coupled_sink) << 2
        info_bitfield |= int(self.available) << 4
        info_bitfield |= int(self.tdls_prefered) << 7
        info_bitfield |= int(self.content_protection) << 8
        info_bitfield |= int(self.time_synchronisation) << 9
        info_bitfield |= int(self.audio_only) << 11

        content = struct.pack('>hhh', info_bitfield, self.rtsp_port, self.throughput)
        assert len(content) == 6
        wfd_dev_info = hdr + content

        # Other headers? extended device info?

        return wfd_dev_info

source_ies = WFDSourceIEs()
source_ies.port = 7236

elems = source_ies.to_bytes()
elems = list(elems)

bus = dbus.SystemBus()
obj = bus.get_object('fi.w1.wpa_supplicant1', '/fi/w1/wpa_supplicant1')
supplicant_props = dbus.Interface(obj, dbus_interface='org.freedesktop.DBus.Properties')
supplicant_props.Set('fi.w1.wpa_supplicant1', 'WFDIEs', dbus.Array(elems, signature='y'))
print("WFDIEs have been set directly on wpa_supplicant, current value is: ", bytes(supplicant_props.Get('fi.w1.wpa_supplicant1', 'WFDIEs')))

Probably as there're lot of parameters different ways to set would be great: