XEP-xxxx: Multiplexed In-Band Bytestreams (XIBB)

This document defines an XMPP extension for multiplexing bidirectional bytestreams between two entities over XMPP.


WARNING: This document has not yet been accepted for consideration or approved in any official manner by the XMPP Standards Foundation, and this document must not be referred to as an XMPP Extension Protocol (XEP). If this document is accepted as a XEP by the XMPP Council, it will be published at <http://www.xmpp.org/extensions/> and announced on the <standards@xmpp.org> mailing list.


Document Information

Series: XEP
Number: xxxx
Publisher: XMPP Standards Foundation
Status: ProtoXEP
Type: Standards Track
Version: 0.0.2
Last Updated: 2007-09-30
Approving Body: XMPP Council
Dependencies: XMPP Core, XEP-0047
Supersedes: None
Superseded By: None
Short Name: xibb

Author Information

Adrien Pinet

Email: adrien.pinet@gmail.com
JabberID: adrien.pinet@gmail.com

Legal Notice

This XMPP Extension Protocol is copyright 1999 - 2007 by the XMPP Standards Foundation (XSF) and is in full conformance with the XSF's Intellectual Property Rights Policy (<http://www.xmpp.org/extensions/ipr-policy.shtml>). This material may be distributed only subject to the terms and conditions set forth in the Creative Commons Attributeion License (<http://creativecommons.org/licenses/by/2.5/>).

Discussion Venue

The preferred venue for discussion of this document is the Standards discussion list: <http://mail.jabber.org/mailman/listinfo/standards>.

Relation to XMPP

The Extensible Messaging and Presence Protocol (XMPP) is defined in the XMPP Core (RFC 3920) and XMPP IM (RFC 3921) specifications contributed by the XMPP Standards Foundation to the Internet Standards Process, which is managed by the Internet Engineering Task Force in accordance with RFC 2026. Any protocol defined in this document has been developed outside the Internet Standards Process and is to be understood as an extension to XMPP rather than as an evolution, development, or modification of XMPP itself.

Conformance Terms

The following keywords as used in this document are to be interpreted as described in RFC 2119: "MUST", "SHALL", "REQUIRED"; "MUST NOT", "SHALL NOT"; "SHOULD", "RECOMMENDED"; "SHOULD NOT", "NOT RECOMMENDED"; "MAY", "OPTIONAL".


Table of Contents


1. Introduction
2. Glossary
3. Use Cases
    3.1. Discovering Support
    3.2. The Finite state automaton related to the XIBB protocol
    3.3. Managing channels
       3.3.1. Opening a channel
       3.3.2. Setting up a channel
       3.3.3. Sending data in a channel
       3.3.4. Closing a channel
    3.4. Managing bytestreams
       3.4.1. Opening a bytestream
       3.4.2. Setting up a bytestream
       3.4.3. Sending data in a bytestream
       3.4.4. Closing a bytestream
4. Security Considerations
5. IANA Considerations
6. XMPP Registrar Considerations
    6.1. Protocol Namespaces
7. XML Schema
Notes
Revision History


1. Introduction

Some applications and protocols as tcp-udp/ip tunneling or multiplayer games, require several bidirectional bytestreams. It seems to be necessary to build a protocol allowing the multiplexing of several bytestreams attached to a single service in a unique channel. A configuration mechanism in real-time of channels and bytstreams such as: the number of maximal bytestreams, the block size or the byterate will be able to quantify the configuration in accordance with the needs. This protocol MAY be useful to be used for instance to establish remote X11 connections, port forwarding or NAT over the XMPP protocol.

2. Glossary

XIBB is composed of 8 kind of elements.

Table 1: Elements definition

Element Description
<channel-open/> Open a channel between two XMPP entities.
<channel-data/> Send data inside the opened channel.
<channel-close/> Close an opened channel.
<channel-setup/> Setting up an opened channel.
<stream-open/> Open a bytestream inside an opened channel.
<stream-data/> Send data inside an opened bytestream.
<stream-close/> Close an opened bytestream.
<stream-setup/> Setting up an opened bytestream.

3. Use Cases

