_loraFiles.ino 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. // 1-channel LoRa Gateway for ESP8266
  2. // Copyright (c) 2016, 2017, 2018, 2019 Maarten Westenberg version for ESP8266
  3. //
  4. // based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
  5. // and many others.
  6. //
  7. // All rights reserved. This program and the accompanying materials
  8. // are made available under the terms of the MIT License
  9. // which accompanies this distribution, and is available at
  10. // https://opensource.org/licenses/mit-license.php
  11. //
  12. // NO WARRANTY OF ANY KIND IS PROVIDED
  13. //
  14. // Author: Maarten Westenberg (mw12554@hotmail.com)
  15. //
  16. // This file contains the LoRa filesystem specific code
  17. #if _MONITOR>=1
  18. // ----------------------------------------------------------------------------
  19. // LoRa Monitor logging code.
  20. // Define one print function and depending on the loggin parameter output
  21. // to _USB of to the www screen function
  22. // ----------------------------------------------------------------------------
  23. int initMonitor(struct moniLine *monitor) {
  24. for (int i=0; i< _MONITOR; i++) {
  25. //monitor[i].txt[0]=0;
  26. monitor[i].txt="";
  27. }
  28. return(1);
  29. }
  30. #endif //_MONITOR
  31. // ============================================================================
  32. // LORA SPIFFS FILESYSTEM FUNCTIONS
  33. //
  34. // The LoRa supporting functions are in the section below
  35. // ----------------------------------------------------------------------------
  36. // Supporting function to readConfig
  37. // ----------------------------------------------------------------------------
  38. void id_print (String id, String val) {
  39. #if _DUSB>=1
  40. if (( debug>=0 ) && ( pdebug & P_MAIN )) {
  41. Serial.print(id);
  42. Serial.print(F("=\t"));
  43. Serial.println(val);
  44. }
  45. #endif //_DUSB
  46. }
  47. // ----------------------------------------------------------------------------
  48. // INITCONFIG; Init the gateway configuration file
  49. // Espcecially when calling SPIFFS.format() the gateway is left in an init
  50. // which is not very well defined. This function will init some of the settings
  51. // to well known settings.
  52. // ----------------------------------------------------------------------------
  53. int initConfig(struct espGwayConfig *c) {
  54. (*c).ch = 0;
  55. (*c).sf = _SPREADING;
  56. (*c).debug = 1;
  57. (*c).pdebug = P_GUI;
  58. (*c).cad = _CAD;
  59. (*c).hop = false;
  60. (*c).seen = false;
  61. (*c).expert = false;
  62. (*c).monitor = false;
  63. (*c).txDelay = 0; // First Value without saving is 0;
  64. (*c).trusted = 1;
  65. }
  66. // ----------------------------------------------------------------------------
  67. // Read the gateway configuration file
  68. // ----------------------------------------------------------------------------
  69. int readConfig(const char *fn, struct espGwayConfig *c) {
  70. int tries = 0;
  71. #if _DUSB>=1
  72. Serial.println(F("readConfig:: Starting "));
  73. #endif //_DUSB
  74. if (!SPIFFS.exists(fn)) {
  75. #if _DUSB>=1
  76. Serial.print(F("readConfig ERR:: file="));
  77. Serial.print(fn);
  78. Serial.println(F(" does not exist .. Formatting"));
  79. #endif //_DUSB
  80. SPIFFS.format();
  81. initConfig(c); // If we cannot read teh config, at least init known values
  82. return(-1);
  83. }
  84. File f = SPIFFS.open(fn, "r");
  85. if (!f) {
  86. #if _DUSB>=1
  87. Serial.println(F("ERROR:: SPIFFS open failed"));
  88. #endif //_DUSB
  89. return(-1);
  90. }
  91. while (f.available()) {
  92. #if _DUSB>=1
  93. if (( debug>=0 ) && ( pdebug & P_MAIN )) {
  94. Serial.print('.');
  95. }
  96. #endif //_DUSB
  97. // If we wait for more than 10 times, reformat the filesystem
  98. // We do this so that the system will be responsive (over OTA for example).
  99. //
  100. if (tries >= 10) {
  101. f.close();
  102. #if _DUSB>=1
  103. if (( debug>=0 ) && ( pdebug & P_MAIN )) {
  104. Serial.println(F("Formatting"));
  105. }
  106. #endif //_DUSB
  107. SPIFFS.format();
  108. initConfig(c);
  109. f = SPIFFS.open(fn, "r");
  110. tries = 0;
  111. }
  112. String id =f.readStringUntil('='); // Read keyword until '=', C++ thing
  113. String val=f.readStringUntil('\n'); // Read value until End of Line (EOL)
  114. #if _DUSB>=2
  115. Serial.print(F("readConfig:: reading line="));
  116. Serial.print(id);
  117. Serial.print(F("="));
  118. Serial.print(val);
  119. Serial.println();
  120. #endif //_DUSB
  121. if (id == "SSID") { // WiFi SSID
  122. id_print(id, val);
  123. (*c).ssid = val; // val contains ssid, we do NO check
  124. }
  125. else if (id == "PASS") { // WiFi Password
  126. id_print(id, val);
  127. (*c).pass = val;
  128. }
  129. else if (id == "CH") { // Frequency Channel
  130. id_print(id,val);
  131. (*c).ch = (uint32_t) val.toInt();
  132. }
  133. else if (id == "SF") { // Spreading Factor
  134. id_print(id, val);
  135. (*c).sf = (uint32_t) val.toInt();
  136. }
  137. else if (id == "FCNT") { // Frame Counter
  138. id_print(id, val);
  139. (*c).fcnt = (uint32_t) val.toInt();
  140. }
  141. else if (id == "DEBUG") { // Debug Level
  142. id_print(id, val);
  143. (*c).debug = (uint8_t) val.toInt();
  144. }
  145. else if (id == "PDEBUG") { // pDebug Pattern
  146. id_print(id, val);
  147. (*c).pdebug = (uint8_t) val.toInt();
  148. }
  149. else if (id == "CAD") { // CAD setting
  150. id_print(id, val);
  151. (*c).cad = (uint8_t) val.toInt();
  152. }
  153. else if (id == "HOP") { // HOP setting
  154. id_print(id, val);
  155. (*c).hop = (uint8_t) val.toInt();
  156. }
  157. else if (id == "BOOTS") { // BOOTS setting
  158. id_print(id, val);
  159. (*c).boots = (uint8_t) val.toInt();
  160. }
  161. else if (id == "RESETS") { // RESET setting
  162. id_print(id, val);
  163. (*c).resets = (uint8_t) val.toInt();
  164. }
  165. else if (id == "WIFIS") { // WIFIS setting
  166. id_print(id, val);
  167. (*c).wifis = (uint8_t) val.toInt();
  168. }
  169. else if (id == "VIEWS") { // VIEWS setting
  170. id_print(id, val);
  171. (*c).views = (uint8_t) val.toInt();
  172. }
  173. else if (id == "NODE") { // NODE setting
  174. id_print(id, val);
  175. (*c).isNode = (uint8_t) val.toInt();
  176. }
  177. else if (id == "REFR") { // REFR setting
  178. id_print(id, val);
  179. (*c).refresh = (uint8_t) val.toInt();
  180. }
  181. else if (id == "REENTS") { // REENTS setting
  182. id_print(id, val);
  183. (*c).reents = (uint8_t) val.toInt();
  184. }
  185. else if (id == "NTPERR") { // NTPERR setting
  186. id_print(id, val);
  187. (*c).ntpErr = (uint8_t) val.toInt();
  188. }
  189. else if (id == "NTPETIM") { // NTPERR setting
  190. id_print(id, val);
  191. (*c).ntpErrTime = (uint32_t) val.toInt();
  192. }
  193. else if (id == "NTPS") { // NTPS setting
  194. id_print(id, val);
  195. (*c).ntps = (uint8_t) val.toInt();
  196. }
  197. else if (id == "FILENO") { // FILENO setting
  198. id_print(id, val);
  199. (*c).logFileNo = (uint8_t) val.toInt();
  200. }
  201. else if (id == "FILEREC") { // FILEREC setting
  202. id_print(id, val);
  203. (*c).logFileRec = (uint16_t) val.toInt();
  204. }
  205. else if (id == "FILENUM") { // FILEREC setting
  206. id_print(id, val);
  207. (*c).logFileNum = (uint16_t) val.toInt();
  208. }
  209. else if (id == "EXPERT") { // EXPERT button setting
  210. id_print(id, val);
  211. (*c).expert = (uint8_t) val.toInt();
  212. }
  213. else if (id == "SEEN") { // SEEN button setting
  214. id_print(id, val);
  215. (*c).seen = (uint8_t) val.toInt();
  216. }
  217. else if (id == "MONITOR") { // MONITOR button setting
  218. id_print(id, val);
  219. (*c).monitor = (uint8_t) val.toInt();
  220. }
  221. else if (id == "DELAY") { // DELAY setting
  222. id_print(id, val);
  223. (*c).txDelay = (int32_t) val.toInt();
  224. }
  225. else if (id == "TRUSTED") { // TRUSTED setting
  226. id_print(id, val);
  227. (*c).trusted= (int32_t) val.toInt();
  228. }
  229. else {
  230. #if _DUSB>=1
  231. Serial.print(F("readConfig:: tries++"));
  232. #endif //_DUSB
  233. tries++;
  234. }
  235. }
  236. f.close();
  237. #if _DUSB>=1
  238. if (debug>=1) {
  239. Serial.println(F("readConfig:: Fini"));
  240. }
  241. Serial.println();
  242. #endif //_DUSB
  243. return(1);
  244. }//readConfig
  245. // ----------------------------------------------------------------------------
  246. // Write the current gateway configuration to SPIFFS. First copy all the
  247. // separate data items to the gwayConfig structure
  248. //
  249. // Note: gwayConfig.expert contains the expert setting already
  250. // gwayConfig.txDelay
  251. // ----------------------------------------------------------------------------
  252. int writeGwayCfg(const char *fn) {
  253. gwayConfig.ssid = WiFi.SSID();
  254. gwayConfig.pass = WiFi.psk(); // XXX We should find a way to store the password too
  255. gwayConfig.ch = ifreq; // Frequency Index
  256. gwayConfig.sf = (uint8_t) sf; // Spreading Factor
  257. gwayConfig.debug = debug;
  258. gwayConfig.pdebug = pdebug;
  259. gwayConfig.cad = _cad;
  260. gwayConfig.hop = _hop;
  261. #if GATEWAYNODE==1
  262. gwayConfig.fcnt = frameCount;
  263. #endif //GATEWAYNODE
  264. return(writeConfig(fn, &gwayConfig));
  265. }
  266. // ----------------------------------------------------------------------------
  267. // Write the configuration as found in the espGwayConfig structure
  268. // to SPIFFS
  269. // Parameters:
  270. // fn; Filename
  271. // c; struct config
  272. // Returns:
  273. // 1 when successful, -1 on error
  274. // ----------------------------------------------------------------------------
  275. int writeConfig(const char *fn, struct espGwayConfig *c) {
  276. // Assuming the cibfug file is the first we write...
  277. // If it is not there we should format first.
  278. // NOTE: Do not format for other files!
  279. if (!SPIFFS.exists(fn)) {
  280. #if _DUSB>=1
  281. Serial.print("WARNING:: writeConfig, file not exists, formatting ");
  282. #endif //_DUSB
  283. SPIFFS.format();
  284. initConfig(c); // XXX make all initial declarations here if config vars need to have a value
  285. #if _DUSB>=1
  286. Serial.println(fn);
  287. #endif //_DUSB
  288. }
  289. File f = SPIFFS.open(fn, "w");
  290. if (!f) {
  291. #if _DUSB>=1
  292. Serial.print("writeConfig: ERROR open file=");
  293. Serial.print(fn);
  294. Serial.println();
  295. #endif //_DUSB
  296. return(-1);
  297. }
  298. f.print("SSID"); f.print('='); f.print((*c).ssid); f.print('\n');
  299. f.print("PASS"); f.print('='); f.print((*c).pass); f.print('\n');
  300. f.print("CH"); f.print('='); f.print((*c).ch); f.print('\n');
  301. f.print("SF"); f.print('='); f.print((*c).sf); f.print('\n');
  302. f.print("FCNT"); f.print('='); f.print((*c).fcnt); f.print('\n');
  303. f.print("DEBUG"); f.print('='); f.print((*c).debug); f.print('\n');
  304. f.print("PDEBUG"); f.print('='); f.print((*c).pdebug); f.print('\n');
  305. f.print("CAD"); f.print('='); f.print((*c).cad); f.print('\n');
  306. f.print("HOP"); f.print('='); f.print((*c).hop); f.print('\n');
  307. f.print("NODE"); f.print('='); f.print((*c).isNode); f.print('\n');
  308. f.print("BOOTS"); f.print('='); f.print((*c).boots); f.print('\n');
  309. f.print("RESETS"); f.print('='); f.print((*c).resets); f.print('\n');
  310. f.print("WIFIS"); f.print('='); f.print((*c).wifis); f.print('\n');
  311. f.print("VIEWS"); f.print('='); f.print((*c).views); f.print('\n');
  312. f.print("REFR"); f.print('='); f.print((*c).refresh); f.print('\n');
  313. f.print("REENTS"); f.print('='); f.print((*c).reents); f.print('\n');
  314. f.print("NTPETIM"); f.print('='); f.print((*c).ntpErrTime); f.print('\n');
  315. f.print("NTPERR"); f.print('='); f.print((*c).ntpErr); f.print('\n');
  316. f.print("NTPS"); f.print('='); f.print((*c).ntps); f.print('\n');
  317. f.print("FILEREC"); f.print('='); f.print((*c).logFileRec); f.print('\n');
  318. f.print("FILENO"); f.print('='); f.print((*c).logFileNo); f.print('\n');
  319. f.print("FILENUM"); f.print('='); f.print((*c).logFileNum); f.print('\n');
  320. f.print("DELAY"); f.print('='); f.print((*c).txDelay); f.print('\n');
  321. f.print("TRUSTED"); f.print('='); f.print((*c).trusted); f.print('\n');
  322. f.print("EXPERT"); f.print('='); f.print((*c).expert); f.print('\n');
  323. f.print("SEEN"); f.print('='); f.print((*c).seen); f.print('\n');
  324. f.print("MONITOR"); f.print('='); f.print((*c).monitor); f.print('\n');
  325. f.close();
  326. return(1);
  327. }
  328. // ----------------------------------------------------------------------------
  329. // Add a line with statistics to the log.
  330. //
  331. // We put the check in the function to protect against calling
  332. // the function without STAT_LOG being proper defined
  333. // ToDo: Store the fileNo and the fileRec in the status file to save for
  334. // restarts
  335. //
  336. // Parameters:
  337. // line; char array with characters to write to log
  338. // cnt;
  339. // Returns:
  340. // <none>
  341. // ----------------------------------------------------------------------------
  342. int addLog(const unsigned char * line, int cnt)
  343. {
  344. #if STAT_LOG==1
  345. char fn[16];
  346. if (gwayConfig.logFileRec > LOGFILEREC) { // Have to make define for this
  347. gwayConfig.logFileRec = 0; // In new logFile start with record 0
  348. gwayConfig.logFileNo++; // Increase file ID
  349. gwayConfig.logFileNum++; // Increase number of log files
  350. }
  351. gwayConfig.logFileRec++;
  352. // If we have too many logfies, delete the oldest
  353. //
  354. if (gwayConfig.logFileNum > LOGFILEMAX){
  355. sprintf(fn,"/log-%d", gwayConfig.logFileNo - LOGFILEMAX);
  356. #if _DUSB>=1
  357. if (( debug>=0 ) && ( pdebug & P_GUI )) {
  358. Serial.print(F("G addLog:: Too many logfile, deleting="));
  359. Serial.println(fn);
  360. }
  361. #endif //_DUSB
  362. SPIFFS.remove(fn);
  363. gwayConfig.logFileNum--;
  364. }
  365. // Make sure we have the right fileno
  366. sprintf(fn,"/log-%d", gwayConfig.logFileNo);
  367. // If there is no SPIFFS, Error
  368. // Make sure to write the config record/line also
  369. if (!SPIFFS.exists(fn)) {
  370. #if _DUSB>=1
  371. if (( debug >= 1 ) && ( pdebug & P_GUI )) {
  372. Serial.print(F("G ERROR:: addLog:: file="));
  373. Serial.print(fn);
  374. Serial.print(F(" does not exist .. rec="));
  375. Serial.print(gwayConfig.logFileRec);
  376. Serial.println();
  377. }
  378. #endif //_DUSB
  379. }
  380. File f = SPIFFS.open(fn, "a");
  381. if (!f) {
  382. #if _DUSB>=1
  383. if (( debug>=1 ) && ( pdebug & P_GUI )) {
  384. Serial.println("G file open failed=");
  385. Serial.println(fn);
  386. }
  387. #endif //_DUSB
  388. return(0); // If file open failed, return
  389. }
  390. int i;
  391. #if _DUSB>=1
  392. if (( debug>=1 ) && ( pdebug & P_GUI )) {
  393. Serial.print(F("G addLog:: fileno="));
  394. Serial.print(gwayConfig.logFileNo);
  395. Serial.print(F(", rec="));
  396. Serial.print(gwayConfig.logFileRec);
  397. Serial.print(F(": "));
  398. #if _DUSB>=2
  399. for (i=0; i< 12; i++) { // The first 12 bytes contain non printable characters
  400. Serial.print(line[i],HEX);
  401. Serial.print(' ');
  402. }
  403. #else
  404. i+=12;
  405. #endif //_DUSB>=2
  406. Serial.print((char *) &line[i]); // The rest if the buffer contains ascii
  407. Serial.println();
  408. }
  409. #endif //_DUSB
  410. for (i=0; i< 12; i++) { // The first 12 bytes contain non printable characters
  411. // f.print(line[i],HEX);
  412. f.print('*');
  413. }
  414. f.write(&(line[i]), cnt-12); // write/append the line to the file
  415. f.print('\n');
  416. f.close(); // Close the file after appending to it
  417. #endif //STAT_LOG
  418. return(1);
  419. }
  420. // ----------------------------------------------------------------------------
  421. // Print (all) logfiles
  422. //
  423. // ----------------------------------------------------------------------------
  424. void printLog()
  425. {
  426. char fn[16];
  427. int i=0;
  428. #if _DUSB>=1
  429. while (i< LOGFILEMAX ) {
  430. sprintf(fn,"/log-%d", gwayConfig.logFileNo - i);
  431. if (!SPIFFS.exists(fn)) break; // break the loop
  432. // Open the file for reading
  433. File f = SPIFFS.open(fn, "r");
  434. int j;
  435. for (j=0; j<LOGFILEREC; j++) {
  436. String s=f.readStringUntil('\n');
  437. if (s.length() == 0) break;
  438. Serial.println(s.substring(12)); // Skip the first 12 Gateway specific binary characters
  439. yield();
  440. }
  441. i++;
  442. }
  443. #endif //_DUSB
  444. } //printLog
  445. #if _SEENMAX >= 1
  446. // ----------------------------------------------------------------------------
  447. // initSeen
  448. // Init the lisrScreen array
  449. // ----------------------------------------------------------------------------
  450. int initSeen(struct nodeSeen *listSeen) {
  451. int i;
  452. for (i=0; i< _SEENMAX; i++) {
  453. listSeen[i].idSeen=0;
  454. listSeen[i].sfSeen=0;
  455. listSeen[i].cntSeen=0;
  456. listSeen[i].chnSeen=0;
  457. listSeen[i].timSeen=0;
  458. }
  459. return(1);
  460. }
  461. // ----------------------------------------------------------------------------
  462. // readSeen
  463. // This function read the stored information from writeSeen.
  464. //
  465. // Parameters:
  466. // Return:
  467. // ----------------------------------------------------------------------------
  468. int readSeen(const char *fn, struct nodeSeen *listSeen) {
  469. int i;
  470. if (!SPIFFS.exists(fn)) {
  471. #if _DUSB>=1
  472. Serial.print("WARNING:: readSeen, history file not exists ");
  473. #endif //_DUSB
  474. initSeen(listSeen); // XXX make all initial declarations here if config vars need to have a value
  475. Serial.println(fn);
  476. return(-1);
  477. }
  478. File f = SPIFFS.open(fn, "r");
  479. if (!f) {
  480. #if _DUSB>=1
  481. Serial.print("readConfig:: ERROR open file=");
  482. Serial.print(fn);
  483. Serial.println();
  484. #endif //_DUSB
  485. return(-1);
  486. }
  487. for (i=0; i<_SEENMAX; i++) {
  488. String val;
  489. if (!f.available()) {
  490. #if _DUSB>=1
  491. Serial.println(F("readSeen:: No more info left in file"));
  492. #endif //_DUSB
  493. }
  494. val=f.readStringUntil('\t'); listSeen[i].timSeen = (uint32_t) val.toInt();
  495. val=f.readStringUntil('\t'); listSeen[i].idSeen = (uint32_t) val.toInt();
  496. val=f.readStringUntil('\t'); listSeen[i].cntSeen = (uint32_t) val.toInt();
  497. val=f.readStringUntil('\t'); listSeen[i].chnSeen = (uint8_t) val.toInt();
  498. val=f.readStringUntil('\n'); listSeen[i].sfSeen = (uint8_t) val.toInt();
  499. }
  500. f.close();
  501. #if _DUSB>=1
  502. printSeen(listSeen);
  503. #endif //_DUSB
  504. }
  505. // ----------------------------------------------------------------------------
  506. // writeSeen
  507. // Once every few messages, update the SPIFFS file and write the array.
  508. // Parameters:
  509. // - fn contains the filename to write
  510. // - listSeen contains the _SEENMAX array of list structures
  511. // Return values:
  512. // - return 1 on success
  513. // ----------------------------------------------------------------------------
  514. int writeSeen(const char *fn, struct nodeSeen *listSeen) {
  515. int i;
  516. if (!SPIFFS.exists(fn)) {
  517. #if _DUSB>=1
  518. Serial.print("WARNING:: writeSeen, file not exists, formatting ");
  519. #endif //_DUSB
  520. initSeen(listSeen); // XXX make all initial declarations here if config vars need to have a value
  521. #if _DUSB>=1
  522. Serial.println(fn);
  523. #endif //_DUSB
  524. }
  525. File f = SPIFFS.open(fn, "w");
  526. if (!f) {
  527. #if _DUSB>=1
  528. Serial.print("writeConfig:: ERROR open file=");
  529. Serial.print(fn);
  530. Serial.println();
  531. #endif //_DUSB
  532. return(-1);
  533. }
  534. for (i=0; i<_SEENMAX; i++) {
  535. unsigned long timSeen;
  536. f.print(listSeen[i].timSeen); f.print('\t');
  537. // Typecast to long to avoid errors in unsigned conversion!
  538. f.print((long) listSeen[i].idSeen); f.print('\t');
  539. f.print(listSeen[i].cntSeen); f.print('\t');
  540. f.print(listSeen[i].chnSeen); f.print('\t');
  541. f.print(listSeen[i].sfSeen); f.print('\n');
  542. //f.print(listSeen[i].rssiSeen); f.print('\t');
  543. //f.print(listSeen[i].datSeen); f.print('\n');
  544. }
  545. f.close();
  546. return(1);
  547. }
  548. // ----------------------------------------------------------------------------
  549. // printSeen
  550. // - This function writes the last seen array to the USB
  551. // ----------------------------------------------------------------------------
  552. int printSeen(struct nodeSeen *listSeen) {
  553. int i;
  554. #if _DUSB>=1
  555. if (( debug>=2 ) && ( pdebug & P_MAIN )) {
  556. Serial.println(F("printSeen:: "));
  557. for (i=0; i<_SEENMAX; i++) {
  558. if (listSeen[i].idSeen != 0) {
  559. String response;
  560. Serial.print(i);
  561. Serial.print(F(", TM="));
  562. stringTime(listSeen[i].timSeen, response);
  563. Serial.print(response);
  564. Serial.print(F(", addr=0x"));
  565. Serial.print(listSeen[i].idSeen,HEX);
  566. Serial.print(F(", SF=0x"));
  567. Serial.print(listSeen[i].sfSeen,HEX);
  568. Serial.println();
  569. }
  570. }
  571. }
  572. #endif //_DUSB
  573. return(1);
  574. }
  575. // ----------------------------------------------------------------------------
  576. // addSeen
  577. // With every new message received:
  578. // - Look whether the message is already in the array, if so update existing
  579. // message. If not, create new record.
  580. // - With this record, update the SF settings
  581. // ----------------------------------------------------------------------------
  582. int addSeen(struct nodeSeen *listSeen, struct stat_t stat) {
  583. int i;
  584. // ( message[4]<<24 | message[3]<<16 | message[2]<<8 | message[1] )
  585. for (i=0; i< _SEENMAX; i++) {
  586. if ((listSeen[i].idSeen==stat.node) ||
  587. (listSeen[i].idSeen==0))
  588. {
  589. #if _DUSB>=2
  590. if (( debug>=0 ) && ( pdebug & P_MAIN )) {
  591. Serial.print(F("addSeen:: index="));
  592. Serial.print(i);
  593. }
  594. #endif //_DUSB
  595. listSeen[i].idSeen = stat.node;
  596. listSeen[i].chnSeen = stat.ch;
  597. listSeen[i].sfSeen |= stat.sf; // Or the argument
  598. listSeen[i].timSeen = stat.tmst;
  599. listSeen[i].cntSeen++; // Not included on functiin paras
  600. writeSeen(_SEENFILE, listSeen);
  601. break;
  602. }
  603. }
  604. if (i>=_SEENMAX) {
  605. #if _DUSB>=1
  606. if (( debug>=0 ) && ( pdebug & P_MAIN )) {
  607. Serial.print(F("addSeen:: exit=0, index="));
  608. Serial.println(i);
  609. }
  610. #endif //_DUSB
  611. return(0);
  612. }
  613. return(1);
  614. }
  615. // ----------------------------------------------------------------------------
  616. // listDir
  617. // List the directory and put it in
  618. // ----------------------------------------------------------------------------
  619. void listDir(char * dir)
  620. {
  621. #if _DUSB>=1
  622. // Nothing here
  623. #endif //_DUSB
  624. }
  625. #endif //_SEENMAX>=1 End of File