<?xml version="1.0"?>

<!-- $Id$
  -
  -->

<xsd:schema
  targetNamespace="http://www.ibr.cs.tu-bs.de/chat-message"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns="http://www.ibr.cs.tu-bs.de/chat-message"
  elementFormDefault="qualified"
  attributeFormDefault="unqualified"
  xml:lang="en">

  <xsd:annotation>
    <xsd:documentation>
      This XML Schema defines the p2p-chat protocol messages.
    </xsd:documentation>
  </xsd:annotation>

  <!--
    -                              Types
    -->

  <xsd:simpleType name="UserIDType">
    <xsd:annotation>
      <xsd:documentation>
        Elements of this type represent a globally unique user
        identification. It has to contain a user name part followed by
        an @ character and a domain part. It is highly recommended to
        use the users valid Internet email address.  Note that it has
        to be treated case-insensitive.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="[a-zA-Z0-9_\.\-]{1,127}@[a-zA-Z0-9_\.\-]{1,128}"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="MessageIDType">
    <xsd:annotation>
      <xsd:documentation>
        Elements of this type are used to form a unique identification
        for messages per user. The pair of a UserID and a MessageID
        builds a globally unique message identification. How the
        MessageID is actually built is an implementation issue. It
        might be a persistent counter incremented with each message
        generation, or it might be based on a timestamp, for example.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="[a-zA-Z0-9@_\.\-]{1,256}"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="ChannelIDType">
    <xsd:annotation>
      <xsd:documentation>
        Elements of this type are used to form a unique identification
        for channels. The pair of a channel name and a channelID
        builds a globally unique channel identification. How the
        channelID is actually built is an implementation issue. The
        channelID MUST differ from other known IDs. Is consists of two
        parts sperarated by an "@". The first part SHOULD be
        generated randomly on the basis of UUIDs. The second part is
        the name of the local host.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="[a-zA-Z0-9_\.\-]{1,127}@[a-zA-Z0-9_\.\-]{1,128}"/>
    </xsd:restriction>
  </xsd:simpleType>


  <xsd:simpleType name="TTLType">
    <xsd:annotation>
      <xsd:documentation>
        An integer time-to-live value. Note that the value range is
        restricted.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:int">
      <xsd:minInclusive value="1"/>
      <xsd:maxInclusive value="360"/>
   </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="ChannelNameType">
    <xsd:annotation>
      <xsd:documentation>
        The name of a channel.  Note that it has to be treated
        case-insensitive. The name "Anonymous" is reserved for the
        anonymous channel and MUST NOT be used for other channels.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="[a-zA-Z0-9_\.\-]{1,16}"/>
    </xsd:restriction>
  </xsd:simpleType>


  <xsd:complexType name="DestinationType">
    <xsd:annotation>
      <xsd:documentation>
        A destination is part of a routing message. It signals
	the number of hops to reach a user via the link on which
	the routing message is sent.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="user" type="UserIDType"/>
      <xsd:element name="hops" type="xsd:unsignedInt"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="CertificateType">
    <xsd:annotation>
      <xsd:documentation>
        A certificate consists of the user ID to which the certificate
        belongs and the certificate itself encoded in Base64.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="user" type="UserIDType"/>
      <xsd:element name="data" type="xsd:base64Binary"/>
    </xsd:sequence>
  </xsd:complexType>



  <xsd:complexType name="AttachmentType">
    <xsd:annotation>
      <xsd:documentation>
        A message attachment. The applicationtype states the MIME Type
        of the attached file.
        The application data MUST always be Base64 encoded.
        If the iv attribute is present,
	it is a message of a closed channel and uses the
	initialization
	vector given by the iv attribute. The content of all elements
	MUST be de-/encrypted individually.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="filename" type="xsd:string"/>
      <xsd:element name="applicationtype" type="xsd:string"/>
      <xsd:element name="data" type="xsd:base64Binary"/>
    </xsd:sequence>
    <xsd:attribute name="iv" type="xsd:base64Binary"/>
  </xsd:complexType>


  <xsd:simpleType name="CipherType">
    <xsd:annotation>
      <xsd:documentation>
        A label to identify a symmetric cipher algorithm.  So far,
        just one (reasonable) cipher is defined, but others may be
        added in future revision of the protocol.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="NONE">
        <xsd:annotation>
          <xsd:documentation>
            No encryption.
          </xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
      <xsd:enumeration value="DES-CBC">
        <xsd:annotation>
          <xsd:documentation>
            64(56) bit DES in Cipher Block Chaining mode with PKCS #5
	    padding.
          </xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="SignType">
    <xsd:annotation>
      <xsd:documentation>
        A label to identify a message digest algorithm.  So far, just
        one algorithm is defined, but others may be added in future
        revision of the protocol.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:NMTOKEN">
      <xsd:enumeration value="MD5">
        <xsd:annotation>
          <xsd:documentation>
            MD5 digest (encrypted with the senders private key).
          </xsd:documentation>
        </xsd:annotation>
      </xsd:enumeration>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="SignatureType">
    <xsd:annotation>
      <xsd:documentation>
        A Base64 encoded signature. It is calculated for the
        concatenated UTF-8 encoded values (without attributes) of all
        child elements of the chat-message element in depth-first
        order.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:base64Binary"/>
  </xsd:simpleType>




  <!--
    -                   Root Element and Message Types
    -->

  <xsd:element name="chat-message" type="ChatMessage"/>

  <xsd:complexType name="ChatMessage">
    <xsd:annotation>
      <xsd:documentation>
        This element represents a p2p-chat protocol
        message.
      </xsd:documentation>
    </xsd:annotation>
      <xsd:sequence>
        <xsd:choice>
          <xsd:element name="hello"          type="HelloMessage"/>
          <xsd:element name="ack"            type="AckMessage"/>
          <xsd:element name="nack"           type="NackMessage"/>
          <xsd:element name="channel"        type="ChannelMessage"/>
          <xsd:element name="join"           type="JoinMessage"/>
          <xsd:element name="leave"          type="LeaveMessage"/>
          <xsd:element name="getcertificate"
          type="GetCertificateMessage"/>
          <xsd:element name="certificate"
          type="CertificateMessage"/>
          <xsd:element name="getkey"         type="GetKeyMessage"/>
          <xsd:element name="key"            type="KeyMessage"/>
          <xsd:element name="routing"        type="RoutingMessage"/>
          <xsd:element name="message"        type="MessageMessage"/>
          <xsd:element name="obscure"        type="ObscureMessage"/>
        </xsd:choice>
      </xsd:sequence>
      <xsd:attribute name="ttl"        type="TTLType"
      default="1"/>
      <xsd:attribute name="delay"      type="xsd:int"
      default="0"/>
      <xsd:attribute name="flood"      type="xsd:boolean"
      default="false"/>
      <xsd:attribute name="signtype"   type="SignType"/>
      <xsd:attribute name="signature"  type="SignatureType"/>
  </xsd:complexType>

  <xsd:complexType name="HelloMessage">
    <xsd:annotation>
      <xsd:documentation>
        The "hello" message is the first message sent by each peer of
        a newly established connection. The peer may send an informal
        greeting text. A HELLO message MAY contain more than one sender
        if a node serves more than one user.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="sender"    type="UserIDType"
        minOccurs="1" maxOccurs="unbounded"/>
      <xsd:element name="messageid" type="MessageIDType"/>
      <xsd:element name="version"   type="xsd:int"/>
      <xsd:element name="greeting"  type="xsd:string" minOccurs="0"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="AckMessage">
    <xsd:annotation>
      <xsd:documentation>
        The "ack" message is sent by a peer that receives a
        multicasted
        message from another peer in order to inform the sender that
        this message reached the next hop. It always includes the ID
        of the received message.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="sender"    type="UserIDType"/>
      <xsd:element name="messageid" type="MessageIDType"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="NackMessage">
    <xsd:annotation>
      <xsd:documentation>
        The "Nack" message is sent by a peer that receives a
        multicasted
        message from another peer and is not able to forward it
        towards its destination. The "Nack" message is always sent to
        the original source of that message and informs the sender
        that its message has not received its destination. The
        original message has to be attached to the "Nack".
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="sender"    type="UserIDType"/>
      <xsd:element name="messageid" type="MessageIDType"/>
      <xsd:element name="message"   type="ChatMessage"/>
    </xsd:sequence>
  </xsd:complexType>


  <xsd:complexType name="ChannelMessage">
    <xsd:annotation>
      <xsd:documentation>
        The "channel" message announces an active channel. The
	"closed" flag denotes whether it is a closed channel.
	Each known subscriber is listed in a "member" child element.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="sender"        type="UserIDType"/>
      <xsd:element name="messageid"     type="MessageIDType"/>
      <xsd:element name="channel"       type="ChannelNameType"/>
      <xsd:element name="channelid"     type="ChannelIDType"/>
      <xsd:element name="description"   type="xsd:string"/>
      <xsd:element name="member"        type="UserIDType"
        minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attribute name="closed"        type="xsd:boolean"
    default="false"/>
  </xsd:complexType>

  <xsd:complexType name="JoinMessage">
    <xsd:annotation>
      <xsd:documentation>
	The "join" message signal the subscription of a user to
	a non-closed channel.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="sender"        type="UserIDType"/>
      <xsd:element name="messageid"     type="MessageIDType"/>
      <xsd:element name="channel"       type="ChannelNameType"/>
      <xsd:element name="channelid"     type="ChannelIDType"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="LeaveMessage">
    <xsd:annotation>
      <xsd:documentation>
	The "leave" message signal the unsubscription of a user from
	a non-closed channel.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="sender"        type="UserIDType"/>
      <xsd:element name="messageid"     type="MessageIDType"/>
      <xsd:element name="channel"       type="ChannelNameType"/>
      <xsd:element name="channelid"     type="ChannelIDType"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="GetCertificateMessage">
    <xsd:annotation>
      <xsd:documentation>
        A node may send a "getcertificate" message to request a
        certificate for a given user ID.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="sender"    type="UserIDType"/>
      <xsd:element name="receiver"  type="UserIDType"/>
      <xsd:element name="messageid" type="MessageIDType"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="CertificateMessage">
    <xsd:annotation>
      <xsd:documentation>
        A node can send a certificate encapsulated in
        a "certificate" message. It's not only the owner of
        the certificate who can send such a message.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="sender"      type="UserIDType"/>
      <xsd:element name="receiver"    type="UserIDType"
        minOccurs="0" maxOccurs="unbounded"/>
      <xsd:element name="messageid"   type="MessageIDType"/>
      <xsd:element name="certificate" type="CertificateType"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="GetKeyMessage">
    <xsd:annotation>
      <xsd:documentation>
        A node may request a channel key for a given closed channel
        through a "getkey" message.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="sender"      type="UserIDType"/>
      <xsd:element name="receiver"    type="UserIDType"/>
      <xsd:element name="messageid"   type="MessageIDType"/>
      <xsd:element name="channel"     type="ChannelNameType"/>
      <xsd:element name="channelid"     type="ChannelIDType"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="KeyMessage">
    <xsd:annotation>
      <xsd:documentation>
        A node can send a channel key encapsulated in a "key"
        message. The actual data part of the key has to be encrypted
        with the according receiver's public key. It is the duty of
        the sender of a "key" message to ensure that the public key
        really belongs to the receiver and that the receiver is
        really a member of the channel.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="sender"    type="UserIDType"/>
      <xsd:element name="receiver"  type="UserIDType"/>
      <xsd:element name="messageid" type="MessageIDType"/>
      <xsd:element name="channel"   type="ChannelNameType"/>
      <xsd:element name="channelid"     type="ChannelIDType"/>
      <xsd:element name="cipher"    type="CipherType"/>
      <xsd:element name="key"       type="xsd:base64Binary"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="RoutingMessage">
    <xsd:annotation>
      <xsd:documentation>
        Routing messages are exchanged on links to form a converging
        knowledge on the network topology on every node.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="messageid"   type="MessageIDType"/>
      <xsd:element name="destination" type="DestinationType"
        minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="MessageMessage">
    <xsd:annotation>
      <xsd:documentation>
        The "message" message carries the actual content of the chat
        message in its text element. If the iv attribute is present
	it is a message of a closed channel and uses the
	initialization
	vector given by the iv attribute.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="sender"    type="UserIDType"
        minOccurs="0"/>
      <xsd:element name="receiver"  type="UserIDType"
        minOccurs="0" maxOccurs="unbounded"/>
      <xsd:element name="messageid" type="MessageIDType"
        minOccurs="0"/>
      <xsd:element name="timestamp" type="xsd:dateTime"/>
      <xsd:element name="channel"   type="ChannelNameType"
        minOccurs="0"/>
      <xsd:element name="channelid"   type="ChannelIDType"
        minOccurs="0"/>
      <xsd:element name="text">
        <xsd:complexType>
          <xsd:simpleContent>
            <xsd:extension base="xsd:string">
              <xsd:attribute name="iv" type="xsd:base64Binary"/>
            </xsd:extension>
          </xsd:simpleContent>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="attachment" type="AttachmentType"
      minOccurs="0" maxOccurs="unbounded"/>
      </xsd:sequence>
  </xsd:complexType>

  <xsd:complexType name="ObscureMessage">
    <xsd:annotation>
      <xsd:documentation>
        The "obscure" is created by a user who intends to emit a
        "message" message but remain anonymous as the sender of the
	message. The "text" payload is in turn an "obscure" message
	or a "message" message after decryption.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="receiver"  type="UserIDType" />
      <xsd:element name="messageid" type="MessageIDType"
        minOccurs="0"/>
      <xsd:element name="text"	    type="xsd:string" />
    </xsd:sequence>
  </xsd:complexType>


</xsd:schema>








