Ejemplo n.º 1
0
        public virtual IEnumerator <ITask> QueryFilesHandler(QueryFiles queryFiles)
        {
            ResponseFiles response = new ResponseFiles();

            response.Files = new List <LegoFile>();
            bool done   = false;
            int  handle = 0;

            nxtcmd.LegoCommand cmd = new nxtcmd.LegoFindFirst(queryFiles.Body.Filespec);
            yield return(Arbiter.Choice(_legoBrickPort.SendNxtCommand(cmd),
                                        delegate(nxtcmd.LegoResponse ok)
            {
                nxtcmd.LegoResponseFindFirst ffResponse = nxtcmd.LegoResponse.Upcast <nxtcmd.LegoResponseFindFirst>(ok);
                if (ffResponse.Success)
                {
                    response.Files.Add(new LegoFile(ffResponse.FileName, (int)ffResponse.FileSize));
                    handle = ffResponse.Handle;
                }
                else
                {
                    done = true;
                }
            },
                                        delegate(Fault fault)
            {
                done = true;
            }));

            while (!done)
            {
                cmd = new nxtcmd.LegoFindNext(handle);
                yield return(Arbiter.Choice(_legoBrickPort.SendNxtCommand(cmd),
                                            delegate(nxtcmd.LegoResponse ok)
                {
                    nxtcmd.LegoResponseFindNext fnResponse = nxtcmd.LegoResponse.Upcast <nxtcmd.LegoResponseFindNext>(ok);
                    if (fnResponse.Success)
                    {
                        response.Files.Add(new LegoFile(fnResponse.FileName, (int)fnResponse.FileSize));
                        handle = fnResponse.Handle;
                    }
                    else
                    {
                        done = true;
                    }
                },
                                            delegate(Fault fault)
                {
                    done = true;
                }));
            }

            _state.ResponseFiles = response;
            queryFiles.ResponsePort.Post(response);
            yield break;
        }
Ejemplo n.º 2
0
        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;
        }