|
By Richard Marejka, April 12, 2005
|
|
|
The Generic Connection Framework (GCF) is a widely useful set of network and I/O classes for the Java 2 Platform, Micro Edition (J2ME). This tech tip will explain the key features of GCF, then distill key information about the various kinds of connections down into a "cheat sheet" that will come in handy when you make and use connections in your own applications.
You create a connection using one of the three open() methods in the javax.microedition.io.Connector class, as in this snippet:
...
import java.lang.String;
import javax.microedition.io.*;
static Connection Connector.open( String name );
...
|
The interesting questions here are: What is name, and what is a Connection? The specification of the Connected Limited Device
Configuration (CLDC) defines name as the URI for the connection – perhaps more precisely, the URI to connect
to. The generic syntax of URIs is described by the Internet Engineering Task Force (IETF) in RFC 2396. Here's the essence of it:
scheme : [address] [params]
|
Where:
scheme is the name of a protocol, http for example.
address is a scheme-specific encoding of the endpoint for
the connection.
params is an optional series of equates of the form: ;x=y, such as ;lang=en.
What's in a Name?
Before we go on to the question about what a Connection is, let's
ask one more question about its name: What schemes does a device support?
Let's assume that the device is a MIDP 2.0 platform and may include some
optional APIs. In the MIDP case, some schemes must be supported, some should be
supported, and some may be supported. In discussions of these categories,
they're routinely capitalized for emphasis: MUST, SHOULD, and MAY.
The MIDP schemes a device MUST support are http and
https; all other schemes fall into the SHOULD and MAY categories.
You can find out whether a scheme is supported by implementing the following
algorithm, replacing scheme and address
with appropriate values:
...
Type t;
Boolean hasScheme;
String name = "scheme://address";
try {
t = (Type) Connector.open( name );
t.close();
hasScheme = true;
} catch ( ConnectionNotFoundException cnfe ) {
hasScheme = false;
// handle exception
}
...
|
Where:
Type is a class derived from
javax.micoredition.io.Connection.
scheme is the protocol associated with
Type.
address is a valid address for the given scheme.
The value of hasScheme will be true if the scheme is
supported, false if it's not. Your application should be prepared
to handle the absence of a scheme, by fallingback to a supported scheme or
disabling any features that depend on the unsupported scheme.
Optional APIs can be detected in two ways, one easy, one more difficult.
Detection is easy when a system property is used to indicate the presence of an
optional package – and any included schemes. For example, an
application can discover whether the
PDA Optional Packages, which provide access to personal information
management data and file systems, are present by querying the
microedition.io.file.FileConnection.version system property:
...
import java.lang.System;
import java.lang.String;
String name = "microedition.io.file.FileConnection.version";
String value = System.getProperty( name );
Boolean hasFile;
if ( ( value != null ) && value.equals( "1.0" ) )
hasFile = true;
else
hasFile = false;
...
|
In this example, the Boolean variable hasFile will indicate the
presence of the optional package.
In the more difficult case, you can't determine the presence of a scheme simply
by querying a system property. You must resort to the technique I described for detecting the presence of schemes in the SHOULD and MAY categories.
Connections
Now we return to the question, what is a Connection? The answer is in the CLDC specification. Connection is the base interface of the Generic Connection Framework, representing a generic connection. There are an
additional six interfaces to support the characteristics of various protocols, along with an exception class and a few other sundry bits. All other connection types extend these seven.

