direcetory listings maybe?

Added LISTDIR command and notify responses.
This commit is contained in:
Tim Keller 2021-10-17 16:04:23 +00:00
parent f57f797ff5
commit 91c644b43c
4 changed files with 129 additions and 31 deletions

View File

@ -1,5 +1,6 @@
#include <nrf_log.h> #include <nrf_log.h>
#include "FSService.h" #include "FSService.h"
#include "components/ble/BleController.h"
using namespace Pinetime::Controllers; using namespace Pinetime::Controllers;
@ -14,7 +15,7 @@ int FSServiceCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gat
FSService::FSService(Pinetime::Controllers::FS& fs) FSService::FSService(Pinetime::Controllers::FS& fs)
: fs {fs}, : fs {fs},
characteristicDefinition {{.uuid = &fsVersionUuid.u, characteristicDefinition {{.uuid = &fsVersionUuid.u,
.access_cb = FSServiceCallback, .access_cb = FSServiceCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_READ, .flags = BLE_GATT_CHR_F_READ,
@ -24,7 +25,7 @@ FSService::FSService(Pinetime::Controllers::FS& fs)
.access_cb = FSServiceCallback, .access_cb = FSServiceCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY,
.val_handle = nullptr, .val_handle = &transferCharacteristicHandle,
}, },
{0}}, {0}},
serviceDefinition { serviceDefinition {
@ -51,5 +52,71 @@ int FSService::OnFSServiceRequested(uint16_t connectionHandle, uint16_t attribut
int res = os_mbuf_append(context->om, &fsVersion, sizeof(fsVersion)); int res = os_mbuf_append(context->om, &fsVersion, sizeof(fsVersion));
return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
} }
if (attributeHandle == transferCharacteristicHandle) {
return FSCommandHandler(connectionHandle, context->om);
}
return 0;
}
int FSService::FSCommandHandler(uint16_t connectionHandle, os_mbuf* om) {
auto command = static_cast<commands>(om->om_data[0]);
NRF_LOG_INFO("[FS_S] -> FSCommandHandler");
switch (command) {
case commands::LISTDIR: {
NRF_LOG_INFO("[FS_S] -> ListDir");
ListDirHeader *header = (ListDirHeader *)&om->om_data[0];
uint16_t plen = header->pathlen;
char path[plen+1] = {0};
memcpy(path, header->pathstr, plen);
NRF_LOG_INFO("[FS_S] -> DIR %.10s", path);
lfs_dir_t dir;
struct lfs_info info;
ListDirResponse resp;
resp.command = 0x51; // LISTDIR_ENTRY;
resp.status = 1; // TODO actually use res above!
resp.totalentries = 0;
resp.entry = 0;
int res = fs.DirOpen(path, &dir);
while (fs.DirRead(&dir, &info)) {
resp.totalentries++;
}
NRF_LOG_INFO("[FS_S] -> %d ", resp.totalentries);
fs.DirClose(&dir);
fs.DirOpen(path, &dir);
while (fs.DirRead(&dir, &info)) {
switch(info.type){
case LFS_TYPE_REG:
{
resp.flags = 0;
resp.file_size = info.size;
break;
}
case LFS_TYPE_DIR:
{
resp.flags = 1;
resp.file_size = 0;
break;
}
}
resp.modification_time = 0; // TODO Does LFS actually support TS?
strcpy(resp.path,info.name);
resp.path_length = strlen(info.name);
NRF_LOG_INFO("[FS_S] ->Path %s ,", info.name);
auto* om = ble_hs_mbuf_from_flat(&resp,sizeof(ListDirResponse));
ble_gattc_notify_custom(connectionHandle,transferCharacteristicHandle,om);
resp.entry++;
}
resp.entry++;
resp.file_size = 0;
resp.path_length = 0;
resp.flags = 0;
//Todo this better
auto* om = ble_hs_mbuf_from_flat(&resp,sizeof(ListDirResponse)-70+resp.path_length);
ble_gattc_notify_custom(connectionHandle,transferCharacteristicHandle,om);
NRF_LOG_INFO("[FS_S] -> done ");
}
}
return 0; return 0;
} }

View File

