public virtual IEnumerator<ITask> SendFileHandler(CopyFileToBrick sendFile) { Fault faultResponse = null; bool fileExists = false; bool done = false; #region See if the file is already on the LEGO NXT. nxtcmd.LegoCommand cmd = new nxtcmd.LegoFindFirst(sendFile.Body.FileName); yield return Arbiter.Choice(_legoBrickPort.SendNxtCommand(cmd), delegate(nxtcmd.LegoResponse ok) { nxtcmd.LegoResponseFindFirst ffResponse = nxtcmd.LegoResponse.Upcast<nxtcmd.LegoResponseFindFirst>(ok); if (ffResponse.Success && (ffResponse.FileName == sendFile.Body.FileName)) { fileExists = true; bool fileMatches = (sendFile.Body.FileData != null && sendFile.Body.FileData.Length == ffResponse.FileSize); if (!sendFile.Body.ReplaceExistingFile) { string msg = ((fileMatches) ? "A matching file" : "A different file with the same name") + " already exists on the LEGO NXT Brick."; sendFile.ResponsePort.Post(Fault.FromException(new System.IO.IOException(msg))); done = true; } } }, delegate(Fault fault) { sendFile.ResponsePort.Post(fault); done = true; }); #endregion if (done) yield break; if (fileExists) { #region Remove the existing file cmd = new nxtcmd.LegoDelete(sendFile.Body.FileName); yield return Arbiter.Choice(_legoBrickPort.SendNxtCommand(cmd), EmptyHandler<nxtcmd.LegoResponse>, delegate(Fault fault) { done = true; sendFile.ResponsePort.Post(fault); }); #endregion } if (done) yield break; #region Upload the file to the Brick. byte[] fileData = sendFile.Body.FileData; string fileName = sendFile.Body.FileName; if (fileData != null) { int pgmLength = fileData.Length; int handle = -1; LogInfo(LogGroups.Console, "Downloading " + fileName + " to LEGO NXT."); PortSet<nxtcmd.LegoResponse, Fault> responsePort = new PortSet<nxtcmd.LegoResponse, Fault>(); done = false; int trial = 0; while (trial < 5 && !done) { nxtcmd.LegoOpenWriteLinear openWrite = new nxtcmd.LegoOpenWriteLinear(fileName, pgmLength); responsePort = _legoBrickPort.SendNxtCommand(openWrite); yield return Arbiter.Choice( Arbiter.Receive<nxtcmd.LegoResponse>(false, responsePort, delegate(nxtcmd.LegoResponse response) { nxtcmd.LegoResponseOpenWriteLinear responseOpenWriteLinear = new nxtcmd.LegoResponseOpenWriteLinear(response.CommandData); if (response.ErrorCode == LegoErrorCode.Success || response.ErrorCode == LegoErrorCode.FileExists) { handle = responseOpenWriteLinear.Handle; done = true; } else if (response.ErrorCode == LegoErrorCode.NoSpace) { faultResponse = Fault.FromException(new System.IO.IOException("Out of space on LEGO NXT Brick.\nPlease remove one or more LEGO NXT programs on the NXT Brick.")); trial = 999; } else { faultResponse = Fault.FromException(new System.IO.IOException("Error preparing to upload " + fileName + " file to the LEGO NXT: " + response.ErrorCode.ToString())); } }), Arbiter.Receive<Fault>(false, responsePort, delegate(Fault fault) { faultResponse = fault; })); trial++; } if (!done) { if (faultResponse == null) faultResponse = Fault.FromException(new System.IO.IOException("Failed to create the new file")); sendFile.ResponsePort.Post(faultResponse); yield break; } done = false; trial = 0; while (trial < 5 && !done) { nxtcmd.LegoWrite legoWrite = new nxtcmd.LegoWrite(handle, fileData); responsePort = _legoBrickPort.SendNxtCommand(legoWrite); yield return Arbiter.Choice( Arbiter.Receive<nxtcmd.LegoResponse>(false, responsePort, delegate(nxtcmd.LegoResponse response) { nxtcmd.LegoResponseWrite responseWrite = new nxtcmd.LegoResponseWrite(response.CommandData); if (response.ErrorCode == LegoErrorCode.Success) { if (pgmLength != responseWrite.BytesWritten) LogWarning(LogGroups.Console, "Warning: " + fileName + " file length on LEGO NXT does not match the PC."); done = true; } else { faultResponse = Fault.FromException(new System.IO.IOException("Error sending " + fileName + " file to the LEGO NXT: " + response.ErrorCode.ToString())); LogError(faultResponse); } }), Arbiter.Receive<Fault>(false, responsePort, delegate(Fault fault) { faultResponse = fault; LogError(LogGroups.Console, "Timed out sending " + fileName + " file to the LEGO NXT"); })); trial++; } if (!done) { if (faultResponse == null) faultResponse = Fault.FromException(new System.IO.IOException("Failed to write to the new file,")); sendFile.ResponsePort.Post(faultResponse); yield break; } // Now Close the Write Buffer. done = false; nxtcmd.LegoClose legoClose = new nxtcmd.LegoClose(handle); legoClose.TryCount = 5; responsePort = _legoBrickPort.SendNxtCommand(legoClose); yield return Arbiter.Choice( Arbiter.Receive<nxtcmd.LegoResponse>(false, responsePort, delegate(nxtcmd.LegoResponse response) { if (response.ErrorCode == LegoErrorCode.Success) { sendFile.ResponsePort.Post(DefaultSubmitResponseType.Instance); done = true; } else { faultResponse = Fault.FromException(new System.IO.IOException("Error closing " + fileName + " file on the LEGO NXT: " + response.ErrorCode.ToString())); LogError(faultResponse); } }), Arbiter.Receive<Fault>(false, responsePort, delegate(Fault fault) { faultResponse = fault; LogError(LogGroups.Console, "Timed out closing file during SendFile."); })); } else { faultResponse = Fault.FromException(new ArgumentNullException("The source file was not provided")); } if (done) yield break; if (faultResponse == null) faultResponse = Fault.FromException(new System.IO.IOException("Failed to write to the new file,")); sendFile.ResponsePort.Post(faultResponse); #endregion yield break; }
public virtual IEnumerator <ITask> SendFileHandler(CopyFileToBrick sendFile) { Fault faultResponse = null; bool fileExists = false; bool done = false; #region See if the file is already on the LEGO NXT. nxtcmd.LegoCommand cmd = new nxtcmd.LegoFindFirst(sendFile.Body.FileName); yield return(Arbiter.Choice(_legoBrickPort.SendNxtCommand(cmd), delegate(nxtcmd.LegoResponse ok) { nxtcmd.LegoResponseFindFirst ffResponse = nxtcmd.LegoResponse.Upcast <nxtcmd.LegoResponseFindFirst>(ok); if (ffResponse.Success && (ffResponse.FileName == sendFile.Body.FileName)) { fileExists = true; bool fileMatches = (sendFile.Body.FileData != null && sendFile.Body.FileData.Length == ffResponse.FileSize); if (!sendFile.Body.ReplaceExistingFile) { string msg = ((fileMatches) ? "A matching file" : "A different file with the same name") + " already exists on the LEGO NXT Brick."; sendFile.ResponsePort.Post(Fault.FromException(new System.IO.IOException(msg))); done = true; } } }, delegate(Fault fault) { sendFile.ResponsePort.Post(fault); done = true; })); #endregion if (done) { yield break; } if (fileExists) { #region Remove the existing file cmd = new nxtcmd.LegoDelete(sendFile.Body.FileName); yield return(Arbiter.Choice(_legoBrickPort.SendNxtCommand(cmd), EmptyHandler <nxtcmd.LegoResponse>, delegate(Fault fault) { done = true; sendFile.ResponsePort.Post(fault); })); #endregion } if (done) { yield break; } #region Upload the file to the Brick. byte[] fileData = sendFile.Body.FileData; string fileName = sendFile.Body.FileName; if (fileData != null) { int pgmLength = fileData.Length; int handle = -1; LogInfo(LogGroups.Console, "Downloading " + fileName + " to LEGO NXT."); PortSet <nxtcmd.LegoResponse, Fault> responsePort = new PortSet <nxtcmd.LegoResponse, Fault>(); done = false; int trial = 0; while (trial < 5 && !done) { nxtcmd.LegoOpenWriteLinear openWrite = new nxtcmd.LegoOpenWriteLinear(fileName, pgmLength); responsePort = _legoBrickPort.SendNxtCommand(openWrite); yield return(Arbiter.Choice( Arbiter.Receive <nxtcmd.LegoResponse>(false, responsePort, delegate(nxtcmd.LegoResponse response) { nxtcmd.LegoResponseOpenWriteLinear responseOpenWriteLinear = new nxtcmd.LegoResponseOpenWriteLinear(response.CommandData); if (response.ErrorCode == LegoErrorCode.Success || response.ErrorCode == LegoErrorCode.FileExists) { handle = responseOpenWriteLinear.Handle; done = true; } else if (response.ErrorCode == LegoErrorCode.NoSpace) { faultResponse = Fault.FromException(new System.IO.IOException("Out of space on LEGO NXT Brick.\nPlease remove one or more LEGO NXT programs on the NXT Brick.")); trial = 999; } else { faultResponse = Fault.FromException(new System.IO.IOException("Error preparing to upload " + fileName + " file to the LEGO NXT: " + response.ErrorCode.ToString())); } }), Arbiter.Receive <Fault>(false, responsePort, delegate(Fault fault) { faultResponse = fault; }))); trial++; } if (!done) { if (faultResponse == null) { faultResponse = Fault.FromException(new System.IO.IOException("Failed to create the new file")); } sendFile.ResponsePort.Post(faultResponse); yield break; } done = false; trial = 0; while (trial < 5 && !done) { nxtcmd.LegoWrite legoWrite = new nxtcmd.LegoWrite(handle, fileData); responsePort = _legoBrickPort.SendNxtCommand(legoWrite); yield return(Arbiter.Choice( Arbiter.Receive <nxtcmd.LegoResponse>(false, responsePort, delegate(nxtcmd.LegoResponse response) { nxtcmd.LegoResponseWrite responseWrite = new nxtcmd.LegoResponseWrite(response.CommandData); if (response.ErrorCode == LegoErrorCode.Success) { if (pgmLength != responseWrite.BytesWritten) { LogWarning(LogGroups.Console, "Warning: " + fileName + " file length on LEGO NXT does not match the PC."); } done = true; } else { faultResponse = Fault.FromException(new System.IO.IOException("Error sending " + fileName + " file to the LEGO NXT: " + response.ErrorCode.ToString())); LogError(faultResponse); } }), Arbiter.Receive <Fault>(false, responsePort, delegate(Fault fault) { faultResponse = fault; LogError(LogGroups.Console, "Timed out sending " + fileName + " file to the LEGO NXT"); }))); trial++; } if (!done) { if (faultResponse == null) { faultResponse = Fault.FromException(new System.IO.IOException("Failed to write to the new file,")); } sendFile.ResponsePort.Post(faultResponse); yield break; } // Now Close the Write Buffer. done = false; nxtcmd.LegoClose legoClose = new nxtcmd.LegoClose(handle); legoClose.TryCount = 5; responsePort = _legoBrickPort.SendNxtCommand(legoClose); yield return(Arbiter.Choice( Arbiter.Receive <nxtcmd.LegoResponse>(false, responsePort, delegate(nxtcmd.LegoResponse response) { if (response.ErrorCode == LegoErrorCode.Success) { sendFile.ResponsePort.Post(DefaultSubmitResponseType.Instance); done = true; } else { faultResponse = Fault.FromException(new System.IO.IOException("Error closing " + fileName + " file on the LEGO NXT: " + response.ErrorCode.ToString())); LogError(faultResponse); } }), Arbiter.Receive <Fault>(false, responsePort, delegate(Fault fault) { faultResponse = fault; LogError(LogGroups.Console, "Timed out closing file during SendFile."); }))); } else { faultResponse = Fault.FromException(new ArgumentNullException("The source file was not provided")); } if (done) { yield break; } if (faultResponse == null) { faultResponse = Fault.FromException(new System.IO.IOException("Failed to write to the new file,")); } sendFile.ResponsePort.Post(faultResponse); #endregion yield break; }