Subversion Repositories HomeAutomation

Rev

Rev 462 | Rev 586 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

using System;
using System.Threading;
using System.Collections.Generic;
using System.Text;

class Program {
    const byte DEBUG_LEVEL = 3; //0, 1, 2, 3
    
    //connects to candaemon on tcp to send and receive packets
    static DaemonConnection dc;
    //a commandline arguments parser
    static Arguments CommandLine;
    //functions for downloading hex to target
    static Downloader dl;
    //maintains a hexfile
    private static HexFile hf;
    
    static bool aBios=false;        //if commandline says it is a bios update
    static bool aReset=false;       //if commandline says a reset should be sent before downloading to target
    static bool aStart=false;       //if commandline says a start should be sent after downloading to target
    static bool aTerminal=false;    //if commandline says we should start in interactive mode
        
    static bool sNodeid=false;      //true when a nodeid has been parsed
    static bool sHexfile=false;     //true when a hexfile has been specified
        
    static string hexfile=null;     //path to a hexfile
    static byte nodeid=0;           //id of current node
    static string host=null;        //address of candaemon-host
    static int port=1200;           //port of candaemon-host
    
    static void Main(string[] args) {
        bool error = false;
        if (args.Length < 4) {
            //if to few arguments then print info and quit
            printSyntax();
            error = true;
        } 

        if (!error) {
            //parse commandline arguments
            CommandLine=new Arguments(args);
            
            //check single arguments
            if (CommandLine["b"] == "true") { aBios = true; }
            if (CommandLine["r"] == "true") { aReset = true; }
            if (CommandLine["s"] == "true") { aStart = true; }
            if (CommandLine["t"] == "true") { aTerminal = true; }
            
            //check hexfile argument
            hexfile = CommandLine["f"];
            if (hexfile != null) {
                sHexfile = true;
            }
            if (!aTerminal && !sHexfile) {
                if (DEBUG_LEVEL>0) { Console.WriteLine("When not in terminal mode a hexfile must be supplied, I quit"); }
                error = true;
            } 
            
            //check nodeid argument
            string node = CommandLine["n"];
            if (node != null) {
                if (!parseNodeId(node)) {
                    error = true;
                }
            }
            if (!aTerminal && !sNodeid) {
                if (DEBUG_LEVEL>0) { Console.WriteLine("When not in terminal mode a nodeid must be supplied, I quit"); }
                error = true;
            } 
            
            //check host and port arguments
            host = CommandLine["h"];
            string sPort = CommandLine["p"];
            if ((host == null) || (sPort.Length == 0)) {
                if (DEBUG_LEVEL>0) { printSyntax(); }
                error = true;
            } else {
                try {
                    port = int.Parse(sPort);
                } catch {
                    if (DEBUG_LEVEL>0) { Console.WriteLine("Was not able to parse port, I quit"); }
                    error = true;
                }
            }
        }
        
        if  (!error) {
            //commandline feedback output
            if (DEBUG_LEVEL>2) { 
                Console.WriteLine("canDude settings:");
                if (sNodeid) { Console.WriteLine("Nodeaddress: 0x" + String.Format("{0:x2}", nodeid)); }
                Console.WriteLine("Host: {0}:{1}", host, port);
                if (hexfile != null) { Console.WriteLine("Hexfile: {0}", hexfile); }
                Console.Write("Parameters: ");
                if (aBios) { Console.Write("Bios "); }
                if (aReset) { Console.Write("Reset "); }
                if (aStart) { Console.Write("Start "); }
                if (aTerminal) { Console.Write("Terminal"); }
                Console.WriteLine("");
            }
        }
        
        if (!error) {
            //connect to candaemon
            dc = new DaemonConnection();
            if (dc.init(host, port)) {
                if (DEBUG_LEVEL>1) { Console.WriteLine("Connected to candaemon"); }
            } else { 
                if (DEBUG_LEVEL>0) { Console.WriteLine("Connection to candaemon could not be established, I quit"); }
                error = true; 
            }
        }
            
        if (!error && aTerminal) {
            //terminal mode (==interactive mode)
            bool success = true;
            //load hexfile if one has been specified as commandline argument
            hf = new HexFile();
            if (sHexfile && success) {
                if (hf.loadHex(hexfile)) {
                    if (DEBUG_LEVEL>1) { Console.WriteLine("Hexfile loaded"); }
                } else { success = false; }
            }
            
            if (success) {
                if (DEBUG_LEVEL>1) {
                    Console.WriteLine("");
                    printHelp();        //print available commands
                    Console.WriteLine("");
                }
                
                string instr;
                do {
                    Console.Write("> ");            //a command has been executed, print a new console char
                    instr = Console.ReadLine();     //read std in
                } while (parseInput(instr));        //parse a line from std in
                
                //exit command
            }
        }

        if (!error && !aTerminal) {
            //not terminal mode
            bool success = true;
            
            //load hexfile (a hexfile must be supplied as commandline argument)
            hf = new HexFile();
            if (hf.loadHex(hexfile)) {
                if (DEBUG_LEVEL>1) { Console.WriteLine("Hexfile loaded"); }
            } else { 
                success = false;
                if (DEBUG_LEVEL>0) { Console.WriteLine("Hexfile could not be loaded, I quit"); }
            }
            
            //if a hexfile is loaded then start autodownloading sequence
            if (success) {
                bool autosuccess = true;
                
                CanNMT cpn = new CanNMT();
                if (aReset) {
                    //send a reset command (and wait for feedback)
                    if (!cpn.doReset(dc, nodeid)) {
                        if (DEBUG_LEVEL>0) { Console.WriteLine("Target node did not respond to reset, I quit"); }
                        autosuccess = false;
                    }
                }
                
                if (autosuccess) {
                    //send application
                    dl = new Downloader(hf, dc, nodeid, aBios);
                    if (!dl.go()) { 
                        if (DEBUG_LEVEL>0) { Console.WriteLine("Error occured during download"); }
                        autosuccess = false;
                    }
                }
                
                if (autosuccess && aStart) {
                    //start application
                    cpn.doStart(dc, nodeid);
                }
                
            }
        }
        if (dc != null) {
            //stop tcp client thread
            dc.stop();
        }
    }
    