@ -4,6 +4,7 @@
#include <host/ble_gap.h> #include <host/ble_gap.h>
#undef max #undef max
#undef min #undef min
#include "components/fs/FS.h" #include "components/fs/FS.h"
namespace Pinetime { namespace Pinetime {
@ -42,8 +43,26 @@ namespace Pinetime {
struct ble_gatt_chr_def characteristicDefinition[3]; struct ble_gatt_chr_def characteristicDefinition[3];
struct ble_gatt_svc_def serviceDefinition[2]; struct ble_gatt_svc_def serviceDefinition[2];
uint16_t versionCharacteristicHandle; uint16_t versionCharacteristicHandle;
uint16_t transferCharacteristicHandle;
typedef struct __attribute__((packed)) {
uint8_t command;
uint8_t padding;
uint16_t pathlen;
char pathstr[70];
} ListDirHeader;
typedef struct __attribute__((packed)) {
uint8_t command;
uint8_t status;
uint16_t path_length;
uint32_t entry;
uint32_t totalentries;
uint32_t flags;
uint32_t modification_time;
uint32_t file_size;
char path[70];
} ListDirResponse;
enum class commands { enum class commands : uint8_t {
INVALID = 0x00, INVALID = 0x00,
READ = 0x10, READ = 0x10,
READ_DATA = 0x11, READ_DATA = 0x11,
@ -58,8 +77,10 @@ namespace Pinetime {
LISTDIR = 0x50, LISTDIR = 0x50,
LISTDIR_ENTRY = 0x51, LISTDIR_ENTRY = 0x51,
MOVE = 0x60, MOVE = 0x60,
MOVE_STATUS = 0x61, MOVE_STATUS = 0x61
} };
int FSCommandHandler(uint16_t connectionHandle, os_mbuf* om);
}; };
} }
} }

View File

@ -5,29 +5,28 @@
using namespace Pinetime::Controllers; using namespace Pinetime::Controllers;
FS::FS(Pinetime::Drivers::SpiNorFlash& driver) : FS::FS(Pinetime::Drivers::SpiNorFlash& driver)
flashDriver{ driver }, : flashDriver {driver},
lfsConfig{ lfsConfig {
.context = this, .context = this,
.read = SectorRead, .read = SectorRead,
.prog = SectorProg, .prog = SectorProg,
.erase = SectorErase, .erase = SectorErase,
.sync = SectorSync, .sync = SectorSync,
.read_size = 16, .read_size = 16,
.prog_size = 8, .prog_size = 8,
.block_size = blockSize, .block_size = blockSize,
.block_count = size / blockSize, .block_count = size / blockSize,
.block_cycles = 1000u, .block_cycles = 1000u,
.cache_size = 16, .cache_size = 16,
.lookahead_size = 16, .lookahead_size = 16,
.name_max = 50,
.attr_max = 50,
}
{ }
.name_max = 50,
.attr_max = 50,
} {
}
void FS::Init() { void FS::Init() {
@ -48,7 +47,6 @@ void FS::Init() {
VerifyResource(); VerifyResource();
LVGLFileSystemInit(); LVGLFileSystemInit();
#endif #endif
} }
void FS::VerifyResource() { void FS::VerifyResource() {
@ -56,7 +54,7 @@ void FS::VerifyResource() {
resourcesValid = true; resourcesValid = true;
} }
int FS::FileOpen(lfs_file_t* file_p, const char* fileName, const int flags) { int FS::FileOpen(lfs_file_t* file_p, const char* fileName, const int flags) {
return lfs_file_open(&lfs, file_p, fileName, flags); return lfs_file_open(&lfs, file_p, fileName, flags);
} }
@ -80,6 +78,17 @@ int FS::FileDelete(const char* fileName) {
return lfs_remove(&lfs, fileName); return lfs_remove(&lfs, fileName);
} }
int FS::DirOpen(const char* path, lfs_dir_t* lfs_dir) {
return lfs_dir_open(&lfs, lfs_dir, path);
}
int FS::DirClose(lfs_dir_t* lfs_dir) {
return lfs_dir_close(&lfs, lfs_dir);
}
int FS::DirRead(lfs_dir_t* dir, lfs_info* info) {
return lfs_dir_read(&lfs, dir, info);
}
int FS::DirCreate(const char* path) { int FS::DirCreate(const char* path) {
return lfs_mkdir(&lfs, path); return lfs_mkdir(&lfs, path);
@ -148,8 +157,7 @@ namespace {
if (file->type == 0) { if (file->type == 0) {
return LV_FS_RES_FS_ERR; return LV_FS_RES_FS_ERR;
} } else {
else {
return LV_FS_RES_OK; return LV_FS_RES_OK;
} }
} }
@ -193,5 +201,4 @@ void FS::LVGLFileSystemInit() {
fs_drv.user_data = this; fs_drv.user_data = this;
lv_fs_drv_register(&fs_drv); lv_fs_drv_register(&fs_drv);
} }

View File

@ -21,6 +21,9 @@ namespace Pinetime {
int FileDelete(const char* fileName); int FileDelete(const char* fileName);
int DirOpen(const char* path, lfs_dir_t* lfs_dir);
int DirClose(lfs_dir_t* lfs_dir);
int DirRead(lfs_dir_t* dir, lfs_info* info);
int DirCreate(const char* path); int DirCreate(const char* path);
int DirDelete(const char* path); int DirDelete(const char* path);