Skip to content

Discover fails if there is a misbehaved device in the network #201

@gpothier

Description

@gpothier

The discover function in code.py does not check the response received to the SSDP search query, as explicited in this comment:

# Only Zone Players will respond, given the value of ST in the
# PLAYER_SEARCH message. It doesn't matter what response they make. All
# we care about is the IP address

If a device on the network is misbehaved and responds faster than the Zone Players, the discovery function fails. Unfortunately, this is not just a theoretical issue: for some reason, the leapcast software (https://github.com/dz0ny/leapcast) does respond to SoCo's search query. I know leapcast is probably at fault here, but a little sanity check in SoCo wouldn't hurt.

A quick fix is to check if the response contains the "Sonos" string, it is quite crude and could probably be refined, but it works. Like this:

while True:
    response, _, _ = select.select([_sock], [], [], timeout)
    # Only Zone Players will respond, given the value of ST in the
    # PLAYER_SEARCH message. It doesn't matter what response they make. All
    # we care about is the IP address
    if response:
        data, addr = _sock.recvfrom(1024)
        if not "Sonos" in data:
            continue

        # Now we have an IP, we can build a SoCo instance and query that player
        # for the topology to find the other players. It is much more efficient
        # to rely upon the Zone Player's ability to find the others, than to
        # wait for query responses from them ourselves.
        zone = config.SOCO_CLASS(addr[0])
        if include_invisible:
            return zone.all_zones
        else:
            return zone.visible_zones
    else:
        return None

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions