Skip to content

Commit

Permalink
Merge pull request #85 from sidoh/48899_discovery
Browse files Browse the repository at this point in the history
Add support for 48899 discovery
  • Loading branch information
sidoh authored Jun 3, 2017
2 parents 0765404 + 186f3fc commit e27c3c6
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 15 deletions.
8 changes: 5 additions & 3 deletions data/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@
<script lang="text/javascript">
var FORM_SETTINGS = [
"admin_username", "admin_password", "ce_pin", "csn_pin", "reset_pin","packet_repeats",
"http_repeat_factor", "auto_restart_period", "mqtt_server", "mqtt_topic_pattern",
"mqtt_username", "mqtt_password", "radio_interface_type"
"http_repeat_factor", "auto_restart_period", "discovery_port", "mqtt_server",
"mqtt_topic_pattern", "mqtt_username", "mqtt_password", "radio_interface_type"
];

var FORM_SETTINGS_HELP = {
Expand All @@ -141,7 +141,9 @@
mqtt_server : "Domain or IP address of MQTT broker. Optionally specify a port " +
"with (example) mymqqtbroker.com:1884.",
mqtt_topic_pattern : "Pattern for MQTT topics to listen on. Example: " +
"lights/:device_id/:type/:group. See README for further details."
"lights/:device_id/:type/:group. See README for further details.",
discovery_port : "UDP port to listen for discovery packets on. Defaults to " +
"the same port used by MiLight devices, 48899. Use 0 to disable."
}