    static private void printSyntax() {
        Console.WriteLine("Syntax: program.exe [options] -h <host> -p <port>");
        Console.WriteLine("Host and port are host and port of canDaemon, most likely localhost and 1200.");
        Console.WriteLine("Options:");
        Console.WriteLine("  -f <hexfile>   Specify a file to be loaded to target.");
        Console.WriteLine("  -n <nodeid>    Id of target node, hex or decimal.");
        Console.WriteLine("  -t             Enter terminal mode.");
        Console.WriteLine("  -r             Reset node before loading target.");
        Console.WriteLine("  -s             Start node after loading target.");
        Console.WriteLine("  -b             Program hex as bios, use with caution.");
    }
    
    static private void printHelp() {
        Console.WriteLine("canDude commands:");
        Console.WriteLine("load [<hexfile>] - reload hexfile or load new hexfile");
        Console.WriteLine("node <nodeid>    - specify id of target node, hex or decimal");
        Console.WriteLine("reset            - reset node");
        Console.WriteLine("start            - start application in node (no feedback yet)");
        Console.WriteLine("go               - start download application to target");
        Console.WriteLine("go bios          - start download bios to target, use with caution");
        Console.WriteLine("help             - prints this help");
        Console.WriteLine("exit or quit     - exit program");
    }   
    
    static private bool parseNodeId(string node) {
        // the goal here is to find a byte from 0-255 in a string, format in decimal (0-255) or in hex (0x0-0xff)
        // this is probably not done very neat
        sNodeid = false;
        if (node.Length > 0) {
            try {
                nodeid = byte.Parse(node);
                sNodeid = true;
            } catch {}
        }
        if (node.Length > 2) {
            if (node.Substring(0, 2).Equals("0x")) {
                if (node.Length == 3) {
                    try {
                        nodeid = byte.Parse(node.Substring(2, 1), System.Globalization.NumberStyles.HexNumber);
                        sNodeid = true;
                    } catch {
                        if (DEBUG_LEVEL>0) { Console.WriteLine("nodeadress parse error 1"); }
                        return false;
                    }
                } else if (node.Length == 4) {
                    try {
                        nodeid = byte.Parse(node.Substring(2, 2), System.Globalization.NumberStyles.HexNumber);
                        sNodeid = true;
                    } catch {
                        if (DEBUG_LEVEL>0) { Console.WriteLine("nodeadress parse error 2"); }
                        return false;
                    }
                } else {
                    if (DEBUG_LEVEL>0) { Console.WriteLine("nodeadress parse error 3"); }
                    return false;
                }
            }
        }
        
        return true;
    }
    
