BluetoothUrlpublic class BluetoothUrl extends Object Represents a bluetooth url, i.e. connection string.
There are two ways of usage. First one is constructing it giving
url string in order to parse it into a set of fields. Second one
is constructig it giving fields values in order to get string
representation. Whenever incompatible url parts are found
IllegalArgumentException is thrown. |
Fields Summary |
---|
public boolean | isServerIndicates if it is a sever connection string. | public String | addressKeeps server address for client url, "localhost" for server. | public int | portPSM for L2CAP or channel id for RFCOMM. | public boolean | masterMaster parameter, true by default for server. | public boolean | encryptEncrypt parameter. | public boolean | authenticateAuthenticate parameter. | public static final int | L2CAPValue to indicate L2CAP protocol. | public static final int | RFCOMMValue to indicate RFCOMM protocol. | public static final int | OBEXValue to indicate OBEX protocol. | public static final int | UNKNOWNValue to indicate unknown protocol. | public int | protocolIndicates protocol type. | private static final int | PROTOCOLS_AMOUNTAmount of protocols supported. | private static final String[] | protocolNameKeeps protocols indicating strings.
Usage:
protocolName[L2CAP] to get "l2cap" | public String | uuidKeeps uuid from server connection string,
null for client's one.
L2CAP, RFCOMM specific. | public String | nameName parameter of server url, null for client's one.
L2CAP, RFCOMM specific. | private String | urlUrl string to parse, lower case. | public String | caseSensitiveUrlUrl string to parse, original case.
Required for correct "name" parameter parsing for it is case-sensitive. | public boolean | authorizeAuthorize parameter. L2CAP specific. | public int | receiveMTURecieveMTU parameter. L2CAP specific. | public int | transmitMTUTransmitMTU parameter. L2CAP specific. | public static final javax.bluetooth.UUID | UUID_SDPUUID value to create a transport for Service Discovery Protocol. | private boolean | explicitAuthenticateIndicates if an explicit "authenticate" parameter found. | private static final String | LOCALHOSTKeeps server host string. | private int | lengthKeeps length of url. | private static final String | MASTERMaster parameter name. | private static final String | ENCRYPTEncrypt parameter name. | private static final String | AUTHENTICATEAuthenticate parameter name. | private static final String | AUTHORIZEAuthorize parameter name. | private static final String | TRANSMITMTUTransmitMTU parameter name. | private static final String | RECEIVEMTUReceiveMTU parameter name. | private static final String | NAMEName parameter name. | private static final String | TRUE"true" literal. | private static final String | FALSE"false" literal. | private Hashtable | parametersthe URL parameters. | private static final Object | onStub object for values in parameters hashtable. | private boolean | isSystemShows whether this url is generated and validated by SDP routines. |
Constructors Summary |
---|
public BluetoothUrl(String urlString)Constructs url object by specified url string. Constructing
BluetoothUrl in this manner is a way to parse
an url represented by string.
this(UNKNOWN, urlString, null);
| public BluetoothUrl(int protocol, String urlString)Constructs url object by specified protocol and url string without
leading protocol name and colon or if protocol is unknown by s string
that contains full url.
this(protocol, urlString, null);
| public BluetoothUrl(int protocol, String urlString, Object systemToken)Constructs url object with specified protocol, url and special system
token.
this(protocol);
isSystem = SDP.checkSystemToken(systemToken);
caseSensitiveUrl = urlString;
url = urlString.toLowerCase();
length = url.length();
int start;
int separator = url.indexOf(':");
if (protocol == UNKNOWN) {
// url is "PROTOCOL://ADDRESS:...", parsing protocol name
assertTrue(separator > 0, "Cannot parse protocol name: " + url);
start = separator + 3; // skip "://"
String name = urlString.substring(0, start);
for (int i = 0; i < PROTOCOLS_AMOUNT; i++) {
if (protocolName[i].equals(name)) {
this.protocol = i;
separator = url.indexOf(':", start);
break;
}
}
} else {
// url is "//ADDRESS:...", parsing protocol name
assertTrue(urlString.startsWith("//"),
"address and protocol name have to be separated by //: " + url);
// skip "//"
start = 2;
}
assertTrue(separator > start, "Cannot parse address: " + url);
address = url.substring(start, separator);
start = separator + 1;
if (this.protocol == L2CAP) {
// parsing psm or uuid
if (address.equals(LOCALHOST)) {
isServer = true;
// Now uuid goes till end of string or semicolon.
separator = getSeparator(start);
uuid = url.substring(start, separator);
} else {
// Now psm goes which is represented by 4 hex digits.
assertTrue((separator = start + 4) <= length,
"psm has to be represented by 4 hex digits: " + url);
port = parseInt(start, separator, 16);
}
} else if (this.protocol == RFCOMM ||
this.protocol == OBEX) {
separator = getSeparator(start);
if (address.equals(LOCALHOST)) {
isServer = true;
// Now uuid goes till end of string or semicolon.
uuid = url.substring(start, separator);
} else {
// Now channel id goes which is represented by %d1-30.
assertTrue(separator <= length,
"channel id has to go after address: " + url);
port = parseInt(start, separator, 10);
}
} else {
separator = getSeparator(start);
port = parseInt(start, separator, 16);
}
if (isServer) {
int length;
assertTrue(uuid != null && (length = uuid.length()) > 0 &&
length <= 32, "Invalid UUID");
} else {
checkBluetoothAddress();
}
// parsing parameters
parameters = new Hashtable();
for (start = separator; start < length; start = parseParameter(start));
parameters = null;
assertTrue(start == length, "Cannot parse the parameters: " + url);
| private BluetoothUrl(int protocol)Universal private constructor.
assertTrue(protocol <= UNKNOWN, "Unknown protocol name: " + protocol);
this.protocol = protocol;
|
Methods Summary |
---|
private static void | assertTrue(boolean condition, java.lang.String details)Asserts that given condition is true.
if (!condition) {
throw new IllegalArgumentException("unexpected parameter: " +
details);
}
| private void | checkBluetoothAddress()Checks the string given is a valid Bluetooth address, which means
consists of 12 hexadecimal digits.
String errorMessage = "Invalid Bluetooth address";
assertTrue(address != null && address.length() == 12 &&
address.indexOf('-") == -1, errorMessage);
try {
Long.parseLong(address, 16);
} catch (NumberFormatException e) {
assertTrue(false, errorMessage);
}
| private boolean | checkNameFormat(java.lang.String name)Checks name format.
name = 1*( ALPHA / DIGIT / SP / "-" / "_")
The core rules from RFC 2234.
char[] a = name.toCharArray();
boolean ret = a.length > 0;
for (int i = a.length; --i >= 0 && ret;) {
ret &= (a[i] >= 'a" && a[i] <= 'z") ||
(a[i] >= 'A" && a[i] <= 'Z") ||
(a[i] >= '0" && a[i] <= '9") ||
(a[i] == '-") ||
(a[i] == '_") ||
(a[i] == ' ");
}
return ret;
| public static com.sun.midp.io.BluetoothUrl | createClientUrl(int protocol, java.lang.String btaddr, int port)Creates url that represents client connection string.
assertTrue(protocol != UNKNOWN && btaddr != null,
"Either unknown protocol name or address");
BluetoothUrl url = new BluetoothUrl(protocol);
url.address = btaddr.toLowerCase();
url.checkBluetoothAddress();
url.port = port;
return url;
| public java.lang.String | getResourceName()Creates string representation of the URL without parameters.
assertTrue(protocol == L2CAP ||
protocol == RFCOMM ||
protocol == OBEX,
"Incorrect protocol bname: " + protocol);
assertTrue(address != null, "Incorrect address: "+ address);
return protocolName[protocol] + address;
| private int | getSeparator(int start)Retrieves position of semicolon in the rest of url string, returning
length of the string if no semicolon found. It also assertd that a
non-empty substring starts from start given and ends
before semicolon or end of string.
int separator = url.indexOf(';", start);
if (separator < 0) {
separator = length;
}
assertTrue(start < separator, "Correct separator is not found");
return separator;
| public final boolean | isSystem()Tests if this URL is system one. System URL can only by created
by SDP server or client and is processed in special way.
return isSystem;
| private boolean | parseBoolean(int start, int separator)Parses boolean value from url string.
String value = url.substring(start, separator);
if (value.equals(TRUE)) {
return true;
}
assertTrue(value.equals(FALSE), "Incorrect boolean parsing: " + value);
return false;
| private int | parseInt(int start, int separator, int radix)Parses integer value from url string.
int result = -1;
try {
result = Integer.parseInt(
url.substring(start, separator), radix);
} catch (NumberFormatException e) {
assertTrue(false, "Incorrect int parsing: " +
url.substring(start, separator));
}
return result;
| private int | parseParameter(int start)Parses parameter in url starting at given position and cheks simple
rules or parameters compatibility. Parameter is ";NAME=VALUE". If
parsing from given position or a check fails,
IllegalArgumentException is thrown.
assertTrue(url.charAt(start) == ';",
"Cannot parse url parameters: " + url);
int separator = url.indexOf('=", start) + 1;
assertTrue(separator > 0, "Cannot parse url parameters: " + url);
// name is ";NAME="
String name = url.substring(start, separator);
start = separator;
separator = getSeparator(start);
assertTrue(!parameters.containsKey(name),
"Duplicate parameter " + name);
parameters.put(name, on);
if (name.equals(MASTER)) {
master = parseBoolean(start, separator);
} else if (name.equals(ENCRYPT)) {
encrypt = parseBoolean(start, separator);
if (encrypt && !explicitAuthenticate) {
authenticate = true;
}
} else if (name.equals(AUTHENTICATE)) {
authenticate = parseBoolean(start, separator);
explicitAuthenticate = true;
} else if (name.equals(NAME)) {
assertTrue(isServer, "Incorrect parameter for client: " + name);
// this parameter is case-sensitive
this.name = caseSensitiveUrl.substring(start, separator);
assertTrue(checkNameFormat(this.name),
"Incorrect name format: " + this.name);
} else if (name.equals(AUTHORIZE)) {
assertTrue(isServer, "Incorrect parameter for client: " + name);
authorize = parseBoolean(start, separator);
if (authorize && !explicitAuthenticate) {
authenticate = true;
}
} else if (protocol == L2CAP) {
if (name.equals(RECEIVEMTU)) {
receiveMTU = parseInt(start, separator, 10);
assertTrue(receiveMTU > 0,
"Incorrect receive MTU: " + receiveMTU);
} else if (name.equals(TRANSMITMTU)) {
transmitMTU = parseInt(start, separator, 10);
assertTrue(transmitMTU > 0,
"Incorrect transmit MTU: " + transmitMTU);
} else {
assertTrue(false, "Unknown parameter name = " + name);
}
} else {
assertTrue(false, "Unknown parameter name = " + name);
}
return separator;
| public java.lang.String | toString()Checks url parts consistency and creates string representation.
assertTrue(protocol == L2CAP ||
protocol == RFCOMM ||
protocol == OBEX,
"Incorrect protocol bname: " + protocol);
StringBuffer buffer = new StringBuffer();
buffer = new StringBuffer(getResourceName());
buffer.append(':");
if (isServer) {
buffer.append(uuid);
buffer.append(AUTHORIZE).append(authorize ? TRUE : FALSE);
} else {
String portStr;
if (protocol == L2CAP) {
// in case of l2cap, the psm is 4 hex digits
portStr = Integer.toHexString(port);
for (int pad = 4 - portStr.length(); pad > 0; pad--) {
buffer.append('0");
}
} else if (protocol == RFCOMM ||
protocol == OBEX) {
portStr = Integer.toString(port);
} else {
portStr = Integer.toString(port);
}
buffer.append(portStr);
}
/*
* note: actually it's not required to add the boolean parameter if it
* equals to false because if it is not present in the connection
* string, this is equivalent to 'such parameter'=false.
* But some TCK tests check the parameter is always present in
* URL string even its value is false.
* IMPL_NOTE: revisit this code if TCK changes.
*/
buffer.append(MASTER).append(master ? TRUE : FALSE);
buffer.append(ENCRYPT).append(encrypt ? TRUE: FALSE);
buffer.append(AUTHENTICATE).append(authenticate ? TRUE : FALSE);
if (receiveMTU != -1) {
buffer.append(RECEIVEMTU).append(
Integer.toString(receiveMTU, 10));
}
if (transmitMTU != -1) {
buffer.append(TRANSMITMTU).append(
Integer.toString(transmitMTU, 10));
}
return buffer.toString();
|
|