|
|
@@ -2,8 +2,8 @@
|
|
|
#include <ESP8266WiFi.h>
|
|
|
#include <Arduino.h>
|
|
|
|
|
|
-#define MATCHES_PACKET(packet1, packet2, packet2Len) ( \
|
|
|
- matchesPacket(packet1, size(packet1), packet2, packet2Len) \
|
|
|
+#define MATCHES_PACKET(packet1) ( \
|
|
|
+ matchesPacket(packet1, size(packet1), packet, packetSize) \
|
|
|
)
|
|
|
|
|
|
uint8_t V6MiLightUdpServer::START_SESSION_COMMAND[] = {
|
|
|
@@ -27,12 +27,42 @@ uint8_t V6MiLightUdpServer::HEARTBEAT_HEADER[] = {
|
|
|
0xD0, 0x00, 0x00, 0x00, 0x02
|
|
|
};
|
|
|
|
|
|
+uint8_t V6MiLightUdpServer::HEARTBEAT_HEADER2[] = {
|
|
|
+ 0x30, 0x00, 0x00, 0x00, 0x03
|
|
|
+};
|
|
|
+
|
|
|
uint8_t V6MiLightUdpServer::COMMAND_RESPONSE[] = {
|
|
|
0x88, 0x00, 0x00, 0x00, 0x03, 0x00, 0xFF, 0x00
|
|
|
};
|
|
|
|
|
|
uint8_t V6MiLightUdpServer::SEARCH_COMMAND[] = {
|
|
|
- 0x10, 0x00, 0x00, 0x00, 0x24, 0x02, 0xAE, 0x65, 0x02, 0x39, 0x38, 0x35, 0x62
|
|
|
+ 0x10, 0x00, 0x00, 0x00
|
|
|
+ //, 0x24, 0x02
|
|
|
+ //, 0xAE, 0x65, 0x02, 0x39, 0x38, 0x35, 0x62
|
|
|
+};
|
|
|
+
|
|
|
+uint8_t V6MiLightUdpServer::SEARCH_RESPONSE[] = {
|
|
|
+ 0x18, 0x00, 0x00, 0x00, 0x40, 0x02,
|
|
|
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // mac address
|
|
|
+ 0x00, 0x20, 0x39, 0x38, 0x35, 0x62,
|
|
|
+ 0x31, 0x35, 0x37, 0x62, 0x66, 0x36,
|
|
|
+ 0x66, 0x63, 0x34, 0x33, 0x33, 0x36,
|
|
|
+ 0x38, 0x61, 0x36, 0x33, 0x34, 0x36,
|
|
|
+ 0x37, 0x65, 0x61, 0x33, 0x62, 0x31,
|
|
|
+ 0x39, 0x64, 0x30, 0x64, 0x01, 0x00,
|
|
|
+ 0x01,
|
|
|
+ 0x17, 0x63, // port?
|
|
|
+ 0x00, 0x00, 0x05, 0x00, 0x09, 0x78,
|
|
|
+ 0x6C, 0x69, 0x6E, 0x6B, 0x5F, 0x64,
|
|
|
+ 0x65, 0x76, 0x07, 0x5B, 0xCD, 0x15
|
|
|
+};
|
|
|
+
|
|
|
+uint8_t V6MiLightUdpServer::OPEN_COMMAND_RESPONSE[] = {
|
|
|
+ 0x80, 0x00, 0x00, 0x00, 0x15,
|
|
|
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // mac address
|
|
|
+ 0x05, 0x02, 0x00, 0x34, 0x00, 0x00,
|
|
|
+ 0x00, 0x00 ,0x00 ,0x00, 0x00, 0x00,
|
|
|
+ 0x00, 0x00, 0x34
|
|
|
};
|
|
|
|
|
|
template<typename T, size_t sz>
|
|
|
@@ -96,6 +126,23 @@ uint16_t V6MiLightUdpServer::beginSession() {
|
|
|
return id;
|
|
|
}
|
|
|
|
|
|
+void V6MiLightUdpServer::handleSearch() {
|
|
|
+ const size_t packetLen = size(SEARCH_RESPONSE);
|
|
|
+ uint8_t response[packetLen];
|
|
|
+ memcpy(response, SEARCH_RESPONSE, packetLen);
|
|
|
+ WiFi.macAddress(response + 6);
|
|
|
+
|
|
|
+ printf("Sending search response - ");
|
|
|
+ for (size_t i = 0; i < packetLen; i++) {
|
|
|
+ printf("%02X ", response[i]);
|
|
|
+ }
|
|
|
+ printf("\n");
|
|
|
+
|
|
|
+ socket.beginPacket(socket.remoteIP(), socket.remotePort());
|
|
|
+ socket.write(response, packetLen);
|
|
|
+ socket.endPacket();
|
|
|
+}
|
|
|
+
|
|
|
void V6MiLightUdpServer::handleStartSession() {
|
|
|
size_t len = size(START_SESSION_RESPONSE);
|
|
|
uint8_t response[len];
|
|
|
@@ -109,7 +156,7 @@ void V6MiLightUdpServer::handleStartSession() {
|
|
|
sendResponse(sessionId, response, len);
|
|
|
}
|
|
|
|
|
|
-void V6MiLightUdpServer::sendResponse(uint16_t sessionId, uint8_t* responseBuffer, size_t responseSize) {
|
|
|
+bool V6MiLightUdpServer::sendResponse(uint16_t sessionId, uint8_t* responseBuffer, size_t responseSize) {
|
|
|
V6Session* session = firstSession;
|
|
|
|
|
|
while (session != NULL) {
|
|
|
@@ -122,7 +169,7 @@ void V6MiLightUdpServer::sendResponse(uint16_t sessionId, uint8_t* responseBuffe
|
|
|
if (session == NULL || session->sessionId != sessionId) {
|
|
|
Serial.print("Received request with untracked session ID: ");
|
|
|
Serial.println(sessionId);
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
#ifdef MILIGHT_UDP_DEBUG
|
|
|
@@ -132,6 +179,8 @@ void V6MiLightUdpServer::sendResponse(uint16_t sessionId, uint8_t* responseBuffe
|
|
|
socket.beginPacket(session->ipAddr, session->port);
|
|
|
socket.write(responseBuffer, responseSize);
|
|
|
socket.endPacket();
|
|
|
+
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
bool V6MiLightUdpServer::handleRgbBulbCommand(uint8_t group, uint32_t _cmd, uint32_t _arg) {
|
|
|
@@ -218,6 +267,15 @@ bool V6MiLightUdpServer::handleV2BulbCommand(uint8_t group, uint32_t _cmd, uint3
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
+
|
|
|
+bool V6MiLightUdpServer::handleOpenCommand(uint16_t sessionId) {
|
|
|
+ size_t len = size(OPEN_COMMAND_RESPONSE);
|
|
|
+ uint8_t response[len];
|
|
|
+ memcpy(response, OPEN_COMMAND_RESPONSE, len);
|
|
|
+ WiFi.macAddress(response + 5);
|
|
|
+
|
|
|
+ return sendResponse(sessionId, response, len);
|
|
|
+}
|
|
|
|
|
|
void V6MiLightUdpServer::handleCommand(
|
|
|
uint16_t sessionId,
|
|
|
@@ -232,12 +290,14 @@ void V6MiLightUdpServer::handleCommand(
|
|
|
uint32_t cmdArg = readInt<uint32_t>(cmd+5);
|
|
|
|
|
|
#ifdef MILIGHT_UDP_DEBUG
|
|
|
- printf("Command type: %02X, command: %08X, arg: %08X\n", cmdType, cmdHeader, cmdArg);
|
|
|
+ printf("Command cmdType: %02X, cmdHeader: %08X, cmdArg: %08X\n", cmdType, cmdHeader, cmdArg);
|
|
|
#endif
|
|
|
|
|
|
bool handled = false;
|
|
|
|
|
|
- if ((cmdHeader & 0x0800) == 0x0800) {
|
|
|
+ if (cmdHeader == 0) {
|
|
|
+ handled = handleOpenCommand(sessionId);
|
|
|
+ } else if ((cmdHeader & 0x0800) == 0x0800) {
|
|
|
handled = handleV2BulbCommand(group, cmdHeader, cmdArg);
|
|
|
} else if ((cmdHeader & 0x0500) == 0x0500) {
|
|
|
handled = handleRgbBulbCommand(group, cmdHeader, cmdArg);
|
|
|
@@ -272,7 +332,7 @@ void V6MiLightUdpServer::handleHeartbeat(uint16_t sessionId) {
|
|
|
}
|
|
|
|
|
|
bool V6MiLightUdpServer::matchesPacket(uint8_t* packet1, size_t packet1Len, uint8_t* packet2, size_t packet2Len) {
|
|
|
- return packet2Len >= packet1Len && memcmp(packet1, packet2, packet1Len);
|
|
|
+ return packet2Len >= packet1Len && memcmp(packet1, packet2, packet1Len) == 0;
|
|
|
}
|
|
|
|
|
|
void V6MiLightUdpServer::handlePacket(uint8_t* packet, size_t packetSize) {
|
|
|
@@ -280,12 +340,14 @@ void V6MiLightUdpServer::handlePacket(uint8_t* packet, size_t packetSize) {
|
|
|
printf("Packet size: %d\n", packetSize);
|
|
|
#endif
|
|
|
|
|
|
- if (MATCHES_PACKET(START_SESSION_COMMAND, packet, packetSize)) {
|
|
|
+ if (MATCHES_PACKET(START_SESSION_COMMAND)) {
|
|
|
handleStartSession();
|
|
|
- } else if (MATCHES_PACKET(HEARTBEAT_HEADER, packet, packetSize)) {
|
|
|
+ } else if (MATCHES_PACKET(HEARTBEAT_HEADER) || MATCHES_PACKET(HEARTBEAT_HEADER2)) {
|
|
|
uint16_t sessionId = readInt<uint16_t>(packet+5);
|
|
|
handleHeartbeat(sessionId);
|
|
|
- } else if (packetSize == 22 && MATCHES_PACKET(COMMAND_HEADER, packet, packetSize)) {
|
|
|
+ } else if (MATCHES_PACKET(SEARCH_COMMAND)) {
|
|
|
+ handleSearch();
|
|
|
+ } else if (packetSize == 22 && MATCHES_PACKET(COMMAND_HEADER)) {
|
|
|
uint16_t sessionId = readInt<uint16_t>(packet+5);
|
|
|
uint8_t sequenceNum = packet[8];
|
|
|
uint8_t* cmd = packet+10;
|