From e104256985d4e76adf6c7c2dd8b9816d524296de Mon Sep 17 00:00:00 2001 From: Simon Weidacher Date: Sun, 2 Jan 2022 23:20:53 +0100 Subject: [PATCH] Extracts handling the Tag-file structure into an own class. --- device/main/CMakeLists.txt | 2 +- device/main/Tag.cpp | 186 +++++++++++++++++++++++++++++++ device/main/Tag.hpp | 25 +++++ device/main/TagPlayerControl.cpp | 37 +----- 4 files changed, 217 insertions(+), 33 deletions(-) create mode 100644 device/main/Tag.cpp create mode 100644 device/main/Tag.hpp diff --git a/device/main/CMakeLists.txt b/device/main/CMakeLists.txt index f4c64e0..c2911e5 100644 --- a/device/main/CMakeLists.txt +++ b/device/main/CMakeLists.txt @@ -1,2 +1,2 @@ -idf_component_register(SRCS "Networking.cpp" "main.cpp" "WebInterface.cpp" "RFIDInterface.cpp" "audio_setup.c" "AudioPlayer.cpp" "TagPlayerControl.cpp" +idf_component_register(SRCS "Networking.cpp" "main.cpp" "WebInterface.cpp" "RFIDInterface.cpp" "audio_setup.c" "AudioPlayer.cpp" "TagPlayerControl.cpp" "Tag.cpp" INCLUDE_DIRS ".") diff --git a/device/main/Tag.cpp b/device/main/Tag.cpp new file mode 100644 index 0000000..29cbe2d --- /dev/null +++ b/device/main/Tag.cpp @@ -0,0 +1,186 @@ +#include "Tag.hpp" + +#include +#include +#include + +#include + +#define BASE_PATH "/sdcard/internal/"; + +/** + * { + * tagId : "xa5_x1f_x13_xaa_x00", + * playlist : [ + * "file://sdcard/music_intro.mp3", + * "file://sdcard/audiobook_chapter1.mp3", + * "file://sdcard/audiobook_chapter2.mp3" + * ], + * currentIndex : 0, + * currentPosition : 1234 // the position as returned by the player. can be frames, can be ms or anything + * } + */ + +Tag::Tag(char* tagId): Tag(std::string(tagId)) { + +} + +Tag::Tag(std::string tagId): tagId(tagId) { + this->playlist = std::vector(); +} + +std::string Tag::getNextLink() { + return this->playlist.at(this->currentFileIndex); +} + +bool Tag::isLinked() { + return ! this->playlist.empty(); +} + +void Tag::read() { + std::string contents; + + try { + contents = readFileContents(); + } catch (std::invalid_argument& e){ + std::cout << "Execption while reading tag-file: " << e.what() << "\n"; + + write(); + return; + } + + cJSON* data = cJSON_Parse(contents.c_str()); + + char* tagId = cJSON_GetObjectItem(data, "tagId")->valuestring; + + int currentIndex = cJSON_GetObjectItem(data, "currentIndex")->valueint; + + if (currentIndex < 0) { + std::cout << "Bad file index, must be >= 0, was: " << currentIndex << "\n"; + currentIndex = 0; + } + + this->currentFileIndex = currentIndex; + + int currentFilePosition = cJSON_GetObjectItem(data, "currentPosition")->valueint; + + if (currentFilePosition < 0) { + std::cout << "Bad file position, must be >= 0, was: " << currentFilePosition << "\n"; + currentFilePosition = 0; + } + + this->currentFilePosition = 0; + + cJSON* playlist = cJSON_GetObjectItem(data, "playlist"); + + if (playlist) { + int playlistLength = cJSON_GetArraySize(playlist); + + for (int i = 0; i < playlistLength; i++) { + cJSON* item = cJSON_GetArrayItem(playlist, i); + + // each item is just an URL + this->playlist.push_back(std::string(item->valuestring)); + } + } + + cJSON_Delete(data); +} + +void Tag::write() { + std::string contents = createFileContents(); + + std::string filePath = getFilePath(); + + std::ofstream file(filePath); + + if (! file.is_open()) { + std::cout << "Error opening file for tag " << tagId << " before writing"; + + char* errorName; + + switch (errno) { + case EACCES: + errorName = "EACCESS"; + break; + case ENOENT: + errorName = "ENOENT"; + break; + default: + errorName = "not parsed"; + } + + std::cout << errorName << "\n"; + } + + file << contents << std::endl; + + file.close(); +} + +std::string Tag::createFileContents() { + cJSON* root = cJSON_CreateObject(); + cJSON* playlist; + + cJSON_AddStringToObject(root, "tagId", this->tagId.c_str()); + cJSON_AddNumberToObject(root, "currentIndex", this->currentFileIndex); + cJSON_AddNumberToObject(root, "currentPosition", this->currentFilePosition); + playlist = cJSON_AddArrayToObject(root, "playlist"); + + for (auto& link: this->playlist) { + cJSON_AddItemToArray(playlist, cJSON_CreateString(link.c_str())); + } + + char* json = cJSON_Print(root); + cJSON_Delete(root); // playlist is also free'd + + std::cout << json << std::endl; + + return std::string(json); +} + +std::string Tag::readFileContents() { + std::string filePath = getFilePath(); + + std::fstream file(filePath); + + if (! file) { + std::cout << "Error opening file for tag " << tagId; + + char* errorName; + + switch (errno) { + case EACCES: + errorName = "EACCESS"; + break; + case ENOENT: + errorName = "ENOENT"; + break; + default: + errorName = "not parsed"; + } + + std::cout << errorName << "\n"; + + file.close(); + throw std::invalid_argument(errorName); + } + + std::string line; + std::string content; + + while(getline(file, line)) { + content.append(line); + } + + file.close(); + + return content; +} + +std::string Tag::getFilePath() { + std::string filePath = BASE_PATH; + filePath.append(tagId); + + return filePath; +} \ No newline at end of file diff --git a/device/main/Tag.hpp b/device/main/Tag.hpp new file mode 100644 index 0000000..9df1e51 --- /dev/null +++ b/device/main/Tag.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include +#include + +class Tag { + private: + std::string tagId{""}; + std::vector playlist; + uint32_t currentFileIndex{0}; + uint32_t currentFilePosition{0}; + + public: + Tag(std::string tagId); + Tag(char* tagId); + void read(); + void write(); + bool isLinked(); + std::string getNextLink(); + + private: + std::string createFileContents(); + std::string readFileContents(); + std::string getFilePath(); +}; \ No newline at end of file diff --git a/device/main/TagPlayerControl.cpp b/device/main/TagPlayerControl.cpp index 750361c..484700a 100644 --- a/device/main/TagPlayerControl.cpp +++ b/device/main/TagPlayerControl.cpp @@ -1,6 +1,7 @@ #include "TagPlayerControl.hpp" #include "AudioPlayer.hpp" +#include "Tag.hpp" #include #include @@ -25,38 +26,10 @@ void TagPlayerControl::onTagChanged(char* tagId) { } void TagPlayerControl::playTag(char* tagId) { - std::string filePath = "/sdcard/internal/"; - filePath.append(tagId); + Tag tag(tagId); + tag.read(); - std::fstream file(filePath); - - if (! file) { - ESP_LOGE(TAG, "Error opening file for tag %s", tagId); - - char* error_name; - - switch (errno) - { - case EACCES: - ESP_LOGE(TAG, "EACCESS"); - break; - case ENOENT: - ESP_LOGE(TAG, "ENOENT"); - break; - default: - ESP_LOGE(TAG, "not parsed"); - } - return; + if (tag.isLinked()) { + audioPlayer->play(tag.getNextLink()); } - - std::string line; - std::string content; - - while(getline(file, line)) { - content.append(line); - } - - audioPlayer->play(content); - - file.close(); } \ No newline at end of file