Subversion Repositories HomeAutomation

Rev

Rev 473 | Rev 655 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
455 arune 1
using System;
2
using System.Threading;
3
using System.Collections.Generic;
4
using System.Text;
5
 
473 arune 6
///TODO:
7
// argument -v # (debuglevel)
8
// argument till konstruktor på alla objekt: debuglevel
9
 
455 arune 10
class Program {
11
	const byte DEBUG_LEVEL = 3;	//0, 1, 2, 3
459 arune 12
 
13
	//connects to candaemon on tcp to send and receive packets
455 arune 14
	static DaemonConnection dc;
459 arune 15
	//a commandline arguments parser
455 arune 16
	static Arguments CommandLine;
459 arune 17
	//functions for downloading hex to target
455 arune 18
	static Downloader dl;
459 arune 19
	//maintains a hexfile
20
	private static HexFile hf;
455 arune 21
 
459 arune 22
	static bool aBios=false;		//if commandline says it is a bios update
23
	static bool aReset=false;		//if commandline says a reset should be sent before downloading to target
24
	static bool aStart=false;		//if commandline says a start should be sent after downloading to target
25
	static bool aTerminal=false;	//if commandline says we should start in interactive mode
455 arune 26
 
462 arune 27
	static bool sNodeid=false;		//true when a nodeid has been parsed
28
	static bool sHexfile=false;		//true when a hexfile has been specified
455 arune 29
 
462 arune 30
	static string hexfile=null;		//path to a hexfile
31
	static byte nodeid=0;			//id of current node
32
	static string host=null;		//address of candaemon-host
33
	static int port=1200;			//port of candaemon-host
455 arune 34
 
35
	static void Main(string[] args) {
36
		bool error = false;
37
		if (args.Length < 4) {
462 arune 38
			//if to few arguments then print info and quit
39
			printSyntax();
455 arune 40
			error = true;
41
		} 
42
 
43
		if (!error) {
462 arune 44
			//parse commandline arguments
455 arune 45
			CommandLine=new Arguments(args);
46
 
462 arune 47
			//check single arguments
455 arune 48
			if (CommandLine["b"] == "true") { aBios = true; }
49
			if (CommandLine["r"] == "true") { aReset = true; }
50
			if (CommandLine["s"] == "true") { aStart = true; }
51
			if (CommandLine["t"] == "true") { aTerminal = true; }
462 arune 52
 
53
			//check hexfile argument
455 arune 54
			hexfile = CommandLine["f"];
55
			if (hexfile != null) {
56
				sHexfile = true;
57
			}
473 arune 58
			if (!aTerminal && !sHexfile && !aReset && !aStart) {
59
				if (DEBUG_LEVEL>0) { Console.WriteLine("When not in terminal mode a hexfile, a reset or a start parameter must be supplied, I quit"); }
455 arune 60
				error = true;
61
			} 
62
 
462 arune 63
			//check nodeid argument
455 arune 64
			string node = CommandLine["n"];
456 arune 65
			if (node != null) {
66
				if (!parseNodeId(node)) {
67
					error = true;
68
				}
455 arune 69
			}
70
			if (!aTerminal && !sNodeid) {
462 arune 71
				if (DEBUG_LEVEL>0) { Console.WriteLine("When not in terminal mode a nodeid must be supplied, I quit"); }
455 arune 72
				error = true;
73
			} 
74
 
462 arune 75
			//check host and port arguments
455 arune 76
			host = CommandLine["h"];
77
			string sPort = CommandLine["p"];
78
			if ((host == null) || (sPort.Length == 0)) {
462 arune 79
				if (DEBUG_LEVEL>0) { printSyntax(); }
455 arune 80
				error = true;
81
			} else {
82
				try {
83
					port = int.Parse(sPort);
84
				} catch {
462 arune 85
					if (DEBUG_LEVEL>0) { Console.WriteLine("Was not able to parse port, I quit"); }
455 arune 86
					error = true;
87
				}
88
			}
89
		}
90
 
91
		if  (!error) {
462 arune 92
			//commandline feedback output
93
			if (DEBUG_LEVEL>2) { 
94
				Console.WriteLine("canDude settings:");
95
				if (sNodeid) { Console.WriteLine("Nodeaddress: 0x" + String.Format("{0:x2}", nodeid)); }
96
				Console.WriteLine("Host: {0}:{1}", host, port);
97
				if (hexfile != null) { Console.WriteLine("Hexfile: {0}", hexfile); }
98
				Console.Write("Parameters: ");
99
				if (aBios) { Console.Write("Bios "); }
100
				if (aReset) { Console.Write("Reset "); }
101
				if (aStart) { Console.Write("Start "); }
102
				if (aTerminal) { Console.Write("Terminal"); }
103
				Console.WriteLine("");
104
			}
455 arune 105
		}
106
 
462 arune 107
		if (!error) {
108
			//connect to candaemon
109
			dc = new DaemonConnection();
110
			if (dc.init(host, port)) {
111
				if (DEBUG_LEVEL>1) { Console.WriteLine("Connected to candaemon"); }
112
			} else { 
113
				if (DEBUG_LEVEL>0) { Console.WriteLine("Connection to candaemon could not be established, I quit"); }
114
				error = true; 
115
			}
586 arune 116
			Thread.Sleep(100);
459 arune 117
		}
118
 
455 arune 119
		if (!error && aTerminal) {
462 arune 120
			//terminal mode (==interactive mode)
455 arune 121
			bool success = true;
462 arune 122
			//load hexfile if one has been specified as commandline argument
455 arune 123
			hf = new HexFile();
124
			if (sHexfile && success) {
125
				if (hf.loadHex(hexfile)) {
462 arune 126
					if (DEBUG_LEVEL>1) { Console.WriteLine("Hexfile loaded"); }
455 arune 127
				} else { success = false; }
128
			}
129
 
130
			if (success) {
462 arune 131
				if (DEBUG_LEVEL>1) {
455 arune 132
					Console.WriteLine("");
462 arune 133
					printHelp();		//print available commands
455 arune 134
					Console.WriteLine("");
135
				}
136
 
137
				string instr;
138
				do {
462 arune 139
					Console.Write("> ");			//a command has been executed, print a new console char
140
					instr = Console.ReadLine();		//read std in
141
				} while (parseInput(instr));		//parse a line from std in
455 arune 142
 
143
				//exit command
144
			}
145
		}
146
 
147
		if (!error && !aTerminal) {
148
			//not terminal mode
149
			bool success = true;
150
 
473 arune 151
			if (sHexfile) {
152
				//load hexfile (a hexfile must be supplied as commandline argument)
153
				hf = new HexFile();
154
				if (hf.loadHex(hexfile)) {
155
					if (DEBUG_LEVEL>1) { Console.WriteLine("Hexfile loaded"); }
156
				} else { 
157
					success = false;
158
					if (DEBUG_LEVEL>0) { Console.WriteLine("Hexfile could not be loaded, I quit"); }
159
				}
455 arune 160
			}
161
 
462 arune 162
			//if a hexfile is loaded then start autodownloading sequence
455 arune 163
			if (success) {
164
				bool autosuccess = true;
165
 
166
				CanNMT cpn = new CanNMT();
167
				if (aReset) {
168
					//send a reset command (and wait for feedback)
169
					if (!cpn.doReset(dc, nodeid)) {
462 arune 170
						if (DEBUG_LEVEL>0) { Console.WriteLine("Target node did not respond to reset, I quit"); }
455 arune 171
						autosuccess = false;
172
					}
173
				}
174
 
473 arune 175
				if (sHexfile && autosuccess) {
455 arune 176
					//send application
459 arune 177
					dl = new Downloader(hf, dc, nodeid, aBios);
178
					if (!dl.go()) { 
462 arune 179
						if (DEBUG_LEVEL>0) { Console.WriteLine("Error occured during download"); }
459 arune 180
						autosuccess = false;
181
					}
455 arune 182
				}
183
 
184
				if (autosuccess && aStart) {
462 arune 185
					//start application
455 arune 186
					cpn.doStart(dc, nodeid);
187
				}
188
 
189
			}
190
		}
462 arune 191
		if (dc != null) {
192
			//stop tcp client thread
193
			dc.stop();
194
		}
455 arune 195
	}
196
 
462 arune 197
	static private void printSyntax() {
198
		Console.WriteLine("Syntax: program.exe [options] -h <host> -p <port>");
199
		Console.WriteLine("Host and port are host and port of canDaemon, most likely localhost and 1200.");
200
		Console.WriteLine("Options:");
201
		Console.WriteLine("  -f <hexfile>   Specify a file to be loaded to target.");
202
		Console.WriteLine("  -n <nodeid>    Id of target node, hex or decimal.");
203
		Console.WriteLine("  -t             Enter terminal mode.");
204
		Console.WriteLine("  -r             Reset node before loading target.");
205
		Console.WriteLine("  -s             Start node after loading target.");
206
		Console.WriteLine("  -b             Program hex as bios, use with caution.");
207
	}
208
 
458 arune 209
	static private void printHelp() {
210
		Console.WriteLine("canDude commands:");
211
		Console.WriteLine("load [<hexfile>] - reload hexfile or load new hexfile");
212
		Console.WriteLine("node <nodeid>    - specify id of target node, hex or decimal");
213
		Console.WriteLine("reset            - reset node");
214
		Console.WriteLine("start            - start application in node (no feedback yet)");
215
		Console.WriteLine("go               - start download application to target");
216
		Console.WriteLine("go bios          - start download bios to target, use with caution");
217
		Console.WriteLine("help             - prints this help");
218
		Console.WriteLine("exit or quit     - exit program");
219
	}	
220
 
455 arune 221
	static private bool parseNodeId(string node) {
462 arune 222
		// the goal here is to find a byte from 0-255 in a string, format in decimal (0-255) or in hex (0x0-0xff)
223
		// this is probably not done very neat
455 arune 224
		sNodeid = false;
225
		if (node.Length > 0) {
226
			try {
227
				nodeid = byte.Parse(node);
228
				sNodeid = true;
229
			} catch {}
230
		}
231
		if (node.Length > 2) {
232
			if (node.Substring(0, 2).Equals("0x")) {
233
				if (node.Length == 3) {
234
					try {
235
						nodeid = byte.Parse(node.Substring(2, 1), System.Globalization.NumberStyles.HexNumber);
236
						sNodeid = true;
237
					} catch {
462 arune 238
						if (DEBUG_LEVEL>0) { Console.WriteLine("nodeadress parse error 1"); }
455 arune 239
						return false;
240
					}
241
				} else if (node.Length == 4) {
242
					try {
243
						nodeid = byte.Parse(node.Substring(2, 2), System.Globalization.NumberStyles.HexNumber);
244
						sNodeid = true;
245
					} catch {
462 arune 246
						if (DEBUG_LEVEL>0) { Console.WriteLine("nodeadress parse error 2"); }
455 arune 247
						return false;
248
					}
249
				} else {
462 arune 250
					if (DEBUG_LEVEL>0) { Console.WriteLine("nodeadress parse error 3"); }
455 arune 251
					return false;
252
				}
253
			}
254
		}
255
 
256
		return true;
257
	}
258
 
259
	static private bool parseInput(string instr) {
462 arune 260
		//parse commands entered on std in
261
		if (instr.Equals("reset")) {		//reset command, send a reset to current node
455 arune 262
			if (sNodeid) {
466 arune 263
				dc.flushData();
455 arune 264
				CanNMT cpn = new CanNMT();
265
				cpn.doReset(dc, nodeid);
266
			} else {
462 arune 267
				if (DEBUG_LEVEL>0) { Console.WriteLine("No nodeid has been specified"); }
455 arune 268
			}
269
		}
462 arune 270
		else if (instr.Equals("start")) {	//start command, send a start to current node
455 arune 271
			if (sNodeid) {
272
				CanNMT cpn = new CanNMT();
273
				cpn.doStart(dc, nodeid);
274
			} else {
462 arune 275
				if (DEBUG_LEVEL>0) { Console.WriteLine("No nodeid has been specified"); }
455 arune 276
			}
277
		}
462 arune 278
		else if (instr.StartsWith("go")) {	//downloading command
455 arune 279
			bool dlBios = false;
280
			bool error = true;
462 arune 281
			if (instr.Equals("go bios")) {	//if bios should be downloaded
455 arune 282
				dlBios = true;
283
				error = false;
462 arune 284
			} else if (instr.Equals("go")) {	//is an application should be downloaded
455 arune 285
				error = false;
286
			}
287
 
288
			if (!sNodeid) {
462 arune 289
				if (DEBUG_LEVEL>0) { Console.WriteLine("No nodeid has been specified"); }
455 arune 290
				error = true;
291
			}
292
			if (!sHexfile) {
462 arune 293
				if (DEBUG_LEVEL>0) { Console.WriteLine("No hexfile has been specified"); }
455 arune 294
				error = true;
295
			}
296
 
297
			CanNMT cpn = new CanNMT();
462 arune 298
			if (!error && aReset) {				//commandline arguments specified that a reset should be done before download
455 arune 299
				//send a reset command (and wait for feedback)
300
				if (!cpn.doReset(dc, nodeid)) {
462 arune 301
					if (DEBUG_LEVEL>0) { Console.WriteLine("Target node did not respond to reset"); }
455 arune 302
					error = true;
303
				}
304
			}
305
 
306
			if (!error) {
307
				//send application
466 arune 308
				dc.flushData();
455 arune 309
				dl = new Downloader(hf, dc, nodeid, dlBios);
310
				if (!dl.go()) { 
462 arune 311
					if (DEBUG_LEVEL>0) { Console.WriteLine("Error occured during download"); }
455 arune 312
					error = true;
313
				}
314
			}
315
 
462 arune 316
			if (!error && aStart) {				//commandline arguments specified that a start should be done after download
455 arune 317
				//start applikation
318
				cpn.doStart(dc, nodeid);
319
			}
320
 
321
		}
462 arune 322
		else if (instr.StartsWith("load")) {	//load hexfile or reload current hexfile
455 arune 323
			if (instr.Length > 5) {
324
				//second argument is a hexfile, this file should be loaded
325
				hexfile = instr.Substring(5);
326
				if (hf.loadHex(hexfile)) {
327
					sHexfile = true;
462 arune 328
					if (DEBUG_LEVEL>1) { Console.WriteLine("Hexfile loaded"); }
455 arune 329
				} else { 
462 arune 330
					if (DEBUG_LEVEL>0) { Console.WriteLine("Hexfile could not be loaded"); }
455 arune 331
				}
332
			} else {
333
				//reload current hexfile. if a hexfile already has been specified
334
				if (sHexfile) {
335
					if (hf.loadHex(hexfile)) {
462 arune 336
						if (DEBUG_LEVEL>1) { Console.WriteLine("Hexfile reloaded"); }
455 arune 337
					} else { 
462 arune 338
						if (DEBUG_LEVEL>0) { Console.WriteLine("Hexfile could not be reloaded"); }
455 arune 339
					}
340
				} else {
462 arune 341
					if (DEBUG_LEVEL>0) { Console.WriteLine("No hexfile has been specified"); }
455 arune 342
				}
343
 
344
			}
345
		}
346
		else if (instr.StartsWith("node")) {
347
			//change nodeid
348
			if (instr.Length > 5) {
349
				//second argument is nodeid
350
				string node = instr.Substring(5);
351
				parseNodeId(node);
352
			}
462 arune 353
			if (DEBUG_LEVEL>1) { Console.WriteLine("NodeId is 0x"+ String.Format("{0:x2}", nodeid)); }
455 arune 354
		}
458 arune 355
		else if (instr.Equals("help")) {
356
			printHelp();
357
		}
462 arune 358
		else if (instr.Equals("exit") || instr.Equals("quit") || instr.Equals("q")) {
455 arune 359
			return false;
360
		}
361
		else {
362
			Console.WriteLine("Unknown command.");
363
		}
364
 
365
		return true;
366
	}
367
 
368
}