FD-/RPiPlay

Cannot connect to Rpi400 from Mac 12

Opened this issue · 12 comments

Pucur commented

Hello!

I'm using raspberry pi with stock image, the build was successful, and it doesnt gave back any error message, and when i started i seen in the airplay logo the name of my server, but when i tried to connect, it always failed, and on my terminal, it gaves back this message:

rpiplay: plist.c:765: plist_get_uint_val: Assertion `length == sizeof(uint64_t) || length == 16' failed.

I googled so much about this error but i cant figure it out why it brings it to me.

Please help!

Thanks!

FD- commented

Please include details about the device you're trying to connect from.

Pucur commented

MacBook Air (M1, 2020)

and the server is a Raspberry Pi 400 Rev 1.0, using Raspbian GNU/Linux 10 (buster) armv7l (5.10.63-v7l+)

FD- commented

What OS are you running on the MB Air?

My guess is you're running Mojave, and they changed the format of a field in one of the setup plists.

Pucur commented

I'm using Monterey, the freshest
Im using the notebook system language as English but the keyboard is Hungarian, maybe this could cause this?

FD- commented

Sorry, I meant to say Monterey instead of Mojave :D I doubt the keyboard language is the culprit here. I'm afraid I don't have a MB running Monterey, but it would be great if anyone who has could debug the plist parsing logic used in RPiPlay's setup process.

Pucur commented

I have time to figure it out if you wish, where could i find the plist parsing exactly?

FD- commented

The problem seems to be here:

plist_t time_note = plist_dict_get_item(req_root_node, "timingPort");

Please try to figure out the correct data type of the timing port in the plist. It may e.g. be a string.

@Pucur
you can get to see the plist that is a problem by using plist_to _xml (in /usr/include/plist/plist.h)

after line 337

plist_from_bin(data, data_len, &req_root_node)

add code

char *plist_xml;
uint32_t plist_length;
plist_to_xml(req_root_node,  &plist_xml, &plist_length);
printf("%s\n",plist_xml);
free(plist_xml);

This should print the plists that are being asked about by the macOS 12 client.
There are 3 requests in which the client sends a plist.

Thee server replies each time with a plist "res_root_node" at line 462 of raop_handlers.h

plist_to_bin(res_root_node, response_data, (uint32_t*) response_datalen);

also add, just before this line

printf("response\n)";
plist_to_xml(res_root_node,  &plist_xml, &plist_length);
printf("%s\n",plist_xml);
free(plist_xml);
printf("end of response\n");

and you will also see the plist send back to the client in response to its request

The first request is about pairing and encryption
A second occurs when the video setup request type 110 for video comes,
A third when the audio setup request type 96 comes.

This should be enough to see what is going on .
I have already noticed that some of the plist items in raop_handlers.h are incorrectly/obsoletely specified,
but that didn't cause problems so far. Maybe macOs 12 is asking about something that was not asked about before and exposed the error.

@FD-

It would in general be useful to have these plists printed when the -d debug option is used.

@Pucur

There is another place to look.

at line 160 of lib/raop_handlers.h

 plist_to_bin(r_node, response_data, (uint32_t *) response_datalen);

this is where the (possibly invalid) plist properties of the server are sent to the client.

before line 160 add

    printf("begining of sent to client\n");
    char *plist_xml;
    uint32_t plist_length;
    plist_to_xml(r_node,  &plist_xml, &plist_length);
    printf("%s\n",plist_xml);
    free(plist_xml);
    printf("end of sent to client\n");

Here is a useful modern description of the expected plist events, (that shows a few errors/obsoleteness in the current rpiplay plist data sent to the client, refreshRate = int 60 missing maxFPS=int 30 bool heightPhysical, widthPhysical .)
I doubt if these are the problem, though.

https://github.com/SteeBono/airplayreceiver/wiki/AirPlay2-Protocol

@Pucur

There are three places where plist_get_uint_val is called ( in raop_handlers.h)
for timing_rport, type, and stream_connection_id.

I'm guessing a request was made that sent a plist that doesnt contain the expected entry so when an attempt to read that entry was made, it was not there (not being there means it fails the test of having the right size....), so post the plist_xml that gets printed out just before the failure.

maybe also put something like

printf("getting timing_rport\n");
plist_get_uint_val(.....)
printf("got timing_rport\n");

around each of the three calls to plist_get_uint_val() to find which attempt fails.

Pucur commented

@fduncanh

Thanks for the info, i'll look up these places and write back shortly. :)