/* * * * 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); }