Example #1
0
        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.&nbsp;&nbsp;"
                                                   + "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);
                }

                // 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();

                // 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);
            }
        }
Example #3
0
        /// <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);
        }