XB Media Streaming Protocol (XBMSP)
-----------------------------------


Abstract
--------

This document describes a simplistic protocol that can be used in
accessing files through network.  Protocol is aimed for media player
applications and it only provides read access to the data provided by
the server.  Protocol runs on top of a reliable stream media
(e.g. TCP/IP) and does not provide error recognition or recovery by
itself.  Protocol is generic in nature and it does not have any
dependencies to actual target architecture.


Basic Description of the Protocol
---------------------------------

This protocol defines version 1.0 of the XBMSP protocol.

Typical protocol session goes like this:

1) Client opens the protocol connection.

2) Server sends protocol identification string containing information
   on what protocol versions it supports.  E.g. string 
   "XBMSP-2.0 2.0,1.2,1.1 Xyzzy Media Server 5.0\n" would mean that
   server application is Xyzzy Media Server 5.0 that speaks XBMSP
   version 2.0 but can also be used by clients using protocol versions
   1.2, or 1.1.  Usual protocol identification string for 1.0 servers
   might be "XBMSP-1.0 1.0 Media Server 1.0.1\n".  Notice that version
   number 1.0.1 in the string has no significance towards the
   protocol. 


3) Client sends a protocol identification response string with
   selected protocol version.  E.g. protocol initiation with string 
   "XBMSP-2.0 FooBar Media Player 42.0\n" would mean that client is
   going to use protocol version 2.0 while talking to the server and
   expects replies also using the same protocol version.  The client
   in question in this case would be FooBar Media Player 42.0.  Usual
   protocol identification response string for version 1.0 client
   might be "XBMSP-1.0 Media Player 1.0.2\n".  Notice that version
   number 1.0.2 in the string has no significance towards the
   protocol. 

4) After this, protocol enters into protocol version specific main 
   protocol mode.  In XBSMP version 1.0, all messaging in this phase,
   which is actually the rest of the session, is client driven.
   Each message sent by the client is answered by excatly one
   message sent by the server.  Protocol is asynchronous so that
   client can send multiple commands to the server without waiting for
   response to the previous message before sending another one.

5) Connection can be terminated by the client or server simply by
   disconnecting the connection (e.g. TCP connection).


Protocol Message Format
-----------------------

Protocol is defined as a purely binary messages.  This makes the
parsing of the messages easy and efficient.  All messages are of
following format:


  |        |  |        |                          |
  +--------+--+--------+--------------------------+
   msg-len type   id     message specific payload


The length of fields msg-len and id is 32 bits (4 bytes) each.  Type
field is 8 bits (one byte).  Message specific payload is of optional
length and can contain fields defined in individual message
description.

