MediaMVP ======== This document is a state of flux - it will be updated as I figure out more information. Overview ======== The MediaMVP server listens on the following ports: TCP: 5906 - RFB display port TCP: 6337 - Media transfer port UDP: 16869 - tftpd UDP: 16867 - bootp UDP: 16881 - Service locator port In this document, the protocol for the proprietry services will be (mostly documented) In the following document, the client has an IP address of 192.168.155.25 and the server an address of 192.168.155.37. Booting the MVP =============== The MediaMVP initially makes a bootp probe, this is sent out on two ports - port 67 (the traditional port) and port 16867. This latter port is created by the MVP server on the PC. This permits the MVP to work even when a traditional bootp server is not available on the network. To boot off a normal server you need to set up dhcp/bootp and tftpd. The dhcp config should be as usual, but contain a filename option, as an example here's my one: host mvp { filename "dongle.bin"; hardware ethernet XX:XX:XX:XX:XX:XX; fixed-address 192.168.155.25; } The mediamvp then proceeds to tftp load the file dongle.bin (which contains the linux kernel and ramdisk), boots linux and then once more asks for a dhcp adddress. Following this it then proceeds to query for the MVP servers. Querying the MVP Servers ======================== The MVP then sends out a UDP broadcast message on port 16882, this message has a length of 52 bytes. The message sent out has the following data: 0000 0001 babe fafe XXXX XXXX XXXX 0000 c0a8 9b19 41f2 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 The server then responds to the client_port specified in the incoming message with the following message: 0000 0001 fafe babe 0000 0000 0000 0000 c0a8 9b19 0800 0000 c0a8 9b25 16ae 0000 c0a8 9b25 18c1 0000 0000 0000 c0a8 9b25 41f6 0000 This can be described by the following structure: typedef struct { uint32_t unknown; uint16_t id1; uint16_t id2; uint8_t mac[6]; uint8_t pad[2]; uint32_t client_addr; uint16_t client_port; uint8_t pad2[2]; uint32_t guiserv_addr; uint16_t guiserv_port; uint8_t pad3[2]; uint32_t mediaserv_addr; uint16_t mediaserv_port; uint8_t pad4[6]; uint32_t remoteconsole_addr; uint16_t remoteconsole_port; } udpprot_t; The MediaMVP then connects to the guiserv_addr:guiserv_port and media_addr:media_port. The mediaserv is the data retrieval port whose protocol will be discussed later. The GUI is a modified version of the rfb protocol and is discussed in the next section. client_(addr|port) are used as the originating port of the media connection. remoteconsole_addr:remoteconsole_port data has never been observed, thus I presume it was used for development debugging. GUI RFB Protocol ================ The GUI of the MediaMVP is supplied over TCP using a modified RFB (vnc) protocol, it generally obeys the rules of rfb, so take a look at the vnc protocol specification for details, here's the rough sequence: Server Sends Protocol Version ----------------------------- 52 46 42 20 30 30 33 2e 30 30 33 0a RFB 003.003\012 Client Agrees on Protocol Version --------------------------------- 52 46 42 20 30 30 33 2e 30 30 33 0a RFB 003.003\012 Server Sends Authentication Requirement --------------------------------------- 00 00 00 01 No authentication Required Client Sends Shared Display Status ---------------------------------- 00 Don't share display, disconnect previous clients Server notifies client of display format ---------------------------------------- 02 d0 02 40 18 18 00 00 00 07 00 07 00 03 00 03 06 00 00 00 Display width = 720, depth = 576, bits per pixel = 24, depth = 24, bigendian = 0, true colour = 0, red-max = 7, green-max = 7, blue-max = 3, red-shift = 0, green-shift = 3, blue-shift = 0, 3 bytes padding Server notifies client of display name -------------------------------------- 00 00 00 0a 72 66 62 77 69 6e 64 6f 77 73 Length 10, 'rfbwindows' Server sends down a display image (this is out of sequence!) --------------------------------- 00 cc 00 01 00 3c 00 30 02 58 01 e0 00 00 00 07 x posn = 1, y posn = 60, width = 600, height = 480. Encoding type = 7 Here we have our first problem - an unknown encoding type! The data then consists of: XX XX XX XX 00 00 00 ?? Where XX is the length of the image, where ?? maybe 01, 02, 03. 01 - gzipped yuv image 02 - ?? 03 - ?? Following these bytes, an encoded rectangle follows. Client sends SetPixelFormat message ----------------------------------- 00 00 02 40 08 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Only significance here is 8 bits per pixel, 8 bit depth Client sends SetEncodings Message --------------------------------- 02 00 00 04 00 00 00 01 00 00 00 05 00 00 00 04 00 00 00 02 4 encoding types - 1 = Copyrect, 5 = Hextile, 4 = CoRRE, 2 = RRE This is the crazy bit, the client accepts these 4 encoding types, but the data that's sent back is encoding type 7, of which we know nothing! Client sends FramebufferUpdateRequest Message --------------------------------------------- 03 00 00 00 00 00 02 d0 02 40 - PAL 03 00 00 00 00 00 02 d0 02 40 03 01 00 00 00 00 02 d0 01 e0 - NTSC 03 01 00 00 00 00 02 d0 01 e0 Non-incremental/incremental update for whole screen 0,0 -> 720,576 (480) NB. It seems that sending an image larger than 620x480 is not supported. Ping Message Type ----------------- 08 00 This is a rfb ping message - the server should reply with the same message, this is sent out roughly once per second and is used to ensure that the connection to the server has not timed out. Media Control Messages sent from server to client over RFB ---------------------------------------------------------- As of beta 21365 these messages are now 34 bytes long before any additional parameters (eg filename). This is to support skipping in files. 04 01 00 00 00 00 00 00 XX 00 Followed by path, XX is length of path This is sent by the server when OK has been pressed on a media file. The client then requests it from the media stream. 04 02 00 00 00 00 00 00 00 00 Sent by server when client should PauseMediaStream (i.e. not request any more) 04 03 00 00 00 00 00 00 00 00 Sent by server when client should send StopMediaStream 04 04 00 00 00 00 00 00 00 00 Sent by server when client should send RewindMediaStream 04 05 00 00 00 00 00 00 00 00 Sent by server when client should send ForwardMediaStream 04 08 00 00 00 00 00 02 00 00 Sent either side of playing an MPEG file 04 09 00 00 00 00 00 00 00 00 Send by server when the client should toggle mute 04 0a 00 00 00 00 00 XX 00 00 CC TT PP FF AA 00 00 00 00 00 00 00 Send settings to client [Slightly unsure about the following, it's roughly correct!] XX = length of data CC = sub command - if 00, the remainder are blank and client replies with ack message followed by settings - if 01, then "test" the settings - if 02, then cancel the "testing" settings - if 03, then save settings into xram TT = tv mode - 00 = ntsc, 01 = pal PP = output - 00 = rgb detected 01 = svideo, 02 = composite, 03 = rgb/composite FF = flicker - 00 = none, 01 = low, 02 = medium, 03 = high AA = aspect ratio - 00 = 4:3, 01 = 16:9 Media Control Message Acks (client to server) -------------------------- As of beta 21365 these are now 34 bytes long 07 01 01 00 00 00 00 00 00 00 - Filename 07 02 01 00 00 00 00 00 00 00 - Pause 07 03 01 00 00 00 00 00 00 00 - Stop 07 04 01 00 00 00 00 00 00 00 - Rewind (I guess) 07 05 01 00 00 00 00 00 00 00 - Forward (I guess) 07 06 01 00 00 00 00 00 00 00 - Volume down 07 07 01 00 00 00 00 00 00 00 - Volume up 07 08 01 00 00 00 00 00 00 00 - Menu 07 09 01 00 00 00 00 00 00 00 - Toggle mute 07 0a 01 00 00 00 00 00 00 00 - Settings - may be followed by setting data 01 00 - Sent before mpeg play - turn menu off 00 00 - Send after mpeg play - turn menu on Client Remote Key Event ----------------------- 04 DD 00 XX 00 00 00 XX A key event, DD is the down state and with the MVP it is always sent as down. XX is the key code on the remote control (big endian), the one's I've bothered sniffing out are as follows: $01 = Key 0 $02 = Key 1 $03 = Key 2 $04 = Key 3 $05 = Key 4 $06 = Key 5 $07 = Key 6 $08 = Key 7 $09 = Key 8 $0a = Key 9 $0d = OK $0e = Rewind $0f = Fastforward $10 = Vol+ $11 = Vol- $12 = Ch+ $13 = Ch- $14 = Power $15 = Mute $19 = Play $1a = Record $1b = Stop $1c = Pause $1e = Menu $20 = Back/exit $23 = Go $24 = Red $25 = Green $26 = Yellow $27 = Blue $28 = Blank $29 = Full $2a = Replay $2b = Skip The RFB protocol states that the key code is 4 bytes, though this is obviously not applicable in this case. Media Transfer Protocol ======================= As of beta 21365 these messages are now 40 bytes long (padded with 0's) StopMediaStream Message ----------------------- 03 00 00 00 00 00 XX XX 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Stop playing the mediastream, XX XX is the file ID - this doesn't seem to change?!?!? RequestMediaStream Message --------------------------- 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 XX XX 00 00 [nul terminated filename follows] Client sends this initially to the server, XXXX represents the length of filename. The server then replies with: RequestMediaStream ACK Message ------------------------------ For an mp3: 02 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 II II XX XX 00 00 Where IIII is the file id (used afterwards in all messages) and XXXX is the length of the filename (reusing buffers perchance?) For an mpeg: 02 00 00 00 01 00 ff 00 XX XX YY YY 00 00 BB BB 00 00 II II XX XX 00 00 Where XXXX and YYYY is the resolution of the mpeg and BBBB is the bitrate (NB, this bit rate appears to ignored?) SeekMediaStream Message ----------------------- 07 00 00 00 00 00 II II XX XX XX XX 00 00 00 00 00 00 00 00 00 00 00 00 Where IIII is the file ID. XXXX XXXX is the offset within the media stream to seek to. The server then acknowledges this. StepMediaBlock Message ---------------------- 05 00 00 00 00 00 II II 00 DD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Appears to request the server to step back a block in the media stream. DD = 0 for rewind, = 1 for forward. An 05 message is sent back from the server followed by the data: 05 00 00 00 00 00 II II 00 DD 00 00 00 00 LL LL XX XX XX XX 00 00 00 00 Where XX is the current offset in the file and DD is the direction of skipping. II is of course the file id. LLLL is the length of the data that follows. The data should begin with 000001b3 - sequence start code and should end after just before the picture header of the next frame. i.e. the data should contain a single I Frame. (Actually it doesn't matter if there are multiple frames, since only I Frames appear to be displayed). ConfirmMediaStreamID ACK Message -------------------------------- 07 00 00 00 00 00 II II 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 The client then requests a block: MediaStreamRequestBlock Message ------------------------------- 04 00 00 00 00 00 II II LL LL LL LL 00 00 00 00 00 00 00 00 00 00 00 00 Where IIII is file ID and LLLLLLLL is the length of each block (in little endian format) mpeg, LLLLLLLL = 0x00030d40 mp3, LLLLLLLL = 0x000007d0 The server then replies with a data block MediaStreamData Message ----------------------- 04 00 00 00 00 00 II II LL LL LL LL NN NN NN NN 00 00 00 00 00 00 00 00 Where IIII is the file ID and LLLLLLLL is the length of the block (if LLLLLLLL=0 then the file has ended). NNNNNNNN is the offset into the file of the next block. Media????? Message ------------------ 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 From beta 21317 this message is sent prior to the media file being requested. I've only seen it containing 00 and return the same message seems to satisfy the MVP. And thus ends the protocol dissection! - For more details take a look at the code! enjoy, d.