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.