    static private bool parseInput(string instr) {
        //parse commands entered on std in
        if (instr.Equals("reset")) {        //reset command, send a reset to current node
            if (sNodeid) {
                dc.flushData();
                CanNMT cpn = new CanNMT();
                cpn.doReset(dc, nodeid);
            } else {
                if (DEBUG_LEVEL>0) { Console.WriteLine("No nodeid has been specified"); }
            }
        }
        else if (instr.Equals("start")) {   //start command, send a start to current node
            if (sNodeid) {
                CanNMT cpn = new CanNMT();
                cpn.doStart(dc, nodeid);
            } else {
                if (DEBUG_LEVEL>0) { Console.WriteLine("No nodeid has been specified"); }
            }
        }
        else if (instr.StartsWith("go")) {  //downloading command
            bool dlBios = false;
            bool error = true;
            if (instr.Equals("go bios")) {  //if bios should be downloaded
                dlBios = true;
                error = false;
            } else if (instr.Equals("go")) {    //is an application should be downloaded
                error = false;
            }
            
            if (!sNodeid) {
                if (DEBUG_LEVEL>0) { Console.WriteLine("No nodeid has been specified"); }
                error = true;
            }
            if (!sHexfile) {
                if (DEBUG_LEVEL>0) { Console.WriteLine("No hexfile has been specified"); }
                error = true;
            }
            
            CanNMT cpn = new CanNMT();
            if (!error && aReset) {             //commandline arguments specified that a reset should be done before download
                //send a reset command (and wait for feedback)
                if (!cpn.doReset(dc, nodeid)) {
                    if (DEBUG_LEVEL>0) { Console.WriteLine("Target node did not respond to reset"); }
                    error = true;
                }
            }
                
            if (!error) {
                //send application
                dc.flushData();
                dl = new Downloader(hf, dc, nodeid, dlBios);
                if (!dl.go()) { 
                    if (DEBUG_LEVEL>0) { Console.WriteLine("Error occured during download"); }
                    error = true;
                }
            }
                
            if (!error && aStart) {             //commandline arguments specified that a start should be done after download
                //start applikation
                cpn.doStart(dc, nodeid);
            }
            
        }
        else if (instr.StartsWith("load")) {    //load hexfile or reload current hexfile
            if (instr.Length > 5) {
                //second argument is a hexfile, this file should be loaded
                hexfile = instr.Substring(5);
                if (hf.loadHex(hexfile)) {
                    sHexfile = true;
                    if (DEBUG_LEVEL>1) { Console.WriteLine("Hexfile loaded"); }
                } else { 
                    if (DEBUG_LEVEL>0) { Console.WriteLine("Hexfile could not be loaded"); }
                }
            } else {
                //reload current hexfile. if a hexfile already has been specified
                if (sHexfile) {
                    if (hf.loadHex(hexfile)) {
                        if (DEBUG_LEVEL>1) { Console.WriteLine("Hexfile reloaded"); }
                    } else { 
                        if (DEBUG_LEVEL>0) { Console.WriteLine("Hexfile could not be reloaded"); }
                    }
                } else {
                    if (DEBUG_LEVEL>0) { Console.WriteLine("No hexfile has been specified"); }
                }
                
            }
        }
        else if (instr.StartsWith("node")) {
            //change nodeid
            if (instr.Length > 5) {
                //second argument is nodeid
                string node = instr.Substring(5);
                parseNodeId(node);
            }
            if (DEBUG_LEVEL>1) { Console.WriteLine("NodeId is 0x"+ String.Format("{0:x2}", nodeid)); }
        }
        else if (instr.Equals("help")) {
            printHelp();
        }
        else if (instr.Equals("exit") || instr.Equals("quit") || instr.Equals("q")) {
            return false;
        }
        else {
            Console.WriteLine("Unknown command.");
        }
        
        return true;
    }
    
}