import java.io.*; import java.lang.*; /** * ServerBeacon is a stand-alone class that acts as a broadcasting station * for use in an ultrasound/802.11 indoor positioning system. It is meant * to run on a stationary computer with speakers and 802.11 broadcast * capabilities. This class instantiates a Broadcaster thread with its * host computer's room information. The Broadcaster thread periodically * sends out concurrent 802.11 room information-bearing broadcasts and * ultrasound pulses. By listening for these broadcasts, mobile clients * should be able to identify their room location within a building. *
* The room information that is wirelessly broadcasted is read from a * configuration file in the same directory as this class. This file, * called 'beacon.conf' should have a "MESSAGE=" identifier that defines * a unique room-identifying string. For example, the following * beacon.conf could be used on a computer in a 5th-floor office of * building "CompSci": MESSAGE=CompSci Room 534. The format of the * message string should match the format required by whatever * location-dependent application is running on the mobile clients. * * @author Tony Offer * @author Chris Palistrant * @version 1.0 */ public class ServerBeacon { // Define the default name of the configuration file that // contains the room identification message. public static final String CONFIG_FILE = "beacon.conf"; // FileReader.read() method returns -1 at the end of a stream, // so let this program know what that looks like as a char. public static final char EOF = (char) -1; /** * Simple method for reading the next character from a file * encapsulates the catching of an IOException. * * @param theFile the FileReader object from which to read * @return the next character (as an int) in the file */ public static int getNextChar(FileReader theFile) { int returnChar = -1; try { returnChar = theFile.read(); } catch (IOException ioe) { System.out.println("Error: IO Exception"); ioe.printStackTrace(); } return returnChar; } /** * Simple method for reading the next character from the command * line. It is meant to encapsulate the catching of an IOException. * * @return the next character from standard input */ public static int getStdIn() { int returnChar = -1; try { returnChar = System.in.read(); } catch (IOException ioe) { System.out.println("Error: IO Exception"); ioe.printStackTrace(); } return returnChar; } /** * Can be given two parameters which are the MIN and MAX times to wait between * transmissions. */ public static void main(String [] args) { // Get the configuration file from its default location, which // is the same directory from which this class is being run. File f = new File(CONFIG_FILE); // First make sure that the configuration file exists and is // readable. boolean fileError = false; if (!f.exists()) { System.out.println("Error: Configuration file " + CONFIG_FILE + " does not exist."); fileError = true; } if (!f.canRead()) { System.out.println("Error: Could not read configuration file " + CONFIG_FILE + "."); fileError = true; } if (fileError) System.exit(0); // Instantiate a file reader for this configuration file. FileReader conf = null; try { conf = new FileReader(f); } catch (FileNotFoundException fnfe) { fnfe.printStackTrace(); System.exit(1); } // Parse the configuration file. char nextChar = (char) getNextChar(conf); String message = ""; while (nextChar != EOF) { // Read from the file up to the first occurrence of '=', at which // point an identifier has been completely parsed. Switch on // this identifier in order to determine what to do with the // information. String identifier = ""; while (nextChar != '=' && nextChar != EOF) { identifier += nextChar; nextChar = (char) getNextChar(conf); } if (identifier.equals("MESSAGE")) { // Don't include '=' in the message. nextChar = (char) getNextChar(conf); // Read in the entire string after the '='. while (nextChar != '\n' && nextChar != '\r' && nextChar != EOF) { message += nextChar; nextChar = (char) getNextChar(conf); } } // Put any other additional identifiers here, as needed. else { System.out.println("Improper configuration file format. " + "Identifier " + identifier + " is invalid."); System.exit(0); } if (nextChar != -1) nextChar = (char) getNextChar(conf); } // About to start broadcasting. Tell the user how to exit. System.out.println("Server beacon activating ..."); System.out.println("Press 'x' and then ENTER to terminate program."); // Convert string to bytes and start a Broadcaster thread with these bytes. Broadcaster beacon = new Broadcaster(message.getBytes()); if(args.length == 2) { beacon.MINTIME = Integer.parseInt(args[0]); beacon.MAXTIME = Integer.parseInt(args[1]); } beacon.start(); // Read in a character from stdin until the character 'x' is // read. If 'x' is read, terminate the broadcaster thread. char ch = (char) getStdIn(); while(ch != 'x' && ch != 'X') { ch = (char) getStdIn(); } beacon.terminate(); // Sleep for a short period of time so that the Java Virtual // Machine is not destroyed before the Broadcaster thread has a // chance to gracefully shut itself down. try { Thread.sleep(250); } catch (InterruptedException ie) { ie.printStackTrace(); } System.exit(0); } }