JetSend is a media-independent communications protocol that can exchange information in its proper context without any product-specific knowledge or device drivers. This article provides an overview of the JetSend protocol.
JetSend is a media-independent communications protocol, developed by Hewlett-Packard, that provides interoperability among a wide variety of devices in differing vertical markets. You may be thinking, “Do we really need another communications protocol?” The answer is yes, and here is the reason: a need exists for a protocol that supports device-to-device content exchange. True, protocols already exist for point-to-point data exchange (FTP, IrTranP, and so on), but the problem with these protocols is that they don’t fully describe the content being exchanged, and as a result the data transferred is both machine dependent and OS dependent.
The fact that JetSend is able to exchange information in its proper context, without any product-specific knowledge or device drivers, gives it tremendous value. Increasingly, embedded devices are required to exchange data with other devices directly (that is, no PC will be required). With JetSend, the user of a device doesn’t need to know what protocol is being used to transfer data. These devices might be digital cameras, cell phones, PDAs, printers, scanners, or set-top boxes, to name just a few. Another compelling reason for using JetSend is that it already has support in many of the devices just listed. All of Hewlett-Packard’s standalone printers and scanners support JetSend. Also, JetSend printer support for Windows CE PDAs — although not native — can be obtained via download from HP. This article will attempt to provide an overview of the JetSend protocol.
Overview of JetSend
The HP JetSend protocol is a peer-to-peer communication protocol. The protocol allows two devices to connect, negotiate data types, and exchange information. With this new protocol comes a new paradigm for job control in embedded devices. For example, say a person wants to print a picture from a digital camera. The current job control model requires the user to transfer the picture to a printer through a two-step process. First the user must launch a compatible digital camera application on a PC to receive the desired pictures from the camera. Then a host application — possibly the same one — prints the desired pictures using a compatible printer driver. In this job model, the host computer acts as a translator between two devices that speak different languages.
The JetSend job control model differs in that it is a one-step, peer-to-peer communication process. A host PC no longer controls the exchange of data between two devices, which removes the need to load a special driver on the sending device because both devices speak a common language. One side effect, however, is that the host PC can no longer be relied upon for any data translation.
Within JetSend, all data exchanged between devices is accomplished using surfaces. Each surface object has a name, a description, and content. The description is analogous to a file header, and contains information about the type and content of the surface. The content portion may be null, data, or a reference to another surface (a child surface). The data contained in a surface is called electronic material (e-material).
As an example, a two-page document, one with image and text and the second with just an image, can be represented by six surfaces, as shown in Figure 1. The encodings of the surfaces are also shown. In a printing example, the vAssociation encoding describes the entire document or print job. The vPlane encoding controls the layout of pages to be printed. The vImage and vText encoding describe the content of the image and text.
In this example the “Text1” child surface on the first page of the document is a text description of the “Image1” picture. This description might be something like “Billy’s first birthday — January 01, 1999.” A raster image of this text string is also offered in case the receiving device does not support the vText encoding. In other nonprinting applications, surface encodings may take on different meanings.
JetSend is a layered protocol designed to be machine independent as well as transport independent. The components of the protocol shown in Figure 2 are as follows:
Data sent by the application layer (device-specific code) must progress down through each layer before being sent out over a transport medium and then back up through the JetSend stack of the receiving device.
Machine independence is achieved through the use of e-material, which specifies data types and formats that do not rely on software language data types. An example of this would be the e-material definition of a simple integer type. The first byte of the type definition is a value type identifier, which tells what type of integer it is, as shown in Figure 3. The byte(s) that follows is the actual value of the integer in network byte order (big endian — most significant byte first).
The TI layer is responsible for providing a generic API to the non-JetSend transport protocols. Operating system-specific code is needed to translate generic TI API messages into OS network driver calls and vise versa.
Using the JetSend API
To communicate using JetSend, device-specific code must interact with an API composed of three main sections: the Activity Manager, Interaction Policies, and e-material routines.
Activity manager API . The Activity Manager is the heart of the JetSend API and fulfills two main functions. First, the Activity Manager is responsible for managing JetSend sessions. A session is a reliable full duplex communication channel established between two JetSend-enabled devices. All user data transferred from one device to another is conveyed over one or more sessions. The second main function is event handling. The Activity Manager manages events coming from the lower layers of the JetSend stack by providing an event queue and polling mechanism to process and free events. Listing 1 shows the routines that make up Activity Manager API. More about how the Activity Manager works will be discussed in the section on sending application data.
/* Initialization */Tstatus jamInitialize();Tstatus jamShutdown();/* Buffer Management*/BD* jamCreateBuf(Tu32 iSize);/* Event Handling*/Tstatus jamGetNextEvent(JAMEVENT **pEvent);Tstatus jamFreeEvent(JAMEVENT *pEvent);/* Session Management*/Tstatus jamStartSession(Tchar *pAddress);Tstatus jamEndSession(void);Tstatus jamListenForSession(Tchar *pDomain, Tbool bAccept);
JetSend interaction policies . The second main section of the JetSend API is concerned with supporting one or more of the JetSend Interaction Policies. This component of the JetSend Protocol defines various typical sequences of interactions that devices agree to follow. Most of the toolkits available implement the session policy and a portion of the job policy. Altogether five policies have been defined as follows:
Of the five policies, the session policy is supported directly by the Activity Manager through the use of session management routines. The session policy defines how sessions are created and destroyed. In the session policy, roles for both passive and active devices are defined. The passive device acts as a consumer and the active device acts as a producer. In order for two devices to communicate, one device must begin listening for another device to connect to it on a given transport channel. The listening device opens a passive session and waits for notification of a connecting device.
The remaining policies — job, self, status, and address — define how data is formatted and exchanged between devices.
The job policy is used to send and receive application data over JetSend sessions. Two methods for exchanging data, the PUSH method and the PULL method, are defined by the job policy. As the name implies, the PUSH method is used to push data from a sending device to a receiving device, as would be done for printing, faxing, and so on. I will give an example of a PUSH sender/receiver in the section on sending application data. The PULL method is used when the receiving device needs to be able to select certain pieces of data from a sending device, as would be the case for some type of monitoring device. An example of this might be a JetSend-enabled digital Walkman that is able to download selected songs from a jukebox-like storage device using the PULL method.
The self policy, status policy, and address policy together provide the mechanisms to convey device attribute and status information. The self policy provides the ability for a remote device to obtain device attribute information. This information includes the device’s address, name (in text and in a Windows icon bitmap), and PIN number to allow support for user authentication. The self policy is often used in conjunction with the address policy.
The status policy, as the name implies, allows a device to obtain the status of another device. Using this policy it is possible to report conditions like paper jam, low battery, and so on.
The last policy in this grouping, the address policy, defines a mechanism to convey addressing information about additional devices available on a network. The JetSend protocol doesn’t have a mechanism to automatically discover JetSend devices on a given network, so the address of at least one JetSend device must be known in order to use JetSend to accomplish a given task. Users program a device with the addresses of the devices they wish to use. For point-to-point transports like IrDA, this is as simple as programming a single default address into the device. On network transports like IP, the address policy can be used to program devices with additional addresses. The address policy allows a network administrator to set up a well-known device address on a network that holds the addresses of other JetSend devices. Once addresses are obtained, the type and capabilities of a device can be discovered by using the self policy.
E-material routines . The e-material routines are used to create and parse surfaces in order to intelligently exchange data. E-material data structures have predefined data elements and data types that include values, strings, and lists. Using e-material routines, simple data types like integers and strings are converted to e-material types to build surface descriptions. E-material surface descriptions are constructed to fully describe user data and list possible encodings in which the sending device can transfer the data. This gives the receiving device the ability to choose an encoding that best suits its devices’ capabilities. The process of selecting a data transfer format is called device negotiation . To ensure that devices of the same class will be able to exchange data, a default data format is defined. For example, the default encoding for image devices is 300 x 300 dpi, monochrome, RLE compressed raster data. All JetSend-certified image devices (printers, scanners, copiers, cameras, whiteboards, and so on) must be able to send and/or receive this encoding (Section 2.2.3 of the JetSend Protocol Specification, v. 1.5). The ability to add new encodings while enforcing support for a default encoding will allow JetSend to maintain backwards compatibility. You have a device like a digital Walkman that supports audio clips in MP3 format. The sending device might support new audio formats while still supplying the old digital Walkman with MP3 audio clips. The new digital Walkman can thus take advantage of a new format, while the old devices-having only the old format — are still supported.
The sample PUSH sender given in Listing 2 will be used to describe the steps required to transfer user data from one device to another (see also Figure 5). At the beginning of the routine RunSimpleSender() the Activity Manager, which is responsible for managing sessions, is initialized by calling jamInitialize() . This sets up an event queue inside the Activity Manager that can be polled by the device-specific code using the function jamGetNextEvent() . This polling mechanism allows the device-specific code to process events that have propagated up through the JetSend stack. Next, the PUSH sender is initialized by calling psInitialize() . Upon initialization the PUSH sender installs callbacks for events it will handle as part of the job policy (shown graphically in Figure 4). To communicate from one JetSend-enabled device to another, an active JetSend session must be created, which is accomplished by calling jamStartSession() . The transport address is specified in this call. In this example IrDA is selected as the transport. For a session to succeed in opening, a JetSend receiver must be listening for a session on the same network channel selected in the jamStartSession() call.
When a session is first established (that is, the session opens successfully) the PUSH receiver constructs an “IN” surface and sends it over the newly opened session. The purpose of the IN surface is to inform the connecting device that a receiver is available which supports the job policy. Upon receiving the remote device’s IN surface, the PUSH sender posts a psInArrivedEvent event to the Activity Manager. The sending device-specific code then reads this event via jamGetNextEvent() and begins the process of sending a document.
To illustrate how a document is sent, let’s once again use the document in Figure 2. The vAssociation surface is constructed using routines from the e-material library and then sent out over the open session to the remote device. The PUSH receiver, called by the Activity Manager via a callback routine, posts a prJobStartEvent when the vAssociation surface is received. The remote device code, in processing this event, parses the vAssociation surface description and determines what portion of the data it wishes to receive.
For this example we will assume that the receiving device will ask that the entire document be sent through a series of requests to the sending device. First the receiver requests the first vPlane surface (or page) in our document. The sender receives this request as a psSurfaceRequestEvent from the jamGetNextEvent() routine. A description of the data contained in the requested vPlane must then be constructed via e-material routines and sent to the remote device. The vPlane description defines how a page is laid out. In our sample document this description would contain (x,y ) coordinates of both the image and text objects. The receiving device then knows where to place the objects for display or printing. At this point the receiver has the knowledge that the current job consists of a two-page document, and that the first page has both an image object and a text object on it. So far, no user data (content) has been transferred.
In the next step, the sending device requests the vImage surface which contains a description of the image data. This description is in the form of a list of possible encodings supported by the sender. The receiving device reads the list of data encodings and requests that the content be sent in a format that best suits its device capabilities. The sender — upon receiving a request — sends content messages until the entire body of the vImage is sent. The remote device then requests the vText surface be sent. Our example document has the text content as part of the vText object on page one, so once the vText surface is sent, the first page is fully transferred and can be displayed, printed, or stored. Since there are two vPlanes in the vAssociation surface of our example document, the remaining vPlane will be requested using the same techniques.
When all the data is sent, the session can be closed or left open. A session would be left open if additional data were to be transferred. For example, the sending side could have additional documents (or jobs) that it desires to send. The additional documents would be sent in the same manner as I previously described. The possibility also exists that the receiver would want to get updates of any changes made to a received document by the sending device. An example of this might be a JetSend-enabled display connected to a portable computing device.
A few good reasons
The JetSend protocol is well suited for embedded devices for a couple of reasons. First, the protocol has been kept simple by defining everything in terms of surfaces. Therefore, a typical implementation of the JetSend stack on an embedded device will be somewhere around 60K of code. The second reason is that JetSend is peer to peer, and will allow devices to communicate with a range of other devices, a feature which will likely become a requirement as the number and usage of new devices increase. The third reason why JetSend is a good fit for embedded devices is the negotiation aspect of the protocol. Negotiation allows embedded devices to support a small minimum set of data formats that will be directly used by the device. For example an image class device does not have to support TIIF, JPEG, GIF, Windows bitmap, and so on, but only needs to be able to support raster image data in at least the minimum 300dpi RLE encoding. As long as memory is not free, the negotiation feature of JetSend will allow embedded devices to communicate with a wide variety of other devices at a reasonable cost.
So far I have covered only a few of the possible uses of JetSend. Hewlett-Packard continues to develop the protocol and has added JetSend support to many of their printers and scanners. New e-material encodings such as vCard and vCalendar are currently being added to the specification to enable the exchange of contact and calendar information. A new interaction policy, the control policy, has been developed to support remote control of JetSend-enabled devices. Also added to the specification is support for proxies. As an example, an e-mail proxy can be used to provide e-mail support for devices that do not support e-mail, but do support sending to proxies. To learn more about these new features, as well as for additional information on JetSend, visit www.jetsend.com.