/* * Copyright (c) 2008, Swedish Institute of Computer Science. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Institute nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: MoteProgrammerProcess.java,v 1.1 2010/11/03 14:53:05 adamdunkels Exp $ * * ----------------------------------------------------------------- * * MoteProgrammerProcess * * Authors : Joakim Eriksson, Niclas Finne * Created : 10 jul 2008 * Updated : $Date: 2010/11/03 14:53:05 $ * $Revision: 1.1 $ */ package se.sics.contiki.collect; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * */ public class MoteProgrammerProcess { public static final String BSL_WINDOWS = "./tools/msp430-bsl-windows.exe"; public static final String BSL_LINUX = "./tools/msp430-bsl-linux"; private final String moteID; private final String firmwareFile; private final String[][] commandSet; private int retry = 3; private Process currentProcess; private Thread commandThread; private boolean isRunning; private boolean hasError; public MoteProgrammerProcess(String moteID, String firmwareFile) { this.moteID = moteID; this.firmwareFile = firmwareFile; String osName = System.getProperty("os.name").toLowerCase(); String bslCommand; if (osName.startsWith("win")) { bslCommand = BSL_WINDOWS; } else { bslCommand = BSL_LINUX; } commandSet = new String[][] { { bslCommand, "--telosb", "-c", moteID, "-e" }, { bslCommand, "--telosb", "-c", moteID, "-I", "-p", firmwareFile }, { bslCommand, "--telosb", "-c", moteID, "-r" } }; } public String getMoteID() { return moteID; } public String getFirmwareFile() { return firmwareFile; } public int getRetry() { return retry; } public void setRetry(int retry) { this.retry = retry; } public boolean isRunning() { return isRunning; } public boolean hasError() { return hasError; } public void start() { if (isRunning) { // Already running return; } isRunning = true; commandThread = new Thread(new Runnable() { public void run() { try { int count = 0; do { if (count > 0) { logLine("An error occurred. Retrying.", true, null); } count++; hasError = false; for (int j = 0, m = commandSet.length; j < m && isRunning && !hasError; j++) { runCommand(commandSet[j]); Thread.sleep(2000); } } while (isRunning && hasError && count < retry); } catch (Exception e) { e.printStackTrace(); } finally { isRunning = false; processEnded(); } } }); commandThread.start(); } public void stop() { isRunning = false; Process process = currentProcess; if (process != null) { process.destroy(); } } public void waitForProcess() throws InterruptedException { if (isRunning && commandThread != null) { commandThread.join(); } } protected void processEnded() { } private void runCommand(String[] cmd) throws IOException, InterruptedException { if (currentProcess != null) { currentProcess.destroy(); } currentProcess = Runtime.getRuntime().exec(cmd); final BufferedReader input = new BufferedReader(new InputStreamReader(currentProcess.getInputStream())); final BufferedReader err = new BufferedReader(new InputStreamReader(currentProcess.getErrorStream())); /* Start thread listening on stdout */ Thread readInput = new Thread(new Runnable() { public void run() { String line; try { while ((line = input.readLine()) != null) { handleLine(line, false); } input.close(); } catch (IOException e) { logLine("Error reading from command", false, e); } } }, "read stdout thread"); /* Start thread listening on stderr */ Thread readError = new Thread(new Runnable() { public void run() { String line; try { while ((line = err.readLine()) != null) { handleLine(line, true); } err.close(); } catch (IOException e) { logLine("Error reading from command", true, e); } } }, "read stderr thread"); readInput.start(); readError.start(); // Wait for the bsl program to finish executing readInput.join(); currentProcess = null; } private void handleLine(String line, boolean stderr) { if (line.toLowerCase().contains("error")) { hasError = true; } logLine(line, stderr, null); } protected void logLine(String line, boolean stderr, Throwable e) { if (stderr) { System.err.println("Programmer@" + moteID + "> " + line); } else { System.out.println("Programmer@" + moteID + "> " + line); } if (e != null) { e.printStackTrace(); } } protected String toString(String[] cmd) { StringBuilder sb = new StringBuilder(); for (int i = 0, n = cmd.length; i < n; i++) { if (i > 0) sb.append(' '); sb.append(cmd[i]); } return sb.toString(); } }