direcetory listings maybe?
Added LISTDIR command and notify responses.
This commit is contained in:
parent
f57f797ff5
commit
91c644b43c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user