Explorar el Código

web socket sniffing

Chris Mullins hace 8 años
padre
commit
4e27eab452

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 2
dist/index.html.gz.h


+ 22 - 7
lib/Helpers/IntParsing.h

@@ -7,10 +7,10 @@ template <typename T>
 const T strToHex(const char* s, size_t length) {
   T value = 0;
   T base = 1;
-  
+
   for (int i = length-1; i >= 0; i--) {
     const char c = s[i];
-    
+
     if (c >= '0' && c <= '9') {
       value += ((c - '0') * base);
     } else if (c >= 'a' && c <= 'f') {
@@ -20,10 +20,10 @@ const T strToHex(const char* s, size_t length) {
     } else {
       break;
     }
-    
+
     base <<= 4;
   }
-  
+
   return value;
 }
 
@@ -44,15 +44,30 @@ const T parseInt(const String& s) {
 template <typename T>
 void hexStrToBytes(const char* s, const size_t sLen, T* buffer, size_t maxLen) {
   int idx = 0;
-  
+
   for (int i = 0; i < sLen && idx < maxLen; ) {
     buffer[idx++] = strToHex<T>(s+i, 2);
     i+= 2;
-    
+
     while (i < (sLen - 1) && s[i] == ' ') {
       i++;
     }
   }
 }
 
-#endif
+class IntParsing {
+public:
+  static void bytesToHexStr(const uint8_t* bytes, const size_t len, char* buffer, size_t maxLen) {
+    char* p = buffer;
+
+    for (size_t i = 0; i < len && (p - buffer) < (maxLen - 3); i++) {
+      p += sprintf(p, "%02X", bytes[i]);
+
+      if (i < (len - 1)) {
+        p += sprintf(p, " ");
+      }
+    }
+  }
+};
+
+#endif

+ 43 - 0
lib/WebServer/MiLightHttpServer.cpp

@@ -67,12 +67,19 @@ void MiLightHttpServer::begin() {
       yield();
     }
   );
+  wsServer.onEvent(
+    [this](uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
+      handleWsEvent(num, type, payload, length);
+    }
+  );
+  wsServer.begin();
 
   server.begin();
 }
 
 void MiLightHttpServer::handleClient() {
   server.handleClient();
+  wsServer.loop();
 }
 
 void MiLightHttpServer::on(const char* path, HTTPMethod method, ESP8266WebServer::THandlerFunction handler) {
@@ -367,6 +374,42 @@ void MiLightHttpServer::handleSendRaw(const UrlTokenBindings* bindings) {
   server.send_P(200, TEXT_PLAIN, PSTR("true"));
 }
 
+void MiLightHttpServer::handleWsEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length) {
+  switch (type) {
+    case WStype_DISCONNECTED:
+      if (numWsClients > 0) {
+        numWsClients--;
+      }
+      break;
+
+    case WStype_CONNECTED:
+      numWsClients++;
+      break;
+  }
+}
+
+void MiLightHttpServer::handlePacketSent(uint8_t *packet, const MiLightRadioConfig& config) {
+  if (numWsClients > 0) {
+    size_t packetLen = config.packetFormatter->getPacketLength();
+    char buffer[packetLen*3];
+    IntParsing::bytesToHexStr(packet, packetLen, buffer, packetLen*3);
+
+    char formattedPacket[200];
+    config.packetFormatter->format(packet, formattedPacket);
+
+    char responseBuffer[300];
+    sprintf_P(
+      responseBuffer,
+      PSTR("\n%s packet received (%d bytes):\n%s"),
+      config.name,
+      sizeof(packet),
+      formattedPacket
+    );
+
+    wsServer.broadcastTXT(reinterpret_cast<uint8_t*>(responseBuffer));
+  }
+}
+
 ESP8266WebServer::THandlerFunction MiLightHttpServer::handleServe_P(const char* data, size_t length) {
   return [this, data, length]() {
     server.sendHeader("Content-Encoding", "gzip");

+ 7 - 0
lib/WebServer/MiLightHttpServer.h

@@ -1,6 +1,7 @@
 #include <WebServer.h>
 #include <MiLightClient.h>
 #include <Settings.h>
+#include <WebSocketsServer.h>
 
 #ifndef _MILIGHT_HTTP_SERVER
 #define _MILIGHT_HTTP_SERVER
@@ -16,6 +17,8 @@ class MiLightHttpServer {
 public:
   MiLightHttpServer(Settings& settings, MiLightClient*& milightClient)
     : server(WebServer(80)),
+      wsServer(WebSocketsServer(81)),
+      numWsClients(0),
       milightClient(milightClient),
       settings(settings)
   {
@@ -26,6 +29,7 @@ public:
   void handleClient();
   void onSettingsSaved(SettingsSavedHandler handler);
   void on(const char* path, HTTPMethod method, ESP8266WebServer::THandlerFunction handler);
+  void handlePacketSent(uint8_t* packet, const MiLightRadioConfig& config);
   WiFiClient client();
 
 protected:
@@ -48,13 +52,16 @@ protected:
   void handleUpdateGroup(const UrlTokenBindings* urlBindings);
 
   void handleRequest(const JsonObject& request);
+  void handleWsEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length);
 
   File updateFile;
 
   WebServer server;
+  WebSocketsServer wsServer;
   Settings& settings;
   MiLightClient*& milightClient;
   SettingsSavedHandler settingsSavedHandler;
+  size_t numWsClients;
 
 };
 

+ 2 - 0
platformio.ini

@@ -18,6 +18,8 @@ lib_deps_external =
   ArduinoJson
   PubSubClient
   https://github.com/ratkins/RGBConverter
+  Hash
+  WebSockets
 build_flags = !python .get_version.py -DMQTT_MAX_PACKET_SIZE=200 -Idist
 extra_script =
   .build_web.py

+ 1 - 0
src/main.cpp

@@ -79,6 +79,7 @@ void onPacketSentHandler(uint8_t* packet, const MiLightRadioConfig& config) {
   if (mqttClient) {
     mqttClient->sendUpdate(type, deviceId, groupId, output);
   }
+  httpServer->handlePacketSent(packet, config);
 }
 
 void handleListen() {

+ 8 - 11
web/src/js/script.js

@@ -33,6 +33,14 @@ var DEFAULT_UDP_PROTOCL_VERSION = 5;
 
 var selectize;
 
+var webSocket = new WebSocket("ws://" + location.hostname + ":81");
+webSocket.onmessage = function(e) {
+  if (sniffing) {
+    var message = e.data;
+    $('#sniffed-traffic').prepend('<pre>' + message + '</pre>');
+  }
+}
+
 var toHex = function(v) {
   return "0x" + (v).toString(16).toUpperCase();
 }
@@ -86,15 +94,6 @@ var sendCommand = _.throttle(
   1000
 )
 
-var sniffRequest;
-var sniffing = false;
-var getTraffic = function() {
-  sniffRequest = $.get('/gateway_traffic', function(data) {
-    $('#sniffed-traffic').prepend('<pre>' + data + '</pre>');
-    getTraffic();
-  });
-};
-
 var gatewayServerRow = function(deviceId, port, version) {
   var elmt = '<tr>';
   elmt += '<td>';
@@ -381,12 +380,10 @@ $(function() {
 
   $('#sniff').click(function() {
     if (sniffing) {
-      sniffRequest.abort();
       sniffing = false;
       $(this).html('Start Sniffing');
     } else {
       sniffing = true;
-      getTraffic();
       $(this).html('Stop Sniffing');
     }
   });