News:

Latest versions:
Server plugin: 0.5.1
MVP dongle: 0.5.2
Raspberry Pi client: 0.5.2
Windows client: 0.5.2-1

Main Menu
Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - AndersF

#16
VOMP General / MVP / Vomp protocol
September 02, 2008, 01:11:43
Hi,

I have tried to understand the protocol between Vomp Client and server. I've understood most of the control protocol like list channels, read timers, etc.
I've been able to start streaming live TV, but what is the type of the streamed data?

Below is a specification of the protocol as I've understood it. Maybe someone can fill in some details and add some notes reagarding how to access Live TV and recordings?

   Vomp Protocol for communication between Vomp Client and Server
        ===============================================================

Introduction
=============

The Video Disk Recorder (VDR http://www.cadsoft.de/vdr/) supports a
plugin architecture.
Vomp (http://www.loggytronic.com/vomp.php) is a client application
implementing  set-top box functionality running on a Hauppauge MVP box.
The Vomp client accesses the TV functionality running on the VDR server via an
application specific protocol. The server part of the protocol is implemented
as a plugin on the VDR server.

This document specifies the Vomp protocol.
It is mostly compiled by reverse engineering of vompclientrrproc.c of Vomp
server, version 0.3.0.

The Vomp protocol consists of the following parts:

* Server detection
* Request-Response protocol
* Streaming protocol
* Keep Alive protocol

Server detection uses UDP messaging, whereas Request/Response, Streaming and Keep Alive messages are exchanged over TCP connection. The TCP connection is denoted a Vomp channel in subsequent text.

Multiple clients are supported by the protocol as well as the Vomp server implementation.

Server detection
================

- client broadcasts UDP to Address 255.255.255.255. Source and destination ports are 3024. Payload is 4 octets "VOMP" = 0x56 0x4f 0x4d 0x50
- Server responds to Client Address UDP port 3024 (always regardless of source port in previous broadcast.) Payload is 12 octets containing server name. Padding is NULL.

NOTE!
Current Server (Version 0.3.0) does not support client and server on the same Linux
host because Server always replies to UDP port 3024, which is already bound to server. Solution is to respond to source UDP port.
Server patch:
      ds.send(ds.getFromIPA(),ds.getFromPort(), serverName, strlen(serverName));
instead of:
      ds.send(ds.getFromIPA(),3024, serverName, strlen(serverName));


- Client establishes a TCP connection to Server. Destination IP Address is taken from UDP Unicast packet from server. Destination TCP port is 3024.



Request-Response protocol
=========================

/* Packet format for a request:

4 bytes = Channel ID = 1 (Request/Response channel)
4 bytes = Request ID
4 bytes = Opcode
4 bytes = Length of the rest of the packet
? bytes = rest of packet. depends on packet
*/

Packet format for a Response:

4 bytes = channel ID = 1 (request/response channel)
4 bytes = request ID
4 bytes = length of the rest of the packet
? bytes = rest of packet. depends on packet


The following lists the functional capabilities of the request/response protocol

    Opcode
     1:     Verified
      Login();
      Login Request is 6 octets and contains the client MAC address
      Server responds with 4 octets Unix Time followed by 4 octets GMT offset in
      Unix Time.
     2: V
      GetRecordingsList();
      Response:
      ULONG DiskspaceTotal[MB]
      ULONG DiskspaceFree[MB]
      ULONG DiskSpaceUtilisation[%]
      List Recordings {
   ULONG StartTime [Unix time]
   String Name
   String Filename
   }
     3: V
      DeleteRecording();
      Request:
   String FileName
      Response:
   Reply ULONG { 4=recording_not_found, 3=recording_control_found,
      2=delete_failed,1=ok }
     5: V
      GetChannelsList();
      Request:
      Response:
      List Channel {
      ULONG Number
      ULONG Type (What is type ?)
      String Name
      }
     6:
      StartStreamingChannel();
      Start live TV streaming for Channel number.
   RequestId is used as handle for stream.
   The stream will contain a header according to specification of streaming
   protocol below.
      Request:
   ULONG channelNumber
      Response:
   Failure:
      ULONG 0
   Success:
      ULONG 1
     7:
      GetBlock();
      What is this for for ?
      Request:
   ULONG Position
   ULONG Amount
      Response:
   Failure:
      ULONG 0
   Success:
   Data Block
     8:
      StopStreaming();
      Stop current Streaming of Recording or Live TV .
      Request:
   -
      Response:
   ULONG 1
     9:
      StartStreamingRecording();
      Start Streaming of a recording identified by FileName.
      Request:
   String FileName
      Response:
   Success:
   Ulong LengthBytes
   ULONG LengthFrames
   Failure:
      NO response !
   
     10:
      GetChannelSchedule();
      Request:
   ULONG ChannelNumber
   ULONG StartTime
   ULONG Duration
      Response:
   Failure and no events found:
      Ulong 0
   List {
        ULONG   EventID
        ULONG   EventTime
        ULONG   EventDuration
        String  EventTitle
        String  EventSubTitle
        String  EventDescription
   }


     11:
      ConfigSave();
      Request:
   String Section
   String Key
   String Value
      Response:
   ULONG   { 1=ok, 0=error}
     12:
      ConfigLoad();
      Request:
   String Section
   String Key
      Response:
   Failure:
      Ulong 0
   Success:
      String Value
     13:
      ReScanRecording();
      This Opcode is Obsolete
     14: V
      GetTimers();
      Request:
      Response:
   ULONG   numTimers
   List Timers{
       ULONG   Active
       ULONG   Recording
       ULONG   Pending
       ULONG   Priority
       ULONG   Lifetime
       ULONG   ChannelNumber
       ULONG   StartTime
       ULONG   StopTime
       ULONG   Day
       ULONG   WeekDays
Weekdays;       bitmask, lowest bits: SSFTWTM  (the 'M' is the LSB)

       String   FileName
   }
     15: V
      SetTimer();
      Request:
   String "Flags Channel Day Start Stop, Priority, Lifetime FileName Aux
Flags: unsigned integer
enum eTimerFlags { tfNone      = 0,
                   tfActive    = 1,
                   tfInstant   = 2,
                   tfVps       = 4,
                   tfRecording = 8,
                   tfAll       = 65535,
                 };
Channel:
   integer|String
Day:
  // possible formats are:
  // 19
  // 2005-03-19
  // MTWTFSS
  // MTWTFSS@19
  // MTWTFSS@2005-03-19
Start,Stop HHMM Local time
Priority: 0-99
Lifetime: 0-99
Aux: String Optional ( What is this for? )

      Response:
   ULONG { 2=bad_timerstring, 1=timer_already_set, 0=ok}
     16:
      PositionFromFrameNumber();
      Request:
   ULONG frameNumber
      Response:
   Ulong Position (0 in case of failure)
     17:
      FrameNumberFromPosition()
      Request:
   ULONG Position
      Response:
   Ulong Frame (0 in case of failure)
     18:
      MoveRecording();
      Request:
      Response:
     19:
      GetIFrame();
      Request:
      ULONG frameNumber
      ULONG direction
      Response:
   Failure:
      Ulong 0
   Success:
      ULLONG filePosition
      ULONG frameNumber
      ULONG frameLength
   
     20:
      GetRecInfo();
      Request:
   String FileName
      Response:
   Failure:
      ULONG 0
   Success:
      ULONG   StartTime
      ULONG   StopTime
      ULONG   ResumePoint
      String   Summary
      ULONG   NumberOfChannels
      List Components {
           UCHAR   Stream
           UCHAR   Type
           String   Language
           String   Description
      }
     21:
      GetMarks();
      Request:
   String   FileName
      Response:
   Failure:
      ULONG 0
   Success:
   List Mark {
        ULONG   Position
   }
     22:
      GetChannelPids();
      Request:
   ULONG channelNumber
      Response:
   Failure:
      ULONG 0
   Success:
   ULONG vpid
   ULONG numberOfApids
   List {
        ULONG apid
        String language
   }
   ULONG numberOfDpids
   List {
        ULONG dpid
        String language
   }
   ULONG    numberOfSpids
   List {
        ULONG spid
        String language
        }
   ULONG   tpid
      
     23:
      DeleteTimer();
      Request:
   ULONG ChannelNumber
   ULONG Weekdays
   ULONG Day
   ULONG StartTime
   ULONG StopTime

      Response:
   ULONG { 10=ok,4=no_matching_timer, 3=unable_to_delete, 1=timers_being_edited }

   ULONG Position


Media protocol extensions
     30:
      GetMediaList();
  * media List Request:
  * 4 length
  * 4 VDR_GETMEDIALIST
  * 4 flags (currently unused)
  * n dirname
  * n+1 0
  * Media List response:
  * 4 length
  * 4 VDR_
  * 4 numentries
  * per entry:
  * 4 media type
  * 4 time stamp
  * 4 flags
  * 4 strlen (incl. 0 Byte)
  * string
  * 0
     31:
      GetPicture();
  * get image Request: = GetPicture
  * 4 flags (currently unused)
  * 4 x size
  * 4 y size
  * n filename
  * n+1 0
  * get image response:
  * 4 length
  * 4 VDR_GETIMAGE
  * 4 len of image

     32:
      GetImageBlock();
      Request:
   ULONG Position
   ULONG Amount
      Response:
   Failure:
      ULONG 0
   Success:
   Data Block
     33:
      GetLanguageList();
     34:
      GetLanguageContent();



Streaming protocol
=========================
Packet format for a stream packet:

4 bytes = Channel ID = 2 (stream channel)
4 bytes = Stream ID (from requestID)
4 bytes = Code ( 0 = stream, 1= stream_end)
4 bytes = Length of the stream data (=0 when stream_end)
? bytes = stream data


Keep Alive protocol
=========================
Keep Alive (KA) Channel:

Request:
4 bytes = Channel ID = 3
4 Bytes Timestamp

Response:
4 bytes = channel ID = 3
4 Bytes Timestamp ( Copied from request )





#17
I'm running Ubuntu and get the following compilation error:
Does anyone have a clue?

g++ -c -pipe -fpermissive -g -D_REENTRANT -Wall -W -DQT_SHARED -DQT_GUI_LIB -DQT_CORE_LIB -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I/usr/include/phonon -I/usr/include/qt4/QtNetwork -I../build/src -I. -o ../build/src/dlgaudioplayer.o dlgaudioplayer.cpp
In file included from vdr.h:31,
                 from vdrthread.h:25,
                 from dlgaudioplayer.h:35,
                 from dlgaudioplayer.cpp:22:
ringbuffer.h:339:23: warning: no newline at end of file
dlgaudioplayer.cpp: In member function \u2018void DLGAudioPlayer::setupActions()\u2019:
dlgaudioplayer.cpp:175: error: \u2018SP_MediaPlay\u2019 is not a member of \u2018QStyle\u2019
dlgaudioplayer.cpp:178: error: \u2018SP_MediaPause\u2019 is not a member of \u2018QStyle\u2019
dlgaudioplayer.cpp:181: error: \u2018SP_MediaStop\u2019 is not a member of \u2018QStyle\u2019
dlgaudioplayer.cpp:184: error: \u2018SP_MediaSkipForward\u2019 is not a member of \u2018QStyle\u2019
dlgaudioplayer.cpp:186: error: \u2018SP_MediaSkipBackward\u2019 is not a member of \u2018QStyle\u2019
#18
Quote from: muellerph on August 25, 2008, 18:05:20
Quote from: Chris on August 25, 2008, 17:14:36
Firstly, when I run it, it broadcasts for the server, but doesn't acknowledge any responses. IPTraf shows that responses are returning from the VDR server.

Are you running it on the same machine as a vdr instance is running? In this case, I know I had issues as the port was occupied, but didn't try to solve it (yet).
Otherwise I changed the way the server is search 3 weeks ago, made a short test and thought it is working (which may not be the general case).

Vomp clients may run on the same host as VDR server with the following Vomp server patch for udpreplier.c
      ds.send(ds.getFromIPA(),ds.getFromPort(), serverName, strlen(serverName));
instead of:
      ds.send(ds.getFromIPA(),3024, serverName, strlen(serverName));

The patch returns response to the source UDP address of the request for Vomp servers instead of always using 3024.


#19
VOMP General / MVP / Re: Vomp media player
November 28, 2007, 14:20:47

QuoteHow about setting up the UPNP protocol on the server plugin? Should also do the trick, but for sure a bit more tricky than on the client.
This would make traffic go from NAS to Media Server and from Media server to MVP. Wasting bandwidth, but maybe functional on 100Mb network.
Another solution would be to run a Media server and UPNP client on localhost. But I guess the Vomp does not support multiple Media servers?

QuoteVomp client doesn't do any NFS or similar things. Vomp client gets the data directly from the serverplug-in within an own protocol (binary for sure, the client needs to be highly efficient). The server plugin gets the data from the local FS, which could for sure be a mounted NFS directory.
This avoids having a full blown UPNP implementation on the client.
Are you sure there is not multiple protocols, like a telnet/text based protocol for listing media files and a binary protocol for the actual media access?
I believe I have seen a telnet interface in the Vomp code!

QuoteBut for sure, some code exists already for the MVPMC project (MythTV as server). Similar project, but different codebase. Only some structures are equal.
There are pro's and cons when comparing the two. I would prefer to use one of them. Since I've good experience in using Vomp, the Media player functionality adds momentum to the Vomp solution!

QuoteTill some months ago, we couldn't use UPNP because of the kernel/compiler dependencies, which is now solved (but still patches are needed for the kernel AFAIK). So basically if you want to have a look into code merge from MVPMC there is a starting point.
OK! I will look in to it, but I doubt I will have time to conclude anything useful

QuoteCode:
The client has a lot of sourcecode, but not the server. As the server is one side of the protocol, it's much easier to look at and find the relevant things.
I don't think it's too much to read and understand (but for sure I didn't do that yet in detail - I'm not working with the protocol stuff).
OK Thanks!
#20
VOMP General / MVP / Re: Vomp media player
November 28, 2007, 09:34:50
Quote from: avvdr on November 27, 2007, 20:14:47

Quotehmm - what would be the use case for it?
One good thing about UPNP is that it is a standard. By using a standard protocol between Set-top box and the server one could use the set-top box without
the need for set-top box specific components on the server.
With the support for UPNP on the Vomp I could use my NAS (Qnap TS-109) as media server without doing anyting on the NAS.
UPNP with its' support for advertising Media servers in the network adds additional flexibility. The Vomp would be able to find several Media servers in the network without the need for configuration of servers' IP addresses. For exampe the NAS could provide my own made films and a MythTV server or VDR the TV shows.

Quotevomp has an own limited - but very functional, stable and fast GUI application. How should the UPnP fit into this?
I got the impression that the Vomp Media player browsed a file system (NFS mounted or locally stored)
If it was then djmount would have made it transparent to Vomp whether UPNP was used or not, since the interface to djmount is the file system.


QuoteWhat I'm currently thinking about is to make a small standalone server part (already available in a firts version in the latest patches), that only contains the media player (server) functions and can run without VDR (I've got a DS101j NAS and my goal is to have the server running on this one in the future). So my alternative is:
Compile the server part for your device that has the data (even windows should not be to difficult) - and use VOMP as it is.
Nice, but then I need to dig into how to add new software to the TS-109, which is supported by NSLUG2 so it is doable.
When I bought my NAS I had the ambition to stay away tweaking it and just use it as it is, since it stores my valuable private films and fotos.


QuoteFor the protocol there is not much description there (utf-rts ;) )
If you have any question - just try to ask them here - lots of people will answer...
Of course the code is there to find out the details. It would be interesting to know high level  information about the protocol, like if it is a binary or a textal protol. TCP or UDP, etc. without digging in to the code.

Regards
Anders
#21
VOMP General / MVP / Re: Vomp media player
November 26, 2007, 09:17:18
Hi,

The new Media Player functionality is a nice enhancement to the Vomp. It would be nice to be able to use UPNP together with the Vomp.
Is it somehow possible to unpack a dongle so that I can add fusermount/djmount from MVPmc and pack it again?


I would also like to look into the design of Vomp/VDR, are there any good links describing the design, especially the protocol between VDR and VOMP?

Best regards and thanks for the Vomp
Anders