Figure 1: Connection Interface Hierarchy
Supported Schemes
The following sections summarize the connection types that GCF currently supports. The information is grouped by JSR and includes interface, BNF syntax, and examples for each scheme. Several identify MUST, SHOULD, and MAY schemes. In
addition, the section for each JSR describes how to detect included schemes.
JSR 118 Mobile Information Device Profile, version 2.0
Comm Connection (Chapter 7)
Support: MAY
Interface: javax.microedition.io.CommConnection extends StreamConnection
BNF:
url ::== "comm:" port_id *(option_list)
port_id ::== 1*(characters)
option_list ::== *(baudrate | bitsperchar | stopbits | parity | blocking
| autocts | autorts)
baudrate ::== ";baudrate=" digits
bitsperchar ::== ";bitsperchar=" bit_value
bit_value ::== "7" | "8"
stopbits ::== ";stopbits=" stop_value
stop_value ::== "1" | "2"
parity ::== ";parity=" parity_value
parity_value ::== "even" | "odd" | "none"
blocking ::== ";blocking=" on_off
autocts ::== ";autocts=" on_off
autorts ::== ";autorts=" on_off
on_off ::== "on" | "off"
|
Examples:
"comm:0;bitsperchar=8;stopbits=1;parity=none"
"IR1"
|
The value of port_id, in the form of a comma-separated list of port identifiers, comes from:
import java.lang.System;
import java.lang.String;
String ports = System.getProperty( "microedition.commports" );
|
HTTP Connection (Chapter 7)
Support: MUST
Interface: javax.microedition.io.HttpConnection extends ContentConnection
Definition:
IETF RFC 1738, Section 3.3 HTTP
The HTTP protocol is specified elsewhere. This RFC only describes
the syntax of HTTP URLs.
An HTTP URL takes the form:
http://<host>:<port>/<path>?<searchpart>
where <host> and <port> are as described in Section 3.1. If :<port>
is omitted, the port defaults to 80. No user name or password is
allowed. <path> is an HTTP selector, and <searchpart> is a query
string. The <path> is optional, as is the <searchpart> and its
preceding "?". If neither <path> nor <searchpart> is present, the "/"
may also be omitted.
Within the <path> and <searchpart> components, "/", ";", "?" are
reserved. The "/" character may be used within HTTP to designate a
hierarchical structure.
|
Examples:
"http://java.sun.com"
"http://www.sun.com:80"
|
HTTPS Connection (Chapter 7)
Support: MUST
Interface: javax.microedition.io.HttpsConnection extends HttpConnection
Definition: See "HTTP Connection" above.
Examples:
"https://java.sun.com"
"https://www.sun.com:443"
|
Secure Connection (Chapter 7)
Support: SHOULD
Interface: javax.microedition.io.SecureConnection extends SocketConnection
BNF:
url ::== "ssl://" hostport
hostport ::== host ":" port
host ::== host name or IP address
port ::== numeric port number
|
Examples:
"ssl://www.sun.com"
"ssl://java.sun.com:443"
|
Note: Client-side only; no server support on device.
Server Socket Connection (Chapter 7)
Support: SHOULD
Interface: javax.microedition.io.ServerSocketConnection extends StreamConnectionNotifier
BNF:
url ::== "socket://" | "socket://" hostport
hostport ::== host ":" port
host ::== omitted for inbound connections
port ::== numeric port number (omitted for system assigned port)
|
Examples:
"socket://:25"
"socket://:17"
"socket://"
|
Socket Connection (Chapter 7)
Support: SHOULD
Interface: javax.microedition.io.SocketConnection extends StreamConnection
BNF:
url ::== "socket://" hostport
hostport ::== host ":" port
host ::== host name or IP address (omitted for inbound connections)
port ::== numeric port number
|
Examples:
"socket://developers.sun.com/mobility:80"
"socket://www.sun.com:53"
|
Datagram Connection (Chapter 7)
Support: SHOULD
Interface: javax.microedition.io.UDPDatagram.Connection extends DatagramConnection
BNF:
url ::== "datagram://" | "datagram://" hostport
hostport ::== host ":" port
host ::== host name or IP address (omitted for inbound connections)
port ::== numeric port number (omitted for system assigned port)
|
Examples:
"datagram://" - server with system assigned port
"datagram://:7" - server with specified port
"datagram://java.sun.com:80" - client
|
JSR 75 PDA Optional Packages
Discovery: System.getProperty( "microedition.io.file.FileConnection.version" ).equals( "1.0" );
Interface: javax.microedition.io.file.FileConnection extends StreamConnection
Definition:
IETF RFC 1738, Section 3.10 Files
A file URL takes the form:
file://<host>/<path>
where <host> is the fully qualified domain name of the system on
which the <path> is accessible, and <path> is a hierarchical
directory path of the form <directory>/<directory>/.../<name>.
...
As a special case, <host> can be the string "localhost" or the empty
string; this is interpreted as "the machine from which the URL is
being interpreted."
|
Examples:
"file:///CFCard/music/thewayup/opening.mp3"
"file:///RWM/photos/emma.jpg"
"file://localhost/RWM/photos/thekids.jpg"
|
JSR 82 Java APIs for Bluetooth Wireless Technology, version 1.0a
The presence of any Bluetooth scheme can be detected only by attempting to use it.
Serial Port Profile (SPP) (Chapter 9)
Interface: javax.microedition.io.StreamConnection
Interface: javax.microedition.io.StreamConnectionNotifier
BNF:
url ::== srvString | cliString
srvString ::== "btspp" ":" "//" srvHost 0*5(srvParams)
cliString ::== "btspp" ":" "//" cliHost 0*3(cliParams)
cliHost ::== btAddress ":" channel
srvHost ::== "localhost" ":" uuid
channel ::== %d1-30
uuid ::== 1*32(HEXDIG)
bool ::== "true" | "false"
btAddress ::== 12*12(HEXDIG)
text ::== 1*( ALPHA | DIGIT | " " | "-" | "_" )
HEXDIG ::== "A".."F" | "a".."f" | "0".."9"
ALPHA ::== "A".."Z" | "a".."z"
DIGIT ::== "0".."9"
name ::== ";name=" text
master ::== ";master=" bool
encrypt ::== ";encrypt=" bool
authorize ::== ";authorize=" bool
authenticate ::== ";authenticate=" bool
cliParams ::== master | encrypt | authenticate
srvParams ::== name | master | encrypt | authorize | authenticate
|
Examples:
"btspp://000a95020c7b:5;name=SPPex"
"btspp://localhost:8CDF20D5A6B711D99042000A95BDA676;name=SPPex"
|
Logical Link Control and Adaptation Profile (L2CAP) (Chapter 10)
Interface: javax.bluetooth.L2CAPConnection extends Connection
Interface: javax.bluetooth.L2CAPConnectionNotifier extends Connection
BNF:
url ::== srvString | cliString
srvString ::== "btl2cap" ":" "//" srvHost 0*7(srvParams)
cliString ::== "btl2cap" ":" "//" cliHost 0*5(cliParams)
cliHost ::== address ":' psm
srvHost ::== "localhost" ":" uuid
psm ::== 4*4(HEXDIG)
receiveMTU ::== ";receiveMTU=" 1*(DIGIT)
transmitMTU ::== ";transmitMTU=" 1*(DIGIT)
cliParams ::== master | encrypt | authenticate | receiveMTU | transmitMTU
srvParams ::== name | master | encrypt | authorize | authenticate |
receiveMTU | transmitMTU
|
Examples:
"btl2cap://000a95020c7b:5;name=sync l2cap"
"btl2cap://localhost:8CDF20D5A6B711D99042000A95BDA676;name=sync l2cap"
|
Object Exchange Protocol (OBEX) (Chapter 11)
Interface: javax.obex.SessionNotifier extends Connection
Interface: javax.obex.ClientSession extends Connection
Interface: javax.obex.Operation extends ContentConnection
BNF:
url ::== tcpObex | irdaObex | btObex
btObex ::== btSrvString | btCliString
tcpObex ::== tcpSrvString | tcpCliString
irdaObex ::== irdaSrvString | irdaCliString
tcpCliString ::== "tcpobex" ":" "//" tcpHost
tcpSrvString ::== "tcpobex" ":" "//" 0*1(ipPort)
ipPort ::== 1*(DIGIT)
ipAddress ::== 3*3(%d0-255 ".") (%d0-255)
ipName ::== 1*( hostLabel "." ) topLabel
topLabel ::== ALPHA | ALPHA *(alphaNum | "-") alphaNum
hostLabel ::== alphaNum | alphaNum *(alphaNum | "-") alphaNum
tcpHost ::== ipName 0*1(":" ipPort) | ipAddress 0*1(colon ipPort)
btSrvString ::== "btgoep" ":" "//" btSrvHost 0*5(btSrvParams)
btCliString ::== "btgoep" ":" "//" btCliHost 0*3(btCliParams)
btCliParams ::== master | encrypt | authenticate
btSrvParams ::== name | master | encrypt | authorize | authenticate
btCliHost ::== btAddress ":" channel
btSrvHost ::== "localhost" ":" uuid
irdaSrvString ::== "irdaobex" ":" "//" irdaSrvHost 0*1(irdaParams)
irdaCliString ::== "irdaobex" ":" "//" irdaCliHost 0*1(irdaParams)
irdaSrvHost ::== "localhost" 0*1("." 1*(DIGIT))
irdaCliHost ::== "discover" 0*1("." 1*(DIGIT))
| "addr." 2*8(HEXDIG)
| "conn"
| "name." 1*(characters)
irdaParams ::== ";ias=" 1*(characters) 0*("," 1*(characters))
characters ::== %d0-255
alphaNum ::== ALPHA | DIGIT
|
Examples:
"tcpobex://litespeed:6512"
"tcpobex://:6512"
"btgoep://000a95020c7b:996"
"btgoep://localhost:8CDF20D5A6B711D99042000A95BDA676;name=playlist"
"irdaobex://discover.08;ias=fax"
"irdaobex://localhost.08;ias=fax,OBEX,OBEX:IrXfer"
|
JSR 120 Wireless Messaging API (WMA), version 1.1
Discovery: System.getProperty( "wireless.messaging.sms.smsc" ) != null
GSM SMS Adapter (Appendix A)
Interface: javax.wireless.messaging.MessageConnection extends Connection
BNF:
url ::== "sms://" address_part
address_part ::== foreign_host_address | local_host_address
local_host_address ::== port_number_part
port_number_part ::== ":" digits
foreign_host_address ::== msisdn | msisdn port_number_part
msisdn ::== "+" digits | digits
digits ::== DIGIT | DIGIT digits
|
Examples:
"sms://+19055551212"
"sms://+14165551212:5009"
"sms://:5009"
|
GSM Cell Broadcast Adapter (Appendix B)
Interface: javax.wireless.messaging.MessageConnection extends Connection
BNF:
url ::== "cbs://" address_part
address_part ::== message_identifier_part
message_identifier_part ::== ":" digits
digits ::== DIGIT | DIGIT digits
|
Examples:
"cbs://:5009"
"cbs://:1089"
|
JSR 205 Wireless Messaging API (WMA), version 2.0
MMS Adapter (Appendix D)
Discovery: System.getProperty( "wireless.messaging.mms.mmsc" ) != null
Interface: javax.wireless.messaging.MessageConnection extends Connection
BNF:
url ::== "mms://" address_part
address_part ::== (e-mail-address | device-address | shortcode-address
| application-id)
device-address ::== general-phone-address [application-id]
general-phone-address ::== (global-telephone-type "/TYPE=PLMN")
| (ipv4 "/TYPE=IPv4")
| (ipv6 "/TYPE=IPv6")
| (escaped value "/TYPE=" address-type)
global-telephone-type ::== "+" *(DIGIT)
ipv6 ::== IETF RFC 1884
ipv4 ::== 1 *DIGIT "." 1*DIGIT "." 1*DIGIT "." 1*DIGIT
application-id ::== ":" [("com" | "org" | "edu" | "gov")] [organization] [*(package-name)] class-name
organization ::== "." *applicationID-symbol
package-name ::== "." *applicationID-symbol
class-name ::== "." *applicationID-symbol
address-type ::== *address-char
address-char ::== *(ALPHA | DIGIT | "_")
e-mail-address ::== mailbox | group
group ::== phrase "." [#mailbox] ";"
phrase ::== *(space word space)
mailbox ::== addr-spec | [phrase] route-addr
route-addr ::== "<" [route] addr-spec ">"
route ::== 1#("@" domain) ":"
addr-spec ::== local-part "@" domain
local-part ::== word *("." word)
domain ::== sub-domain *("." sub-domain)
sub-domain ::== domain-ref | domain-literal
domain-ref ::== atom
domain-literal ::== "[" *(dtext | quoted-pair) "]"
atom ::== ALPHA | DIGIT | "!" | "#" | "$" | "%" | "'" | "*"
| "+" | "-" | "=" | "?" | "{" | "}" | "|" | "~"
| "^" | "_"
word ::== atom | quoted-string
quoted-string ::== '"' (qtext | qpair) *endq"
qtext ::== (^'"')["\"]
endq ::== [^"\\"]
space ::== *(" ")
qpair ::== "\\."
shortcode-address ::== shortcode-string
shortcode-string ::== *(ALPHA | DIGIT | "!" | '"' | "$" | "%" | "&"
| "/" | "(" | ")" | "+" | "*" | "." | "-"
| "/" | "=" | "< | ">" | "[" | "]" | "_"
| "^" | "?" | "{" | "}" | "'" | "~" | ";"
applicationID-symbol ::== ALPHA | DIGIT | "." | "_"
|
Note: There is no definition of dtext.
Examples:
"mms://+14165552112"
"mms://richard@sun.com"
"mms://+16475551212:com.sun.wireless.photo"
"mms://:com.sun.wireless.voicenote"
|
References
Acknowledgements
Thanks to Roger Riggs, who took the time to review this tip.
|