public void TestScriptStart(IDictionary <string, string> args) { if (_testScriptThread != null && _testScriptThread.ThreadState == Thread.eThreadStates.ThreadRunning) { throw new Exception("Script already running"); } _testScriptThread = new Thread(TestScriptThreadProcess, args) { Priority = Thread.eThreadPriority.LowestPriority, Name = "System Testing Script Thread" }; }
private void DispatchAsync(CodecRequest request, CodecHttpClientRequestCallback callback) { Lock.Enter(); Callbacks[request] = callback; Lock.Leave(); //CrestronConsole.PrintLine("Queuing request id:{0}", request.Id); RequestQueue.Enqueue(request); if (_dispatchThread == null || _dispatchThread.ThreadState == Thread.eThreadStates.ThreadFinished) { _dispatchThread = new Thread(DispatchThreadProcess, null) { Name = "CodecHttpClient Process Thread", Priority = Thread.eThreadPriority.HighPriority }; } }
public static void ListenForUpdateServers() { if (_udpServer != null) { return; } _udpServer = new UDPServer(IPAddress.Any, 15000, 1000); _udpServer.EnableUDPServer(); CrestronEnvironment.ProgramStatusEventHandler += type => { _programStopping = type == eProgramStatusEventType.Stopping; if (!_programStopping) { return; } try { _udpServer.DisableUDPServer(); _udpServer.Dispose(); } catch (Exception e) { CloudLog.Exception(e); } if (_listenThread.ThreadState == Thread.eThreadStates.ThreadRunning) { _listenThread.Abort(); } }; _listenThread = new Thread(ProcessUdpData, null) { Name = "Software Update Listener" }; }
private void InternalClockInitialize() { _clockInitThread = new Thread(specific => { CloudLog.Debug("InternalClockInitialize(), Waiting for seconds to be 0", GetType().Name); while (DateTime.Now.Second != 0) { Thread.Sleep(50); CrestronEnvironment.AllowOtherAppsToRun(); } CloudLog.Notice("InternalClockInitialize(), Seconds should now be zero, time is now {1}, creating CTimer to track time", GetType().Name, DateTime.Now.ToString("T")); _clockTimer = new CTimer(s => OnTimeChange(), null, 60000, 60000); OnTimeChange(); CloudLog.Info("InternalClockInitialize(), OnTimeChange() will be called every time time is 0 seconds", GetType().Name); return(null); }, null, Thread.eThreadStartOptions.CreateSuspended) { Name = "Clock Init Thread", Priority = Thread.eThreadPriority.HighPriority }; _clockInitThread.Start(); }
private object SystemThreadProcess(object userSpecific) { try { while (true) { if (_userPrompts.Count == 0) { _systemWait.Wait(2000); } if (_programStopping) { return(null); } if (_userPrompts.Count == 0) { goto CheckTimers; } try { var prompts = _userPrompts.ToArray(); // We have queued prompts that aren't showing as current system prompts if (prompts.Any(p => p.State == PromptState.Queued) && !prompts.Any(p => p.State == PromptState.Shown && p.Room == null)) { //Debug.WriteInfo("Prompts queued! System {0}, Room {1}", // _userPrompts.Count(p => p.State == PromptState.Queued && p.Room == null), // _userPrompts.Count(p => p.State == PromptState.Queued && p.Room != null)); // Look for any system prompts (not specific to a room) var prompt = prompts.FirstOrDefault(p => p.State == PromptState.Queued && p.Room == null); if (prompt != null) { var roomPrompts = prompts.Where(p => p.State == PromptState.Shown && p.Room != null); // Close any active room prompts and reset to queue as system will override var pArray = roomPrompts as UserPrompt[] ?? roomPrompts.ToArray(); foreach (var roomPrompt in pArray) { roomPrompt.State = PromptState.Queued; } if (pArray.Any()) { Thread.Sleep(200); } prompt.State = PromptState.Shown; //Debug.WriteInfo("Showing system prompt on all UIs!"); foreach (var uiController in UIControllers) { uiController.ShowPrompt(prompt); } } else { // No system prompts to show so we can show any room prompts foreach (var room in Rooms) { var room1 = room; // Already showing a prompt in this room ... skip the room if (_userPrompts.Any(p => p.State == PromptState.Shown && p.Room == room1)) { continue; } prompt = prompts.FirstOrDefault( p => p.State == PromptState.Queued && p.Room == room1); if (prompt != null && prompt.State != PromptState.Cancelled) { prompt.State = PromptState.Shown; foreach (var uiController in UIControllers.ForRoom(room1)) { uiController.ShowPrompt(prompt); } } } } } //if (prompts.Length > 0) // Debug.WriteInfo("Removing {0} expired prompts", prompts.Length); foreach (var userPrompt in prompts.Where(p => p.State != PromptState.Queued && p.State != PromptState.Shown)) { _userPromptsLock.Enter(); _userPrompts.Remove(userPrompt); _userPromptsLock.Leave(); } } catch (Exception e) { CloudLog.Exception(e); Thread.Sleep(1000); } CheckTimers: if (!Booted) { continue; } if (SecondsSinceLastSystemTimerCallback > 10 && !_timersBrokenFlag) { _timersBrokenFlag = true; CloudLog.Error( "System Timer last checked in {0} seconds ago. Will reboot processor in 10 minutes if not fixed!!", SecondsSinceLastSystemTimerCallback); } else if (SecondsSinceLastSystemTimerCallback > 600 && _timersBrokenFlag) { CloudLog.Error("Automatic reboot now!"); var response = string.Empty; CrestronConsole.SendControlSystemCommand("REBOOT", ref response); } else if (_timersBrokenFlag && SecondsSinceLastSystemTimerCallback < 10) { _timersBrokenFlag = false; CloudLog.Warn("System Timer checked in {0} seconds ago after a delay", SecondsSinceLastSystemTimerCallback); } CrestronEnvironment.AllowOtherAppsToRun(); } } catch (Exception e) { CloudLog.Exception(e, "Unhandled Exception in SystemThreadProcess()!"); return(null); } }
public virtual void Initialize() { if (_initialized) { return; } _initialized = true; _systemTimer = new CTimer(SystemTimerCallback, null, 1000, 1000); InternalClockInitialize(); var response = string.Empty; CrestronConsole.SendControlSystemCommand("webport", ref response); var match = Regex.Match(response, @"Webserver port *= *(\d+)"); if (match.Success) { var port = int.Parse(match.Groups[1].Value); Debug.WriteWarn("Built-web server is using port {0}", port); } foreach (var process in GetSystemItemsToInitialize()) { _initializeQueue.Enqueue(process); } foreach (var source in Sources.Where(s => s.Device != null)) { var device = source.Device as IInitializeComplete; if (device != null) { _initializeQueue.Enqueue(new InitializeProcess(source.Device.Initialize, string.Format("Initializing Source Device: {0}", device.GetType().Name), TimeSpan.Zero, device.CheckInitializedOk)); } else { _initializeQueue.Enqueue(new InitializeProcess(source.Device.Initialize, string.Format("Initializing Source Device: {0}", source.Device.GetType().Name))); } } foreach (var room in Rooms) { _initializeQueue.Enqueue(new InitializeProcess(room.Initialize, string.Format("Initializing Room: \"{0}\"", room.Name))); } var displays = Displays.Where(d => d.Device != null).ToArray(); var count = 0; foreach (var display in displays) { count++; _initializeQueue.Enqueue(new InitializeProcess(display.Initialize, string.Format("Initializing Display {0}", count))); } foreach (var room in Rooms.Where(r => r.FusionEnabled)) { _initializeQueue.Enqueue(new InitializeProcess(room.FusionRegisterInternal, string.Format("Registering Fusion for Room: \"{0}\"", room.Name), TimeSpan.FromSeconds(5))); } /*if (Rooms.Any(r => r.FusionEnabled)) * { * _initializeQueue.Enqueue(new InitializeProcess(FusionRVI.GenerateFileForAllFusionDevices, * "Generating Fusion RVI file for discovery")); * }*/ if (UIControllers.Any()) { _initializeQueue.Enqueue(new InitializeProcess(UIControllers.ConnectToDefaultRooms, "Setting up UI Controllers")); } if (UIControllers.Any()) { _initializeQueue.Enqueue(new InitializeProcess(UIControllers.Initialize, "Initializing UI Controllers")); } if (_systemThread != null) { return; } _systemThread = new Thread(SystemThreadProcess, null) { Name = "UX.Lib2.SystemBase SystemThreadProcess()", Priority = Thread.eThreadPriority.LowestPriority }; _systemStartupThread = new Thread(SystemStartupThreadProcess, null) { Name = "System Startup Thread Process", Priority = Thread.eThreadPriority.MediumPriority }; }
public static object UpdateFromPushedUpdateProcess(object o) { var random = new Random(); var attemptCount = 0; if (_status == UpdateStatus.Failed) { CloudLog.Notice("Previous update had failed, clearing status!"); _status = UpdateStatus.NotRunning; Thread.Sleep(1000); } while (_status == UpdateStatus.NotRunning && !_programStopping) { try { attemptCount++; if (attemptCount == 1) { var ms = random.Next((int)TimeSpan.FromSeconds(30).TotalMilliseconds, (int)TimeSpan.FromMinutes(20).TotalMilliseconds); Debug.WriteSuccess("Update push process running", "waiing for {0}", TimeSpan.FromMilliseconds(ms).ToString()); CrestronEnvironment.AllowOtherAppsToRun(); Thread.Sleep(ms); } else { Thread.Sleep(60000); } if (attemptCount > 5) { CloudLog.Error("Software update push failed after 5 attempts. Exiting process"); _status = UpdateStatus.Failed; return(null); } if (_status != UpdateStatus.NotRunning) { return(null); } Debug.WriteInfo("Getting current list of updates..."); try { GetAppUpdates(); } catch (Exception e) { CloudLog.Exception(e); _httpClient.Dispose(); _httpClient = new HttpClient(); } var info = _updates.FirstOrDefault(f => new Version(f.Version).CompareTo(_pushedVersion) == 0); if (info != null) { Debug.WriteInfo("Found update available at URL", info.Url); CloudLog.Info("Software update push can be downloaded from: {0}", info.Url); var downloadResult = Download(info.Url); if (downloadResult == 0) { try { OnUpdateShouldLoad(); } catch (Exception e) { CloudLog.Exception(e); continue; } return(null); } _status = UpdateStatus.NotRunning; CloudLog.Warn("Attempt {0} to download update failed, Error {1}", attemptCount, downloadResult); continue; } CloudLog.Error("Pushed update failed, could not find an update matching version {0}", _pushedVersion); _status = UpdateStatus.Failed; return(null); } catch (Exception e) { if (attemptCount <= 5) { continue; } CloudLog.Error("Pushed update failed to get version {0}, {1}", _pushedVersion, e.Message); _status = UpdateStatus.Failed; return(null); } } return(null); }
public static int Download(string url) { Debug.WriteInfo("SoftwareUpdate.Download() Called"); if (_status == UpdateStatus.Pending) { throw new Exception("Download process already running"); } try { ResetDownloads(); _downloadCancelled = false; _status = UpdateStatus.Pending; _progress = 10; var attemptCount = 0; while (true) { if (_downloadCancelled) { Debug.WriteWarn("SoftwareUpdate.Download()", "Cancelled"); _status = UpdateStatus.Cancelled; return(-1); } attemptCount++; if (attemptCount > 10) { Debug.WriteWarn("SoftwareUpdate.Download()", "Too many attempts, cancelling"); _status = UpdateStatus.Failed; _httpClient.Dispose(); _httpClient = new HttpClient(); return(-3); } var getTask = _httpClient.GetAsync(url); Debug.WriteInfo("SoftwareUpdate.Download()", "Awaiting response"); var response = getTask.Await(); var message = response.EnsureSuccessStatusCode(); Debug.WriteWarn("SoftwareUpdate.Download()", "Status = {0}", message.StatusCode.ToString()); if (message.StatusCode == HttpStatusCode.OK) { _status = UpdateStatus.Waiting; } else { Thread.Sleep(5000); continue; } if (response.Content.Headers.ContentLength == null) { Debug.WriteWarn("SoftwareUpdate.Download()", "ContentLength is null"); Thread.Sleep(5000); continue; } var totalBytes = (long)response.Content.Headers.ContentLength; Debug.WriteInfo("SoftwareUpdate.Download()", "Received {0} bytes, {1}", totalBytes, Tools.PrettyByteSize(totalBytes, 2)); if (_downloadCancelled) { Debug.WriteWarn("SoftwareUpdate.Download()", "Cancelled"); _status = UpdateStatus.Cancelled; return(-1); } using (var contentStream = response.Content.ReadAsStreamAsync().Await()) { _status = UpdateStatus.Downloading; var totalBytesRead = 0L; var readCount = 0L; var buffer = new byte[8192]; var isMoreToRead = true; using ( var fileStream = new FileStream(InitialParametersClass.ProgramDirectory + @"\update.cpz", FileMode.Create, FileAccess.Write, FileShare.None)) { try { do { var bytesRead = contentStream.ReadAsync(buffer, 0, buffer.Length).Await(); if (bytesRead == 0) { isMoreToRead = false; _progress = (int)Tools.ScaleRange(totalBytesRead, 0, totalBytes, 0, 100); Debug.WriteInfo("Download progress:", "{0}%", _progress); continue; } fileStream.WriteAsync(buffer, 0, bytesRead).Await(); totalBytesRead += bytesRead; readCount += 1; if (readCount % 100 != 0) { continue; } _progress = (int)Tools.ScaleRange(totalBytesRead, 0, totalBytes, 0, 100); Debug.WriteInfo("Download progress:", "{0}%", _progress); } while (isMoreToRead); Debug.WriteSuccess("Download complete"); _status = UpdateStatus.Downloaded; _progress = 100; return(0); } catch (Exception e) { CloudLog.Exception(e); _status = UpdateStatus.Failed; _httpClient.Dispose(); _httpClient = new HttpClient(); return(-2); } } } } } catch { _status = UpdateStatus.Failed; return(-2); } }
private static object ProcessUdpData(object o) { var buffer = new byte[1000]; var byteIndex = 0; while (!_programStopping) { try { var count = _udpServer.ReceiveData(); for (var i = 0; i < count; i++) { var b = _udpServer.IncomingDataBuffer[i]; if (b == 13) { try { var str = Encoding.ASCII.GetString(buffer, 0, byteIndex); var match = Regex.Match(str, @"UpdateServer: *([\w-.]+)"); if (match.Success) { _serverAddress = match.Groups[1].Value; if (_checkUpdatesTimer == null) { _checkUpdatesTimer = new CTimer(specific => { try { GetAppUpdates(); } catch (Exception e) { CloudLog.Error("Could not check for updates, {0}", e.Message); } }, null, 1000, (long)TimeSpan.FromHours(1).TotalMilliseconds); } byteIndex = 0; continue; } match = Regex.Match(str, @"UpdatePush\s+Version:\s*([\d\.]+)"); if (match.Success) { Debug.WriteWarn("Update Push!!! Version", match.Groups[1].Value); CloudLog.Notice("Software Update Push command received. Version = {0}", match.Groups[1].Value); _pushedVersion = new Version(match.Groups[1].Value); if (_pushedVersion.CompareTo(Assembly.GetExecutingAssembly().GetName().Version) == 0) { CloudLog.Notice("New version is current so will skip the push!"); } else { if (_pushUpdateProcessThread != null && _pushUpdateProcessThread.ThreadState == Thread.eThreadStates.ThreadRunning) { byteIndex = 0; continue; } Debug.WriteInfo("Update push ok to run, launching process now"); CloudLog.Info("Starting software update push process", match.Groups[1].Value); _pushUpdateProcessThread = new Thread(UpdateFromPushedUpdateProcess, null); } } } catch (Exception e) { CloudLog.Exception(e); } byteIndex = 0; } else { buffer[byteIndex] = b; byteIndex++; } } } catch (Exception e) { if (e is ThreadAbortException) { return(null); } CloudLog.Exception(e); } } return(null); }