private Status CheckAsyncWebServerResp(AsyncWebExchange asyncWebExchange, int timeoutMs, out bool isDone) { string response = string.Empty; Status retval = Status.Ok; isDone = false; /* async web response handler */ retval = asyncWebExchange.PollResponse(timeoutMs, out response); if (retval == Status.AsyncWebReqNotDone) { /* this is okay, its just not done yet */ retval = Status.Ok; } else if (retval != Status.Ok) { /* let caller something went wrong */ _firmwareStatus.progressPerc = 100; _firmwareStatus.message = "Received Error" + retval; isDone = true; } else { /* we are done - parse firmware-update resp */ FirmwareUpdateReturn jsonDeser = JsonConvert.DeserializeObject <FirmwareUpdateReturn>(response); retval = (Status)jsonDeser.GeneralReturn.Error; /* save status update so calling application can poll it */ if (retval == Status.Ok) { _firmwareStatus.progressPerc = 100; _firmwareStatus.message = "Successful Firmware Update"; } else { _firmwareStatus.progressPerc = 100; _firmwareStatus.message = jsonDeser.UpdateMessage; } /* let caller know the field upgrade did stop/finish */ isDone = true; } return(retval); }
private Status ExecuteFieldUpgrade(DeviceDescrip ddRef, AsyncWebExchange asyncWebExchange, string fileName, bool usingSftp) { Status retval = Status.Ok; string response = string.Empty; /* let user know action is being processed */ SetFieldUpgradeStatus("Reading CRF...", 0); byte[] fileContents = null; /* If we're using POST, we need to make sure the file has contents */ if (!usingSftp) { /* copy out CRF */ fileContents = File.Read(_action.filePath); /* check file read */ if (retval == Status.Ok) { if (fileContents == null) { retval = Status.CouldNotOpenFile; } } } /* check firmUpdate progress first */ if (retval == Status.Ok) { SetFieldUpgradeStatus("Confirm server is ready", 0); /* we are confirming if field upgrade is already occuring */ /* Make double sure that we aren't field upgrading. Server already does this but there's no harm in checking again */ retval = ConfirmIfFieldUpgradeIsOccuring(ddRef, false); SetFieldUpgradeStatus("Confirm server is ready : " + retval, 0); /* display the result of this check */ } /* request firmware-update of device */ if (retval == Status.Ok) { SetFieldUpgradeStatus("Starting field-upgrade", 0); /* now we will request to start a new FU session */ /* If we're using sftp, use Get */ if (usingSftp) { /* start firmware-update */ retval = asyncWebExchange.StartHttpGet(_hostName, ddRef.model, ddRef.deviceID, ActionType.FieldUpgradeDevice, 60000, "&file=" + fileName); } else /* Otherwise use Post */ { /* start firmware-update */ retval = asyncWebExchange.StartHttpPost(_hostName, ddRef.model, ddRef.deviceID, ActionType.FieldUpgradeDevice, fileContents, 60000); } } /* confirm FU started okay */ if (retval == Status.Ok) { /* wait until we get the rising edge of the flash event - a percent update with healthy error code, or a failed response from async web request. */ int i = 0; const int kMaxLoops = 50; for (; i < kMaxLoops; ++i) { const int kTimePerLoopMs = 100; /* check if flashing has started */ retval = ConfirmIfFieldUpgradeIsOccuring(ddRef, true); /* leave for-loop if flashing started */ if (retval == Status.Ok) { break; } /* wait for kTimePerLoopMs to see if firmUpdate finishes early */ bool bIsDone = false; var respErr = CheckAsyncWebServerResp(asyncWebExchange, kTimePerLoopMs, out bIsDone); /* leave for-loop if FU request completed */ if (bIsDone) { /* since we are leaving the loop because of this, save the error code */ retval = respErr; break; } } /* uncomment to help better debug where errors are sourced */ //SetFieldUpgradeStatus("Starting field-upgrade : " + retval, 0); } /* poll status - loop while status is ok and firmUpdate is not complete*/ int notUpdatingCnt = 0; while (retval == Status.Ok) { /* request an update */ if (retval == Status.Ok) { retval = _WebServerScripts.HttpGet(_hostName, ddRef.model, ddRef.deviceID, ActionType.CheckUpdateProgress, out response, "", 200); } /* proces the update response */ if (retval == Status.Ok) { /* parse the response that has the field-upgrade status */ ProgressReturn jsonResp = JsonConvert.DeserializeObject <ProgressReturn>(response); retval = (Status)jsonResp.GeneralReturn.Error; if (retval == Status.CTRE_DI_NotUpdating) { ++notUpdatingCnt; /* most likely flash has finished */ retval = Status.Ok; } else { /* save it so calling application can poll it */ SetFieldUpgradeStatus(jsonResp); } } /* check on the first async web exchange */ if (retval == Status.Ok) { bool bIsDone = false; retval = CheckAsyncWebServerResp(asyncWebExchange, 100, out bIsDone); /* leave while-loop if FU request completed */ if (bIsDone) { break; } } /* check on our state in case GUI is shutting down */ if (GetState_NoLock() != State.ExecAction) { retval = Status.Aborted; } } return(retval); }
/// <summary> /// Service _action and update _action.Error. /// </summary> private Status PerformAction(out bool setStateToConnecting) { setStateToConnecting = false; /* get info on this device */ byte devID = _action.deviceID; var model = _action.model; /* lookup device descriptor */ DeviceDescrip ddRef; bool foundOk = _descriptors.Get(model, devID, out ddRef); /* track the error status */ Status retval = Status.Ok; /* temp for catching JSON responses */ string response = string.Empty; string fileName = string.Empty; switch (_action.type) { case ActionType.Blink: /* make sure device was found in our collection */ if (retval == Status.Ok) { retval = (foundOk) ? Status.Ok : Status.DeviceNotFound; } /* perform http exchange */ if (retval == Status.Ok) { retval = _WebServerScripts.HttpGet(_hostName, ddRef.model, ddRef.deviceID, ActionType.Blink, out response); } /* parse resp */ if (retval == Status.Ok) { BlinkReturn jsonDeser = JsonConvert.DeserializeObject <BlinkReturn>(response); retval = (Status)jsonDeser.GeneralReturn.Error; } break; case ActionType.SelfTest: /* make sure device was found in our collection */ if (retval == Status.Ok) { retval = (foundOk) ? Status.Ok : Status.DeviceNotFound; } /* perform http exchange */ if (retval == Status.Ok) { retval = _WebServerScripts.HttpGet(_hostName, ddRef.model, ddRef.deviceID, ActionType.SelfTest, out response, "", 5000); } /* parse resp */ if (retval == Status.Ok) { SelfTestReturn jsonDeser = JsonConvert.DeserializeObject <SelfTestReturn>(response); retval = (Status)jsonDeser.GeneralReturn.Error; if (retval == Status.Ok) { _action.selfTestResults = jsonDeser.SelfTest; } else { _action.selfTestResults = "Self-Test Failed"; } } break; case ActionType.SetDeviceName: /* get params for this action */ String newName = _action.stringParam; /* make sure device was found in our collection */ if (retval == Status.Ok) { retval = (foundOk) ? Status.Ok : Status.DeviceNotFound; } /* perform http exchange */ if (retval == Status.Ok) { retval = _WebServerScripts.HttpGet(_hostName, ddRef.model, ddRef.deviceID, ActionType.SetDeviceName, out response, "&newname=" + newName, 2000); } /* parse resp */ if (retval == Status.Ok) { NameReturn jsonDeser = JsonConvert.DeserializeObject <NameReturn>(response); retval = (Status)jsonDeser.GeneralReturn.Error; } break; case ActionType.SetID: /* get params for this action */ byte newId = (byte)_action.newID; /* make sure device was found in our collection */ if (retval == Status.Ok) { retval = (foundOk) ? Status.Ok : Status.DeviceNotFound; } /* perform http exchange */ if (retval == Status.Ok) { retval = _WebServerScripts.HttpGet(_hostName, ddRef.model, ddRef.deviceID, ActionType.SetID, out response, "&newid=" + newId.ToString(), 2000); } /* parse resp */ if (retval == Status.Ok) { IDReturn jsonDeser = JsonConvert.DeserializeObject <IDReturn>(response); retval = (Status)jsonDeser.GeneralReturn.Error; } /* if ID change was successful, update our local device list */ if (retval == Status.Ok) { _descriptors.ChangeID(ddRef, newId); } if (retval == Status.Ok) { /* Update device cache with new deviceID, this is important when resolving/creating device ID conflicts */ UpdateConfigs(ddRef); } break; case ActionType.SetConfig: /* Specify the filename so it's somewhat unique */ fileName = (ddRef.model + ": " + ddRef.deviceID + ".json").ToLower(); //ToLower Everything to make it parsable in URL /* get params for this action */ string serializedData = _action.stringParam; /* Get content payload from action */ byte[] dataBytes = System.Text.Encoding.UTF8.GetBytes(serializedData); /* If we're using GET we need to send the file up */ if (EnableSftpTransfer) { _rioUpdater = new RioUpdater(_hostName); _rioUpdater.SendFileContents(dataBytes, _serverSearchDirectory + fileName); System.Threading.Thread.Sleep(250); //Wait a bit to make sure file got onto the RIO } /* make sure device was found in our collection */ if (retval == Status.Ok) { retval = (foundOk) ? Status.Ok : Status.DeviceNotFound; } /* perform http exchange */ if (retval == Status.Ok) { /* Decide if we're posting or getting from the _usingPost flag */ if (EnableSftpTransfer) { retval = _WebServerScripts.HttpGet(_hostName, ddRef.model, ddRef.deviceID, ActionType.SetConfig, out response, "&file=" + fileName, 5000); } else { retval = _WebServerScripts.HttpPost(_hostName, ddRef.model, ddRef.deviceID, ActionType.SetConfig, dataBytes, out response, 5000); } } /* parse resp */ if (retval == Status.Ok) { SetConfigReturn jsonDeser = JsonConvert.DeserializeObject <SetConfigReturn>(response); retval = (Status)jsonDeser.GeneralReturn.Error; } if (retval == Status.Ok) { /* Backend should immediately update device config cache */ retval = UpdateConfigs(ddRef); } break; case ActionType.FieldUpgradeDevice: /* Specify file name as generic so it gets overwritten every time */ fileName = "firmwarefile.crf"; /* If we're using POST, we don't need to send the file up */ if (EnableSftpTransfer) { /* Create a RioFile to be sent to the server */ RioFile file = new RioFile(_action.filePath, _serverSearchDirectory + fileName); /* First put the files onto the RIO */ _rioUpdater = new RioUpdater(_hostName); _rioUpdater.SendFile(file); } /* make a new web exchange that allows for overlapped operation */ _asyncWebExchange = new AsyncWebExchange(); /* make sure device was found in our collection */ if (retval == Status.Ok) { retval = (foundOk) ? Status.Ok : Status.DeviceNotFound; } if (retval == Status.Ok) { retval = ExecuteFieldUpgrade(ddRef, _asyncWebExchange, fileName, EnableSftpTransfer); } /* free resouces */ _asyncWebExchange.Dispose(); break; case ActionType.InstallDiagServerToRobotController: _rioUpdater = new RioUpdater(_hostName); _rioUpdater.StartUpdate(); retval = Status.Ok; setStateToConnecting = true; break; case ActionType.UninstallDiagServerToRobotController: _rioUpdater = new RioUpdater(_hostName); _rioUpdater.StartRevert(); retval = Status.Ok; setStateToConnecting = true; break; case ActionType.StartServer: _rioUpdater = new RioUpdater(_hostName); retval = _rioUpdater.StartServer(); setStateToConnecting = true; break; case ActionType.StopServer: _rioUpdater = new RioUpdater(_hostName); retval = _rioUpdater.StopServer(); setStateToConnecting = true; break; /* Unit Testing Cases */ case ActionType.GetVersion: //Used for Unit Testing VersionReturn responseClass = null; if (retval == Status.Ok) { retval = _WebServerScripts.HttpGet(_hostName, "", 0, ActionType.GetVersion, out response); } if (retval == Status.Ok) { responseClass = JsonConvert.DeserializeObject <VersionReturn>(response); retval = responseClass.Version.Equals(_action.stringParam) ? Status.Ok : Status.VersionDoesNotMatch; } break; case ActionType.GetNumOfDevices: GetDevicesReturn numDeviceReturn = null; if (retval == Status.Ok) { retval = _WebServerScripts.HttpGet(_hostName, "", 0, ActionType.GetDeviceList, out response); } if (retval == Status.Ok) { numDeviceReturn = JsonConvert.DeserializeObject <GetDevicesReturn>(response); retval = numDeviceReturn.DeviceArray.Length >= _action.param ? Status.Ok : Status.NotEnoughDevices; } break; case ActionType.RebootRio: _rioUpdater = new RioUpdater(_hostName); retval = _rioUpdater.RebootRio(); setStateToConnecting = true; break; case ActionType.CheckProcess: _rioUpdater = new RioUpdater(_hostName); retval = _rioUpdater.CheckProcessStarted(); break; default: retval = Status.UnsupportedAction; break; } /* callback to GUI */ _action.Error = retval; _action.callback(_action, retval); /* free it */ _action = null; /* pass error to caller */ return(retval); }