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  serv_addr;
    uint16_t  serv_port;
} udpprot_t;

The MediaMVP then connects to the guiserv_addr:guiserv_port and 
media_addr:media_port. The conserv 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.

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  ?? ?? ?? ??

Where XX is the length of the image, and ?? is unknown at present. The
data following this is a gzipped yvuy image.

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 
03 01 00 00 00 00 02 d0 02 40 

Non-incremental/incremental update for whole screen 0,0 -> 720,576


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
----------------------------------------------------------

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

Media Control Message Acks (client to server)
--------------------------

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   - MPEG mode
07 09 01 00 00 00 00 00 00 00	- Toggle mute

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
=======================

I've done very little work on understanding this, here's a brief description
of the message types that I've seen so far:

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 ?? 00
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.


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.

Conclusion
==========

Thanks to Stephen, I now know what encoding type 7 is - it's a proprietry
gzip'd yvuy image. Now, all I've got to do is to find some code to 
create them. Work on playing with the MVP has been put on hold till Hauppauge
release the GPL sourcecode, which will hopefully shed some light on the
message types I don't fully understand.

In the mean time, I've uncovered enough information to write a fake media
server that will stream TV from my vdr box to the MVP. It can also handle
internet mp3 radio stations. It's a bit hacky, but seems to work, and would
work  lot better if the windows display server didn't keep dropping the
network connection!
