The SyncML Reference Implementation comes with a communication API as a complementary component. It helps developers to access the underlying transports using a simple API. It currently supports HTTP [RFC2616] and OBEX [OBEX99]. Originally the support of WSP was also planned, but is not yet implemented. This is due to the fact that WSP would be only attractive to mobile phone platforms, as the supported client platforms can use HTTP instead. Also, the WAP APIs on each platform differ substantially. WSP [WSP01] clients connect to servers using a WAP Gateway, which transforms WSP into HTTP. Therefore servers do not need to contend with WSP, since they get the data via HTTP.
Figure 10-7 shows the architecture of the Communication API. The Communication Manager layer shields the application developer from directly dealing with the different underlying layers. The application just needs to select the appropriate transport and to pass the settings for this transport to the Communication API. This generic approach enables an application to support the transports supported by this API, without writing much extra code for each transport.
Figure 10-7. Communication API architecture
Using the Communications Toolkit API
When the Communications Manager is started, each available transport is also initialized. Each transport registers itself with a string identifier and a short description. The transport's description could be used by an application to allow the user to select the appropriate communication bearer. A list of available transports is available to the application via the xptGetProtocols call. The description of a particular transport could be retrieved using the xptGetProtocol call, which takes the transport's identifier as an input parameter.
The first step in sending or receiving data is to select and activate a specific transport using the xptSelectProtocol call. With this call, the application specifies whether it is a client or a server for the transport's communication protocol. Transport-specific metainformation is passed by the application, providing the transport with the information it needs to perform its tasks (e.g., host name to connect to, port number to listen on). It is also possible to open several concurrent connections. In server mode, the xptSelectProtocol call causes the transport to start "listening" for incoming requests. Once a protocol is selected, it may be used multiple times to initiate communications. Since some transports open a physical communication path to a particular destination at this time, the application should use a different xptSelectProtocol call for each new destination when in client mode. Each call to xptSelectProtocol returns a handle (called protocol service ID) for the new protocol instance. This handle is used on subsequent calls to identify the protocol instance.
 Ideally, the meta information needed by a transport could be interrogated by an application, so that it might present visual dialogs to the user. This allows the application to be transport-independent, obtaining the meta data from the user or from saved property files. Presently, however, there is no means provided to programmatically describe the transport's meta information, so the application must contain transport-specific settings.
The xptOpenCommunication call is used to initiate communication. In client mode, this typically causes the transport to make a physical connection. In server mode, this causes the transport to wait until it receives an incoming request from a client. A parameter to the xptOpenCommunication call indicates whether the caller will first send a document or first receive one. The simplest approach is to begin by sending a document when the transport is being used in client mode and by receiving a document when the transport is being used in server mode. Each call to xptOpenCommunication returns a handle for the newly created communication instance. This handle is used on subsequent calls to identify the instance. Each communication instance may be used to exchange multiple documents.
A document exchange consists of the sender sending a single document and the receiver replying with a single document, as shown in Figure 10-8. Each exchange is surrounded by calls to xptBeginExchange and xptEndExchange. These serve to clearly delineate the boundaries of the exchange and to provide the transport implementation an opportunity to initialize and clean up buffers and other internal management information.
Figure 10-8. Sending a document and receiving a document
If the application opened the communication using xptOpenCommunication as a sender, it now should call xptSetDocumentInfo to provide the name and MIME type of the document (i.e., "header information"). With calling xptSendData in a loop, the actual body of the document is provided and sent. It then calls xptGetDocumentInfo to retrieve the name and MIME type of the response document, and then calls xptReceiveData in a loop to read the body of the response document.
In case the application acts as a receiver, it first calls xptGetDocumentInfo to retrieve the name and MIME type of the incoming document, and then calls xptReceiveData in a loop to read the body of the incoming document. After everything is received, it sends a response by calling xptSetDocumentInfo to provide the name and MIME type of the response document, and then calls xptSendData in a loop to provide the body of the response document. Figure 10-9 shows the API sequence for an application first being a receiver and then a sender.
Figure 10-9. Receiving a document and sending a document
When the communication instance is no longer needed, the application should call xptCloseCommuncation, and when the transport selection instance is no longer needed, the application should call xptDeselectProtocol.