/// <summary> /// Retrieves docking station's cylinder information at a given valve ( position ID ). /// </summary> /// <param name="position">Position ID of the valve that the cylinder is installed on</param> /// <returns>Retrieved cylinder</returns> public static Cylinder ReadCard(int position) { const int CARD_TRIES = 10; const int CARD_BUF_SIZE = 127; const int CARD_RETRY_SLEEPTIME = 1000; // 1 sec string funcName = "ReadCard(" + position + "): "; Log.Debug(funcName + "..."); byte[] dataBuf = new byte[CARD_BUF_SIZE]; // Make the buffer. int readTries; for (readTries = 1; readTries <= CARD_TRIES; readTries++) { if (readTries > 1) { Thread.Sleep(CARD_RETRY_SLEEPTIME); } if (!IsCardPresent(position)) // Check for the presence of a card to read. { return(null); } int driverErrorCode = -1; uint bytesRead = 0; int driverTries; for (driverTries = 1; driverTries <= CARD_TRIES; driverTries++) { for (int i = 0; i < CARD_BUF_SIZE; i++) { dataBuf[i] = 0; // zero out the buffer } bytesRead = 0; if (driverTries > 1 || readTries > 1) { Thread.Sleep(CARD_RETRY_SLEEPTIME); } unsafe { // Need to ensure that we zero out bytesRead before each call because the // the call seems to add on to whatever the current value is. // ReadSmartCard returns zero if successful, or a nonzero error code on failure driverErrorCode = ReadSmartCard((byte)position, dataBuf, CARD_BUF_SIZE, &bytesRead); } if (driverErrorCode == 0) { break; } Log.Debug(funcName + "driverErrorCode=" + driverErrorCode + ", driverTries=" + driverTries + ", bytesRead=" + bytesRead); } // end-for driverTries if (driverErrorCode != 0) // Driver failure? { // If we still are getting an error trying to read the card after max retries, // then the docking station may be in some unstable state that it can't get out of. // Time to punt, i.e., reboot the docking station. // Incase the IDS is so bad off that it's going to be continually trying and failing // to read the card causing it to continously reboot, we also display an LCD // message so the user knows why their docking station is rebooting. LCD.Display("<a>SMARTCARD " + position + "</a><a>DRIVER ERROR</a><a>" + driverErrorCode + "</a>"); //Log.Error( funcName + "Rebooting, driverErrorCode=" + driverErrorCode + " driverTries=" + CARD_TRIES ); Log.Error(funcName + "Driver failed, driverErrorCode=" + driverErrorCode + " driverTries=" + CARD_TRIES); Thread.Sleep(5000); //RebootDockingStation(); return(null); } Log.Debug(funcName + "driver successful, driverTries=" + driverTries); // Find the last non-zero byte we read, then convert byte buffer to ascii string. if (bytesRead > 0) { while (dataBuf[bytesRead - 1] == '\0') { bytesRead--; } } string cardXML = Encoding.ASCII.GetString(dataBuf, 0, (int)bytesRead); Log.Debug(funcName + "Deserializing Card contents (attempt " + readTries + "): \"" + cardXML + "\""); // Deserialize (parse) the XML data into a SmartCard instance. // If there's something wrong with the XML (due to corrupted // card, etc.), this call will throw an exception. ISerializer cardSerializer = new SmartCardXMLSerializer(); SmartCard smartCard = null; try { smartCard = (SmartCard)cardSerializer.Deserialize(cardXML); } catch (Exception e) { Log.Error(funcName + "Deserializing, tries=" + readTries, e); continue; // May have misread the card (even though driver returned no error). Retry again. } Log.Debug(funcName + "ContentCount=" + smartCard.ContentCount + " PartNumber=" + smartCard.PartNumber + " ProgramDate=" + Log.DateTimeToString(smartCard.ProgramDate)); // Cycle through the contents looking for a cylinder. for (int i = 0; i < smartCard.ContentCount; i++) { object cardContent = smartCard.GetContent(i); if (cardContent is Cylinder) // Success? Dump the cylinder's contents then return it. { Cylinder cylinder = (Cylinder)cardContent; Log.Debug(funcName + "Deserializing successful, tries=" + readTries); #if DEBUG // FOR debugging purposes only... create a fake zero-air cylinder. //if ( position == 1 ) //{ // cylinder.PartNumber = "1810-0693"; // cylinder.ExpirationDate = new DateTime( 2011, 06, 15 ); // cylinder.FactoryId = "20110405-01"; //} #endif Log.Debug("Cylinder Part Number: " + cylinder.PartNumber); Log.Debug("Cylinder Expiration Date: " + Log.DateTimeToString(cylinder.ExpirationDate)); Log.Debug("Cylinder Refill Date: " + Log.DateTimeToString(cylinder.RefillDate)); Log.Debug("Cylinder Factory ID: " + cylinder.FactoryId); return(cylinder); } else if (cardContent != null) { Log.Error(funcName + "Non-Cylinder found on card. Content is [" + cardContent.ToString() + "] tries=" + readTries); } } // end-for smartCard.ContentCount // If we make it to here, we must not have found a Cylinder instance // within the card's content. Log.Error(funcName + "No Cylinder found on card, tries=" + readTries); } // end-for readTries LCD.Display("<a>SMARTCARD " + position + "</a><a>ERROR</a>"); //Log.Error( funcName + "Rebooting. Failed to successfully read smartcard, tries=" + CARD_TRIES ); Log.Error(funcName + "Failed to successfully read smartcard " + position + ", tries=" + CARD_TRIES); Thread.Sleep(5000); //RebootDockingStation(); return(null); }
public virtual void Display(string text) { LCD.Display(text); }