private static void KeyCallback(Window window, Keys key, int scanCode, InputState state, ModifierKeys mods) { if (key == GLFW.Keys.W && state == GLFW.InputState.Press) { // load following minute's observations VerticeData.VerticeSlice = DataSelector.FetchNewerRecords(VerticeData.NormalizedReports, DataSelector.currentAP); VerticeData.SquareVertices = DataTransform.GenerateQuads(VerticeData.VerticeSlice, DisplayManager.ViewportWidth, DisplayManager.ViewportHeight); } else if (key == GLFW.Keys.S && state == GLFW.InputState.Press) { // load preceeding minute VerticeData.VerticeSlice = DataSelector.FetchOlderRecords(VerticeData.NormalizedReports, DataSelector.currentAP); VerticeData.SquareVertices = DataTransform.GenerateQuads(VerticeData.VerticeSlice, DisplayManager.ViewportWidth, DisplayManager.ViewportHeight); } else if (key == GLFW.Keys.A && state == GLFW.InputState.Press) { // load previous AP's data DataSelector.currentAP = DataSelector.currentAP - 1; if (DataSelector.currentAP < 0) { DataSelector.currentAP = VerticeData.NumberOfAPs - 1; } VerticeData.VerticeSlice = DataSelector.FetchOlderRecords(VerticeData.NormalizedReports, DataSelector.currentAP); VerticeData.SquareVertices = DataTransform.GenerateQuads(VerticeData.VerticeSlice, DisplayManager.ViewportWidth, DisplayManager.ViewportHeight); } else if (key == GLFW.Keys.D && state == GLFW.InputState.Press) { // load next AP's data DataSelector.currentAP = DataSelector.currentAP + 1; if (DataSelector.currentAP > VerticeData.NumberOfAPs - 1) { DataSelector.currentAP = 0; } VerticeData.VerticeSlice = DataSelector.FetchOlderRecords(VerticeData.NormalizedReports, DataSelector.currentAP); VerticeData.SquareVertices = DataTransform.GenerateQuads(VerticeData.VerticeSlice, DisplayManager.ViewportWidth, DisplayManager.ViewportHeight); } else if (key == GLFW.Keys.R && state == GLFW.InputState.Press) { // pull fresh observation data from the DB DataSelector.InitData(myWidth, myHeight); VerticeData.VerticeSlice = DataSelector.FetchOlderRecords(VerticeData.NormalizedReports, DataSelector.currentAP); VerticeData.SquareVertices = DataTransform.GenerateQuads(VerticeData.VerticeSlice, DisplayManager.ViewportWidth, DisplayManager.ViewportHeight); } else if (key == GLFW.Keys.Escape && state == GLFW.InputState.Press) { // die Running = false; } }
private static KeyCallback mlvKeyCallback; // required to keep c# garbage collector from moving the callbacks static void Main(string[] args) { bool listenOnlyMode = false; bool viewOnlyMode = false; bool mixedMode = false; int height, width; string title; HTTPServer httpServer = null; if (args.Length == 1 && args[0] == "--listenonly") { listenOnlyMode = true; } else if (args.Length == 3) { if (args[0] != "-h" || Convert.ToInt32(args[1]) < 1 || args[2] != "--viewonly") { Console.WriteLine("\nUSAGE:"); Console.WriteLine("======================================================================================"); Console.WriteLine("mlv.exe --listenonly (listen for new data only)"); Console.WriteLine("mlv.exe -h window-height --viewonly (visualize existing data only)"); Console.WriteLine("mlv.exe -h window-height (listen and visualize)"); return; } viewOnlyMode = true; } else if (args.Length == 2) { if (args[0] != "-h" || Convert.ToInt32(args[1]) < 1) { Console.WriteLine("\nUSAGE:"); Console.WriteLine("======================================================================================"); Console.WriteLine("mlv.exe --listenonly (listen for new data only)"); Console.WriteLine("mlv.exe -h window-height --viewonly (visualize existing data only)"); Console.WriteLine("mlv.exe -h window-height (listen and visualize)"); return; } mixedMode = true; } else { Console.WriteLine("\nUSAGE:"); Console.WriteLine("======================================================================================"); Console.WriteLine("mlv.exe --listenonly (listen for new data only)"); Console.WriteLine("mlv.exe -h window-height --viewonly (visualize existing data only)"); Console.WriteLine("mlv.exe -h window-height (listen and visualize)"); return; } if (listenOnlyMode || mixedMode) { // launch the http server thread var httpListener = new HttpListener(); // local machine binding //httpServer = new HTTPServer(httpListener, "https://IP.ADDRESS:PORT/URL/"); httpServer = new HTTPServer(httpListener, "https://192.168.100.100:1234/MerakiLocationVisualizer/"); httpServer.Start(); } if (viewOnlyMode || mixedMode) { height = Convert.ToInt32(args[1]); width = height; // hard coding square viewport myHeight = height; myWidth = width; title = "WiFi Radar"; // load the initial batch of observation reports bool successfulDataInit = DataSelector.InitData(width, height); if (VerticeData.NumberOfAPs == 0) { Console.WriteLine("There are no reporting access points. Aborting!"); Console.Read(); return; } if (!successfulDataInit) { Console.WriteLine("There is no observation data in the database. Aborting!"); Console.Read(); return; } Running = true; Glfw.Init(); DisplayManager.CreateWindow(height, width, title); // input events registered below in KeyCallBack() Glfw.SetKeyCallback(DisplayManager.Window, mlvKeyCallback = KeyCallback); uint[] textures = Renderer.LoadTextures(); Shader.Load(); float degrees = 0f; float sweepDegrees = 0f; bool isAscending = true; // visualization loop while (!Glfw.WindowShouldClose(DisplayManager.Window) && Running) { glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); Shader.Use(); // BACKGROUND GRAPHIC glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textures[0]); glUniform1i(glGetUniformLocation(Shader.ProgramID, "backgroundTexture"), 0); // tell the shaders what is being sent to them glUniform1i(glGetUniformLocation(Shader.ProgramID, "isAp"), 0); glUniform1i(glGetUniformLocation(Shader.ProgramID, "isBackground"), 1); glUniform1i(glGetUniformLocation(Shader.ProgramID, "isClient"), 0); glUniform1i(glGetUniformLocation(Shader.ProgramID, "isSweep"), 0); float alphaTime = ((((float)Math.Sin(degrees * 3.0f)) + 1f) / 2) + .05f; glUniform1f(glGetUniformLocation(Shader.ProgramID, "alphaTime"), alphaTime); uint vao = Renderer.Render(VerticeData.backgroundVertices()); glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, VerticeData.backgroundVertices().Length / 8); glBindVertexArray(0); glDeleteVertexArray(vao); glBindTexture(GL_TEXTURE_2D, 0); // RADAR SWEEP GRAPHIC glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glUniform1i(glGetUniformLocation(Shader.ProgramID, "isAp"), 0); glUniform1i(glGetUniformLocation(Shader.ProgramID, "isBackground"), 0); glUniform1i(glGetUniformLocation(Shader.ProgramID, "isClient"), 0); glUniform1i(glGetUniformLocation(Shader.ProgramID, "isSweep"), 1); vao = Renderer.Render(VerticeData.sweepVertices(sweepDegrees)); if (sweepDegrees == 360) { sweepDegrees = 0.0f; } else { sweepDegrees += 0.001f; } glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, 3); glBindVertexArray(0); glDeleteVertexArray(vao); // WIFI CLIENT DEVICE GRAPHICS glBlendFunc(GL_ONE, GL_ONE); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textures[1]); glUniform1i(glGetUniformLocation(Shader.ProgramID, "greenTexture"), 1); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, textures[2]); glUniform1i(glGetUniformLocation(Shader.ProgramID, "redTexture"), 2); glUniform1i(glGetUniformLocation(Shader.ProgramID, "isAp"), 0); glUniform1i(glGetUniformLocation(Shader.ProgramID, "isBackground"), 0); glUniform1i(glGetUniformLocation(Shader.ProgramID, "isClient"), 1); glUniform1i(glGetUniformLocation(Shader.ProgramID, "isSweep"), 0); if (isAscending) { degrees += 0.0012f; } else { degrees -= 0.0012f; } if (degrees == 0) { isAscending = true; } else if (degrees == 360.0f) { isAscending = false; } vao = Renderer.Render(VerticeData.SquareVertices); glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, VerticeData.SquareVertices.Length / 8); glBindVertexArray(0); glDeleteVertexArray(vao); glBindTexture(GL_TEXTURE_2D, 0); // ACCESS POINT GRAPHIC glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glActiveTexture(GL_TEXTURE + DataSelector.currentAP + 3); glBindTexture(GL_TEXTURE_2D, textures[DataSelector.currentAP + 3]); glUniform1i(glGetUniformLocation(Shader.ProgramID, "apTexture"), DataSelector.currentAP + 3); glUniform1i(glGetUniformLocation(Shader.ProgramID, "isAp"), 1); glUniform1i(glGetUniformLocation(Shader.ProgramID, "isBorder"), 0); glUniform1i(glGetUniformLocation(Shader.ProgramID, "isClient"), 0); glUniform1i(glGetUniformLocation(Shader.ProgramID, "isSweep"), 0); float[] tmpVertices = VerticeData.apVertices(); vao = Renderer.Render(tmpVertices); glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, tmpVertices.Length / 8); glBindVertexArray(0); glDeleteVertexArray(vao); glBindTexture(GL_TEXTURE_2D, 0); Glfw.SwapBuffers(DisplayManager.Window); Glfw.PollEvents(); } DisplayManager.DestroyWindow(); } else // listen only { ConsoleKey input; do { input = Console.ReadKey(true).Key; if (input == ConsoleKey.Escape) { httpServer.Stop(); Console.WriteLine("Listener terminated..."); } } while (input != ConsoleKey.Escape); } }