/// <summary> /// Invoked when the heartbeat timer ticks. /// </summary> void HeartbeatTimer_Tick(object sender, object e) { // Log telemetry event that the device is alive TelemetryHelper.TrackMetric("DeviceHeartbeat", heartbeatInterval); }
private async Task writeResponseAsync(string request, IOutputStream os, StreamSocketInformation socketInfo) { try { string[] requestParts = request.Split('/'); // Request for the root page, so redirect to home page if (request.Equals("/")) { await redirectToPage(NavConstants.HOME_PAGE, os); } // Request for the home page else if (request.Contains(NavConstants.HOME_PAGE)) { // Generate the default config page string html = await helper.GenerateStatusPage(); await WebHelper.WriteToStream(html, os); } // Request for the settings page else if (request.Contains(NavConstants.SETTINGS_PAGE)) { // Process the GET parameters if (request.Contains("?")) { // Format the URI with the get parameters Uri uri = new Uri("http://1.2.3.4:8000" + request); // Take the parameters from the URL and put it into Settings helper.ParseUriIntoSettings(uri); await AppSettings.SaveAsync(App.Controller.XmlSettings, "Settings.xml"); // This is an event that lets us know what the controller is done restarting after the settings are applied AutoResetEvent ase = new AutoResetEvent(false); // Dispose and Initialize need to be called on UI thread because of DispatcherTimers await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async() => { try { // Restart the controller to apply new settings App.Controller.Dispose(); await App.Controller.Initialize(); // Create the settings page and add a confirmation message that the settings were applied successfully string html = helper.GeneratePage("Security System Config", "Security System Config", helper.CreateHtmlFormFromSettings(), "<span style='color:Green'>Configuration saved!</span><br><br>"); await WebHelper.WriteToStream(html, os); } catch (Exception ex) { Debug.WriteLine("Error restarting controller: " + ex.Message); } // Signal that the restart is done ase.Set(); }); // Wait for controller restart to finish ase.WaitOne(); } else { // Generate the default config page string html = helper.GeneratePage("Security System Config", "Security System Config", helper.CreateHtmlFormFromSettings()); await WebHelper.WriteToStream(html, os); } } // Request for the OneDrive page else if (request.Contains(NavConstants.ONEDRIVE_PAGE)) { // Take in the parameters and try to login to OneDrive if (request.Contains("?")) { // I just put some arbitrary IP and port just so I have a correctly formatted URI, it's not important to have an actual IP + port Uri uri = new Uri("http://1.2.3.4:8000" + request); await helper.ParseOneDriveUri(uri); var oneDrive = App.Controller.Storage as OneDrive; if (oneDrive != null) { if (oneDrive.IsLoggedIn()) { // Save tokens to settings file if we successfully logged in await AppSettings.SaveAsync(App.Controller.XmlSettings, "Settings.xml"); } } } // Generate page and write to stream string html = helper.GenerateOneDrivePage(); await WebHelper.WriteToStream(html, os); } // Request for gallery page else if (request.Contains(NavConstants.GALLERY_PAGE)) { string html = ""; var storageType = App.Controller.Storage.GetType(); // If the storage type is OneDrive, generate page with link to OneDrive if (storageType == typeof(OneDrive)) { html = helper.GeneratePage("Gallery", "Gallery", "<b>" + storageType.Name + "</b> is set as your storage provider. " + "Please view your pictures on <a href='http://www.onedrive.com' target='_blank'>OneDrive</a>.<br><br>" + "To view your pictures here, please select <b>" + StorageProvider.Local + "</b> as your storage provider."); } // Otherwise show the gallery for the files on the device else { StorageFolder folder = KnownFolders.PicturesLibrary; int page = 1; int pageSize = 30; // Parse GET parameters if (request.Contains("?")) { Uri uri = new Uri("http://1.2.3.4:8000" + request); var parameters = helper.ParseGetParametersFromUrl(uri); try { // Find the folder that's specified in the parameters folder = await StorageFolder.GetFolderFromPathAsync(parameters["folder"]); if (parameters.ContainsKey("page")) { try { page = Convert.ToInt32(parameters["page"]); } catch (Exception) { } } if (parameters.ContainsKey("pageSize")) { try { pageSize = Convert.ToInt32(parameters["pageSize"]); } catch (Exception) { } } } catch (Exception ex) { Debug.WriteLine("Exception finding folder: " + ex.Message); folder = await folder.GetFolderAsync(AppSettings.FolderName); // Log telemetry event about this exception var events = new Dictionary <string, string> { { "WebServer", ex.Message } }; TelemetryHelper.TrackEvent("FailedToGetFolderFromPath", events); } } else { folder = await folder.GetFolderAsync(AppSettings.FolderName); } // Generate gallery page and write to stream string galleryHtml = await helper.GenerateGallery(folder, page, pageSize); html = helper.GeneratePage("Gallery", "Gallery", galleryHtml); } await WebHelper.WriteToStream(html, os); } // Request for API else if (request.Contains("api")) { try { if (requestParts.Length > 2) { switch (requestParts[2].ToLower()) { // An image from the gallery was requested case "gallery": var temp = request.Split(new string[] { "gallery/" }, StringSplitOptions.None); // HTML decode the file path string decodedPath = WebUtility.UrlDecode(temp[1]); // Retrieve the file StorageFile file = await StorageFile.GetFileFromPathAsync(decodedPath); // Write the file to the stream await WebHelper.WriteFileToStream(file, os); break; } } }catch (Exception ex) { Debug.WriteLine("Exception in web API: " + ex.Message); // Log telemetry event about this exception var events = new Dictionary <string, string> { { "WebServer", ex.Message } }; TelemetryHelper.TrackEvent("FailedToProcessApiRequest", events); } } // Request for a file that is in the Assets\Web folder (e.g. logo, css file) else { using (Stream resp = os.AsStreamForWrite()) { bool exists = true; try { var folder = Windows.ApplicationModel.Package.Current.InstalledLocation; // Map the requested path to Assets\Web folder string filePath = @"Assets\Web" + request.Replace('/', '\\'); // Open the file and write it to the stream using (Stream fs = await folder.OpenStreamForReadAsync(filePath)) { string header = String.Format("HTTP/1.1 200 OK\r\n" + "Content-Length: {0}\r\n{1}" + "Connection: close\r\n\r\n", fs.Length, ((request.Contains("css")) ? "Content-Type: text/css\r\n" : "")); byte[] headerArray = Encoding.UTF8.GetBytes(header); await resp.WriteAsync(headerArray, 0, headerArray.Length); await fs.CopyToAsync(resp); } } catch (FileNotFoundException ex) { exists = false; // Log telemetry event about this exception var events = new Dictionary <string, string> { { "WebServer", ex.Message } }; TelemetryHelper.TrackEvent("FailedToOpenStream", events); } // Send 404 not found if can't find file if (!exists) { byte[] headerArray = Encoding.UTF8.GetBytes( "HTTP/1.1 404 Not Found\r\n" + "Content-Length:0\r\n" + "Connection: close\r\n\r\n"); await resp.WriteAsync(headerArray, 0, headerArray.Length); } await resp.FlushAsync(); } } }catch (Exception ex) { Debug.WriteLine("Exception in writeResponseAsync(): " + ex.Message); Debug.WriteLine(ex.StackTrace); // Log telemetry event about this exception var events = new Dictionary <string, string> { { "WebServer", ex.Message } }; TelemetryHelper.TrackEvent("FailedToWriteResponse", events); try { // Try to send an error page back if there was a problem servicing the request string html = helper.GeneratePage("Error", "Error", "There's been an error: " + ex.Message + "<br><br>" + ex.StackTrace); await WebHelper.WriteToStream(html, os); } catch (Exception e) { TelemetryHelper.TrackException(e); } } }
/// <summary> /// Initializes the controller: Loads settings, starts web server, sets up the camera and storage providers, /// tries to log into OneDrive (if OneDrive is selected), and starts the file upload and deletion timers /// </summary> /// <returns></returns> public async Task Initialize() { try { // Load settings from file XmlSettings = await AppSettings.RestoreAsync("Settings.xml"); // Create securitysystem-cameradrop sub folder if it doesn't exist StorageFolder folder = KnownFolders.PicturesLibrary; if (await folder.TryGetItemAsync(AppSettings.FolderName) == null) { await folder.CreateFolderAsync(AppSettings.FolderName); } // Copy sample "known" images to users Pictures folder. //await CreateAndPopulateKnownImages(folder); // Start web server on port 8000 if (!Server.IsRunning) { Server.Start(8000); } Camera = CameraFactory.Get(XmlSettings.CameraType); Storage = StorageFactory.Get(XmlSettings.StorageProvider); await Camera.Initialize(); // Configure the FaceAPI client if (XmlSettings.FaceAPIKey != String.Empty) { //FaceClient = new FaceClient(XmlSettings.FaceAPIKey); } // Try to log into OneDrive using existing Access Token in settings file if (Storage.GetType() == typeof(OneDrive)) { var oneDrive = App.Controller.Storage as OneDrive; if (oneDrive != null) { if (!oneDrive.IsLoggedIn()) { try { await oneDrive.AuthorizeWithRefreshToken(XmlSettings.OneDriveRefreshToken); } catch (Exception ex) { Debug.WriteLine(ex.Message); // Log telemetry event about this exception var events = new Dictionary <string, string> { { "Controller", ex.Message } }; TelemetryHelper.TrackEvent("FailedToLoginOneDrive", events); } } } } this.alljoynManager = new AllJoynManager(); await this.alljoynManager.Initialize(this.Camera, this.Storage); //Timer controlling camera pictures with motion uploadPicturesTimer = new DispatcherTimer(); uploadPicturesTimer.Interval = TimeSpan.FromSeconds(uploadInterval); uploadPicturesTimer.Tick += uploadPicturesTimer_Tick; uploadPicturesTimer.Start(); //Timer controlling deletion of old pictures deletePicturesTimer = new DispatcherTimer(); deletePicturesTimer.Interval = TimeSpan.FromHours(deleteInterval); deletePicturesTimer.Tick += deletePicturesTimer_Tick; deletePicturesTimer.Start(); IsInitialized = true; } catch (Exception ex) { Debug.WriteLine("Controller.Initialize() Error: " + ex.Message); // Log telemetry event about this exception var events = new Dictionary <string, string> { { "Controller", ex.Message } }; TelemetryHelper.TrackEvent("FailedToInitialize", events); } }