Open repomaa opened 6 years ago
Thank you for the old professor... ;-)
Actually, I havn't thought about reverse engineering the various stock firmwares. Trying to analyze the default cloud communication might be interesting. As it has only 1MB flash it has perhaps not OTA. If it had, it is most probably not secured by TLS...
Will think about it. Nice work for a student's thesis... ;-)
That's quite easy in the end. Just add a few lines to include the WebUpdate feature that is already included in the ESP library. You then have a small webserver running which you can use to upload new code (as long the sketch size is max 1/2 of the available memory). The link is YourDeviceIPAddress/update. You can then upload the compiled *.bin file (e.g. OBISocket.ino.bin) from the Arduino IDE compile folder. After upload it restarts with the new firmware loaded.
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
//WebUpdate
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPUpdateServer.h>
// Controller-Type in IDE: Wemos D1 mini Lite
// WiFi Settings
const char* ssid = "YourSSID";
const char* password = "YourPassword";
//WebUpdate
const char* host = "obisocket0-webupdate";
// MQTT Settings
const char* mqtt_server = "YourBroker";
const char* mqtt_command_topic = "obisocket/0/command";
const char* mqtt_status_topic = "obisocket/0/status";
bool relay_status = false;
WiFiClient espClient;
PubSubClient client(espClient);
// WebUpdate
ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;
void setRelay(bool new_status){
relay_status = new_status;
if (relay_status){
digitalWrite(12, 0);
delay(50);
digitalWrite(12, 1);
} else {
digitalWrite(5, 0);
delay(50);
digitalWrite(5, 1);
}
client.publish(mqtt_status_topic, relay_status?"1":"0", true);
//Serial.print("relay ");
//Serial.println(relay_status?"on":"off");
}
void setup(void){
Serial.begin(115200);
delay(200);
// Setting the I/O pin modes
pinMode(14, INPUT); // Push button
pinMode(4, OUTPUT); // Blue LED
pinMode(5, OUTPUT); // Relay off
pinMode(12, OUTPUT); // Relay on
delay(200);
setRelay(true);
setRelay(false);
// Connecting to a WiFi network
Serial.println();
Serial.println("Connecting to WiFi");
WiFi.mode(WIFI_OFF);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println();
Serial.print("WiFi connected with ip ");
Serial.println(WiFi.localIP());
digitalWrite(4, 1);
client.setServer(mqtt_server, 1883);
client.setCallback(mqttCallback);
// WebUpdate
MDNS.begin(host);
httpUpdater.setup(&httpServer);
httpServer.begin();
MDNS.addService("http", "tcp", 80);
Serial.printf("HTTPUpdateServer ready! Open http://%s.local/update in your browser\n", host);
}
void mqttCallback(char* topic, byte* payload, unsigned int length) {
if (length == 0) return;
setRelay((char)payload[0] == '1');
}
void mqttReconnect() {
String clientID = "OBISocket_";
clientID += WiFi.macAddress();
Serial.print("Connect to MQTT-Broker");
if (client.connect(clientID.c_str())) {
Serial.print("connected as clientID:");
Serial.println(clientID);
client.subscribe(mqtt_command_topic);
client.publish(mqtt_status_topic, relay_status?"1":"0", true);
} else {
Serial.print("failed: ");
Serial.println(client.state());
}
}
bool inp_status = 1;
void loop(void){
bool inp = digitalRead(14);
if (inp == 0 and inp != inp_status) {
setRelay(!relay_status);
}
inp_status = inp;
// WebUpdate
httpServer.handleClient();
if (!client.connected()) {
mqttReconnect();
}
client.loop();
delay (50);
}
One last remark: I didn't know which type of ESP to choose, but "Wemos D1 mini Lite" seems to work quite well. Maybe you can add this note to the Readme document (or the correct settings if this one is not correct).
Thank you for the hint. Actually, I havn't done anything wih the Arduino OTA so far. Btw, do you have any experience with the resulution of the ".local" address on Linux (or Windows) as these do not support mDNS by default, as far as I know?
Also I think, the first idea from jreinert was, to hack any OTA mechanism of the stock firmware of the socket switch in order to be able to reflash it without opening it and soldering.
I'm no expert in Arduino OTA, I just used this code in a few of my smarthome sensors and so far it works quite well. I also didn't test the mDNS stuff, I just use IPs in my home network.
Ah, ok, I didn't get that right. Unfortunately I don't have any un-flashed plugs anymore and I didn't test the original software, so I can't check if there is any OTA functionality out of the box..
Thank you for the old professor... ;-)
Haha. I couldn't resist after seeing your github name. :)
Also I think, the first idea from jreinert was, to hack any OTA mechanism of the stock firmware of the socket switch in order to be able to reflash it without opening it and soldering.
Exactly.
OTA updates (if any) will probably be done via polling to a centralized update server. I also doubt that it will have any serious security, but you never know.
If what I'm suspecting is correct, it will most likely contact the update server just after booting so it should be easy enough to sniff the communication with tcpdump/wireshark.
There's also open specification of how the update server should respond and which headers it should set (MD5 sum for one):
https://esp8266.github.io/Arduino/versions/2.0.0/doc/ota_updates/ota_updates.html#http-server
This is all assuming that the stock firmware is built using the arduino toolchain. Could be something else which would be trickier.
I still have to get my hands on a plug to test this all this out. Will report back, when I've got the chance to stop by an OBI with the plugs in stock.
Nice to see old professors from the uni doing useful tinkering with consumer products ;)
Have you tried intercepting any OTA updates as a way to flash the ESP without having to open up and solder the pin header to it? Or is it the usual IOT product which was never designed to get any updates.
Also take a look at marvinroger/homie-esp8266 It's perfect for these kinds of things and brings you easy configuration, mqtt, some metrics and OTA out of the box.