var UDP_PROTOCOL_VERSIONS = [ 5, 6 ];
Expand Down
2 changes: 2 additions & 0 deletions lib/Settings/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ void Settings::patch(JsonObject& parsedSettings) {
this->setIfPresent(parsedSettings, "mqtt_username", mqttUsername);
this->setIfPresent(parsedSettings, "mqtt_password", mqttPassword);
this->setIfPresent(parsedSettings, "mqtt_topic_pattern", mqttTopicPattern);
this->setIfPresent(parsedSettings, "discovery_port", discoveryPort);

if (parsedSettings.containsKey("radio_interface_type")) {
this->radioInterfaceType = Settings::typeFromString(parsedSettings["radio_interface_type"]);
Expand Down Expand Up @@ -139,6 +140,7 @@ void Settings::serialize(Stream& stream, const bool prettyPrint) {
root["mqtt_username"] = this->mqttUsername;
root["mqtt_password"] = this->mqttPassword;
root["mqtt_topic_pattern"] = this->mqttTopicPattern;
root["discovery_port"] = this->discoveryPort;

if (this->deviceIds) {
JsonArray& arr = jsonBuffer.createArray();
Expand Down
4 changes: 3 additions & 1 deletion lib/Settings/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ class Settings {
numGatewayConfigs(0),
packetRepeats(10),
httpRepeatFactor(5),
_autoRestartPeriod(0)
_autoRestartPeriod(0),
discoveryPort(48899)
{ }

~Settings() {
Expand Down Expand Up @@ -106,6 +107,7 @@ class Settings {
String mqttUsername;
String mqttPassword;
String mqttTopicPattern;
uint16_t discoveryPort;

protected:
size_t _autoRestartPeriod;
Expand Down
85 changes: 85 additions & 0 deletions lib/Udp/MiLightDiscoveryServer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include <MiLightDiscoveryServer.h>
#include <Size.h>
#include <ESP8266WiFi.h>

const char V3_SEARCH_STRING[] = "Link_Wi-Fi";
const char V6_SEARCH_STRING[] = "HF-A11ASSISTHREAD";

MiLightDiscoveryServer::MiLightDiscoveryServer(Settings& settings)
: settings(settings)
{ }

MiLightDiscoveryServer::MiLightDiscoveryServer(MiLightDiscoveryServer& other)
: settings(other.settings)
{ }

MiLightDiscoveryServer& MiLightDiscoveryServer::operator=(MiLightDiscoveryServer other) {
this->settings = other.settings;
this->socket = other.socket;
}

MiLightDiscoveryServer::~MiLightDiscoveryServer() {
socket.stop();
}

void MiLightDiscoveryServer::begin() {
socket.begin(settings.discoveryPort);
}

void MiLightDiscoveryServer::handleClient() {
size_t packetSize = socket.parsePacket();

if (packetSize) {
char buffer[size(V6_SEARCH_STRING) + 1];
socket.read(buffer, packetSize);
buffer[packetSize] = 0;

#ifdef MILIGHT_UDP_DEBUG
printf("Got discovery packet: %s\n", buffer);
#endif

if (strcmp(buffer, V3_SEARCH_STRING) == 0) {
handleDiscovery(5);
} else if (strcmp(buffer, V6_SEARCH_STRING) == 0) {
handleDiscovery(6);
}
}
}

void MiLightDiscoveryServer::handleDiscovery(uint8_t version) {
#ifdef MILIGHT_UDP_DEBUG
printf("Handling discovery for version: %u, %d configs to consider\n", version, settings.numGatewayConfigs);
#endif

char buffer[40];

for (size_t i = 0; i < settings.numGatewayConfigs; i++) {
GatewayConfig* config = settings.gatewayConfigs[i];

if (config->protocolVersion != version) {
continue;
}

IPAddress addr = WiFi.localIP();
char* ptr = buffer;
ptr += sprintf_P(
buffer,
PSTR("%d.%d.%d.%d,00000000%02X%02X"),
addr[0], addr[1], addr[2], addr[3],
(config->deviceId >> 8), (config->deviceId & 0xFF)
);

if (config->protocolVersion == 5) {
sendResponse(buffer);
} else {
sprintf_P(ptr, PSTR(",HF-LPB100"));
sendResponse(buffer);
}
}
}

void MiLightDiscoveryServer::sendResponse(char* buffer) {
socket.beginPacket(socket.remoteIP(), socket.remotePort());
socket.write(buffer);
socket.endPacket();
}
25 changes: 25 additions & 0 deletions lib/Udp/MiLightDiscoveryServer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <WiFiUdp.h>
#include <Settings.h>

#ifndef MILIGHT_DISCOVERY_SERVER_H
#define MILIGHT_DISCOVERY_SERVER_H

class MiLightDiscoveryServer {
public:
MiLightDiscoveryServer(Settings& settings);
MiLightDiscoveryServer(MiLightDiscoveryServer&);
MiLightDiscoveryServer& operator=(MiLightDiscoveryServer other);
~MiLightDiscoveryServer();

void begin();
void handleClient();

private:
Settings& settings;
WiFiUDP socket;

void handleDiscovery(uint8_t version);
void sendResponse(char* buffer);
};

#endif
12 changes: 6 additions & 6 deletions lib/Udp/MiLightUdpServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <ESP8266WiFi.h>

MiLightUdpServer::MiLightUdpServer(MiLightClient*& client, uint16_t port, uint16_t deviceId)
: client(client),
: client(client),
port(port),
deviceId(deviceId),
lastGroup(0)
Expand All @@ -24,18 +24,18 @@ void MiLightUdpServer::stop() {

void MiLightUdpServer::handleClient() {
const size_t packetSize = socket.parsePacket();

if (packetSize) {
socket.read(packetBuffer, packetSize);

#ifdef MILIGHT_UDP_DEBUG
printf("[MiLightUdpServer port %d] - Handling packet: ", port);
for (size_t i = 0; i < packetSize; i++) {
printf("%02X ", packetBuffer[i]);
}
printf("\n");
#endif

handlePacket(packetBuffer, packetSize);
}
}
Expand All @@ -46,6 +46,6 @@ MiLightUdpServer* MiLightUdpServer::fromVersion(uint8_t version, MiLightClient*&
} else if (version == 6) {
return new V6MiLightUdpServer(client, port, deviceId);
}

return NULL;
}
}
2 changes: 1 addition & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ lib_deps_external =
ArduinoJson
PubSubClient
https://github.com/ratkins/RGBConverter
build_flags = !python .get_version.py
build_flags = !python .get_version.py -D MILIGHT_UDP_DEBUG
# -D MQTT_DEBUG
# -D MILIGHT_UDP_DEBUG
# -D DEBUG_PRINTF
Expand Down
23 changes: 19 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@
#include <ESP8266SSDP.h>
#include <MqttClient.h>
#include <RGBConverter.h>
#include <MiLightDiscoveryServer.h>

WiFiManager wifiManager;

Settings settings;

MiLightClient* milightClient;
MiLightRadioFactory* radioFactory;
MiLightHttpServer *httpServer;
MqttClient* mqttClient;
MiLightClient* milightClient = NULL;
MiLightRadioFactory* radioFactory = NULL;
MiLightHttpServer *httpServer = NULL;
MqttClient* mqttClient = NULL;
MiLightDiscoveryServer* discoveryServer = NULL;

int numUdpServers = 0;
MiLightUdpServer** udpServers;
Expand Down Expand Up @@ -88,6 +90,15 @@ void applySettings() {
}

initMilightUdpServers();

if (discoveryServer) {
delete discoveryServer;
discoveryServer = NULL;
}
if (settings.discoveryPort != 0) {
discoveryServer = new MiLightDiscoveryServer(settings);
discoveryServer->begin();
}
}

bool shouldRestart() {
Expand Down Expand Up @@ -138,6 +149,10 @@ void loop() {
}
}

if (discoveryServer) {
discoveryServer->handleClient();
}

if (shouldRestart()) {
Serial.println(F("Auto-restart triggered. Restarting..."));
ESP.restart();
Expand Down

0 comments on commit e27c3c6

Please sign in to comment.