esp8266.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. /*
  2. /* From: https://chromium.googlesource.com/chromium/src.git/+/4.1.249.1050/third_party/sqlite/src/os_symbian.cc
  3. * https://github.com/spsoft/spmemvfs/tree/master/spmemvfs
  4. * http://www.sqlite.org/src/doc/trunk/src/test_demovfs.c
  5. * http://www.sqlite.org/src/doc/trunk/src/test_vfstrace.c
  6. * http://www.sqlite.org/src/doc/trunk/src/test_onefile.c
  7. * http://www.sqlite.org/src/doc/trunk/src/test_vfs.c
  8. **/
  9. #include <stdio.h>
  10. #include <stddef.h>
  11. #include <string.h>
  12. #include <stdint.h>
  13. #include <osapi.h>
  14. #include <vfs.h>
  15. #include <time.h>
  16. #include <spi_flash.h>
  17. #include <sqlite3.h>
  18. #undef dbg_printf
  19. #define dbg_printf(...) 0
  20. #define CACHEBLOCKSZ 64
  21. #define ESP8266_DEFAULT_MAXNAMESIZE 32
  22. static int esp8266_Close(sqlite3_file*);
  23. static int esp8266_Lock(sqlite3_file *, int);
  24. static int esp8266_Unlock(sqlite3_file*, int);
  25. static int esp8266_Sync(sqlite3_file*, int);
  26. static int esp8266_Open(sqlite3_vfs*, const char *, sqlite3_file *, int, int*);
  27. static int esp8266_Read(sqlite3_file*, void*, int, sqlite3_int64);
  28. static int esp8266_Write(sqlite3_file*, const void*, int, sqlite3_int64);
  29. static int esp8266_Truncate(sqlite3_file*, sqlite3_int64);
  30. static int esp8266_Delete(sqlite3_vfs*, const char *, int);
  31. static int esp8266_FileSize(sqlite3_file*, sqlite3_int64*);
  32. static int esp8266_Access(sqlite3_vfs*, const char*, int, int*);
  33. static int esp8266_FullPathname( sqlite3_vfs*, const char *, int, char*);
  34. static int esp8266_CheckReservedLock(sqlite3_file*, int *);
  35. static int esp8266_FileControl(sqlite3_file *, int, void*);
  36. static int esp8266_SectorSize(sqlite3_file*);
  37. static int esp8266_DeviceCharacteristics(sqlite3_file*);
  38. static void* esp8266_DlOpen(sqlite3_vfs*, const char *);
  39. static void esp8266_DlError(sqlite3_vfs*, int, char*);
  40. static void (*esp8266_DlSym (sqlite3_vfs*, void*, const char*))(void);
  41. static void esp8266_DlClose(sqlite3_vfs*, void*);
  42. static int esp8266_Randomness(sqlite3_vfs*, int, char*);
  43. static int esp8266_Sleep(sqlite3_vfs*, int);
  44. static int esp8266_CurrentTime(sqlite3_vfs*, double*);
  45. static int esp8266mem_Close(sqlite3_file*);
  46. static int esp8266mem_Read(sqlite3_file*, void*, int, sqlite3_int64);
  47. static int esp8266mem_Write(sqlite3_file*, const void*, int, sqlite3_int64);
  48. static int esp8266mem_FileSize(sqlite3_file*, sqlite3_int64*);
  49. static int esp8266mem_Sync(sqlite3_file*, int);
  50. typedef struct st_linkedlist {
  51. uint16_t blockid;
  52. struct st_linkedlist *next;
  53. uint8_t data[CACHEBLOCKSZ];
  54. } linkedlist_t, *pLinkedList_t;
  55. typedef struct st_filecache {
  56. uint32_t size;
  57. linkedlist_t *list;
  58. } filecache_t, *pFileCache_t;
  59. typedef struct esp8266_file {
  60. sqlite3_file base;
  61. int fd;
  62. filecache_t *cache;
  63. char name[ESP8266_DEFAULT_MAXNAMESIZE];
  64. } esp8266_file;
  65. static sqlite3_vfs esp8266Vfs = {
  66. 1, // iVersion
  67. sizeof(esp8266_file), // szOsFile
  68. FS_OBJ_NAME_LEN, // mxPathname
  69. NULL, // pNext
  70. "esp8266", // name
  71. 0, // pAppData
  72. esp8266_Open, // xOpen
  73. esp8266_Delete, // xDelete
  74. esp8266_Access, // xAccess
  75. esp8266_FullPathname, // xFullPathname
  76. esp8266_DlOpen, // xDlOpen
  77. esp8266_DlError, // xDlError
  78. esp8266_DlSym, // xDlSym
  79. esp8266_DlClose, // xDlClose
  80. esp8266_Randomness, // xRandomness
  81. esp8266_Sleep, // xSleep
  82. esp8266_CurrentTime, // xCurrentTime
  83. 0 // xGetLastError
  84. };
  85. static const sqlite3_io_methods esp8266IoMethods = {
  86. 1,
  87. esp8266_Close,
  88. esp8266_Read,
  89. esp8266_Write,
  90. esp8266_Truncate,
  91. esp8266_Sync,
  92. esp8266_FileSize,
  93. esp8266_Lock,
  94. esp8266_Unlock,
  95. esp8266_CheckReservedLock,
  96. esp8266_FileControl,
  97. esp8266_SectorSize,
  98. esp8266_DeviceCharacteristics
  99. };
  100. static const sqlite3_io_methods esp8266MemMethods = {
  101. 1,
  102. esp8266mem_Close,
  103. esp8266mem_Read,
  104. esp8266mem_Write,
  105. esp8266_Truncate,
  106. esp8266mem_Sync,
  107. esp8266mem_FileSize,
  108. esp8266_Lock,
  109. esp8266_Unlock,
  110. esp8266_CheckReservedLock,
  111. esp8266_FileControl,
  112. esp8266_SectorSize,
  113. esp8266_DeviceCharacteristics
  114. };
  115. static uint32_t linkedlist_store (linkedlist_t **leaf, uint32_t offset, uint32_t len, const uint8_t *data) {
  116. const uint8_t blank[CACHEBLOCKSZ] = { 0 };
  117. uint16_t blockid = offset/CACHEBLOCKSZ;
  118. linkedlist_t *block;
  119. if (!memcmp(data, blank, CACHEBLOCKSZ))
  120. return len;
  121. block = *leaf;
  122. if (!block || ( block->blockid != blockid ) ) {
  123. block = sqlite3_malloc ( sizeof( linkedlist_t ) );
  124. if (!block)
  125. return SQLITE_NOMEM;
  126. memset (block->data, 0, CACHEBLOCKSZ);
  127. block->blockid = blockid;
  128. }
  129. if (!*leaf) {
  130. *leaf = block;
  131. block->next = NULL;
  132. } else if (block != *leaf) {
  133. if (block->blockid > (*leaf)->blockid) {
  134. block->next = (*leaf)->next;
  135. (*leaf)->next = block;
  136. } else {
  137. block->next = (*leaf);
  138. (*leaf) = block;
  139. }
  140. }
  141. memcpy (block->data + offset%CACHEBLOCKSZ, data, len);
  142. return len;
  143. }
  144. static uint32_t filecache_pull (pFileCache_t cache, uint32_t offset, uint32_t len, uint8_t *data) {
  145. uint16_t i;
  146. float blocks;
  147. uint32_t r = 0;
  148. blocks = ( offset % CACHEBLOCKSZ + len ) / (float) CACHEBLOCKSZ;
  149. if (blocks == 0.0)
  150. return 0;
  151. if (( blocks - (int) blocks) > 0.0)
  152. blocks = blocks + 1.0;
  153. for (i = 0; i < (uint16_t) blocks; i++) {
  154. uint16_t round;
  155. float relablock;
  156. linkedlist_t *leaf;
  157. uint32_t relaoffset, relalen;
  158. uint8_t * reladata = (uint8_t*) data;
  159. relalen = len - r;
  160. reladata = reladata + r;
  161. relaoffset = offset + r;
  162. round = CACHEBLOCKSZ - relaoffset%CACHEBLOCKSZ;
  163. if (relalen > round) relalen = round;
  164. for (leaf = cache->list; leaf && leaf->next; leaf = leaf->next) {
  165. if ( ( leaf->next->blockid * CACHEBLOCKSZ ) > relaoffset )
  166. break;
  167. }
  168. relablock = relaoffset/((float)CACHEBLOCKSZ) - leaf->blockid;
  169. if ( ( relablock >= 0 ) && ( relablock < 1 ) )
  170. memcpy (data + r, leaf->data + (relaoffset % CACHEBLOCKSZ), relalen);
  171. r = r + relalen;
  172. }
  173. return 0;
  174. }
  175. static uint32_t filecache_push (pFileCache_t cache, uint32_t offset, uint32_t len, const uint8_t *data) {
  176. uint16_t i;
  177. float blocks;
  178. uint32_t r = 0;
  179. uint8_t updateroot = 0x1;
  180. blocks = ( offset % CACHEBLOCKSZ + len ) / (float) CACHEBLOCKSZ;
  181. if (blocks == 0.0)
  182. return 0;
  183. if (( blocks - (int) blocks) > 0.0)
  184. blocks = blocks + 1.0;
  185. for (i = 0; i < (uint16_t) blocks; i++) {
  186. uint16_t round;
  187. uint32_t localr;
  188. linkedlist_t *leaf;
  189. uint32_t relaoffset, relalen;
  190. uint8_t * reladata = (uint8_t*) data;
  191. relalen = len - r;
  192. reladata = reladata + r;
  193. relaoffset = offset + r;
  194. round = CACHEBLOCKSZ - relaoffset%CACHEBLOCKSZ;
  195. if (relalen > round) relalen = round;
  196. for (leaf = cache->list; leaf && leaf->next; leaf = leaf->next) {
  197. if ( ( leaf->next->blockid * CACHEBLOCKSZ ) > relaoffset )
  198. break;
  199. updateroot = 0x0;
  200. }
  201. localr = linkedlist_store(&leaf, relaoffset, (relalen > CACHEBLOCKSZ) ? CACHEBLOCKSZ : relalen, reladata);
  202. if (localr == SQLITE_NOMEM)
  203. return SQLITE_NOMEM;
  204. r = r + localr;
  205. if (updateroot & 0x1)
  206. cache->list = leaf;
  207. }
  208. if (offset + len > cache->size)
  209. cache->size = offset + len;
  210. return r;
  211. }
  212. static void filecache_free (pFileCache_t cache) {
  213. pLinkedList_t this = cache->list, next;
  214. while (this != NULL) {
  215. next = this->next;
  216. sqlite3_free (this);
  217. this = next;
  218. }
  219. }
  220. static int esp8266mem_Close(sqlite3_file *id)
  221. {
  222. esp8266_file *file = (esp8266_file*) id;
  223. filecache_free(file->cache);
  224. sqlite3_free (file->cache);
  225. dbg_printf("esp8266mem_Close: %s OK\n", file->name);
  226. return SQLITE_OK;
  227. }
  228. static int esp8266mem_Read(sqlite3_file *id, void *buffer, int amount, sqlite3_int64 offset)
  229. {
  230. sint32_t ofst;
  231. esp8266_file *file = (esp8266_file*) id;
  232. ofst = (sint32_t)(offset & 0x7FFFFFFF);
  233. filecache_pull (file->cache, ofst, amount, buffer);
  234. dbg_printf("esp8266mem_Read: %s [%ld] [%d] OK\n", file->name, ofst, amount);
  235. return SQLITE_OK;
  236. }
  237. static int esp8266mem_Write(sqlite3_file *id, const void *buffer, int amount, sqlite3_int64 offset)
  238. {
  239. sint32_t ofst;
  240. esp8266_file *file = (esp8266_file*) id;
  241. ofst = (sint32_t)(offset & 0x7FFFFFFF);
  242. filecache_push (file->cache, ofst, amount, buffer);
  243. dbg_printf("esp8266mem_Write: %s [%ld] [%d] OK\n", file->name, ofst, amount);
  244. return SQLITE_OK;
  245. }
  246. static int esp8266mem_Sync(sqlite3_file *id, int flags)
  247. {
  248. esp8266_file *file = (esp8266_file*) id;
  249. dbg_printf("esp8266mem_Sync: %s OK\n", file->name);
  250. return SQLITE_OK;
  251. }
  252. static int esp8266mem_FileSize(sqlite3_file *id, sqlite3_int64 *size)
  253. {
  254. esp8266_file *file = (esp8266_file*) id;
  255. *size = 0LL | file->cache->size;
  256. dbg_printf("esp8266mem_FileSize: %s [%d] OK\n", file->name, file->cache->size);
  257. return SQLITE_OK;
  258. }
  259. static int esp8266_Open( sqlite3_vfs * vfs, const char * path, sqlite3_file * file, int flags, int * outflags )
  260. {
  261. int rc;
  262. char *mode = "r";
  263. esp8266_file *p = (esp8266_file*) file;
  264. if ( path == NULL ) return SQLITE_IOERR;
  265. if( flags&SQLITE_OPEN_READONLY ) mode = "r";
  266. if( flags&SQLITE_OPEN_READWRITE || flags&SQLITE_OPEN_MAIN_JOURNAL ) {
  267. int result;
  268. if (SQLITE_OK != esp8266_Access(vfs, path, flags, &result))
  269. return SQLITE_CANTOPEN;
  270. if (result == 1)
  271. mode = "r+";
  272. else
  273. mode = "w+";
  274. }
  275. dbg_printf("esp8266_Open: 1o %s %s\n", path, mode);
  276. memset (p, 0, sizeof(esp8266_file));
  277. strncpy (p->name, path, ESP8266_DEFAULT_MAXNAMESIZE);
  278. p->name[ESP8266_DEFAULT_MAXNAMESIZE-1] = '\0';
  279. if( flags&SQLITE_OPEN_MAIN_JOURNAL ) {
  280. p->fd = 0;
  281. p->cache = sqlite3_malloc(sizeof (filecache_t));
  282. if (! p->cache )
  283. return SQLITE_NOMEM;
  284. memset (p->cache, 0, sizeof(filecache_t));
  285. p->base.pMethods = &esp8266MemMethods;
  286. dbg_printf("esp8266_Open: 2o %s %d MEM OK\n", p->name, p->fd);
  287. return SQLITE_OK;
  288. }
  289. p->fd = vfs_open (path, mode);
  290. if ( p->fd <= 0 ) {
  291. return SQLITE_CANTOPEN;
  292. }
  293. p->base.pMethods = &esp8266IoMethods;
  294. dbg_printf("esp8266_Open: 2o %s %d OK\n", p->name, p->fd);
  295. return SQLITE_OK;
  296. }
  297. static int esp8266_Close(sqlite3_file *id)
  298. {
  299. esp8266_file *file = (esp8266_file*) id;
  300. int rc = vfs_close(file->fd);
  301. dbg_printf("esp8266_Close: %s %d %d\n", file->name, file->fd, rc);
  302. return rc ? SQLITE_IOERR_CLOSE : SQLITE_OK;
  303. }
  304. static int esp8266_Read(sqlite3_file *id, void *buffer, int amount, sqlite3_int64 offset)
  305. {
  306. size_t nRead;
  307. sint32_t ofst, iofst;
  308. esp8266_file *file = (esp8266_file*) id;
  309. iofst = (sint32_t)(offset & 0x7FFFFFFF);
  310. dbg_printf("esp8266_Read: 1r %s %d %d %lld[%ld] \n", file->name, file->fd, amount, offset, iofst);
  311. ofst = vfs_lseek(file->fd, iofst, VFS_SEEK_SET);
  312. if (ofst != iofst) {
  313. dbg_printf("esp8266_Read: 2r %ld != %ld FAIL\n", ofst, iofst);
  314. return SQLITE_IOERR_SHORT_READ /* SQLITE_IOERR_SEEK */;
  315. }
  316. nRead = vfs_read(file->fd, buffer, amount);
  317. if ( nRead == amount ) {
  318. dbg_printf("esp8266_Read: 3r %s %u %d OK\n", file->name, nRead, amount);
  319. return SQLITE_OK;
  320. } else if ( nRead >= 0 ) {
  321. dbg_printf("esp8266_Read: 3r %s %u %d FAIL\n", file->name, nRead, amount);
  322. return SQLITE_IOERR_SHORT_READ;
  323. }
  324. dbg_printf("esp8266_Read: 4r %s FAIL\n", file->name);
  325. return SQLITE_IOERR_READ;
  326. }
  327. static int esp8266_Write(sqlite3_file *id, const void *buffer, int amount, sqlite3_int64 offset)
  328. {
  329. size_t nWrite;
  330. sint32_t ofst, iofst;
  331. esp8266_file *file = (esp8266_file*) id;
  332. iofst = (sint32_t)(offset & 0x7FFFFFFF);
  333. dbg_printf("esp8266_Write: 1w %s %d %d %lld[%ld] \n", file->name, file->fd, amount, offset, iofst);
  334. ofst = vfs_lseek(file->fd, iofst, VFS_SEEK_SET);
  335. if (ofst != iofst) {
  336. return SQLITE_IOERR_SEEK;
  337. }
  338. nWrite = vfs_write(file->fd, buffer, amount);
  339. if ( nWrite != amount ) {
  340. dbg_printf("esp8266_Write: 2w %s %u %d\n", file->name, nWrite, amount);
  341. return SQLITE_IOERR_WRITE;
  342. }
  343. dbg_printf("esp8266_Write: 3w %s OK\n", file->name);
  344. return SQLITE_OK;
  345. }
  346. static int esp8266_Truncate(sqlite3_file *id, sqlite3_int64 bytes)
  347. {
  348. esp8266_file *file = (esp8266_file*) id;
  349. dbg_printf("esp8266_Truncate:\n");
  350. return 0 ? SQLITE_IOERR_TRUNCATE : SQLITE_OK;
  351. }
  352. static int esp8266_Delete( sqlite3_vfs * vfs, const char * path, int syncDir )
  353. {
  354. sint32_t rc = vfs_remove( path );
  355. if (rc == VFS_RES_ERR)
  356. return SQLITE_IOERR_DELETE;
  357. dbg_printf("esp8266_Delete: %s OK\n", path);
  358. return SQLITE_OK;
  359. }
  360. static int esp8266_FileSize(sqlite3_file *id, sqlite3_int64 *size)
  361. {
  362. esp8266_file *file = (esp8266_file*) id;
  363. *size = 0LL | vfs_size( file->fd );
  364. dbg_printf("esp8266_FileSize: %s %u[%lld]\n", file->name, vfs_size(file->fd), *size);
  365. return SQLITE_OK;
  366. }
  367. static int esp8266_Sync(sqlite3_file *id, int flags)
  368. {
  369. esp8266_file *file = (esp8266_file*) id;
  370. int rc = vfs_flush( file->fd );
  371. dbg_printf("esp8266_Sync: %d\n", rc);
  372. return rc ? SQLITE_IOERR_FSYNC : SQLITE_OK;
  373. }
  374. static int esp8266_Access( sqlite3_vfs * vfs, const char * path, int flags, int * result )
  375. {
  376. struct vfs_stat st;
  377. sint32_t rc = vfs_stat( path, &st );
  378. *result = ( rc != VFS_RES_ERR );
  379. dbg_printf("esp8266_Access: %d\n", *result);
  380. return SQLITE_OK;
  381. }
  382. static int esp8266_FullPathname( sqlite3_vfs * vfs, const char * path, int len, char * fullpath )
  383. {
  384. struct vfs_stat st;
  385. sint32_t rc = vfs_stat( path, &st );
  386. if ( rc == VFS_RES_OK ){
  387. strncpy( fullpath, st.name, len );
  388. } else {
  389. strncpy( fullpath, path, len );
  390. }
  391. fullpath[ len - 1 ] = '\0';
  392. dbg_printf("esp8266_FullPathname: %s\n", fullpath);
  393. return SQLITE_OK;
  394. }
  395. static int esp8266_Lock(sqlite3_file *id, int lock_type)
  396. {
  397. esp8266_file *file = (esp8266_file*) id;
  398. dbg_printf("esp8266_Lock:\n");
  399. return SQLITE_OK;
  400. }
  401. static int esp8266_Unlock(sqlite3_file *id, int lock_type)
  402. {
  403. esp8266_file *file = (esp8266_file*) id;
  404. dbg_printf("esp8266_Unlock:\n");
  405. return SQLITE_OK;
  406. }
  407. static int esp8266_CheckReservedLock(sqlite3_file *id, int *result)
  408. {
  409. esp8266_file *file = (esp8266_file*) id;
  410. *result = 0;
  411. dbg_printf("esp8266_CheckReservedLock:\n");
  412. return SQLITE_OK;
  413. }
  414. static int esp8266_FileControl(sqlite3_file *id, int op, void *arg)
  415. {
  416. esp8266_file *file = (esp8266_file*) id;
  417. dbg_printf("esp8266_FileControl:\n");
  418. return SQLITE_OK;
  419. }
  420. static int esp8266_SectorSize(sqlite3_file *id)
  421. {
  422. esp8266_file *file = (esp8266_file*) id;
  423. dbg_printf("esp8266_SectorSize:\n");
  424. return SPI_FLASH_SEC_SIZE;
  425. }
  426. static int esp8266_DeviceCharacteristics(sqlite3_file *id)
  427. {
  428. esp8266_file *file = (esp8266_file*) id;
  429. dbg_printf("esp8266_DeviceCharacteristics:\n");
  430. return 0;
  431. }
  432. static void * esp8266_DlOpen( sqlite3_vfs * vfs, const char * path )
  433. {
  434. dbg_printf("esp8266_DlOpen:\n");
  435. return NULL;
  436. }
  437. static void esp8266_DlError( sqlite3_vfs * vfs, int len, char * errmsg )
  438. {
  439. dbg_printf("esp8266_DlError:\n");
  440. return;
  441. }
  442. static void ( * esp8266_DlSym ( sqlite3_vfs * vfs, void * handle, const char * symbol ) ) ( void )
  443. {
  444. dbg_printf("esp8266_DlSym:\n");
  445. return NULL;
  446. }
  447. static void esp8266_DlClose( sqlite3_vfs * vfs, void * handle )
  448. {
  449. dbg_printf("esp8266_DlClose:\n");
  450. return;
  451. }
  452. static int esp8266_Randomness( sqlite3_vfs * vfs, int len, char * buffer )
  453. {
  454. int rc = os_get_random(buffer, len);
  455. dbg_printf("esp8266_Randomness: %d\n", rc);
  456. return SQLITE_OK;
  457. }
  458. static int esp8266_Sleep( sqlite3_vfs * vfs, int microseconds )
  459. {
  460. dbg_printf("esp8266_Sleep:\n");
  461. return SQLITE_OK;
  462. }
  463. static int esp8266_CurrentTime( sqlite3_vfs * vfs, double * result )
  464. {
  465. // This is stubbed out until we have a working RTCTIME solution;
  466. // as it stood, this would always have returned the UNIX epoch.
  467. // time_t t = time(NULL);
  468. // *result = t / 86400.0 + 2440587.5;
  469. *result = 2440587.5;
  470. dbg_printf("esp8266_CurrentTime: %g\n", *result);
  471. return SQLITE_OK;
  472. }
  473. int sqlite3_os_init(void){
  474. sqlite3_vfs_register(&esp8266Vfs, 1);
  475. return SQLITE_OK;
  476. }
  477. int sqlite3_os_end(void){
  478. return SQLITE_OK;
  479. }