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

bpd: support MPD 0.16 protocol and more clients #3214

Merged
merged 14 commits into from
Jun 3, 2019
Merged

bpd: support MPD 0.16 protocol and more clients #3214

merged 14 commits into from
Jun 3, 2019

Conversation

arcresu
Copy link
Member

@arcresu arcresu commented Apr 13, 2019

Now that idle has been implemented, we're almost all the way to MPD 0.16 support. There are a couple of small commands that need adding, but most of what we need is already in place. More importantly, claiming to support the newer protocol version means that more clients will talk to us; fixes #800.

  • nextsong and nextsongid fields in status output.
  • playlist range support in playlistinfo.
  • playlist range support in move.
  • stickers (which are basically flexible attrs). Moved to bpd: support MPD stickers #3290

I've expanded my local tests to include ncmpcpp and two Android clients (MPDroid and MALP). So far bpd breaks all three of these clients. Known compatibility issues are listed below.

ncmpcpp (Linux, libmpdclient)

  • ncmpcpp sends noidle when bpd doesn't expect it to be in the idle state.
  • ncmpcpp uses the deprecated volume command to change the volume and we ignore it.
  • ncmpcpp sometimes causes an error with errno 104 ECONNRESET when quitting.
  • ncmpcpp issues the unimplemented command decoders (fixed in bpd: support decoders command #3222).
  • It notices when playback is paused, but doesn't notice when it's resumed again, even if it was resumed using ncmpcpp itself! Issuing a different command (e.g. changing the volume) will prompt it to refresh the status and update the playback state. This doesn't seem to happen any more. I'm not sure what fixed it.
  • ncmpcpp expects stored playlists to be supported and when bpd sends an error it gets stuck in an infinite loop and the UI freezes. Moved to BPD: Persistent playlist #176.
  • When it receives a playlist event and tries to update its playlist using plchanges it doesn't like the response returned by bpd and ncmpcpp's playlist becomes blank.

M.A.L.P. (Android)

MPDroid (Android)

  • MPDroid uses extra idle events that we don't support yet (idle "database" "mixer" "options" "output" "player" "playlist" "sticker" "update").
  • MPDroid crashes at startup although there is no MPD error sent over the protocol. We must be giving it wrong output in the successful commands somehow.

mpDris2 (Linux)

  • mpDris2 seeks using fractional seconds and crashes when bpd doesn't accept that.
  • mpDris2 (and another client but I've forgotten which) crash sometimes with an error that implies that bpd forgot the state field in a response to the status command. This doesn't seem to be possible though. Its backtrace starts with KeyError: 'state'

mpdscribble (Linux, libmpdclient)

  • mpdscribble tries to register a client channel. It doesn't mind that it fails, but it would be nice to support it. Moved to bpd: support client channels #3291
  • I noticed it stopped scrobbling and there was an error in the log: mpd error (7): expected more list_OK's. I didn't manage to correlate it to the protocol log in bpd though so I'm not sure what happened.

Other clients

@arcresu arcresu marked this pull request as ready for review June 2, 2019 13:24
@arcresu
Copy link
Member Author

arcresu commented Jun 2, 2019

I've been using this branch myself for some time now and it's mostly working OK. The main issues are because of parts of the MPD protocol we're missing, but I'd prefer to handle those additions separately.

The other issue I've seen is that after running fine for some time, clients connected to bpd will sometimes crash. I caught mpDris2 and ncmpcpp crashing at the same time with log output that suggested a malformed response from bpd. This is rare enough that I haven't been able to correlate it with the specific output in bpd's protocol traffic dump. Whenever this has happened I've only needed to restart the clients to get things back to normal, without having to restart bpd.

In the course of implementing this PR I encountered issues that went away when I implemented support for apparently unrelated protocol features. I guess the clients aren't robust to unexpected server behaviour since there's normally only one server implementation to test against. I'm hopeful that the issue I mentioned above will solve itself in the same way.

So I think I'd like to merge this now and keep working on the unchecked todo items during the release cycle. This should hopefully encourage some other people to test the changes too :)

arcresu added 14 commits June 2, 2019 23:37
When ncmpcpp quits after an error it causes a "connection reset by peer"
exception, also known as ECONNRESET (104) in errno terms. In Python
2 this is mapped to a `socket.error` and in Python 3 this is
  `ConnectionResetError` which is thankfully a subclass of the
  `socket.error` exception class.
The playlistid command is supposed to list the whole playlist if no
argument is provided, but we were accidentally trying to look up an
impossible negative id in that case causing an error to always be
returned.
The documented type is float, not integer, and clients like mpDris2 send
fractional seconds, causing them to crash if these values ar enot
accepted.
The real MPD ignores `noidle` when the client is not idle. It doesn't
even send a successful response, just ignores the command. Although
I don't understand why a client would fail to keep track of its own
state, it seems that this is necessary to get ncmpcpp working.
Copy link
Member

@sampsyo sampsyo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! Everything looks good to me, so let's go for it. I agree that getting more "eyes" on your new features will be the right way to shake out any bugs.

@arcresu arcresu added this to the Modern MPD support milestone Jun 3, 2019
@arcresu
Copy link
Member Author

arcresu commented Jun 3, 2019

Alright, I've opened a bunch of issues to keep track of missing features, and collected them in a new milestone. Let's get this in 🎉

@arcresu arcresu merged commit be1daa9 into beetbox:master Jun 3, 2019
@arcresu arcresu deleted the bpd-mpd16 branch June 3, 2019 00:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BPD: Update to newer MPD protocol version
2 participants