ref: fdc89f1a20889c0295534f58dc2e82ce8c55a18b
src/components/ble/FSService.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
#pragma once #define min // workaround: nimble's min/max macros conflict with libstdc++ #define max #include <host/ble_gap.h> #undef max #undef min #include "components/fs/FS.h" namespace Pinetime { namespace System { class SystemTask; } namespace Controllers { class Ble; class FSService { public: FSService(Pinetime::System::SystemTask& systemTask, Pinetime::Controllers::FS& fs); void Init(); int OnFSServiceRequested(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt* context); void NotifyFSRaw(uint16_t connectionHandle); private: Pinetime::System::SystemTask& systemTask; Pinetime::Controllers::FS& fs; static constexpr uint16_t FSServiceId {0xFEBB}; static constexpr uint16_t fsVersionId {0x0100}; static constexpr uint16_t fsTransferId {0x0200}; uint16_t fsVersion = {0x0004}; static constexpr uint16_t maxpathlen = 256; static constexpr ble_uuid16_t fsServiceUuid { .u {.type = BLE_UUID_TYPE_16}, .value = {0xFEBB}}; // {0x72, 0x65, 0x66, 0x73, 0x6e, 0x61, 0x72, 0x54, 0x65, 0x6c, 0x69, 0x46, 0xBB, 0xFE, 0xAF, 0xAD}}; static constexpr ble_uuid128_t fsVersionUuid { .u {.type = BLE_UUID_TYPE_128}, .value = {0x72, 0x65, 0x66, 0x73, 0x6e, 0x61, 0x72, 0x54, 0x65, 0x6c, 0x69, 0x46, 0x00, 0x01, 0xAF, 0xAD}}; static constexpr ble_uuid128_t fsTransferUuid { .u {.type = BLE_UUID_TYPE_128}, .value = {0x72, 0x65, 0x66, 0x73, 0x6e, 0x61, 0x72, 0x54, 0x65, 0x6c, 0x69, 0x46, 0x00, 0x02, 0xAF, 0xAD}}; struct ble_gatt_chr_def characteristicDefinition[3]; struct ble_gatt_svc_def serviceDefinition[2]; uint16_t versionCharacteristicHandle; uint16_t transferCharacteristicHandle; enum class commands : uint8_t { INVALID = 0x00, READ = 0x10, READ_DATA = 0x11, READ_PACING = 0x12, WRITE = 0x20, WRITE_PACING = 0x21, WRITE_DATA = 0x22, DELETE = 0x30, DELETE_STATUS = 0x31, MKDIR = 0x40, MKDIR_STATUS = 0x41, LISTDIR = 0x50, LISTDIR_ENTRY = 0x51, MOVE = 0x60, MOVE_STATUS = 0x61 }; enum class FSState : uint8_t { IDLE = 0x00, READ = 0x01, WRITE = 0x02, }; FSState state; char filepath[maxpathlen]; // TODO ..ugh fixed filepath len int fileSize; using ReadHeader = struct __attribute__((packed)) { commands command; uint8_t padding; uint16_t pathlen; uint32_t chunkoff; uint32_t chunksize; char pathstr[]; }; using ReadResponse = struct __attribute__((packed)) { commands command; uint8_t status; uint16_t padding; uint32_t chunkoff; uint32_t totallen; uint32_t chunklen; uint8_t chunk[]; }; using ReadPacing = struct __attribute__((packed)) { commands command; uint8_t status; uint16_t padding; uint32_t chunkoff; uint32_t chunksize; }; using WriteHeader = struct __attribute__((packed)) { commands command; uint8_t padding; uint16_t pathlen; uint32_t offset; uint64_t modTime; uint32_t totalSize; char pathstr[]; }; using WriteResponse = struct __attribute__((packed)) { commands command; uint8_t status; uint16_t padding; uint32_t offset; uint64_t modTime; uint32_t freespace; }; using WritePacing = struct __attribute__((packed)) { commands command; uint8_t status; uint16_t padding; uint32_t offset; uint32_t dataSize; uint8_t data[]; }; using ListDirHeader = struct __attribute__((packed)) { commands command; uint8_t padding; uint16_t pathlen; char pathstr[]; }; using ListDirResponse = struct __attribute__((packed)) { commands command; uint8_t status; uint16_t path_length; uint32_t entry; uint32_t totalentries; uint32_t flags; uint64_t modification_time; uint32_t file_size; char path[]; }; using MKDirHeader = struct __attribute__((packed)) { commands command; uint8_t padding; uint16_t pathlen; uint32_t padding2; uint64_t time; char pathstr[]; }; using MKDirResponse = struct __attribute__((packed)) { commands command; uint8_t status; uint32_t padding1; uint16_t padding2; uint64_t modification_time; }; using DelHeader = struct __attribute__((packed)) { commands command; uint8_t padding; uint16_t pathlen; char pathstr[]; }; using DelResponse = struct __attribute__((packed)) { commands command; uint8_t status; }; using MoveHeader = struct __attribute__((packed)) { commands command; uint8_t padding; uint16_t OldPathLength; uint16_t NewPathLength; char pathstr[]; }; using MoveResponse = struct __attribute__((packed)) { commands command; uint8_t status; }; int FSCommandHandler(uint16_t connectionHandle, os_mbuf* om); void prepareReadDataResp(ReadHeader* header, ReadResponse* resp); }; } } |