Protocol messages in this document are described using data types
below:

  byte   -  8 bits (one byte) of data

  int32  -  32 bit unsigned integer (4 bytes) in most significant byte
            first order

  int64  -  64 bit unsigned integer (8 bytes) in most significant byte
            first order (equal to two int32s with the first one
            holding the most significant 32 bits of the integer and
            the second one holding the least significant 32 bits of
            the integer

  string -  int32 with length of the string payload followed by the
            payload of the string (payload is not null terminated)

  data   -  unspecified data with undetermined length (can be only the
            last part of the packet in order to parse correctly)

The format of the message in this notation is then:

  int32     length of the message (excluding the length field itself)
  byte      type of the message
  int32     message id that is selected by the client so that server
            uses the same message id in its response packet
  data      packet specific payload



Packet Types
------------

Client sends packets of following types:

  #define XBMSP_PACKET_NULL                      10
  #define XBMSP_PACKET_SETCWD                    11
  #define XBMSP_PACKET_FILELIST_OPEN             12
  #define XBMSP_PACKET_FILELIST_READ             13
  #define XBMSP_PACKET_FILE_INFO                 14
  #define XBMSP_PACKET_FILE_OPEN                 15
  #define XBMSP_PACKET_FILE_READ                 16
  #define XBMSP_PACKET_FILE_SEEK                 17
  #define XBMSP_PACKET_CLOSE                     18
  #define XBMSP_PACKET_CLOSE_ALL                 19
  #define XBMSP_PACKET_SET_CONFIGURATION_OPTION  20
  #define XBMSP_PACKET_AUTHENTICATION_INIT       21
  #define XBMSP_PACKET_AUTHENTICATE              22
  #define XBMSP_PACKET_UPCWD                     23

Server sends packets of following types:

  #define XBMSP_PACKET_OK                         1
  #define XBMSP_PACKET_ERROR                      2
  #define XBMSP_PACKET_HANDLE                     3
  #define XBMSP_PACKET_FILE_DATA                  4
  #define XBMSP_PACKET_FILE_CONTENTS              5
  #define XBMSP_PACKET_AUTHENTICATION_CONTINUE    6

Server discovery protocol consists of following packet types: 

  #define XBMSP_PACKET_SERVER_DISCOVERY_QUERY    90
  #define XBMSP_PACKET_SERVER_DISCOVERY_REPLY    91


Message Id
----------

Most of the protocol packets contain a message id field.  The purpose
of the field is to tie together the client message with the
corresponding reply packet.  Message id numbers 0x00000000 and
0xffffffff are reserved and must not be used unless particularly
specified in the protocol documentation.


XBMSP_PACKET_NULL
-----------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_NULL
  int32     message id that is selected by the client
  data      optional data that is ignored by the server

Server responds always with packet XBMSP_PACKET_OK with the same id.
No other action is taken in the server side.


XBMSP_PACKET_SETCWD
-------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_SETCWD
  int32     message id that is selected by the client
  string    directory name

Set current working directory to directory `directory name'.
Following directory names have predetermined meaning:

  (empty)   current directory (zero length string, not string 
            saying "(empty)") 

Server may interpret following directory names in the following way:

  /         root directory of the server
  .         current working directory itself
  ..        the parent directory of the current directory

If other directory name is used, it should be identical to one that
would be returned by command XBMSP_PACKET_FILELIST_READ.  Only single
directory element can be present in XBMSP_PACKET_SETCWD packet.
Navigating to more complex path (e.g. foo/bar/zap) must be performed
with multiple XBMSP_PACKET_SETCWD commands.

XBMSP_PACKET_OK is returned if call is succesful, otherwise
XBMSP_PACKET_ERROR is returned.


XBMSP_PACKET_UPCWD
------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_UPCWD
  int32     message id that is selected by the client
  int32     number of levels (0 = no-op, 0xffffffff = go to root)

Move number of levels up in the directory hierarchy.  If number of
levels given in the packet is greater than the depth of the current
working directory, then go to root directory.

XBMSP_PACKET_OK is returned if call is succesful, otherwise
XBMSP_PACKET_ERROR is returned.


XBMSP_PACKET_FILELIST_OPEN
--------------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_FILELIST_OPEN
  int32     message id that is selected by the client

Open the filelist in current working directory.  Server returns
packet XBMSP_PACKET_HANDLE containing file handle that can be used in
subsequent XBMSP_PACKET_FILELIST_READ calls.


XBMSP_PACKET_FILELIST_READ
--------------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_FILELIST_READ
  int32     message id that is selected by the client
  int32     directory handle that was returned to
            XBMSP_PACKET_FILELIST_OPEN command

Read single entry in the opened filelist.  Server returns with packet
XBMSP_PACKET_FILE_DATA that has file list entry information.

File Data is in XML format.  If the packet data contains empty
filename and zero length data, there are no more entries available in
the directory and directory handle is automatically invalidated by the
server.  Client can terminate the directory enumeration even before
receiving the empty file data by sending XBMSP_PACKET_CLOSE or
XBMSP_PACKET_CLOSE_ALL packet.


XBMSP_PACKET_FILE_INFO
----------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_FILE_INFO
  int32     message id that is selected by the client
  string    file (or directory) name

Server returns information of the file entry in packet
XBMSP_PACKET_FILE_DATA.  File information field is in XML format.


XBMSP_PACKET_FILE_OPEN
----------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_FILE_OPEN
  int32     message id that is selected by the client
  string    file name

Server opens the file and returns file handle that can be used in
subsequent XBMSP_PACKET_FILE_READ and XBMSP_PACKET_FILE_SEEK
commands. 


XBMSP_PACKET_FILE_READ
----------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_FILE_READ
  int32     message id that is selected by the client
  int32     file handle that was returned to XBMSP_PACKET_FILE_OPEN
  int32     length

Server reads at most length bytes from the file.  If end of file is
reached, read can be truncated (or even 0 length).  File is not
automatically closed even in the case of eof.

Data is returned in packet XBMSP_PACKET_FILE_CONTENTS with raw file
contents.


XBMSP_PACKET_FILE_SEEK
----------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_FILE_SEEK
  int32     message id that is selected by the client
  int32     file handle that was returned to XBMSP_PACKET_FILE_OPEN
  byte      seek type (0 = forward from the beginning of the file,
                       1 = backward from the end of the file,
                       2 = forward from the current position,
                       3 = backwards from the current position)
  int64     offset

Server seeks the file according to the parameters.  XBMSP_PACKET_OK is
returned if call is succesful, otherwise XBMSP_PACKET_ERROR is
returned. 


XBMSP_PACKET_CLOSE
------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_CLOSE
  int32     message id that is selected by the client
  int32     file or file list handle

Server closes file or file list denoted by the handle and invalidates
the handle.  Server responds with packet XBMSP_PACKET_OK with the
same id if the operation was succesful.  Packet XBMSP_PACKET_ERROR is
sent in case of error (e.g. invalid handle).


XBMSP_PACKET_CLOSE_ALL
----------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_FILE_CLOSE_ALL
  int32     message id that is selected by the client

Server closes all open files, filelists, and authentication sessions
and invalidates the corresponding handles.  Server responds always
with packet XBMSP_PACKET_OK with the same id. 


XBMSP_PACKET_SET_CONFIGURATION_OPTION
-------------------------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_SET_CONFIGURATION_OPTION
  int32     message id that is selected by the client
  string    configuration option name
  string    new value for the configuration option

Server responds with packet XBMSP_PACKET_OK with the
same id if the operation was succesful.  Packet XBMSP_PACKET_ERROR is
sent in case of error (e.g. invalid option name or non-configurable
option)


XBMSP_PACKET_AUTHENTICATION_INIT
--------------------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_AUTHENTICATION_INIT
  int32     message id that is selected by the client
  string    authentication method (e.g. "password")

Server responds with packet XBMSP_PACKET_HANDLE if authentication
session can begin or with XBMSP_PACKET_ERROR if authentication method
is unsupported or too many authentication sessions (usually > 0) is
already open.


XBMSP_PACKET_AUTHENTICATE
-------------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_AUTHENTICATE
  int32     message id that is selected by the client
  int32     file handle that was returned to
            XBMSP_PACKET_AUTHENTICATION_INIT
  data      authentication method dependent data

Server responds with XBMSP_PACKET_OK if authentication is complete and
succesful, or with XBMSP_PACKET_ERROR if authentication was failed.
These both responses invalidate the authentication handle.  If server
responds with packet XBMSP_PACKET_AUTHENTICATION_CONTINUE, it means
that authentication is still imcomplete and client should continue
authentication dialog by sending another XBMSP_PACKET_AUTHENTICATE
packet.  Client can abort incomplete authentication dialog by sending
XBMSP_PACKET_CLOSE or XBMSP_PACKET_CLOSE_ALL packet.


Server Response Packet Types
----------------------------

  #define XBMSP_PACKET_OK                        1
  #define XBMSP_PACKET_ERROR                     2
  #define XBMSP_PACKET_HANDLE                    3
  #define XBMSP_PACKET_FILE_DATA                 4
  #define XBMSP_PACKET_FILE_CONTENTS             5
  #define XBMSP_PACKET_AUTHENTICATION_CONTINUE   6


XBMSP_PACKET_OK
---------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_OK
  int32     message id that is selected by the client


XBMSP_PACKET_ERROR
------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_ERROR
  int32     message id that is selected by the client
  byte      error code
  string    error string (can be empty)


XBMSP_PACKET_HANDLE
-------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_HANDLE
  int32     message id that is selected by the client
  int32     handle

  Error codes are:

  #define XBMSP_ERROR_OK                        0 /* Reserved */
  #define XBMSP_ERROR_FAILURE                   1
  #define XBMSP_ERROR_UNSUPPORTED               2
  #define XBMSP_ERROR_NO_SUCH_FILE              3
  #define XBMSP_ERROR_INVALID_FILE              4
  #define XBMSP_ERROR_INVALID_HANDLE            5
  #define XBMSP_ERROR_OPEN_FAILED               6
  #define XBMSP_ERROR_TOO_MANY_OPEN_FILES       7
  #define XBMSP_ERROR_TOO_LONG_READ             8
  #define XBMSP_ERROR_ILLEGAL_SEEK              9
  #define XBMSP_ERROR_OPTION_IS_READ_ONLY       10
  #define XBMSP_ERROR_INVALID_OPTION_VALUE      11
  #define XBMSP_ERROR_AUTHENTICATION_NEEDED     12
  #define XBMSP_ERROR_AUTHENTICATION_FAILED     13


XBMSP_PACKET_FILE_DATA
----------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_DATA
  int32     message id that is selected by the client
  string    file (or directory) name
  string    file data


XBMSP_PACKET_FILE_CONTENTS
--------------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_DATA
  int32     message id that is selected by the client
  string    data read from the file


XBMSP_PACKET_AUTHENTICATION_CONTINUE
------------------------------------

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_AUTHENTICATION_CONTINUE
  int32     message id that is selected by the client
  data      authentication method dependent data


Authentication Dialog
---------------------

Generic authentication dialog can be described as a following state
machine.  C(x) is a packet sent by the client and S(x) is a packet
sent by the server.  Final state Y means that authentication was
succesful and N means that authentication was failed.

 
                     C(AUTHENTICATION_INIT)
                              |
                              |
                        +-----+-----+ 
                        |           |
                    S(HANDLE)    S(ERROR)
                        |           |
                        |           |
                        |           N
                        |
                        +<------------------------------------+
                        |                                     |
                        |                                     |
       +----------------+                                     |
       |                |                                     |
       |                |                                     |
    C(CLOSE)     C(AUTHENTICATE)                              |
       |                |                                     |
       |                |                                     |
       |      +---------+------------------+                  |
       |      |         |                  |                  |
       |     S(OK)   S(ERROR)    S(AUTHENTICATION_CONTINUE)   |
       |      |         |                  |                  |
       |      |         |                  |                  |
       N      Y         N                  +------------------+


Password Authentication Method
------------------------------

Currently only a simple password authentication method is defined.
Password authentication is done as follows:

   - Client sends XBMSP_PACKET_AUTHENTICATION_INIT packet
     with authentication type "password".
   - Server responds with XBMSP_PACKET_HANDLE
   - Client sends XBSMP_PACKET_AUTHENTICATE with following
     fields in the authentication method specific data:

        string    user id (e.g. "xbox" or "puhpuh"; can be empty)
        string    password (can be empty)

   - Server responds with XBSMP_PACKET_OK or XBSMP_PACKET_ERROR


XBMSP Server Discovery Protocol (XBSDP)
---------------------------------------

A client can attempt to discover XBMSP servers in the local network
by sending UDP datagrams into the network.  The method is currently
only defined in IP network environment.

Discovery queries are sent to UDP port 1400 (default XBMSP port is
TCP/1400).  Even though this datagram protocol is not part of XBMSP
the format of the messages are defined in a compatible way.

The server discovery is initiated by the client with a broadcast
datagram of following format:

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_SERVER_DISCOVERY_QUERY
  int32     message id that is selected by the client
  string    client version string (like in XBMSP session but with
            default protocol version value and without newline in the
            end of the string)

The server that supports and is configured to allow automatic
discovery, replies with a datagram of following format:

  int32     length of the message (excluding the length field itself)
  byte      XBMSP_PACKET_SERVER_DISCOVERY_REPLY
  int32     message id that was in XBMSP_PACKET_SERVER_DISCOVERY_QUERY
  string    server listen address (server address is a printable
            string containing an ip address or an empty string)
  string    server listen port (port number as a printable string or
            an empty string)
  string    server version string (like in XBMSP session but without
            newline in the end of the string)
  string    server comment string (can be an empty string)

Server listen address may be an empty string.  In this case the client
should determine the server address from the source address of the
reply datagram.  Server listen port may also be empty indicating that
server is listening the same (TCP) port number that was the (UDP) port
number of the reply datagram.

In a local network there can be ``name server'' hosts that reply to the
automatic server query by multiple datagrams and thereby enumerate the
list of XBMSP servers.

A server can also send XBMSP_PACKET_SERVER_DISCOVERY_REPLY packets to
the local network (broadcast or unicast) without first receiving
XBMSP_PACKET_SERVER_DISCOVERY_QUERY packet.  Message id field in such
packet must be zero (0).  This message must not be answered.  Another
server (or dedicated service locator server) can store the information
about the server and relay the information when a client searches
servers with XBMSP_PACKET_SERVER_DISCOVERY_QUERY packet.  This is
especially useful when the server itself can't listen the broadcast
port and is running in nonstandard TCP-port.


Using of XBMSP and XBSDP in IP Network
--------------------------------------

XBMSP is generic in nature and is not at all limited to IP networks.
However it is very suitable to be used over TCP/IP connection.  In
this use, the default TCP port the XBMSP server uses is port number
TCP/1400.

XBSDP is more IP specific protocol.  It uses UDP/IP datagrams and the
default port the server listens is UDP/1400.

The protocols can be used with and IPv4 and IPv6 unmodified.  However,
the implementations don't necessarily support IPv6.


Security Considerations
-----------------------

The protocol itself provides only a authentication method framework
and not any kind of confidentiality protection.  Security can however
be easily added to the protocol either by wrapping the stream into
secure transport stream (such as TLS) or defining security extensions
such as password authentication and/or cryptographic key exchange and
encrypted data stream.

The directory traversing model provided by the protocol, in which
single SETCWD command can only traverse one level in the directory
hierarchy (or go to the root directory) is intentional.  In this
model, it is quite easy to enforce boundaries of the data directory
in the server side, because client given pathnames don't have to be
parsed.  It also minimizes the need for reserved characters in the
names of the directory entries (i.e. file and directory names).


Copyright
---------

Copyright (C) 2002 by PuhPuh, All Rights Reserved.  Permission to use
this protocol for any purpose is hereby granted.
