📄 deluge.java
字号:
// $Id: Deluge.java,v 1.10 2005/01/28 18:59:19 jwhui Exp $/* tab:4 * * * "Copyright (c) 2000-2004 The Regents of the University of California. * All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice, the following * two paragraphs and the author appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." * *//** * Parses a binary or ihex file and injects it to a Deluge compatible node. * * @author Jonathan Hui <jwhui@cs.berkeley.edu> */package net.tinyos.tools;import net.tinyos.message.*;import net.tinyos.util.*;import java.io.*; import java.text.*;public class Deluge implements Runnable, MessageListener { private static final int NONE = 0; private static final int PING = 1; private static final int INJECT = 2; private static final int REBOOT = 3; private static final int ERASE = 4; private static final int DUMP = 5; private static final int RECTYP_DATA = 0; private static final int RECTYP_EOF = 1; private static final int RECTYP_EXTSEG = 2; private short TOS_UART_ADDR = 0x007e; private DelugeImg image; private Thread imageThread; private MoteIF intf; private DelugeAdvMsg advMsg = new DelugeAdvMsg(); private short numPgs; private short vNum = (short)DelugeConsts.DELUGE_INVALID_VNUM; private boolean printAllMsgs = false; private short imgID = -1; private int mode = NONE; private void usage() { System.err.println("usage: java net.tinyos.tools.Deluge <action>"); System.err.println(" actions are:"); System.err.println(" -p, --ping : ping status of node"); System.err.println(" -i, --inject : inject a binary"); System.err.println(" -r, --reboot : send reboot command"); System.err.println(" -e, --erase : erase an object"); System.err.println(" -d, --dump : dumps data injected to node"); System.err.println(" -if, --ihexfile <ihex> : ihex file (program images)"); System.err.println(" -f, --file <file> : binary file (arbitrary data)"); System.err.println(" -in, --imgnum <num> : image num"); System.err.println(" -g, --goldenimg : golden image"); System.err.println(" -vn, --vnum <num> : version number"); System.err.println(" -t, --tosbase : use with TOSBase node"); System.err.println(" -v, --verbose : print all sent/received msgs"); System.err.println(" -h, --help : print this message"); System.exit(1); } private void allDone(int n) { System.out.println("-------------------------------------------------------"); System.exit(n); } Deluge(String[] args) { String infile = ""; boolean binMode = false; if (args.length == 0) usage(); System.out.println("-------------------------------------------------------"); for ( int i = 0; i < args.length; i++ ) { if (args[i].equals("-f") || args[i].equals("--file")) { if (++i < args.length) infile = args[i]; binMode = true; } else if (args[i].equals("-if") || args[i].equals("--ihexfile")) { if (++i < args.length) infile = args[i]; } else if (args[i].equals("-in") || args[i].equals("--imgnum")) { if (++i < args.length) imgID = Short.parseShort(args[i]); } else if (args[i].equals("-g") || args[i].equals("--goldenimg")) { imgID = DelugeConsts.DELUGE_GOLDEN_IMAGE_NUM; } else if (args[i].equals("-vn") || args[i].equals("--vnum")) { if (++i < args.length) vNum = (short)Integer.parseInt(args[i]); } else if (args[i].equals("-t") || args[i].equals("--tosbase")) { TOS_UART_ADDR = (short)0xffff; } else if (args[i].equals("-v") || args[i].equals("--verbose")) { printAllMsgs = true; } else if (args[i].equals("-p") || args[i].equals("--ping")) { if (mode == NONE) mode = PING; else { System.out.println("ERROR: Only one action may be specified."); allDone(1); } } else if (args[i].equals("-i") || args[i].equals("--inject")) { if (mode == NONE) mode = INJECT; else { System.out.println("ERROR: Only one action may be specified."); allDone(1); } } else if (args[i].equals("-e") || args[i].equals("--erase")) { if (mode == NONE) mode = ERASE; else { System.out.println("ERROR: Only one action may be specified."); allDone(1); } } else if (args[i].equals("-d") || args[i].equals("--dump")) { if (mode == NONE) mode = DUMP; else { System.out.println("ERROR: Only one action may be specified."); allDone(1); } } else if (args[i].equals("-r") || args[i].equals("--reboot")) { if (mode == NONE) mode = REBOOT; else { System.out.println("ERROR: Only one action may be specified."); allDone(1); } } else if (args[i].equals("-h") || args[i].equals("--help")) usage(); else usage(); } // check arguments switch(mode) { case PING: case DUMP: break; case INJECT: case ERASE: if (imgID < 0 || imgID >= DelugeConsts.DELUGE_NUM_IMGS) { System.err.println("ERROR: Image ID not specified or out of range."); allDone(1); } break; case REBOOT: if ((imgID < 0 || imgID >= DelugeConsts.DELUGE_NUM_IMGS) && (imgID != DelugeConsts.DELUGE_GOLDEN_IMAGE_NUM)) { System.err.println("ERROR: Image ID not specified or out of range."); allDone(1); } break; default: System.err.println("ERROR: No action specified."); allDone(1); break; } if (mode == DUMP || mode == INJECT) { if (binMode) { if (!readBinary(infile)) allDone(1); } else { if (!readIhex(infile)) allDone(1); } } // if simply dumping, dump and exit early if (mode == DUMP) { image.dump(); allDone(0); } System.out.println("Openning connection to node ..."); try { intf = new MoteIF((Messenger)null); intf.registerListener(new DelugeAdvMsg(), this); intf.registerListener(new DelugeReqMsg(), this); } catch (Exception e) { System.out.println("ERROR: Couldn't contact serial forwarder."); allDone(1); } intf.start(); System.out.println("Connection to node established ..."); System.out.println("-------------------------------------------------------"); for ( int i = 0; i < advMsg.get_imgSummaries_vNum().length; i++ ) advMsg.setElement_imgSummaries_vNum(i, (short)DelugeConsts.DELUGE_INVALID_VNUM); } public void run() { // setup advertisement message advMsg.set_type((short)DelugeConsts.DELUGE_ADV_PC); advMsg.set_sourceAddr(TOS_UART_ADDR); advMsg.set_globalVNum((short)DelugeConsts.DELUGE_INVALID_VNUM); advMsg.set_runningImgNum((short)DelugeConsts.DELUGE_INVALID_IMGNUM); while(true) { try { // send an advertisement message every second if (mode == PING) System.out.println("Pinging node ..."); // calc crc of adv message byte[] tmpBytes = advMsg.dataGet(); short crc = 0; for ( int i = 0; i < DelugeAdvMsg.DEFAULT_MESSAGE_SIZE-DelugeAdvMsg.size_crc(); i++ ) crc = crcByte(crc, tmpBytes[i]); advMsg.set_crc(crc); if (printAllMsgs) System.out.print(advMsg); send(advMsg); if (mode == REBOOT) { advMsg.set_globalVNum((short)DelugeConsts.DELUGE_INVALID_VNUM); advMsg.set_runningImgNum((short)DelugeConsts.DELUGE_INVALID_IMGNUM); } Thread.currentThread().sleep(1000); } catch (Exception e) { e.printStackTrace(); } } } synchronized public void messageReceived(int to, Message m) { switch(m.amType()) { case DelugeAdvMsg.AM_TYPE: DelugeAdvMsg rxAdvMsg = (DelugeAdvMsg)m; byte[] tmpBytes = rxAdvMsg.dataGet(); short crc = 0; // calc crc for ( int i = 0; i < DelugeAdvMsg.DEFAULT_MESSAGE_SIZE-DelugeAdvMsg.size_crc(); i++ ) crc = crcByte(crc, tmpBytes[i]); // drop packet if crc fails if (crc != (short)rxAdvMsg.get_crc()) return; if (printAllMsgs) System.out.print(rxAdvMsg); if (rxAdvMsg.get_type() == DelugeConsts.DELUGE_ADV_NOT_READY) { System.out.println("ERROR: Deluge is not running on node " + rxAdvMsg.get_sourceAddr() + "."); allDone(1); } switch(mode) { case PING: System.out.println(); System.out.println("Reply from node " + rxAdvMsg.get_sourceAddr() + ": "); System.out.print(" Executing image: "); if (rxAdvMsg.get_runningImgNum() == DelugeConsts.DELUGE_INVALID_IMGNUM) System.out.println("N/A"); else if (rxAdvMsg.get_runningImgNum() == DelugeConsts.DELUGE_GOLDEN_IMAGE_NUM) System.out.println("Golden Image"); else System.out.println(rxAdvMsg.get_runningImgNum()); System.out.println(" Image states: "); System.out.println("\tImage\tVersion\tPages\tComplete"); System.out.println("\t-----\t-------\t-----\t--------"); for ( int i = 0; i < DelugeConsts.DELUGE_NUM_IMGS; i++ ) { short tmpVNum = rxAdvMsg.getElement_imgSummaries_vNum(i); if (tmpVNum == DelugeConsts.DELUGE_INVALID_VNUM) { System.out.println("\t" + i + "\t------- No Image -------"); } else { System.out.println("\t" + i + "\t" + ((int)rxAdvMsg.getElement_imgSummaries_vNum(i) & 0xffff) + "\t" + rxAdvMsg.getElement_imgSummaries_numPgs(i) + "\t" + rxAdvMsg.getElement_imgSummaries_numPgsComplete(i)); } } allDone(0); break; case REBOOT: if (vNum != (short)DelugeConsts.DELUGE_INVALID_VNUM && vNum == rxAdvMsg.get_globalVNum()) { // ALL DONE, QUIT! System.out.println("Reboot message sent."); System.out.println("Please use cntl-c to exit."); while(true); //allDone(0); } if (imgID != DelugeConsts.DELUGE_GOLDEN_IMAGE_NUM) { if (rxAdvMsg.getElement_imgSummaries_numPgs(imgID) != rxAdvMsg.getElement_imgSummaries_numPgsComplete(imgID)) { System.out.println("ERROR: Cannot reboot to an incomplete image."); allDone(1); } else if (rxAdvMsg.getElement_imgSummaries_numPgs(imgID) == 0) { System.out.println("ERROR: Cannot reboot to an empty image."); allDone(1); } } if (vNum == (short)DelugeConsts.DELUGE_INVALID_VNUM) { vNum = (short)((short)rxAdvMsg.get_globalVNum() + (short)1); if (vNum == (short)DelugeConsts.DELUGE_INVALID_VNUM) vNum = 0; } else if ((short)(vNum - (short)rxAdvMsg.get_globalVNum()) < 0) { System.out.println("ERROR: Invalid version number."); allDone(1); } advMsg.set_globalVNum(vNum); advMsg.set_runningImgNum(imgID); break; case ERASE: numPgs = 0; // fall through case INJECT: if (vNum == rxAdvMsg.getElement_imgSummaries_vNum(imgID) && numPgs == rxAdvMsg.getElement_imgSummaries_numPgsComplete(imgID)) { // ALL DONE, QUIT! if (mode == ERASE) System.out.println("ERASE message sent."); else if (mode == INJECT) { System.out.println(); System.out.println("INJECTION COMPLETE!"); } allDone(0); } if (advMsg.get_runningImgNum() == 0) return; advMsg.set_globalVNum(rxAdvMsg.get_globalVNum()); advMsg.set_runningImgNum((short)0); for ( int i = 0; i < advMsg.get_imgSummaries_vNum().length; i++ ) { if ((rxAdvMsg.getElement_imgSummaries_numPgsComplete(i) != rxAdvMsg.getElement_imgSummaries_numPgs(i)) && (i < imgID)) { System.out.println("ERROR: Image " + i + " incomplete."); System.out.println(" First complete or erase image " + i + "."); allDone(1); } advMsg.setElement_imgSummaries_vNum(i, rxAdvMsg.getElement_imgSummaries_vNum(i)); advMsg.setElement_imgSummaries_numPgsComplete(i, rxAdvMsg.getElement_imgSummaries_numPgsComplete(i)); advMsg.setElement_imgSummaries_numPgs(i, rxAdvMsg.getElement_imgSummaries_numPgs(i)); } if (vNum == (short)DelugeConsts.DELUGE_INVALID_VNUM) { vNum = (short)((short)rxAdvMsg.getElement_imgSummaries_vNum(imgID) + (short)1); if (vNum == (short)DelugeConsts.DELUGE_INVALID_VNUM) vNum = 0; } else if ((short)(vNum - (short)rxAdvMsg.getElement_imgSummaries_vNum(imgID)) < 0) { System.out.println("ERROR: Invalid version number."); allDone(1); } short prevVNum = rxAdvMsg.getElement_imgSummaries_vNum(imgID);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -