Kaynağa Gözat

Add ability to send raw packet

Chris Mullins 8 yıl önce
ebeveyn
işleme
e8c71c11ae

+ 22 - 3
lib/Helpers/IntParsing.h

@@ -4,12 +4,12 @@
 #include <Arduino.h>
 
 template <typename T>
-const T strToHex(const String& s) {
+const T strToHex(const char* s, size_t length) {
   T value = 0;
   T base = 1;
   
-  for (int i = s.length() - 1; i >= 0; i--) {
-    const char c = s.charAt(i);
+  for (int i = length-1; i >= 0; i--) {
+    const char c = s[i];
     
     if (c >= '0' && c <= '9') {
       value += ((c - '0') * base);
@@ -28,6 +28,11 @@ const T strToHex(const String& s) {
 }
 
 template <typename T>
+const T strToHex(const String& s) {
+  return strToHex<T>(s.c_str(), s.length());
+}
+
+template <typename T>
 const T parseInt(const String& s) {
   if (s.startsWith("0x")) {
     return strToHex<T>(s.substring(2));
@@ -36,4 +41,18 @@ 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

+ 22 - 0
lib/WebServer/MiLightHttpServer.cpp

@@ -15,6 +15,7 @@ void MiLightHttpServer::begin() {
   server.onPattern("/gateway_traffic/:type", HTTP_GET, [this](const UrlTokenBindings* b) { handleListenGateway(b); });
   server.onPattern("/gateways/:device_id/:type/:group_id", HTTP_PUT, [this](const UrlTokenBindings* b) { handleUpdateGroup(b); });
   server.onPattern("/gateways/:device_id/:type", HTTP_PUT, [this](const UrlTokenBindings* b) { handleUpdateGateway(b); });
+  server.onPattern("/send_raw/:type", HTTP_PUT, [this](const UrlTokenBindings* b) { handleSendRaw(b); });
   server.on("/web", HTTP_POST, [this]() { server.send(200, "text/plain", "success"); }, handleUpdateFile(WEB_INDEX_FILENAME));
   server.on("/firmware", HTTP_POST, 
     [this](){
@@ -278,4 +279,25 @@ void MiLightHttpServer::handleUpdateGateway(const UrlTokenBindings* urlBindings)
   }
   
   server.send(200, "application/json", "true");
+}
+
+void MiLightHttpServer::handleSendRaw(const UrlTokenBindings* bindings) {
+  DynamicJsonBuffer buffer;
+  JsonObject& request = buffer.parse(server.arg("plain"));
+  MiLightRadioConfig config = milightClient->getRadioConfig(bindings->get("type"));
+  
+  uint8_t packet[config.packetLength];
+  const String& hexPacket = request["packet"];
+  hexStrToBytes<uint8_t>(hexPacket.c_str(), hexPacket.length(), packet, config.packetLength);
+  
+  size_t numRepeats = MILIGHT_DEFAULT_RESEND_COUNT;
+  if (request.containsKey("num_repeats")) {
+    numRepeats = request["num_repeats"];
+  }
+  
+  for (size_t i = 0; i < numRepeats; i++) {
+    milightClient->getRadio(config.type)->write(packet, config.packetLength);
+  }
+  
+  server.send(200, "text/plain", "true");
 }

+ 1 - 0
lib/WebServer/MiLightHttpServer.h

@@ -33,6 +33,7 @@ protected:
   
   void handleUpdateSettings();
   void handleListenGateway(const UrlTokenBindings* urlBindings);
+  void handleSendRaw(const UrlTokenBindings* urlBindings);
   void handleUpdateGroup(const UrlTokenBindings* urlBindings);
   void handleUpdateGateway(const UrlTokenBindings* urlBindings);