Send file system manifest up on want_config (#4176)

* Send file system manifest up on want_config

* Platform specific methods

* Helps to actually make the change

* Clear
This commit is contained in:
Ben Meadors 2024-06-27 07:07:27 -05:00 committed by GitHub
parent 0425551341
commit a966d84e3d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 81 additions and 3 deletions

View File

@ -84,6 +84,56 @@ bool renameFile(const char *pathFrom, const char *pathTo)
#endif
}
#include <vector>
/**
* @brief Get the list of files in a directory.
*
* This function returns a list of files in a directory. The list includes the full path of each file.
*
* @param dirname The name of the directory.
* @param levels The number of levels of subdirectories to list.
* @return A vector of strings containing the full path of each file in the directory.
*/
std::vector<meshtastic_FileInfo> getFiles(const char *dirname, uint8_t levels)
{
std::vector<meshtastic_FileInfo> filenames = {};
#ifdef FSCom
File root = FSCom.open(dirname, FILE_O_READ);
if (!root)
return filenames;
if (!root.isDirectory())
return filenames;
File file = root.openNextFile();
while (file) {
if (file.isDirectory() && !String(file.name()).endsWith(".")) {
if (levels) {
#ifdef ARCH_ESP32
std::vector<meshtastic_FileInfo> subDirFilenames = getFiles(file.path(), levels - 1);
#else
std::vector<meshtastic_FileInfo> subDirFilenames = getFiles(file.name(), levels - 1);
#endif
filenames.insert(filenames.end(), subDirFilenames.begin(), subDirFilenames.end());
file.close();
}
} else {
meshtastic_FileInfo fileInfo = {"", file.size()};
#ifdef ARCH_ESP32
strcpy(fileInfo.file_name, file.path());
#else
strcpy(fileInfo.file_name, file.name());
#endif
filenames.push_back(fileInfo);
file.close();
}
file = root.openNextFile();
}
root.close();
#endif
return filenames;
}
/**
* Lists the contents of a directory.
*

View File

@ -1,6 +1,7 @@
#pragma once
#include "configuration.h"
#include <vector>
// Cross platform filesystem API
@ -49,6 +50,7 @@ using namespace Adafruit_LittleFS_Namespace;
void fsInit();
bool copyFile(const char *from, const char *to);
bool renameFile(const char *pathFrom, const char *pathTo);
std::vector<meshtastic_FileInfo> getFiles(const char *dirname, uint8_t levels);
void listDir(const char *dirname, uint8_t levels, bool del);
void rmDir(const char *dirname);
void setupSDCard();

View File

@ -5,6 +5,7 @@
#include "Channels.h"
#include "Default.h"
#include "FSCommon.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "PhoneAPI.h"
@ -47,6 +48,8 @@ void PhoneAPI::handleStartConfig()
// even if we were already connected - restart our state machine
state = STATE_SEND_MY_INFO;
pauseBluetoothLogging = true;
filesManifest = getFiles("/", 10);
LOG_DEBUG("Got %d files in manifest\n", filesManifest.size());
LOG_INFO("Starting API client config\n");
nodeInfoForPhone.num = 0; // Don't keep returning old nodeinfos
@ -149,6 +152,7 @@ bool PhoneAPI::handleToRadio(const uint8_t *buf, size_t bufLength)
STATE_SEND_CONFIG,
STATE_SEND_MODULE_CONFIG,
STATE_SEND_OTHER_NODEINFOS, // states progress in this order as the device sends to the client
STATE_SEND_FILEMANIFEST,
STATE_SEND_COMPLETE_ID,
STATE_SEND_PACKETS // send packets or debug strings
*/
@ -324,8 +328,9 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
// Advance when we have sent all of our ModuleConfig objects
if (config_state > (_meshtastic_AdminMessage_ModuleConfigType_MAX + 1)) {
// Clients sending special nonce don't want to see other nodeinfos
state = config_nonce == SPECIAL_NONCE ? STATE_SEND_COMPLETE_ID : STATE_SEND_OTHER_NODEINFOS;
state = config_nonce == SPECIAL_NONCE ? STATE_SEND_FILEMANIFEST : STATE_SEND_OTHER_NODEINFOS;
config_state = 0;
filesManifest.clear();
}
break;
@ -340,13 +345,28 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
nodeInfoForPhone.num = 0; // We just consumed a nodeinfo, will need a new one next time
} else {
LOG_INFO("Done sending nodeinfos\n");
state = STATE_SEND_COMPLETE_ID;
state = STATE_SEND_FILEMANIFEST;
// Go ahead and send that ID right now
return getFromRadio(buf);
}
break;
}
case STATE_SEND_FILEMANIFEST: {
LOG_INFO("getFromRadio=STATE_SEND_FILEMANIFEST\n");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_fileInfo_tag;
if (config_state < filesManifest.size()) {
fromRadioScratch.fileInfo = filesManifest.at(config_state);
config_state++;
// last element
if (config_state == filesManifest.size()) {
state = STATE_SEND_COMPLETE_ID;
config_state = 0;
}
}
break;
}
case STATE_SEND_COMPLETE_ID:
LOG_INFO("getFromRadio=STATE_SEND_COMPLETE_ID\n");
fromRadioScratch.which_payload_variant = meshtastic_FromRadio_config_complete_id_tag;
@ -401,6 +421,7 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
void PhoneAPI::handleDisconnect()
{
filesManifest.clear();
pauseBluetoothLogging = false;
LOG_INFO("PhoneAPI disconnect\n");
}
@ -443,6 +464,7 @@ bool PhoneAPI::available()
case STATE_SEND_MODULECONFIG:
case STATE_SEND_METADATA:
case STATE_SEND_OWN_NODEINFO:
case STATE_SEND_FILEMANIFEST:
case STATE_SEND_COMPLETE_ID:
return true;
@ -457,7 +479,6 @@ bool PhoneAPI::available()
}
}
return true; // Always say we have something, because we might need to advance our state machine
case STATE_SEND_PACKETS: {
if (!queueStatusPacketForPhone)
queueStatusPacketForPhone = service.getQueueStatusForPhone();

View File

@ -2,7 +2,9 @@
#include "Observer.h"
#include "mesh-pb-constants.h"
#include <iterator>
#include <string>
#include <vector>
// Make sure that we never let our packets grow too large for one BLE packet
#define MAX_TO_FROM_RADIO_SIZE 512
@ -29,6 +31,7 @@ class PhoneAPI
STATE_SEND_CONFIG, // Replacement for the old Radioconfig
STATE_SEND_MODULECONFIG, // Send Module specific config
STATE_SEND_OTHER_NODEINFOS, // states progress in this order as the device sends to to the client
STATE_SEND_FILEMANIFEST, // Send file manifest
STATE_SEND_COMPLETE_ID,
STATE_SEND_PACKETS // send packets or debug strings
};
@ -65,6 +68,8 @@ class PhoneAPI
uint32_t config_nonce = 0;
uint32_t readIndex = 0;
std::vector<meshtastic_FileInfo> filesManifest = {};
void resetReadIndex() { readIndex = 0; }
public: