<?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="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="32"/>
   </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.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="[a-zA-Z0-9_\.\-]{1,16}"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="DomainNameType">
    <xsd:annotation>
      <xsd:documentation>
        A fully qualified domain name of a listening endpoint.
        Note that it has to be treated case-insensitive.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string"/>
  </xsd:simpleType>

  <xsd:simpleType name="IPv4AddressType">
    <xsd:annotation>
      <xsd:documentation>
        An IPv4 address of a listening endpoint.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
      <xsd:pattern value="[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"/>
    </xsd:restriction>
  </xsd:simpleType>

  <xsd:simpleType name="PortNumberType">
    <xsd:annotation>
      <xsd:documentation>
        A TCP port number of a listening endpoint.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:int">
      <xsd:minInclusive value="1"/>
      <xsd:maxInclusive value="65535"/>
   </xsd:restriction>
  </xsd:simpleType>

  <xsd:complexType name="PeerAddressType">
    <xsd:annotation>
      <xsd:documentation>
        A peer address consists of a hostname (or if a hostname
        is not available, an IPv4 address) and a TCP port number.
        This pair specifies a potential listening peer endpoint
        to which other peers might try to connect.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:choice>
        <xsd:element name="hostname" type="DomainNameType"/>
        <xsd:element name="ipaddress" type="IPv4AddressType"/>
      </xsd:choice>
      <xsd:element name="port" type="PortNumberType"/>
    </xsd:sequence>
  </xsd:complexType>

  <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: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">
    <xsd:annotation>
      <xsd:documentation>
        This is the root element. It represents a p2p-chat protocol
        message.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:complexType>
      <xsd:sequence>
        <xsd:choice>
          <xsd:element name="hello"          type="HelloMessage"/>
          <xsd:element name="quit"           type="QuitMessage"/>
          <xsd:element name="channel"        type="ChannelMessage"/>
          <xsd:element name="join"           type="JoinMessage"/>
          <xsd:element name="leave"          type="LeaveMessage"/>
          <xsd:element name="getpeers"       type="GetPeersMessage"/>
          <xsd:element name="peers"          type="PeersMessage"/>
          <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="flood"      type="xsd:boolean" default="false"/>
      <xsd:attribute name="signtype"   type="SignType"/>
      <xsd:attribute name="signature"  type="SignatureType"/>
    </xsd:complexType>
  </xsd:element>

  <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.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <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="QuitMessage">
    <xsd:annotation>
      <xsd:documentation>
        The "quit" message is sent by a peer as the last message
        before actively shutting down the connection. The peer SHOULD
        give an informal reason why the connection is shut down.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="messageid" type="MessageIDType"/>
      <xsd:element name="reason"    type="xsd:string" minOccurs="0"/>
    </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="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: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:sequence>
  </xsd:complexType>
  
  <xsd:complexType name="GetPeersMessage">
    <xsd:annotation>
      <xsd:documentation>
        A node may send a "getpeers" message to request a list of
        other node addresses in order to extend its own list of
        potential connection peers.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="messageid" type="MessageIDType"/>
    </xsd:sequence>
  </xsd:complexType>
  
  <xsd:complexType name="PeersMessage">
    <xsd:annotation>
      <xsd:documentation>
        A node can make its direct peer nodes aware of a list of peer
        addresses through a "peers" message.
      </xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
      <xsd:element name="messageid" type="MessageIDType"/>
      <xsd:element name="peer"      type="PeerAddressType" 
        minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
  </xsd:complexType>
  
  <xsd:complexType name="GetCertificateMessage">
    <xsd:annotation>
      <xsd:documentation>
        A user 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 user 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 user 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:sequence>
  </xsd:complexType>
    
  <xsd:complexType name="KeyMessage">
    <xsd:annotation>
      <xsd:documentation>
        A user 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 the 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="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="channel"   type="ChannelNameType"
        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: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>

