FirebaseObject FirebaseArduino::readEvent() { auto client = http_->getStreamPtr(); String type = client->readStringUntil('\n').substring(7);; String event = client->readStringUntil('\n').substring(6); client->readStringUntil('\n'); // consume separator FirebaseObject obj = FirebaseObject(event.c_str()); obj.getJsonVariant().asObject()["type"] = type; return obj; }
// // g e t N e x t T o k e n // // Take a look at the state machine of getNextToken() to understand // what is going on here. // // TODO: It seems to be useful that this function throws an exception // if something goes wrong. XmlToken DinoXmlScanner::getNextToken(){ // First skip whitespaces m_pLineBuffer->skipWhitespace(); // Let's have a look at the current character char currentCharacter = m_pLineBuffer->getCurrentCharacter(); // End of file reached if (currentCharacter == EOF){ return endOfFile; } // First we handle single characters with a switch statement switch (currentCharacter){ // Opening Bracket case '<': { m_pLineBuffer->moveToNextCharacter(); return openingBracket; } break; // Closing Bracket case '>': { m_pLineBuffer->moveToNextCharacter(); return closingBracket; } break; // Question Mark case '?': { m_pLineBuffer->moveToNextCharacter(); return questionMark; } break; // Exclamation Mark case '!': { m_pLineBuffer->moveToNextCharacter(); return exclamationMark; } break; // Minus case '-': { m_pLineBuffer->moveToNextCharacter(); return minus; } break; // Slash case '/': { m_pLineBuffer->moveToNextCharacter(); return slash; } break; // Equal Sign case '=': { m_pLineBuffer->moveToNextCharacter(); return equalSign; } break; } // end of switch // Now we handle more complex token // Identifier if (isalpha(currentCharacter)){ // Put a pointer to the beginning of the identifier DinoLineBufferPosition startPosition = m_pLineBuffer->getCurrentPosition(); currentCharacter = m_pLineBuffer->moveToNextCharacter(); // Read valid identifier characters while ((isalnum(currentCharacter)) || // a..z|A..Z|0..9 (currentCharacter == '.') || (currentCharacter == ':') || (currentCharacter == '_')) { currentCharacter = m_pLineBuffer->moveToNextCharacter(); } // Copy identifier to currentTokenString m_pLineBuffer->extractString(startPosition, m_pLineBuffer->getCurrentPosition(), m_pCurrentTokenString); // Return identifier token return identifier; } // end of identifier // Quoted characters " ... " or ' ... ' if ((currentCharacter == '\"') || (currentCharacter == '\'')) { // Distinguish what kind of quote sign we have bool doubleQuote; if (currentCharacter == '\"') doubleQuote = true; else doubleQuote = false; // Skip quote sign currentCharacter = m_pLineBuffer->moveToNextCharacter(); // Read until the closing quotation sign is found // String is copied to m_pCurrentTokenString by readStringUntil() if (doubleQuote){ readStringUntil('\"', false); } else{ readStringUntil('\'', false); } // Skip over the end quote character m_pLineBuffer->moveToNextCharacter(); // Return token for quoted value return quotedValue; } // end of quoted characters // An atributeValue, i.e. a sequence of characters, digits, minus - or dot . if ((isalnum(currentCharacter)) || (currentCharacter == '-') || (currentCharacter == '.')) { // Put a pointer to the beginning of the quoted text DinoLineBufferPosition startPosition = m_pLineBuffer->getCurrentPosition();; // Read until until an invalid character occurs currentCharacter = m_pLineBuffer->moveToNextCharacter(); while ((isalnum(currentCharacter)) || (currentCharacter == '-') || (currentCharacter == '.')) { currentCharacter = m_pLineBuffer->moveToNextCharacter(); } // Copy attributeValue to currentTokenString m_pLineBuffer->extractString(startPosition, m_pLineBuffer->getCurrentPosition(), m_pCurrentTokenString); // Return token for attribute value return attributeValue; } // end of an attributeValue // No valid token m_pLineBuffer->moveToNextCharacter(); return invalidToken; } // getNextToken
void ArduinoOTAClass::_onRx(){ if(!_udp_ota->next()) return; ip_addr_t ota_ip; if (_state == OTA_IDLE) { int cmd = parseInt(); if (cmd != U_FLASH && cmd != U_SPIFFS) return; _ota_ip = _udp_ota->getRemoteAddress(); _cmd = cmd; _ota_port = parseInt(); _size = parseInt(); _udp_ota->read(); _md5 = readStringUntil('\n'); _md5.trim(); if(_md5.length() != 32) return; ota_ip.addr = (uint32_t)_ota_ip; if (_password.length()){ MD5Builder nonce_md5; nonce_md5.begin(); nonce_md5.add(String(micros())); nonce_md5.calculate(); _nonce = nonce_md5.toString(); char auth_req[38]; sprintf(auth_req, "AUTH %s", _nonce.c_str()); _udp_ota->append((const char *)auth_req, strlen(auth_req)); _udp_ota->send(&ota_ip, _udp_ota->getRemotePort()); _state = OTA_WAITAUTH; return; } else { _udp_ota->append("OK", 2); _udp_ota->send(&ota_ip, _udp_ota->getRemotePort()); _state = OTA_RUNUPDATE; } } else if (_state == OTA_WAITAUTH) { int cmd = parseInt(); if (cmd != U_AUTH) { _state = OTA_IDLE; return; } _udp_ota->read(); String cnonce = readStringUntil(' '); String response = readStringUntil('\n'); if (cnonce.length() != 32 || response.length() != 32) { _state = OTA_IDLE; return; } MD5Builder _passmd5; _passmd5.begin(); _passmd5.add(_password); _passmd5.calculate(); String passmd5 = _passmd5.toString(); String challenge = passmd5 + ":" + String(_nonce) + ":" + cnonce; MD5Builder _challengemd5; _challengemd5.begin(); _challengemd5.add(challenge); _challengemd5.calculate(); String result = _challengemd5.toString(); ota_ip.addr = (uint32_t)_ota_ip; if(result.equals(response)){ _udp_ota->append("OK", 2); _udp_ota->send(&ota_ip, _udp_ota->getRemotePort()); _state = OTA_RUNUPDATE; } else { _udp_ota->append("Authentication Failed", 21); _udp_ota->send(&ota_ip, _udp_ota->getRemotePort()); if (_error_callback) _error_callback(OTA_AUTH_ERROR); _state = OTA_IDLE; } } while(_udp_ota->next()) _udp_ota->flush(); }