Subversion Repositories HomeAutomation

Rev

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

  1.  
  2. function CanNode(hardwareId, numberOfModules)
  3. {
  4.     this.myHardwareId = hardwareId;
  5.     this.myNumberOfModules = numberOfModules;
  6.     this.myModules = new Array();
  7.     this.myHeartbeatTime = 0;
  8.     this.myIsOnline = false;
  9.     this.stopProgramming();
  10. }
  11.  
  12. CanNode.prototype.myIsOnline = null;
  13. CanNode.prototype.myHardwareId = null;
  14. CanNode.prototype.myNumberOfModules = null;
  15. CanNode.prototype.myModules = null;
  16. CanNode.prototype.myHeartbeatTime = null;
  17. CanNode.prototype.myProgrammingIsBios = null;
  18. CanNode.prototype.myProgramming = null;
  19. CanNode.prototype.myProgrammingHex = null;
  20. CanNode.prototype.myProgrammingHexAddress = null;
  21. CanNode.prototype.myProgrammingOffset = null;
  22. CanNode.prototype.myProgrammingCallback = null;
  23. CanNode.prototype.myProgrammingWantAck = null;
  24. CanNode.prototype.myProgrammingState = null;
  25.  
  26. CanNode.prototype.isOnline = function()
  27. {
  28.     return this.myIsOnline;
  29. }
  30.  
  31. CanNode.prototype.start = function()
  32. {
  33.     var canMessage = new CanNMTMessage("nmt", "Start_App");
  34.     canMessage.setData("HardwareId", this.myHardwareId);
  35.     canMessage.send();
  36. }
  37.  
  38. CanNode.prototype.reset = function()
  39. {
  40.     var canMessage = new CanNMTMessage("nmt", "Reset");
  41.     canMessage.setData("HardwareId", this.myHardwareId);
  42.     canMessage.send();
  43. }
  44.  
  45. CanNode.prototype.startApplication = function()
  46. {
  47.     var canMessage = new CanNMTMessage("nmt", "Start_App");
  48.     canMessage.setData("HardwareId", this.myHardwareId);
  49.     canMessage.send();
  50. }
  51.  
  52. CanNode.prototype.handleHeartbeat = function(numberOfModules)
  53. {
  54.     if (numberOfModules)
  55.     {
  56.         this.myNumberOfModules = numberOfModules;
  57.     }
  58.    
  59.     if (this.myNumberOfModules == null || this.myNumberOfModules > this.myModules.length)
  60.     {
  61.         var canMessage = new CanMessage("mnmt", "To_Owner", "", 0, "List");
  62.         canMessage.setData("HardwareId", this.myHardwareId);
  63.         canMessage.send();
  64.     }
  65.    
  66.     this.onlineHandler();
  67. }
  68.  
  69. CanNode.prototype.startProgramming = function(hexData, progressCallback, isBios)
  70. {
  71.     if (isBios)
  72.     {
  73.         this.myProgrammingIsBios = isBios;
  74.     }
  75.     else
  76.     {
  77.         this.myProgrammingIsBios = false;
  78.     }
  79.    
  80.     this.myProgramming = true;
  81.     this.myProgrammingHex = hexData;
  82.     this.myProgrammingCallback = progressCallback;
  83.    
  84.     CanProgrammingNode = this;
  85.    
  86.     this.reset();
  87. }
  88.  
  89. CanNode.prototype.handleBiosStart = function(biosVersion, hasApplication)
  90. {
  91. //print("node was reset and bios just started, ver:" + biosVersion);
  92.     if (this.myProgramming)
  93.     {
  94.         this.myProgrammingHexAddress = this.myProgrammingHex.getAddrLower();
  95.         this.myProgrammingWantAck = this.myProgrammingHexAddress&0xffff;
  96.    
  97.         var canMessage = new CanNMTMessage("nmt", "Pgm_Start");
  98.         canMessage.setData("HardwareId", this.myHardwareId);
  99.         canMessage.setData("AddressLow", this.myProgrammingHexAddress&0xffff);
  100.         canMessage.setData("AddressHigh", (this.myProgrammingHexAddress>16)&0xffff);
  101.         canMessage.send();
  102.         this.myProgrammingState = "DATA";
  103.        
  104.         this.myProgrammingCallback(true, "START", "Started programming of node");
  105.     }
  106. }
  107.  
  108. CanNode.prototype.handleNack = function(data)
  109. {
  110.     stopProgramming(true, "Failed, got NACK, sending reset");
  111.     this.reset();
  112.     if (false) 
  113.     {
  114.     }
  115. }
  116.  
  117. CanNode.prototype.handleAck = function(data)
  118. {
  119. //this.myProgrammingCallback(true, "DBG", "data: "+data+", myProgrammingWantAck: "+this.myProgrammingWantAck+"");
  120.    
  121.     if (data == this.myProgrammingWantAck) 
  122.     {
  123.  
  124.         switch (this.myProgrammingState)
  125.         {
  126.         case "DATA":
  127.             var offset = this.myProgrammingHexOffset;
  128.        
  129.             this.myProgrammingWantAck = offset;
  130.             //var bytesLeft = this.myProgrammingHex.getAddrUpper() - (this.myProgrammingHexAddress+this.myProgrammingHexOffset);
  131.             var bytesLeft = this.myProgrammingHex.getLength() - this.myProgrammingHexOffset;
  132.            
  133. this.myProgrammingCallback(true, "DBG", "bytesLeft: "+bytesLeft+", this.myProgrammingHex.getLength(): "+this.myProgrammingHex.getLength()+"");
  134.             //here we must handle the possibility that data is less then 48 bits
  135.             var canMessage = new CanNMTMessage("nmt", "Pgm_Data_48");
  136.             switch (bytesLeft)
  137.             {
  138.             case 1:
  139.                 canMessage = new CanNMTMessage("nmt", "Pgm_Data_8");
  140. this.myProgrammingCallback(true, "DBG", "Pgm_Data_8");
  141.                 break;
  142.             case 2:
  143.                 canMessage = new CanNMTMessage("nmt", "Pgm_Data_16");
  144. this.myProgrammingCallback(true, "DBG", "Pgm_Data_16");
  145.                 break;
  146.             case 3:
  147.                 canMessage = new CanNMTMessage("nmt", "Pgm_Data_24");
  148. this.myProgrammingCallback(true, "DBG", "Pgm_Data_24");
  149.                 break;
  150.             case 4:
  151.                 canMessage = new CanNMTMessage("nmt", "Pgm_Data_32");
  152. this.myProgrammingCallback(true, "DBG", "Pgm_Data_32");
  153.                 break;
  154.             case 5:
  155.                 canMessage = new CanNMTMessage("nmt", "Pgm_Data_40");
  156. this.myProgrammingCallback(true, "DBG", "Pgm_Data_40");
  157.                 break;
  158.             }
  159.            
  160.             canMessage.setData("Offset", offset);
  161.             for (var i=0; i<bytesLeft && i<6; i++)
  162.             {
  163.                 switch (i)
  164.                 {
  165.                 case 0:
  166.                     canMessage.setData("Data0", this.myProgrammingHex.getByte(offset));
  167. this.myProgrammingCallback(true, "DBG", "Data0");
  168.                     break;
  169.                 case 1:
  170.                     canMessage.setData("Data1", this.myProgrammingHex.getByte(offset));
  171. this.myProgrammingCallback(true, "DBG", "Data1");
  172.                     break;
  173.                 case 2:
  174.                     canMessage.setData("Data2", this.myProgrammingHex.getByte(offset));
  175. this.myProgrammingCallback(true, "DBG", "Data2");
  176.                     break;
  177.                 case 3:
  178.                     canMessage.setData("Data3", this.myProgrammingHex.getByte(offset));
  179. this.myProgrammingCallback(true, "DBG", "Data3");
  180.                     break;
  181.                 case 4:
  182.                     canMessage.setData("Data4", this.myProgrammingHex.getByte(offset));
  183. this.myProgrammingCallback(true, "DBG", "Data4");
  184.                     break;
  185.                 case 5:
  186.                     canMessage.setData("Data5", this.myProgrammingHex.getByte(offset));
  187. this.myProgrammingCallback(true, "DBG", "Data5");
  188.                     break;
  189.                 }
  190.                 offset++;
  191.             }
  192.             canMessage.send();
  193.             this.myProgrammingHexOffset = offset;
  194.  
  195.             if (this.myProgrammingHexOffset >= this.myProgrammingHex.getLength()) {
  196.                 this.myProgrammingState = "END";
  197.             }
  198.            
  199.             this.myProgrammingCallback(true, "PROGRESS", this.myProgrammingHexOffset + ":" + this.myProgrammingHex.getLength());
  200.             break;
  201.        
  202.         case "END":
  203.             this.myProgrammingWantAck = this.myProgrammingHex.getCRC16();  ///TODO: Fill in something here
  204.        
  205.             var canMessage = new CanNMTMessage("nmt", "Pgm_End");
  206.             canMessage.send();
  207.  
  208.             this.myProgrammingState = "CRC";
  209.             break;
  210.            
  211.         case "CRC":
  212.             //is this a bios programming?
  213.             if (false)
  214.             {
  215.                 this.myProgrammingState = "COPY";
  216.                 this.myProgrammingCallback(true, "PROGRESS", "Start to copy bios to new location");
  217.                 var canMessage = new CanNMTMessage("nmt", "Pgm_Copy");
  218.                 canMessage.setData("Source", source);
  219.                 canMessage.setData("Destination", destination);
  220.                 canMessage.setData("Length", length);
  221.                 canMessage.send();
  222.                 this.stopProgramming();
  223.             }
  224.             else
  225.             {
  226.                 this.stopProgramming(true, "Done, sucessful");
  227.                 this.reset();
  228.             }
  229.             break;
  230.        
  231.         case "COPY":    //this will never occur, bios does not send ack for copy command, it just moves data in flash then reset itself
  232.             var source = ""; ///TODO: Fill in something here
  233.             var destination = ""; ///TODO: Fill in something here
  234.             var length = ""; ///TODO: Fill in something here
  235.            
  236.             this.myProgrammingWantAck = "";  ///TODO: Fill in something here
  237.        
  238.            
  239.             this.myProgrammingCallback(true, "END", ""); ///TODO: Fill in something meaningfull text
  240.             break;
  241.            
  242.         default:
  243.             break;
  244.         }
  245.     }
  246.     else
  247.     {
  248.         switch (this.myProgrammingState)
  249.         {
  250.         case "DATA":
  251.             //Fall through
  252.         case "END":
  253.             ///TODO: We got something that was not correct... we should abort
  254.             this.stopProgramming(true, "Failed to program, ack had wrong offset, expected data: "+this.myProgrammingWantAck+" got: "+data);
  255.             this.reset();
  256.             break;
  257.         case "CRC":
  258.             this.stopProgramming(true, "Failed to program, CRC not matching, expected data: "+this.myProgrammingWantAck+" got: "+data);
  259.             this.reset();
  260.             break;
  261.         case "COPY":    //this will never occur, bios does not send ack for copy command, it just moves data in flash then reset itself
  262.             break;
  263.         default:
  264.             break;
  265.         }
  266.     }
  267. }
  268.  
  269. CanNode.prototype.stopProgramming = function(status, text)
  270. {
  271.     if (status && text)
  272.     {
  273.         this.myProgrammingCallback(status, "STOP", text);
  274.     }
  275.  
  276.     this.myProgrammingIsBios = false;
  277.     this.myProgramming = false;
  278.     this.myProgrammingHex = new Array();
  279.     this.myProgrammingHexAddress = 0;
  280.     this.myProgrammingHexOffset = 0;
  281.     this.myProgrammingCallback = function() {};
  282.     this.myProgrammingWantAck = null;
  283.     this.myProgrammingState = "";
  284.    
  285.     CanProgrammingNode = null;
  286. }
  287.  
  288.  
  289.  
  290. CanNode.prototype.addService = function(sequenceNumber, service)
  291. {
  292.     this.myModules[sequenceNumber] = service;
  293.     service.setOnline();
  294. }
  295.  
  296. CanNode.prototype.onlineHandler = function()
  297. {
  298.     var date = new Date();
  299.     this.myHeartbeatTime = date.getTimestamp();
  300.  
  301.     if (!this.myIsOnline)
  302.     {
  303.         this.myIsOnline = true;
  304.  
  305.         log(uint2hex(this.myHardwareId, 32) + "> Node went online\n");
  306.        
  307.         for (var n in this.myModules)
  308.         {
  309.             this.myModules[n].setOnline();
  310.         }
  311.     }
  312. }
  313.  
  314. CanNode.prototype.checkOffline = function()
  315. {
  316.     if (this.myIsOnline)
  317.     {
  318.         var date = new Date();
  319.         if (this.myHeartbeatTime + 10 < date.getTimestamp())
  320.         {
  321.             this.setOffline();
  322.         }
  323.     }
  324. }
  325.  
  326. CanNode.prototype.setOffline = function()
  327. {
  328.     if (this.myIsOnline)
  329.     {
  330.         this.myIsOnline = false;
  331.  
  332.         log(uint2hex(this.myHardwareId, 32) + "> Node went offline\n");
  333.        
  334.         for (var n in this.myModules)
  335.         {
  336.             this.myModules[n].setOffline();
  337.         }
  338.     }
  339. }
  340.