/*
*
*
* Copyright 1990-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version
* 2 only, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 for more details (a copy is
* included at /legal/license.txt).
*
* You should have received a copy of the GNU General Public License
* version 2 along with this work; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 or visit www.sun.com if you need additional
* information or have any questions.
*/
package com.sun.jsr082.bluetooth;
import java.io.IOException;
import javax.bluetooth.DiscoveryAgent;
import com.sun.jsr082.bluetooth.btl2cap.L2CAPNotifierImpl;
import com.sun.jsr082.bluetooth.btspp.BTSPPNotifierImpl;
/*
* Bluetooth connect-anytime services support class.
*/
public class BluetoothPush {
/* 'authenticated' AllowedSender parameter. */
private static final String AUTHENTICATED = ";AUTHENTICATED";
/* 'authorized' AllowedSender parameter. */
private static final String AUTHORIZED = ";AUTHORIZED";
/* 'blacklist' AllowedSender parameter. */
private static final String BLACKLIST = ";BLACKLIST=";
/* Service record serializer instance. */
private static ServiceRecordSerializer srs = new ServiceRecordSerializer();
/*
* Checks if the specified URL is valid.
*
* @param url URL to verify
* @throws IllegalArgumentException if the URL is malformed
*/
public static void verifyUrl(String url) {
BluetoothUrl btUrl = new BluetoothUrl(url);
if ((btUrl.encrypt || btUrl.authorize) && !btUrl.authenticate) {
throw new IllegalArgumentException(
"'authenticate=true' parameter is required.");
}
}
/*
* Checks if the specified AllowedSender field is valid.
*
* @param filter filter to verify
* @throws IllegalArgumentException if the filter is malformed
*/
public static void verifyFilter(String filter) {
if (filter.length() == 0) {
throw new IllegalArgumentException();
}
filter = filter.toUpperCase();
int i = 0;
while (i < filter.length() && i < 12) {
char c = filter.charAt(i++);
if (c == '*' || c == '?') {
continue;
}
if (c == ';') {
i--;
if (i == 0) {
throw new IllegalArgumentException(
"Invalid Bluetooth address.");
}
break;
}
if ((c < '0' || c > '9') && (c < 'A' || c > 'F')) {
throw new IllegalArgumentException(
"Invalid Bluetooth address.");
}
}
filter = filter.substring(i);
if (filter.length() == 0) {
return;
}
if (filter.startsWith(AUTHENTICATED)) {
filter = filter.substring(AUTHENTICATED.length());
} else if (filter.startsWith(AUTHORIZED)) {
filter = filter.substring(AUTHORIZED.length());
}
if (filter.length() == 0) {
return;
}
if (!filter.startsWith(BLACKLIST)) {
throw new IllegalArgumentException("Invalid parameter.");
}
filter = filter.substring(BLACKLIST.length());
if (filter.length() == 0) {
throw new IllegalArgumentException("Invalid blacklist.");
}
int count = 0;
while (true) {
if (++count > 1024) {
throw new IllegalArgumentException("Blacklist too long.");
}
i = 0;
while (i < filter.length() && i < 12) {
char c = filter.charAt(i++);
if (c == '*' || c == '?') {
continue;
}
if (c == ';') {
i--;
break;
}
if ((c < '0' || c > '9') && (c < 'A' || c > 'F')) {
throw new IllegalArgumentException(
"Invalid blacklist address.");
}
}
filter = filter.substring(i);
if (filter.length() == 0) {
return;
}
if (filter.charAt(0) != ';' || filter.length() == 1) {
throw new IllegalArgumentException("Invalid blacklist.");
}
filter = filter.substring(1);
}
}
/*
* Registers URL within Bluetooth push subsytem.
*
* @param url URL to register
* @throws IOException if an I/O error occurs
*/
public static void registerUrl(String url) throws IOException {
ServiceRecordImpl record = null;
String protocol = url.substring(0, url.indexOf(':')).toUpperCase();
if (protocol.equals("BTL2CAP")) {
record = L2CAPNotifierImpl.createServiceRecord(url);
} else if (protocol.equals("BTSPP")) {
record = BTSPPNotifierImpl.createServiceRecord(url);
} else if (protocol.equals("BTGOEP")) {
record = BTSPPNotifierImpl.createServiceRecord(url);
} else {
throw new RuntimeException("Unsupported Bluetooth protocol.");
}
record.setHandle(0);
if (!BCC.getInstance().isBluetoothEnabled() &&
!BCC.getInstance().enableBluetooth()) {
throw new IOException("Bluetooth radio is not enabled.");
}
if (!registerUrl(url, srs.serialize(record))) {
throw new IOException("Error registering Bluetooth URL.");
}
if (BCC.getInstance().getAccessCode() != DiscoveryAgent.GIAC) {
BCC.getInstance().setAccessCode(DiscoveryAgent.GIAC);
}
// get the emulation services up and running
SDDB.getInstance();
}
/*
* Retrieves service record associated with a service maintained by
* Bluetooth push subsytem.
*
* @param notifier Bluetooth notifier to be used with the service record
* @param url URL used during push entry registration
* @return service record instance
*/
public static ServiceRecordImpl getServiceRecord(BluetoothNotifier notifier,
String url) {
return SDDB.getInstance().getServiceRecord(getRecordHandle(url),
notifier);
}
/*
* Registers URL within Bluetooth push subsystem.
*
* @param url URL to register
* @param data serialized service record created from the URL
* @return true on success, false on failure
*/
private native static boolean registerUrl(String url, byte[] data);
/*
* Retrieves service record handle for a service maintained by
* Bluetooth push subsytem.
*
* @param url URL used during push entry registration
* @return service record handle
*/
private native static int getRecordHandle(String url);
}