/* * configDTZ.h * File-class for DTZ-Data-Logger * for configuration of user-data * and some utils * * author Creator P.Rebesky * Copyright (©): 2020-2022 by Peter Rebesky * This code can use in private cases only. Every business or companies using of this codes or codes parts is required an approval of us (me) * Every private use can exchange some parts of code or modify some code-lines. This code can change for private use only. * This software is basicly owned by Peter Rebesky and any comercial use is forbidden without approval of us (me). * Version 3.3.OPEN (ohne Datenverschlüsselung des gesendeten Datenstromes) * 05.08.2021 P. Rebesky */ // class for manage config-data into and from file "config.ini" #include // LittleFS is declared #define PostMmeName "mmen" #define PostUser "user" #define PostPW "pw" #define PostID "id" #define PostHash "hash" #define PostUrl "url" #define PostChecked "LEO" /***** class for save data intern into ESP8266 *****/ class configDTZ { private: String USER; String PW; String TARGETURL; String NAMEDTZ; uint32_t USERID = 0; bool MOUNTED = false; void decodeConfig(String s); int calculateFreeSpaceFS(); String decodeOnValue(String s); void setDefault(); unsigned char h2int(char c); public: int dtz_Type; int saveCounter = 0; int FREESPACE=0; int showProtocol = 0; bool begin(); // start to get data from file String getUser(); bool setUser(String user); String getPassw(); bool setPassw(String pw); String getNameDTZ(); bool setNameDTZ(String nameDTZ); String getTargetURL(); bool setTargetURL(String url); uint32_t getUserID(); void setUserID(uint32_t userid); bool readConfigDTZ(); bool saveConfigDTZ(); int getFreeSpace(); bool savePostValues(String saveValues); String urldecode(String str); String urlencode(String str); void saveValues(String str); String readSavedValues(int pointer); bool delFile(int pointer); void end(); }; /**** mount the file-object ****/ bool configDTZ::begin(){ if(LittleFS.begin()){ this->dtz_Type = 0; this->MOUNTED = this->readConfigDTZ(); this->delFile(0); // clear old saved data on file system on every new-start this->calculateFreeSpaceFS(); } return this->MOUNTED; } /**** read values from file or create new default-values ****/ bool configDTZ::readConfigDTZ(){ String s; bool r=false; File Fconfig = LittleFS.open("/config.ini","r"); if (!Fconfig) this->setDefault(); Fconfig = LittleFS.open("/config.ini","r"); if (Fconfig){ s=Fconfig.readString(); this->decodeConfig(s); Fconfig.close(); r = true; } return r; } /****** for compatibility ******/ void configDTZ::end(){ // do nothing, it's just for compatibility } /******** handle user **********/ String configDTZ::getUser(){ return this->USER; } bool configDTZ::setUser(String user){ bool r=false; if(user){ this->USER = user; r = true; } return r; } /******** handle userID ********/ uint32_t configDTZ::getUserID(){ return this->USERID; } void configDTZ::setUserID(uint32_t userid){ // works until 31 bits only this->USERID = userid; } /******** handle password ******/ String configDTZ::getPassw(){ return this->PW; } bool configDTZ::setPassw(String pw){ bool r=false; if(pw){ this->PW = pw; r = true; } return r; } /******** handle DTZ-name *******/ String configDTZ::getNameDTZ(){ return this->NAMEDTZ; } bool configDTZ::setNameDTZ(String nameDTZ){ bool r=false; if(nameDTZ){ this->NAMEDTZ = nameDTZ; r = true; } return r; } /******** handle target URL ******/ String configDTZ::getTargetURL(){ return this->TARGETURL; } bool configDTZ::setTargetURL(String url){ bool r=false; if(url){ this->TARGETURL = url; r = true; } return r; } /**** save actuelle config-data ****/ bool configDTZ::saveConfigDTZ(){ bool r = false; String s = "{\n"; s += "user: \""; s += this->getUser(); s += "\",\n"; s += "pw: \""; s += this->getPassw(); s += "\",\n"; s += "userid: "; s += this->getUserID(); s += ",\n"; s += "url: \""; s += this->getTargetURL(); s += "\",\n"; s += "nameDTZ: \""; s += this->getNameDTZ(); s += "\",\n"; s += "showled: "; s += this->showProtocol; s += "\n"; s += "}"; // Serial.println(s); if(this->MOUNTED){ File Fconfig = LittleFS.open("/config.ini","w"); if (Fconfig){ int w=Fconfig.print(s); Fconfig.close(); if (w > 1) r = true; // write file was successful } } return r; } /**** get file-data and save into class-values ****/ void configDTZ::decodeConfig(String s){ int argEnd = 0; int argBegin = s.indexOf("user:"); if(argBegin>0){ argEnd = s.indexOf(",",argBegin+2); this->USER = this->decodeOnValue(s.substring(argBegin, argEnd)); } argBegin = s.indexOf("pw:"); if(argBegin>0){ argEnd = s.indexOf(",",argBegin+2); this->PW = this->decodeOnValue(s.substring(argBegin, argEnd)); } argBegin = s.indexOf("url:"); if(argBegin>0){ argEnd = s.indexOf(",",argBegin+2); this->TARGETURL = this->decodeOnValue(s.substring(argBegin, argEnd)); } argBegin = s.indexOf("nameDTZ:"); if(argBegin>0){ argEnd = s.indexOf(",",argBegin+2); this->NAMEDTZ = this->decodeOnValue(s.substring(argBegin, argEnd)); } argBegin = s.indexOf("userid:"); if(argBegin>0){ argEnd = s.indexOf(",",argBegin+2); this->USERID = (this->decodeOnValue(s.substring(argBegin, argEnd))).toInt(); } argBegin = s.indexOf("showled:"); if(argBegin>0){ argEnd = s.indexOf(",",argBegin+2); this->showProtocol = (this->decodeOnValue(s.substring(argBegin, argEnd))).toInt(); } // this->encryptPW2Hash(); } /**** extract one value from string ****/ String configDTZ::decodeOnValue(String s){ int valueBegin = s.indexOf("\""); int valueLength = s.length(); if(valueLength >0){ if(valueBegin > 0){ s = s.substring(valueBegin+1,valueLength-1); } else { valueBegin = s.indexOf(":"); s = s.substring(valueBegin+1,valueLength); } } else s = ""; return s; } /****** get free space from file-system ******/ int configDTZ::calculateFreeSpaceFS(){ if(MOUNTED){ FSInfo fsinfo; LittleFS.info(fsinfo); FREESPACE = fsinfo.totalBytes - fsinfo.usedBytes; } else FREESPACE = 0; return FREESPACE; } int configDTZ::getFreeSpace(){ return this->FREESPACE; } /***** set default values if nothing saved*****/ void configDTZ::setDefault(){ this->setUser("User"); this->setPassw("Password"); this->setNameDTZ("mMe"); this->setTargetURL("0.0.0.127"); this->setUserID(1); this->saveConfigDTZ(); } /***** decode values from html-post-arguments *****/ bool configDTZ::savePostValues(String saveValues){ bool r=false; if(saveValues.length()>0){ int mmenBegin = saveValues.indexOf(PostMmeName); if(mmenBegin >= 0){ int argEnd = saveValues.indexOf("&",mmenBegin); if (argEnd == -1) argEnd = saveValues.length(); String value = saveValues.substring(saveValues.indexOf("=",mmenBegin)+1, argEnd); this->setNameDTZ(this->urldecode(value)); } int userBegin = saveValues.indexOf(PostUser); if(userBegin >= 0){ int argEnd = saveValues.indexOf("&",userBegin); if (argEnd == -1) argEnd = saveValues.length(); String value = saveValues.substring(saveValues.indexOf("=",userBegin)+1, argEnd); this->setUser(this->urldecode(value)); } int pwBegin = saveValues.indexOf(PostPW); if(pwBegin >= 0){ int argEnd = saveValues.indexOf("&",pwBegin); if (argEnd == -1) argEnd = saveValues.length(); String value = saveValues.substring(saveValues.indexOf("=",pwBegin)+1, argEnd); this->setPassw(this->urldecode(value)); } int idBegin = saveValues.indexOf(PostID); if(idBegin >= 0){ int argEnd = saveValues.indexOf("&",idBegin); if (argEnd == -1) argEnd = saveValues.length(); String value = saveValues.substring(saveValues.indexOf("=",idBegin)+1, argEnd); this->setUserID(value.toInt()); } int urlBegin = saveValues.indexOf(PostUrl); if(urlBegin >= 0){ int argEnd = saveValues.indexOf("&",urlBegin); if (argEnd == -1) argEnd = saveValues.length(); String value = saveValues.substring(saveValues.indexOf("=",urlBegin)+1, argEnd); this->setTargetURL(this->urldecode(value)); } int checked = saveValues.indexOf(PostChecked); if(checked >=0) showProtocol=1; else showProtocol=0; } return this->saveConfigDTZ(); } /***** url decoding part *****/ unsigned char configDTZ::h2int(char c) { if (c >= '0' && c <='9') return((unsigned char)c - '0'); if (c >= 'a' && c <='f') return((unsigned char)c - 'a' + 10); if (c >= 'A' && c <='F') return((unsigned char)c - 'A' + 10); return(0); } /***** url decoding function ******/ String configDTZ::urldecode(String str) { String encodedString=""; char c; char code0; char code1; for (int i =0; i < str.length(); i++){ c=str.charAt(i); if (c == '+') encodedString+=' '; else if (c == '%') { i++; code0=str.charAt(i); i++; code1=str.charAt(i); c = (h2int(code0) << 4) | h2int(code1); encodedString+=c; } else encodedString+=c; yield(); } return encodedString; } /***** url encoding function ******/ String configDTZ::urlencode(String str) { String encodedString=""; char c; char code0; char code1; char code2; for (int i =0; i < str.length(); i++){ c=str.charAt(i); if (c == ' ') encodedString+= '+'; else if (isalnum(c)) encodedString+=c; else{ code1=(c & 0xf)+'0'; if ((c & 0xf) >9) code1=(c & 0xf) - 10 + 'A'; c=(c>>4)&0xf; code0=c+'0'; if (c > 9) code0=c - 10 + 'A'; code2='\0'; encodedString+='%'; encodedString+=code0; encodedString+=code1; //encodedString+=code2; } yield(); } return encodedString; } /****** save data-stream if connection-error occurs ******/ void configDTZ::saveValues(String str){ if(this->MOUNTED && this->calculateFreeSpaceFS() > 4096){ // don't save more than avialable freespace this->saveCounter ++; String fileName = "/"; fileName += this->saveCounter; fileName += ".val"; File Fvalues = LittleFS.open(fileName,"w"); if (Fvalues){ // str += "-"; str += fileName; //influx database has problem to recognize this int w=Fvalues.print(str); Fvalues.close(); } } else delFile(0); return; } /****** get saved data-stream for new send 2 dbase ******/ String configDTZ::readSavedValues(int pointer){ String s= "*"; if(this->MOUNTED && this->saveCounter > 0 && pointer > 0){ String fileName = "/"; fileName += pointer; fileName += ".val"; File Fvalues = LittleFS.open(fileName,"r"); if (Fvalues){ s=Fvalues.readString(); Fvalues.close(); } } return s; } /***** delete specific or all saved data-streams ****/ bool configDTZ::delFile(int pointer){ // pointer = 0 -> del all files String fileName = "/"; if(pointer == 0){ for (int i=0;i<15;i++){ fileName = "/"; fileName += i; fileName += ".val"; LittleFS.remove(fileName); this->saveCounter=0; if(i > 15) break; } } else { fileName += pointer; fileName += ".val"; LittleFS.remove(fileName); } this->calculateFreeSpaceFS(); return false; } /***** END *****/