3.1 Discovering Support

In order to determine whether a potential responding entity (anais) supports the XIBB protocol, a requesting entity (adrien) SHOULD send a Service Discovery [1] information request to the potential responding entity:

Example 1. Requester queries responder regarding protocol support

		
			<iq from='adrien@example.com/any'
				to='anais@example.com/any' 
				id='disco1'
				type='get'> 
			  <query xmlns='http://jabber.org/protocol/disco#info'/>
			</iq>
			
		

If the responding entity supports the XIBB protocol and the requesting entity is not blocked from communicating with the responding entity, the responding entity MUST include a feature of "http://jabber.org/protocol/xibb" in its reply.

Example 2. Requester queries responder regarding protocol support

		
			<iq type='result' from='anais@example.com/any' id='disco1'>
				<query xmlns='http://www.jabber.org/protocol/disco#info'>
					...
					<feature var='http://www.jabber.org/protocol/xibb'/>
					...
				</query>
			</iq>
		
		

3.2 The Finite state automaton related to the XIBB protocol

This section describes the element sequence permitted between two XMPP entities.

Table 2: The automaton is defined by A = (E, Σ, t, i, Q) as bellow

State listE := {0, 1, 2}
Alphabet listΣ := {<channel-open/>, <channel-setup/>, <channel-data/>, <channel-close/>, <stream-open/>, <stream-setup/>, <stream-data/>, <stream-close/>}
transition functionδ : E * Σ -> E
Initial statei := 0
Acceptation stateQ := {0}

Table 3: Transition table

δCurrent States
Condition012
<channel-open cid='x'/>1ØØ
<channel-setup cid='x'/>Ø1Ø
<channel-data cid='x'/>Ø12
<channel-close cid='x'/>Ø00
<stream-open cid='x' sid='y'/>Ø2Ø
<stream-setup cid='x' sid='y'/>ØØ2
<stream-data cid='x' sid='y'/>ØØ2
<stream-close cid='x' sid='y'/>ØØ1

3.3 Managing channels

This section describes how to open, close, sending/receiving data and setting up a channel.

3.3.1 Opening a channel

First of all, an entity MUST send an opening <channel-open/> element. This element MUST be embeded inside an iq stanza. This element MUST be composed of 5 attributes xmlns='http://jabber.org/protocol/xibb', cid, max-stream, block-size and byte-rate.

Table 4: Attributes definition

