Subversion Repositories HomeAutomation

Rev

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