cidis a 16 bits unsigned integer and it is used to identify the channel. The 2-tuple (requester's full Jid, cid) MUST be unique over all the XMPP network.
max-streamis a 16 bits unsigned integer and it is used to define how many bytestreams are able to be opened.
block-sizeis a 16 bits unsigned integer and it is used to define the maximal size (in byte) of data that CAN BE sended at a time inside the channel itself or inside the attached bytestreams.
byte-rateis a 32 bits unsigned integer and it is used to define the maximal byte-rate in the channel (in bytes/s). If the value is set to 0, the byte-rate is unlimited.

Example 3. Requester (adrien) queries responder (anais) to open a channel

			
			<iq type='set' from='adrien@example.com/any' to='anais@example.com/any' id='co1'>
				<channel-open xmlns='http://www.jabber.org/protocol/xibb'
					cid='0'
					max-stream='65535'
					block-size='4096'
					byte-rate='1024'/>
			</iq>
			
			

Example 4. Responder (anais) answers requester (adrien) that the channel is opened

			
			<iq type='result' from='anais@example.com/any' to='adrien@example.com/any' id='co1'/>
			
			

Example 5. Possible error

			
			<iq type='result' from='anais@example.com/any' to='adrien@example.com/any' id='co1'>
			  <error code='501' type='cancel'>
				<feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
			  </error>
			</iq>
			
			

This is an error response from anais@example.com/any saying that opening the channel is not possible.

Note: The cid attribute MUST be the same all the time that the channel is opened. But it MAY be different localy: If two entities open at the same time a channel, both of them MAY be identicals. To prevent this problem, each entities have to translate local cid to the remote cid before sending data.

3.3.2 Setting up a channel

An opened channel MAY be setting up by both entities. To setup a channel, an entities MUST send a <channel-setup/> element inside an iq stanza. This element MUST be composed of the attribute cid and MAY be composed of one or several attributes from this list: {max-stream, block-size, byte-rate}.

Example 6. Requester (adrien) queries responder (anais) to change the number of maximal stream and the block-size

			
			<iq type='set' from='adrien@example.com/any' to='anais@example.com/any' id='cs1'>
			 <channel-setup xmlns='http://www.jabber.org/protocol/xibb'
				cid='0'
				max-stream='360'
				block-size='2048'/>
			</iq>
			
			

Example 7. Responder (anais) answers requester (adrien) that the channel is setting up

			
			<iq type='result' from='anais@example.com/any' to='adrien@example.com/any' id='cs1'/>
			
			

Example 8. Possible error

			
			<iq type='result' from='anais@example.com/any' to='adrien@example.com/any' id='cs1'>
			  <error code='501' type='cancel'>
				<feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
			  </error>
			</iq>
			
			

This is an error response from anais@example.com/any saying that setting up the channel is not possible.

3.3.3 Sending data in a channel

Sending data inside a channel may be useful to negociate extra protocol related to the attached bytestreams. Data is sent using either <message> or <iq> stanzas. It is encouraged to use <message> stanza to avoid waiting an iq result. In the other case, each entities have to be bufferised.

The data is embedded inside a <channel-data/> element and MUST be composed of the attribute cid. The data MUST be encoded as Base64 as specified in Section 4 of RFC 4648 [2]

Example 9. Requester (adrien) send data to the responder (anais) using a <message> stanza

			
			<message from='adrien@example.com/any' to='anais@example.com/any'>
			 <channel-data xmlns='http://www.jabber.org/protocol/xibb' cid='0'>
				YjG4koXOpawxB9V6UsPlJu0QDE4J668Dg24tHp3LK6G+DrVobR3kRTOl9su8b5QO
				RkchilisG2L+oVTqrpLMB6G4J+rxmpKG+zsKiesJ1LuDt2OY7TWNaW3m+kTpNAEu
				1xP5/6meZjNLOufK1q8iNseSUszPRgojAOBrF9ufMg5aq5KRY+5JVf8ocWPFYIAT
				4DNk+/7enVX93Ft/8NuX1PoitvOxehSFwsHxmeuSuVS/BFOdaZfD2Gog6q8GQa+J
				S8rBagXOC9cvJHR8jANRaJMeCS2H51jJFyNX9aBTdIibmGWJRVVSIdlVpZPj5A3E
				1iFjVTc9/oOG34gaOIHmOW8tEoWYoNTSwv43sNL8/b4kkCjt465Lt3lHCm/j4kxL
			 </channel-data>
			</message>
			
			

Example 10. Requester (adrien) send data to the responder (anais) using a <iq/> stanza

			
			<iq type='set' from='adrien@example.com/any' to='anais@example.com/any' id='cd1'>
			 <channel-data xmlns='http://www.jabber.org/protocol/xibb' cid='0'>
				YjG4koXOpawxB9V6UsPlJu0QDE4J668Dg24tHp3LK6G+DrVobR3kRTOl9su8b5QO
				RkchilisG2L+oVTqrpLMB6G4J+rxmpKG+zsKiesJ1LuDt2OY7TWNaW3m+kTpNAEu
				1xP5/6meZjNLOufK1q8iNseSUszPRgojAOBrF9ufMg5aq5KRY+5JVf8ocWPFYIAT
				4DNk+/7enVX93Ft/8NuX1PoitvOxehSFwsHxmeuSuVS/BFOdaZfD2Gog6q8GQa+J
				S8rBagXOC9cvJHR8jANRaJMeCS2H51jJFyNX9aBTdIibmGWJRVVSIdlVpZPj5A3E
				1iFjVTc9/oOG34gaOIHmOW8tEoWYoNTSwv43sNL8/b4kkCjt465Lt3lHCm/j4kxL
			 </channel-data>
			</iq>
			
			

Example 11. Responder (anais) answers requester (adrien) that the data is received

			
			<iq type='result' from='anais@example.com/any' to='adrien@example.com/any' id='cd1'/>
			
			

3.3.4 Closing a channel

Closing a channel interrupts all communications established inside the channel. If one or several bytestreams are already opened they are considered as closed and the receiving entity MUST NOT use them anymore. A channel is closed using a <channel-close/> element embedded inside an <iq/> stanza. This element MUST be composed of the cid attribute.

Example 12. Requester (adrien) queries the responder (anais) that the channel is closed

			
			<iq type='set' from='adrien@example.com/any' to='anais@example.com/any' id='cc1'>
			 <channel-close xmlns='http://www.jabber.org/protocol/xibb' cid='0'/>
			</iq>
			
			

Example 13. Responder (anais) answers requester (adrien) that the channel is closed

			
			<iq type='result' from='anais@example.com/any' to='adrien@example.com/any' id='cc1'/>
			
			

If a channel is already closed the responder (anais) MUST alway answers with a result <iq/> stanza.

3.4 Managing bytestreams

This section describes how to open, close, sending/receiving data and setting up a bytestream.

3.4.1 Opening a bytestream

A bytestream MUST be opened inside an opened channel. An entity MUST send an opening <stream-open/> element. This element MUST be embeded inside an iq stanza. This element MAY be composed of 2 extra attributes block-size and byte-rate and MUST be composed at least of 3 attributes: xmlns='http://jabber.org/protocol/xibb', cid and sid. The 3-tuple (requester's full Jid, cid, sid) MUST be unique over all the XMPP network and identify the bytestream. If the block-size and byte-rate are specified, those attributes override the channel settings. In the other case the channel settings are used.

Example 14. Requester (adrien) queries responder (anais) to open a bytestream

			
			<iq type='set' from='adrien@example.com/any' to='anais@example.com/any' id='so1'>
				<stream-open xmlns='http://www.jabber.org/protocol/xibb' cid='0' sid='0'/>
			</iq>
			
			

Example 15. Responder (anais) answers requester (adrien) that the bytestream is opened

			
			<iq type='result' from='anais@example.com/any' to='adrien@example.com/any' id='so1'/>
			
			

Example 16. Possible error

			
			<iq type='result' from='anais@example.com/any' to='adrien@example.com/any' id='so1'>
			  <error code='501' type='cancel'>
				<feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
			  </error>
			</iq>
			
			

This is an error response from anais@example.com/any saying that opening the bytestream is not possible.

3.4.2 Setting up a bytestream

An opened bytestream MAY be setting up by both entities. To setup a bytestream, an entity MUST send a <stream-setup/> element inside an iq stanza. This element MUST be composed of the attributes xmlns=http://jabber.org/protocol/xibb, cid and sid and MAY be composed of one or several attributes from this list: {block-size, byte-rate}.

Example 17. Requester (adrien) queries responder (anais) to change the block-size

			
			<iq type='set' from='adrien@example.com/any' to='anais@example.com/any' id='ss1'>
			 <stream-setup xmlns='http://www.jabber.org/protocol/xibb'
			                cid='0' sid='0' block-size='2048'/>
			</iq>
			
			

Example 18. Responder (anais) answers requester (adrien) that the bytestream is setting up

			
			<iq type='result' from='anais@example.com/any' to='adrien@example.com/any' id='ss1'/>
			
			

Example 19. Possible error

			
			<iq type='result' from='anais@example.com/any' to='adrien@example.com/any' id='ss1'>
			  <error code='501' type='cancel'>
				<feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
			  </error>
			</iq>
			
			

This is an error response from anais@example.com/any saying that setting up the bytestream is not possible.

3.4.3 Sending data in a bytestream

Data is sent using either <message> or <iq> stanzas. It is encouraged to use <message> stanza to avoid waiting an iq result. In the other case, each entities have to be bufferised.

The data is embedded inside a <stream-data/> element and MUST be composed of the attributes xmlns=http://jabber.org/protocol/xibb, cid and sid. The data MUST be encoded as Base64 as specified in Section 4 of rfc4648

Example 20. Requester (adrien) send data to the responder (anais) using a <message> stanza

			
			<message from='adrien@example.com/any' to='anais@example.com/any'>
			 <stream-data xmlns='http://www.jabber.org/protocol/xibb' cid='0' sid='0'>
				YjG4koXOpawxB9V6UsPlJu0QDE4J668Dg24tHp3LK6G+DrVobR3kRTOl9su8b5QO
				RkchilisG2L+oVTqrpLMB6G4J+rxmpKG+zsKiesJ1LuDt2OY7TWNaW3m+kTpNAEu
				1xP5/6meZjNLOufK1q8iNseSUszPRgojAOBrF9ufMg5aq5KRY+5JVf8ocWPFYIAT
				4DNk+/7enVX93Ft/8NuX1PoitvOxehSFwsHxmeuSuVS/BFOdaZfD2Gog6q8GQa+J
				S8rBagXOC9cvJHR8jANRaJMeCS2H51jJFyNX9aBTdIibmGWJRVVSIdlVpZPj5A3E
				1iFjVTc9/oOG34gaOIHmOW8tEoWYoNTSwv43sNL8/b4kkCjt465Lt3lHCm/j4kxL
			 </stream-data>
			</message>
			
			

Example 21. Requester (adrien) send data to the responder (anais) using a <iq/> stanza

			
			<iq type='set' from='adrien@example.com/any' to='anais@example.com/any' id='sd1'>
			 <stream-data xmlns='http://www.jabber.org/protocol/xibb' cid='0' sid='0'>
				YjG4koXOpawxB9V6UsPlJu0QDE4J668Dg24tHp3LK6G+DrVobR3kRTOl9su8b5QO
				RkchilisG2L+oVTqrpLMB6G4J+rxmpKG+zsKiesJ1LuDt2OY7TWNaW3m+kTpNAEu
				1xP5/6meZjNLOufK1q8iNseSUszPRgojAOBrF9ufMg5aq5KRY+5JVf8ocWPFYIAT
				4DNk+/7enVX93Ft/8NuX1PoitvOxehSFwsHxmeuSuVS/BFOdaZfD2Gog6q8GQa+J
				S8rBagXOC9cvJHR8jANRaJMeCS2H51jJFyNX9aBTdIibmGWJRVVSIdlVpZPj5A3E
				1iFjVTc9/oOG34gaOIHmOW8tEoWYoNTSwv43sNL8/b4kkCjt465Lt3lHCm/j4kxL
			 </stream-data>
			</iq>
			
			

Example 22. Responder (anais) answers requester (adrien) that the data is received

			
			<iq type='result' from='anais@example.com/any' to='adrien@example.com/any' id='sd1'/>
			
			

3.4.4 Closing a bytestream

A bytestream is closed using a <stream-close/> element embedded inside an <iq/> stanza. This element MUST be composed of the attributes xmlns=http://jabber.org/protocol/xibb, cid and sid.

Example 23. Requester (adrien) queries the responder (anais) that the bytestream is closed

			
			<iq type='set' from='adrien@example.com/any' to='anais@example.com/any' id='cc1'>
			 <stream-close xmlns='http://www.jabber.org/protocol/xibb' cid='0' sid='0'/>
			</iq>
			
			

Example 24. Responder (anais) answers requester (adrien) that the bytestream is closed

			
			<iq type='result' from='anais@example.com/any' to='adrien@example.com/any' id='cc1'/>
			
			

If a bytestream is already closed the responder (anais) MUST alway answers with a result <iq/> stanza.

4. Security Considerations

An entity MUST verify any Base64 data received and check that data size in equal or less than the block-size attribute. An implementation MUST reject (not ignore) any characters that are not explicitly allowed by the Base64 alphabet;

5. IANA Considerations

This document requires no interaction with the Internet Assigned Numbers Authority (IANA) [3].

6. XMPP Registrar Considerations

6.1 Protocol Namespaces

The XMPP Registrar [4] shall register the 'http://jabber.org/protocol/ibb' namespace as a result of this document.

7. XML Schema

<?xml version='1.0' encoding='UTF-8'?>

<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://jabber.org/protocol/xibb'
    xmlns='http://jabber.org/protocol/xibb'
    elementFormDefault='qualified'>

  <xs:annotation>
    <xs:documentation>
      The protocol documented by this schema is defined in
      XEP-XXXX: http://www.xmpp.org/extensions/xep-xxxx.html
    </xs:documentation>
  </xs:annotation>

   <xs:element name='channel-open'>
     <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='cid' type='xs:integer' use='required'/>
          <xs:attribute name='max-stream' type='xs:integer' use='required'/>
          <xs:attribute name='block-size' type='xs:integer' use='required'/>
          <xs:attribute name='byte-rate' type='xs:integer' use='required'/>
        </xs:extension>
      </xs:simpleContent>
     </xs:complexType>
   </xs:element>

   <xs:element name='channel-setup'>
     <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='cid' type='xs:integer' use='required'/>
          <xs:attribute name='max-stream' type='xs:integer' use='optional'/>
          <xs:attribute name='block-size' type='xs:integer' use='optional'/>
          <xs:attribute name='byte-rate' type='xs:integer' use='optional'/>
        </xs:extension>
      </xs:simpleContent>
     </xs:complexType>
   </xs:element>

   <xs:element name='channel-data'>
     <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='xs:string'>
          <xs:attribute name='cid' type='xs:integer' use='required'/>
        </xs:extension>
      </xs:simpleContent>
     </xs:complexType>
   </xs:element>

   <xs:element name='channel-close'>
     <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='cid' type='xs:integer' use='required'/>
        </xs:extension>
      </xs:simpleContent>
     </xs:complexType>
   </xs:element>

   <xs:element name='stream-open'>
     <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='cid' type='xs:integer' use='required'/>
          <xs:attribute name='sid' type='xs:integer' use='required'/>
          <xs:attribute name='block-size' type='xs:integer' use='required'/>
          <xs:attribute name='byte-rate' type='xs:integer' use='required'/>
        </xs:extension>
      </xs:simpleContent>
     </xs:complexType>
   </xs:element>

   <xs:element name='stream-setup'>
     <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='cid' type='xs:integer' use='required'/>
          <xs:attribute name='sid' type='xs:integer' use='required'/>
          <xs:attribute name='block-size' type='xs:integer' use='optional'/>
          <xs:attribute name='byte-rate' type='xs:integer' use='optional'/>
        </xs:extension>
      </xs:simpleContent>
     </xs:complexType>
   </xs:element>

   <xs:element name='stream-data'>
     <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='xs:string'>
          <xs:attribute name='cid' type='xs:integer' use='required'/>
          <xs:attribute name='sid' type='xs:integer' use='required'/>
        </xs:extension>
      </xs:simpleContent>
     </xs:complexType>
   </xs:element>

   <xs:element name='stream-close'>
     <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='cid' type='xs:integer' use='required'/>
          <xs:attribute name='sid' type='xs:integer' use='required'/>
        </xs:extension>
      </xs:simpleContent>
     </xs:complexType>
   </xs:element>

  <xs:simpleType name='empty'>
    <xs:restriction base='xs:string'>
      <xs:enumeration value=''/>
    </xs:restriction>
  </xs:simpleType>

</xs:schema>
  

Notes

1. XEP-0030: Service Discovery <http://www.xmpp.org/extensions/xep-0030.html>.

2. RFC 4648: The Base16, Base32, and Base64 Data Encodings <http://tools.ietf.org/html/rfc4648>.

3. The Internet Assigned Numbers Authority (IANA) is the central coordinator for the assignment of unique parameter values for Internet protocols, such as port numbers and URI schemes. For further information, see <http://www.iana.org/>.

4. The XMPP Registrar maintains a list of reserved protocol namespaces as well as registries of parameters used in the context of XMPP extension protocols approved by the XMPP Standards Foundation. For further information, see <http://www.xmpp.org/registrar/>.


Revision History

Version 0.0.2 (2007-09-30)

Changing all elements name.

(ap)

Version 0.0.1 (2007-09-09)

First draft.

(ap)

END