MeshNet  1.0.0
meshTables.h
Go to the documentation of this file.
1 
15 #ifndef INC_MESHTABLES_H_
16 #define INC_MESHTABLES_H_
17 
18 #include <meshPacket.h>
19 
25  MeshMACTableRow() = default;
26 
28 
33 
37  inline void clear() {
38  MAC = 0;
39  }
40 
46  static size_t printHeader(OSTREAM& stream);
47 
53  size_t printRow(OSTREAM& stream) const;
54 
55  bool operator==(const MeshMACTableRow& another) const {
56  return another.MAC == MAC;
57  }
58 
59 #ifdef SIMULATION
60  std::string printRowForChangeLog() const {
61  return std::to_string((int)MAC);
62  }
63 #endif //SIMULATION
64 };
65 
71  MeshRouteTableRow() = default;
72 
73  MeshRouteTableRow(uint8_t source, uint8_t neighbor, uint8_t hop);
74 
78  uint8_t Source = 0;
82  uint8_t Neighbor = 0;
86  uint8_t Hop = 0;
87 
92  inline bool isDirectNeighbor() const{
93  return Neighbor == Source;
94  }
95 
100  inline bool isGateway() const {
102  }
103 
107  inline void clear(){
108  Source = 0;
109  Neighbor = 0;
110  Hop = 0;
111  }
112 
118  static size_t printHeader(OSTREAM &stream);
119 
125  size_t printRow(OSTREAM &stream) const;
126 
127  bool operator==(const MeshRouteTableRow& another) const {
128  return another.Source == Source && another.Neighbor == Neighbor && another.Hop == Hop;
129  }
130 
131 #ifdef SIMULATION
132  std::string printRowForChangeLog() const {
133  return std::to_string((int)Source) + "|" + std::to_string((int)Neighbor) + "|" + std::to_string((int)Hop);
134  }
135 #endif //SIMULATION
136 };
137 
143  MeshIDTableRow() = default;
144 
145  MeshIDTableRow(uint8_t id, uint8_t source);
146 
150  uint8_t ID = 0;
154  uint8_t Source = 0;
155 
159  inline void clear(){
160  Source = 0;
161  ID = 0;
162  }
163 
169  static size_t printHeader(OSTREAM &stream);
170 
176  size_t printRow(OSTREAM &stream) const;
177 
178  bool operator==(const MeshIDTableRow& another) const {
179  return another.ID == ID && another.Source == Source;
180  }
181 
182 #ifdef SIMULATION
183  std::string printRowForChangeLog() const {
184  return std::to_string((int)ID) + "|" + std::to_string((int)Source);
185  }
186 #endif //SIMULATION
187 };
188 
194  MeshFIDTableRow() = default;
195 
196  MeshFIDTableRow(uint8_t id, uint8_t source, MeshMAC bssid);
197 
201  uint8_t ID = 0;
205  uint8_t Source = 0;
210 
214  inline void clear() {
215  Source = 0;
216  ID = 0;
217  BSSID = 0;
218  }
219 
225  static size_t printHeader(OSTREAM& stream);
226 
232  size_t printRow(OSTREAM& stream) const;
233 
234  bool operator==(const MeshFIDTableRow& another) const {
235  return another.ID == ID && another.Source == Source && another.BSSID == BSSID;
236  }
237 
238 #ifdef SIMULATION
239  std::string printRowForChangeLog() const {
240  return std::to_string((int)ID) + "|" + std::to_string((int)Source) + "|" + std::to_string(BSSID);
241  }
242 #endif //SIMULATION
243 };
244 
250  MeshOIDTableRow() = default;
251 
252  MeshOIDTableRow(uint8_t id, uint8_t destination, SystemPacketType type);
253 
257  uint8_t ID = 0;
261  uint8_t Destination = 0;
262 
267  SystemPacketType Type = SystemPacketType::SPT_DATA;
268 
272  inline void clear() {
274  Destination = 0;
275  ID = 0;
276  }
277 
283  static size_t printHeader(OSTREAM& stream);
284 
290  size_t printRow(OSTREAM& stream) const;
291 
292  bool operator==(const MeshOIDTableRow& another) const {
293  return another.ID == ID && another.Destination == Destination && another.Type == another.Type;
294  }
295 
296 #ifdef SIMULATION
297  std::string printRowForChangeLog() const {
298  return std::to_string((int)ID) + "|" + std::to_string((int)Destination) + "|" + std::to_string((int)Type);
299  }
300 #endif //SIMULATION
301 
302 };
303 
304 HAS_MEM_FUNC(printRowForChangeLog, has_printRowForChangeLog);
305 HAS_MEM_FUNC(printHeader, has_printHeader);
306 HAS_MEM_FUNC(printRow, has_printRow);
307 HAS_MEM_FUNC(clear, has_clear);
308 HAS_MEM_FUNC(operator==, has_equalityOperator);
309 
310 
350 template<typename RowT, int16_t RowsCount, bool IndexIsValue = false>
351 class MicroTable : public Printable
352 #ifdef SIMULATION
353  , public MSHelper
354 #endif //SIMULATION
355 {
356 public:
357 
358 #ifdef SIMULATION
359  static_assert(has_printRowForChangeLog<RowT, std::string(RowT::*)()const>::value || !std::is_class<RowT>::value, "RowT class does not have \"std::string printRowForChangeLog() const\" member function, which is needed when logging table change during simulation.");
360 #endif //SIMULATION
361 
362  static_assert(RowsCount != 0, "RowsCount has to be greather than 0.");
363  static_assert(has_printRow<RowT, size_t(RowT::*)(OSTREAM&) const>::value || !std::is_class<RowT>::value || IndexIsValue, "RowT class has to contain \"size_t printRow(OSTREAM& stream) const\" member function.");
364  static_assert(has_printRow<RowT, size_t(RowT::*)(OSTREAM&, int16_t) const>::value || !std::is_class<RowT>::value || !IndexIsValue, "RowT class has to contain \"size_t printRow(OSTREAM& stream, int16_t index) const\" member function.");
365 #ifdef SIMULATION
366  //TODO make this work also when simulation is not defined
367  static_assert(is_streamable<RowT>::value || std::is_class<RowT>::value, "Row type is not class and is not printable, it cannot be used.");
368 #endif //SIMULATION
369  static_assert(has_equalityOperator<RowT, bool(RowT::*)(const RowT&)const>::value, "RowT has to contain basic const binary equality operator ==.");
370 
375  MicroTable(const uint32_t rowLife) :
376  ValidationInterval(rowLife / 255),
377  RowLife(rowLife) //rowLife have to be divided to get validation interval
378  {
379  clear(); //clear buffer
380  }
381 
387  inline const RowT& get(int16_t index) const {
388  return buffer[index];
389  }
390 
396  inline RowT get(int16_t index) {
397  return buffer[index];
398  }
399 
405  const RowT& operator[](int16_t index) const {
406  return get(index);
407  }
408 
414  RowT operator[](int16_t index) {
415  return get(index);
416  }
417 
424  bool set(int16_t index, const RowT& row) {
425  if (index < RowsCount && index >= 0) {
426  if (lifeTime[index] == 0) {
427  usedBufferSize++; //Item added
428  if (realUsedSize <= index) {
429  realUsedSize = index + 1;
430  }
431  lifeTime[index] = 255;
432  onCreate(index, row, 255);
433  }
434  else {
435  uint8_t oldLifeTime = lifeTime[index];
436  lifeTime[index] = 255;
437  onSet(index, buffer[index], oldLifeTime, row, 255);
438  if (oldLifeTime != lifeTime[index]) {
439  onRowLifeChanged(index, oldLifeTime, lifeTime[index]);
440  }
441  }
442  buffer[index] = row;
443 
444 #ifdef SIMULATION
445  if constexpr (has_printRowForChangeLog<RowT, std::string(RowT::*)()const>::value) {
446  NotifyTableChangeBegin(MST_SET) << (int)index << "|" << buffer[index].printRowForChangeLog() << "|" << (int)lifeTime[index];
447  }
448  else {
449  NotifyTableChangeBegin(MST_SET) << (int)index << "|" << buffer[index] << "|" << (int)lifeTime[index];
450  }
451  NotifyTableChangeEnd();
452 #endif //SIMULATION
453  return true;
454  }
455  return false;
456  }
457 
465  bool set(int16_t index, const RowT& row, int16_t rawLifeTime_) {
466  if (index < RowsCount && index >= 0 && rawLifeTime_ <= 255) {
467  if (rawLifeTime_ < 0) rawLifeTime_ = lifeTime[index];
468  bool lastValid = lifeTime[index] != 0;
469 
470  if (lastValid != (rawLifeTime_ != 0)) {
471  if (lastValid) {
472  usedBufferSize--; //Item removed
473  if (usedBufferSize == 0) {
474  realUsedSize = 0;
475  }
476  else if (realUsedSize - 1 == index) {
477  for (; realUsedSize > 0 && isRowBlank(realUsedSize - 1); realUsedSize--);
478  }
479 
480  uint8_t oldLifeTime = lifeTime[index];
481  lifeTime[index] = 0;
482  onRemove(index, buffer[index], oldLifeTime);
483  onRowLifeChanged(index, oldLifeTime, 0);
484  }
485  else {
486  usedBufferSize++; //Item added
487  if (realUsedSize <= index) {
488  realUsedSize = index + 1;
489  }
490  lifeTime[index] = rawLifeTime_;
491  onCreate(index, row, rawLifeTime_);
492  }
493  }
494  else {
495  //Item set
496  uint8_t oldLifeTime = lifeTime[index];
497  lifeTime[index] = rawLifeTime_;
498  onSet(index, buffer[index], oldLifeTime, row, rawLifeTime_);
499  if (oldLifeTime != lifeTime[index]) {
500  onRowLifeChanged(index, oldLifeTime, rawLifeTime_);
501  }
502  }
503 
504  if (rawLifeTime_ == 0) {
505  //Clear
506  if constexpr (has_clear<RowT, void(RowT::*)()>::value) {
507  //Call clear method if exists
508  buffer[index].clear();
509  }
510  }
511  else {
512  buffer[index] = row;
513  }
514 #ifdef SIMULATION
515  if constexpr (has_printRowForChangeLog<RowT, std::string(RowT::*)()const>::value) {
516  NotifyTableChangeBegin(MST_SET) << (int)index << "|" << buffer[index].printRowForChangeLog() << "|" << (int)lifeTime[index];
517  }
518  else {
519  NotifyTableChangeBegin(MST_SET) << (int)index << "|" << buffer[index] << "|" << (int)lifeTime[index];
520  }
521  NotifyTableChangeEnd();
522 #endif //SIMULATION
523  return true;
524  }
525  return false;
526  }
527 
533  bool remove(const RowT& rowRef) {
534  int16_t index = getIndexOf(rowRef);
535  if (index >= 0) {
536  return remove(index);
537  }
538  return false;
539  }
540 
546  bool remove(int16_t index) {
547  if (index < realUsedSize && index >= 0) {
548  if (!isRowBlank(index)) {
549  usedBufferSize--; //Item removed
550  if (usedBufferSize == 0) {
551  realUsedSize = 0;
552  }
553  else if (realUsedSize - 1 == index) {
554  for (; realUsedSize > 0 && isRowBlank(realUsedSize - 1); realUsedSize--);
555  }
556 
557  uint8_t oldLifeTime = lifeTime[index];
558  lifeTime[index] = 0;
559  onRemove(index, buffer[index], oldLifeTime);
560  onRowLifeChanged(index, oldLifeTime, 0);
561  }
562 #ifdef SIMULATION
563  if constexpr (has_printRowForChangeLog<RowT, std::string(RowT::*)()const>::value) {
564  NotifyTableChangeBegin(MST_REMOVE) << (int)index << "|" << buffer[index].printRowForChangeLog() << "|" << (int)lifeTime[index];
565  }
566  else {
567  NotifyTableChangeBegin(MST_REMOVE) << (int)index << "|" << buffer[index] << "|" << (int)lifeTime[index];
568  }
569  NotifyTableChangeEnd();
570 #endif //SIMULATION
571 
572  //Clear
573  lifeTime[index] = 0;
574  if constexpr (has_clear<RowT, void(RowT::*)()>::value) {
575  //Call clear method if exists
576  buffer[index].clear();
577  }
578  return true;
579  }
580  return false;
581  }
582 
586  void clear() {
587 #ifdef SIMULATION
588  if (count() != 0) {
589  NotifyTableChangeBegin(MST_CLEAR);
590  NotifyTableChangeEnd();
591  }
592 #endif //SIMULATION
593  for (int16_t i = 0; i < RowsCount; i++) {
594  //Clear
595  lifeTime[i] = 0;
596  if constexpr (has_clear<RowT, void(RowT::*)()>::value) {
597  //Call clear method if exists
598  buffer[i].clear();
599  }
600  }
601  realUsedSize = 0;
602  usedBufferSize = 0;
603  onClear();
604  }
605 
611  void validate() {
612  uint32_t sysTime = millis();
613  if (usedBufferSize == 0) {
614  lastValidationTime = sysTime;
615  return;
616  }
617  uint32_t interval = (ValidationInterval == 0) ? 1 : ValidationInterval;
618  uint32_t mil = sysTime;
619  uint8_t step = (mil - lastValidationTime) / interval;
620  if (step > 0) {
621  for (int16_t i = 0; i < realUsedSize; i++) {
622  if (lifeTime[i] <= step) { //Life of row ended, so we need to remove it
623  //Row removing
624  if (lifeTime[i] != 0) {
625  usedBufferSize--; //Item removed
626 
627  if (usedBufferSize == 0) {
628  realUsedSize = 0;
629  }
630  else if (realUsedSize - 1 == i) {
631  for (; realUsedSize > 0 && isRowBlank(realUsedSize - 1); realUsedSize--);
632  }
633 
634  uint8_t oldLifeTime = lifeTime[i];
635  lifeTime[i] = 0;
636  onRemove(i, buffer[i], oldLifeTime, true);
637  onRowLifeChanged(i, oldLifeTime, 0);
638 
639  if constexpr (has_clear<RowT, void(RowT::*)()>::value) {
640  //Call clear method if exists
641  buffer[i].clear();
642  }
643 #ifdef SIMULATION
644  if constexpr (has_printRowForChangeLog<RowT, std::string(RowT::*)()const>::value) {
645  NotifyTableChangeBegin(MST_REMOVE_VLD) << (int)i << "|" << buffer[i].printRowForChangeLog() << "|" << (int)lifeTime[i];
646  }
647  else {
648  NotifyTableChangeBegin(MST_REMOVE_VLD) << (int)i << "|" << buffer[i] << "|" << (int)lifeTime[i];
649  }
650  NotifyTableChangeEnd();
651 #endif //SIMULATION
652  }
653  }
654  else {
655  lifeTime[i] -= step;
656  if (step > 0) {
657  onRowLifeChanged(i, lifeTime[i] + step, lifeTime[i]);
658  }
659  }
660  }
661 
662  //lastValidation set and correction (lastValidation has to be increased by multiples of the interval value, when table is not empty)
663  lastValidationTime += step * interval;
664  }
665  }
666 
673  bool setRawRemainingLifeTime(int16_t index, uint8_t rawLifeTime_ = 255) {
674  if (index < realUsedSize && index >= 0 && !isRowBlank(index) && rawLifeTime_ > 0) {
675  uint8_t old = lifeTime[index];
676  lifeTime[index] = rawLifeTime_;
677  if (old != rawLifeTime_) {
678  onRowLifeChanged(index, old, rawLifeTime_);
679  }
680 #ifdef SIMULATION
681  NotifyTableChangeBegin(MST_PROLONG) << (int)index << "|" << (int)lifeTime[index];
682  NotifyTableChangeEnd();
683 #endif //SIMULATION
684  return true;
685  }
686  return false;
687  }
688 
694  virtual int16_t getIndexOf(const RowT& rowRef) const {
695  for (int16_t i = 0; i < realUsedSize; i++) {
696  if (rowRef == buffer[i] && lifeTime[i] != 0) {
697  return i;
698  }
699  }
700  return -1;
701  }
702 
708  int16_t getFirstBlankRowIndex(int16_t startPos = 0) const {
709  if (count() == RowsCount || startPos >= RowsCount) return -1;
710  if (startPos >= getRealUsedSize()) return startPos;
711  if (!IndexIsValue && count() == getRealUsedSize()) return count();
712  int16_t i = startPos;
713  for (; i < RowsCount && lifeTime[i] != 0; i++);
714  return i;
715  }
716 
721  int16_t getOldestRowIndex() const {
722  uint8_t oldestLifeTime = 255;
723  int16_t index = -1;
724  for (int16_t i = 0; i < realUsedSize; i++) {
725  if (lifeTime[i] != 0) {
726  if (oldestLifeTime > lifeTime[i]) {
727  index = i;
728  oldestLifeTime = lifeTime[i];
729  }
730  }
731  }
732  return index;
733  }
734 
740  inline bool exists(int16_t index) const {
741  return !isRowBlank(index);
742  }
743 
749  bool exists(const RowT& rowRef) const {
750  return getIndexOf(rowRef) >= 0;
751  }
752 
758  inline bool isRowBlank(int16_t index) const {
759  return index < 0 || index >= realUsedSize || lifeTime[index] == 0;
760  }
761 
766  inline int16_t size() const {
767  return RowsCount;
768  }
769 
774  inline int16_t count() const {
775  return usedBufferSize;
776  }
777 
782  inline uint8_t getMaxRowLifeTime() const {
783  return RowLife;
784  }
785 
790  inline int16_t getRealUsedSize() const {
791  return realUsedSize;
792  }
793 
798  template <class = typename std::enable_if<!IndexIsValue>::type> uint8_t getFragmentation() const{
799  if (getRealUsedSize() > 0) {
800  return ((uint32_t)(getRealUsedSize() - count()) * 100UL) / getRealUsedSize();
801  }
802  else return 0;
803  }
804 
808  template <class = typename std::enable_if<!IndexIsValue>::type> void defragment() {
809  if (usedBufferSize == 0) return;
810  int16_t writePos = 0;
811  //Note: readPos has to be still higher than writePos.
812  //Note 2: readPos can start from index 1, because first row cannot be moved.
813 
814  for (int16_t readPos = 1; readPos < realUsedSize; readPos++) { //Iterate through all rows
815  if (lifeTime[readPos] != 0) { //Item was found
816  for (; writePos < readPos && lifeTime[writePos] != 0; writePos++); //Trying to find blank row below readPos
817  if (lifeTime[writePos] == 0) { //Blank row was found, so move row from readPos to this row (at writePos)
818  buffer[writePos] = buffer[readPos];
819  lifeTime[writePos] = lifeTime[readPos];
820 
821  //Clear
822  lifeTime[readPos] = 0;
823 
824  if constexpr (has_clear<RowT, void(RowT::*)()>::value) {
825  //Call clear method if exists
826  buffer[readPos].clear();
827  }
828  }
829  }
830  }
832 #ifdef SIMULATION
833  NotifyTableChangeBegin(MST_DEFRAG);
834  NotifyTableChangeEnd();
835 #endif // SIMULATION
836  }
837 
843  uint32_t getRowRemainingLifeTime(int16_t index) const {
844  if (index < realUsedSize && index >= 0 && !isRowBlank(index)) {
845  uint32_t rawVal = lifeTime[index] * ValidationInterval;
846  uint32_t timeDifference = (millis() - lastValidationTime);
847  if (rawVal <= timeDifference) {
848  //remove(index); //Remove invalid row
849  return 0;
850  }
851  else {
852  return rawVal - timeDifference;
853  }
854  }
855  return 0;
856  }
857 
863  uint8_t getRawRowRemainingLifeTime(int16_t index) const {
864  if (index < realUsedSize && index >= 0) {
865  return lifeTime[index];
866  }
867  return 0;
868  }
869 
873  inline uint32_t getLifeTimeResolution() const {
874  return ValidationInterval;
875  }
876 
882  inline uint8_t convertLifeTimeToRaw(uint32_t lifeTime) const {
883  uint32_t value = lifeTime / ValidationInterval + (lifeTime % ValidationInterval > 0);
884  return ((value > 255) ? 255 : value);
885  }
886 
893  inline uint32_t convertRawToLifeTime(uint8_t rawLifeTime) const {
894  return rawLifeTime * ValidationInterval;
895  }
896 
901  virtual size_t getRawDataSize() const{
902  return 20 + (size_t)usedBufferSize * (sizeof(RowT) + 3);
903  }
904 
929  virtual size_t printRaw(OSTREAM& stream, const char tableIdentifier[4]) const {
930  crc.begin();
931  crc.setInputReverse(true);
932  crc.setOutputReverse(true);
933  crc.setPolynomial32();
934  crc.reset(0xFFFFFFFFUL);
935 
936  size_t ret = 0;
937  ret = stream.print(tableIdentifier);
938  ret = stream.print(':');
939  union WTB {
940  uint32_t word;
941  uint8_t buffer[4];
942  };
943 
944  int16_t row_cnt = RowsCount;
945  ret += stream.write((uint8_t*)&row_cnt, 2);
946  crc.append((uint8_t*)&row_cnt, 2);
947 
948  ret += stream.write((uint8_t*)&RowLife, 4);
949  crc.append((uint8_t*)&RowLife, 4);
950 
951  WTB elapsedTimeFromLastValidation;
952  elapsedTimeFromLastValidation.word = millis() - lastValidationTime;
953  ret += stream.write(elapsedTimeFromLastValidation.buffer, 4);
954  crc.append(elapsedTimeFromLastValidation.buffer, 4);
955 
956  ret += stream.write((uint8_t*)&usedBufferSize, 2);
957  crc.append((uint8_t*)&usedBufferSize, 2);
958 
959  uint16_t sentCnt = 0;
960  for (uint16_t i = 0; i < realUsedSize; i++) { //Printing all used rows
961  if (!isRowBlank(i)) { //which are not blank
962  ret += stream.write((uint8_t*)&i, 2); //Index
963  crc.append((uint8_t*)&i, 2); //Index
964 
965  ret += stream.write((uint8_t*)&buffer[i], sizeof(RowT)); //Value
966  crc.append((uint8_t*)&buffer[i], sizeof(RowT)); //Value
967 
968  ret += stream.write(lifeTime[i]); //Raw life time
969  crc.append(lifeTime[i]); //Raw life time
970 
971  sentCnt++;
972  if (sentCnt >= usedBufferSize) {
973  break;
974  }
975  }
976  }
977 
978  uint32_t CRC_val = crc.getLastCRC(0xFFFFFFFFUL);
979  ret += stream.write((uint8_t*)&CRC_val, 4); //Append CRC-32 at the end of message
980 
981  crc.end();
982 
983  return ret;
984  }
985 
994  size_t print(OSTREAM& stream, bool showIndexes = true, bool doNotPrintBlank = true, bool showRemainingRowLifetime = true) const {
995  size_t ret = 0;
996  if (showIndexes) ret += stream.print("Index|");
997  if constexpr (has_printHeader<RowT, size_t(*)(OSTREAM&)>::value) { //RowT contains printHeader static function
998  ret += RowT::printHeader(stream);
999  }
1000  else {
1001  ret += stream.print("Value");
1002  }
1003  if (showRemainingRowLifetime) ret += stream.print("|Remaining life time");
1004 
1005  size_t dashCnt = ret;
1006  ret += stream.println();
1007  for(size_t i = 0; i < dashCnt; i++) ret += stream.print('-');
1008  ret += stream.println();
1009 
1010  if (usedBufferSize == 0) {
1011  ret += stream.println("Empty");
1012  }
1013  else {
1014  for (uint8_t i = 0; i < realUsedSize; i++) {
1015  if (!(doNotPrintBlank && lifeTime[i] == 0)) {
1016  if (showIndexes) { //Index
1017  char txtBuffer[10] = { 0 };
1018  ITOA(i, txtBuffer, sizeof(txtBuffer) / sizeof(char), 10);
1019  alignText(txtBuffer, 5, ' ', T_LEFT);
1020  ret += stream.print(txtBuffer);
1021  ret += stream.print('|');
1022  }
1023  if constexpr (has_printRow<RowT, size_t(RowT::*)(OSTREAM&) const>::value && !IndexIsValue) { //printRow member function found
1024  ret += buffer[i].printRow(stream);
1025  }
1026  else if constexpr (has_printRow<RowT, size_t(RowT::*)(OSTREAM&, int16_t) const>::value && IndexIsValue) { //printRow member function found
1027  ret += buffer[i].printRow(stream, i);
1028  }
1029  else {
1030  ret += stream.print(buffer[i]);
1031  }
1032  if (showRemainingRowLifetime) { //Life time
1033  ret += stream.print('|');
1034  uint32_t remLifeTime = getRowRemainingLifeTime(i)/1000UL;
1035  char txtBuffer[3] = { 0 };
1036  ret += stream.print(" ");
1037  uint8_t sec = remLifeTime % 60;
1038  remLifeTime /= 60;
1039  uint8_t min = remLifeTime % 60;
1040  remLifeTime /= 60;
1041  uint8_t hrs = remLifeTime % 24;
1042  remLifeTime /= 24;
1043 
1044  //Days
1045  ITOA(remLifeTime, txtBuffer, sizeof(txtBuffer) / sizeof(char), 10);
1046  alignText(txtBuffer, 2, '0', T_RIGHT);
1047  ret += stream.print(txtBuffer);
1048  ret += stream.print("d ");
1049 
1050  //Hours
1051  ITOA(hrs, txtBuffer, sizeof(txtBuffer) / sizeof(char), 10);
1052  alignText(txtBuffer, 2, '0', T_RIGHT);
1053  ret += stream.print(txtBuffer);
1054  ret += stream.print(':');
1055 
1056  //Minutes
1057  ITOA(min, txtBuffer, sizeof(txtBuffer) / sizeof(char), 10);
1058  alignText(txtBuffer, 2, '0', T_RIGHT);
1059  ret += stream.print(txtBuffer);
1060  ret += stream.print(':');
1061 
1062  //Seconds
1063  ITOA(sec, txtBuffer, sizeof(txtBuffer) / sizeof(char), 10);
1064  alignText(txtBuffer, 2, '0', T_RIGHT);
1065  ret += stream.print(txtBuffer);
1066 
1067  // xxd hh:mm:ss
1068  ret += stream.print(" ");
1069  }
1070  ret += stream.println();
1071  }
1072  }
1073  }
1074  return ret;
1075  }
1076 
1082  size_t printTo(Print& p) const override
1083  {
1084  return print(p);
1085  }
1086 
1087 protected:
1088 
1096  virtual void onCreate(int16_t index, const RowT& newValue, uint8_t newRawLifeTime) {}
1097 
1107  virtual void onSet(int16_t index, const RowT& oldValue, uint8_t oldRawLifeTime, const RowT& newValue, uint8_t newRawLifeTime) {}
1108 
1117  virtual void onRemove(int16_t index, const RowT& oldValue, uint8_t oldRawLifeTime, bool removedByValidation = false) {}
1118 
1123  virtual void onClear() {}
1124 
1132  virtual void onRowLifeChanged(int16_t index, uint8_t old_raw, uint8_t new_raw) {}
1133 
1134 
1135  RowT buffer[RowsCount];
1136  uint8_t lifeTime[RowsCount];
1137 
1138  uint32_t lastValidationTime = 0;
1139  int16_t usedBufferSize = 0;
1140  int16_t realUsedSize = 0;
1141  const uint32_t ValidationInterval = 0; //Validation interval in ms
1142  const uint32_t RowLife = 0; //Maximum row life time in ms
1143 };
1144 
1145 
1167 template <int16_t BufferSize>
1169  public MicroTable<MeshMACTableRow, BufferSize>
1170 {
1171 public:
1176  MeshMACTable(const uint32_t rowLife) :
1177  MicroTable<MeshMACTableRow, BufferSize>(rowLife)
1178  {
1179  }
1180 
1188  bool set(uint8_t address, MeshMAC MAC, int16_t valid = -1) {
1189  return MicroTable<MeshMACTableRow, BufferSize>::set((int16_t)address, MeshMACTableRow(MAC), valid);
1190  }
1191 
1199  int16_t add(MeshMAC mac, bool isGateway = false) {
1200  int16_t index = getFreeAddress((isGateway) ? 0 : (MESH_GATEWAY_MAX_ADDRESS + 1));
1201  if (index >= 0) {
1202  //Free address was found
1203  return MicroTable<MeshMACTableRow, BufferSize>::set(index, MeshMACTableRow(mac), 255) ? index : -1;
1204  }
1205  else {
1206  return -1;
1207  }
1208  }
1209 
1229  int16_t getAddressFromMAC(MeshMAC mac, int16_t startPos = 0) const{
1230  if (startPos < 0) return false;
1231  for (int16_t i = startPos; i < MicroTable<MeshMACTableRow, BufferSize>::realUsedSize; i++) {
1233  return i;
1234  }
1235  }
1236  return -1;
1237  }
1238 
1246  MeshMAC getMACFromAddress(uint8_t address) const{
1247  if (MicroTable<MeshMACTableRow, BufferSize>::exists((int16_t)address)) {
1248  return MicroTable<MeshMACTableRow, BufferSize>::get((int16_t)address); //Valid address from table
1249  }
1250  else {
1251  return MeshMAC(); //Invalid mesh MAC address
1252  }
1253  }
1254 
1258  inline bool addressExists(uint8_t address) const {
1259  return MicroTable<MeshMACTableRow, BufferSize>::exists((int16_t)address);
1260  }
1261 
1265  inline bool MACExists(MeshMAC mac) const {
1267  }
1268 
1274  int16_t getFreeAddress(uint8_t startFrom = MESH_GATEWAY_MAX_ADDRESS + 1) {
1276  }
1277 
1291  inline void setValidityChangeCallback(void(*callback)(MeshMACTable<BufferSize>*, int16_t, const MeshMACTableRow&, bool, bool)) {
1292  onValidityChangeCallback = callback;
1293  }
1294 
1295 protected:
1296 
1297  void onRowLifeChanged(int16_t index, uint8_t old_raw, uint8_t new_raw) override {
1298  bool valid = new_raw > DHCPTABLE_ROW_RAW_LIFETIME_RESERVED;
1299  bool removed = new_raw == 0;
1300  bool old_valid = old_raw > DHCPTABLE_ROW_RAW_LIFETIME_RESERVED;
1301  bool old_removed = old_raw == 0;
1302  if (onValidityChangeCallback != NULL && (valid != old_valid || removed != old_removed)) {
1303  onValidityChangeCallback(this, index, MicroTable<MeshMACTableRow, BufferSize>::buffer[index], valid, removed);
1304  }
1305 
1306  }
1307 
1308  void(*onValidityChangeCallback)(MeshMACTable<BufferSize>*, int16_t, const MeshMACTableRow&, bool, bool) = NULL;
1309 };
1310 
1311 
1328 template <int16_t BufferSize>
1330  public MicroTable<MeshRouteTableRow, BufferSize>
1331 {
1332 public:
1333 
1338  MeshRouteTable(const uint32_t rowLife) :
1339  MicroTable<MeshRouteTableRow, BufferSize>(rowLife)
1340  {
1341  }
1342 
1355  bool set(int16_t index, uint8_t source, uint8_t neighbor, uint8_t hop, int16_t valid = -1) {
1356  return MicroTable<MeshRouteTableRow, BufferSize>::set(index, MeshRouteTableRow(source, neighbor, hop), valid);
1357  }
1358 
1370  int16_t set(uint8_t source, uint8_t neighbor, uint8_t hop, int16_t valid = -1) {
1371  int16_t index = getIndexOfSource(source);
1372  if (index >= 0) {
1373  return MicroTable<MeshRouteTableRow, BufferSize>::set(index, MeshRouteTableRow(source, neighbor, hop), valid) ? index : -1;
1374  }
1375  else {
1376  //Searching first blank row
1378  if (index >= 0) {
1379  return MicroTable<MeshRouteTableRow, BufferSize>::set(index, MeshRouteTableRow(source, neighbor, hop), valid) ? index : -1;
1380  }
1381  return -1;
1382  }
1383  }
1384 
1394  int16_t set(const MeshRouteTableRow& row, int16_t valid = -1) {
1395  int16_t index = getIndexOfSource(row.Source);
1396  if (index >= 0) {
1397  return MicroTable<MeshRouteTableRow, BufferSize>::set(index, row, valid) ? index : -1;
1398  }
1399  else {
1400  //Searching first blank row
1402  if (index >= 0) {
1403  return MicroTable<MeshRouteTableRow, BufferSize>::set(index, row, valid) ? index : -1;
1404  }
1405  return -1;
1406  }
1407  }
1408 
1418  inline bool add(uint8_t source, uint8_t neighbor, uint8_t hop) {
1419  return add(MeshRouteTableRow(source, neighbor, hop));
1420  }
1421 
1431  bool add(const MeshRouteTableRow& val) {
1432  int16_t index = getIndexOfSource(val.Source);
1433  if (index >= 0) { //Row with same source was found
1434  //TODO do not check only hops, but also metric
1435  //Path with better metric found
1437  return MicroTable<MeshRouteTableRow, BufferSize>::set(index, val, 255);
1438  }
1439  if (MicroTable<MeshRouteTableRow, BufferSize>::buffer[index].Neighbor == val.Neighbor && val.isDirectNeighbor()) { //Neighbor
1441  MicroTable<MeshRouteTableRow, BufferSize>::setRawRemainingLifeTime(index, 255); //We have received some message from neighbor, we need to prolong it's life time
1442  return true;
1443  }
1444  }
1445  else {
1446  //Creating new row
1447  //Searching first blank row
1449  if (index >= 0) {
1450  return MicroTable<MeshRouteTableRow, BufferSize>::set(index, val, 255);
1451  }
1452  //Buffer is full, so we need to overwrite the oldest row which is not gateway.
1453  index = getOldestRowIndexNotGW();
1454  if (index >= 0) {
1455  return MicroTable<MeshRouteTableRow, BufferSize>::set(index, val, 255);
1456  }
1457  }
1458  return false;
1459  }
1460 
1461  void operator += (const MeshRouteTableRow& val) {
1462  add(val);
1463  }
1464 
1470  bool removeBySource(uint8_t source) {
1471  int16_t index = getIndexOfSource(source);
1473  }
1474 
1481  int16_t removeByNeighbor(uint8_t neighbor) {
1482  int16_t removedCnt = 0;
1483  for (int16_t i = 0; i < MicroTable<MeshRouteTableRow, BufferSize>::realUsedSize; i++) {
1484  if (MicroTable<MeshRouteTableRow, BufferSize>::buffer[i].Neighbor == neighbor) {
1486  }
1487  }
1488  return removedCnt;
1489  }
1490 
1497  int16_t removeByAddress(uint8_t address) {
1498  int16_t removedCnt = 0;
1499  for (int16_t i = 0; i < MicroTable<MeshRouteTableRow, BufferSize>::realUsedSize; i++) {
1502  }
1503  }
1504  return removedCnt;
1505  }
1506 
1512  inline bool isRowDirectNeighbor(int16_t index) const{
1514  }
1515 
1521  bool sourceExists(uint8_t source) const {
1523  for (int16_t i = 0; i < MicroTable<MeshRouteTableRow, BufferSize>::realUsedSize; i++) {
1525  return true;
1526  }
1527  }
1528  return false;
1529  }
1530 
1536  bool neighborExists(uint8_t neighbor) const{
1538  for (int16_t i = 0; i < MicroTable<MeshRouteTableRow, BufferSize>::realUsedSize; i++) {
1540  return true;
1541  }
1542  }
1543  return false;
1544  }
1545 
1552  int16_t getIndexOfSource(uint8_t source) const {
1553  for (int16_t i = 0; i < MicroTable<MeshRouteTableRow, BufferSize>::realUsedSize; i++) {
1555  return i;
1556  }
1557  }
1558  return -1;
1559  }
1560 
1566  int16_t getNeighborFromSource(int8_t source) const{
1567  int16_t index = getIndexOfSource(source);
1568  if (index >= 0) {
1570  }
1571  else {
1572  return -1;
1573  }
1574  }
1575 
1581  inline uint8_t getDirectNeighborCount() const{
1582  return directNeighborCount;
1583  }
1584 
1595  inline void setNewCallback(void(*callback)(MeshRouteTable<BufferSize>*, int16_t, const MeshRouteTableRow&, uint8_t)) {
1596  onNewCallback = callback;
1597  }
1598 
1599 protected:
1600 
1608  void onCreate(int16_t index, const MeshRouteTableRow& newValue, uint8_t newRawLifeTime) override {
1609  if (newValue.isDirectNeighbor()) {
1611  }
1612  if (onNewCallback != NULL) {
1613  onNewCallback(this, index, newValue, newRawLifeTime);
1614  }
1615  }
1616 
1626  /*void onSet(int16_t index, const MeshRouteTableRow& oldValue, uint8_t oldRawLifeTime, const MeshRouteTableRow& newValue, uint8_t newRawLifeTime) override {
1627 
1628  }*/
1629 
1637  void onRemove(int16_t index, const MeshRouteTableRow& oldValue, uint8_t oldRawLifeTime, bool removedByValidation = false) override {
1638  if (oldValue.isDirectNeighbor()) {
1640  }
1641  }
1642 
1647  void onClear() override {
1648  directNeighborCount = 0;
1649  }
1650 
1655  int16_t getOldestRowIndexNotGW() const {
1656  uint8_t oldestLifeTime = 255;
1657  int16_t index = -1;
1658  for (int16_t i = 0; i < MicroTable<MeshRouteTableRow, BufferSize>::realUsedSize; i++) {
1660  if (oldestLifeTime > MicroTable<MeshRouteTableRow, BufferSize>::lifeTime[i]) {
1661  index = i;
1663  }
1664  }
1665  }
1666  return index;
1667  }
1668 
1669  uint8_t directNeighborCount = 0;
1670  void(*onNewCallback)(MeshRouteTable<BufferSize>*, int16_t, const MeshRouteTableRow&, uint8_t) = NULL;
1671 };
1672 
1673 
1690 template <int16_t BufferSize>
1692  public MicroTable<MeshIDTableRow, BufferSize>
1693 {
1694 
1695 public:
1696 
1701  MeshIDTable(const uint32_t rowLife) :
1702  MicroTable< MeshIDTableRow, BufferSize>(rowLife)
1703  {
1704  }
1705 
1714  bool set(uint16_t index, uint8_t id, uint8_t source, int16_t valid = -1) {
1715  return MicroTable< MeshIDTableRow, BufferSize>::set(index, MeshIDTableRow(id, source), valid);
1716  }
1717 
1725  bool add(uint8_t id, uint8_t source) {
1726  int16_t index = getIndexOfIDAndSource(id, source); //Searching, if same row does not exists yet
1727  if (index >= 0) {
1728  return set(index, id, source, 255);
1729  }
1730  else {
1731  //Creating new row, because it does not exists
1733  if (index >= 0) {
1734  return set(index, id, source, 255);
1735  }
1736  //Buffer is full, so we need to overwrite the oldest row.
1738  return set(index, id, source, 255);
1739  }
1740  }
1741 
1748  inline bool add(const MeshIDTableRow& val) {
1749  return add(val.ID, val.Source);
1750  }
1751 
1752  void operator += (const MeshIDTableRow& val) {
1753  add(val);
1754  }
1755 
1762  bool removeByIDAndSource(uint8_t ID, uint8_t source) {
1763  int16_t index = getIndexOfIDAndSource(ID, source);
1764  if(index >= 0){
1766  }
1767  return false;
1768  }
1769 
1776  int16_t getIndexOfIDAndSource(uint8_t id, uint8_t source) const{
1778  }
1779 
1786  bool exists(uint8_t id, uint8_t source) const{
1788  }
1789 
1790 };
1791 
1808 template <int16_t BufferSize>
1810  public MicroTable<MeshFIDTableRow, BufferSize>
1811 {
1812 
1813 public:
1814 
1819  MeshFIDTable(const uint32_t rowLife) :
1820  MicroTable< MeshFIDTableRow, BufferSize>(rowLife)
1821  {
1822  }
1823 
1833  bool set(uint16_t index, uint8_t id, uint8_t source, MeshMAC bssid, int16_t valid = -1) {
1834  return MicroTable< MeshFIDTableRow, BufferSize>::set(index, MeshFIDTableRow(id, source, bssid), valid);
1835  }
1836 
1845  bool add(uint8_t id, uint8_t source, MeshMAC bssid) {
1846  int16_t index = getIndexOfIDSourceAndBSSID(id, source, bssid); //Searching, if same row does not exists yet
1847  if (index >= 0) {
1848  return set(index, id, source, bssid, 255);
1849  }
1850  else {
1851  //Creating new row, because it does not exists
1853  if (index >= 0) {
1854  return set(index, id, source, bssid, 255);
1855  }
1856  //Buffer is full, so we need to overwrite the oldest row.
1858  return set(index, id, source, bssid, 255);
1859  }
1860  }
1861 
1868  inline bool add(const MeshFIDTableRow& val) {
1869  return add(val.ID, val.Source, val.BSSID);
1870  }
1871 
1872  void operator += (const MeshFIDTableRow& val) {
1873  add(val);
1874  }
1875 
1883  bool removeByIDSourceAndBSSID(uint8_t ID, uint8_t source, MeshMAC bssid) {
1884  int16_t index = getIndexOfIDSourceAndBSSID(ID, source, bssid);
1885  if (index >= 0) {
1887  }
1888  return false;
1889  }
1890 
1898  int16_t getIndexOfIDSourceAndBSSID(uint8_t id, uint8_t source, MeshMAC bssid) const {
1900  }
1901 
1909  bool exists(uint8_t id, uint8_t source, MeshMAC bssid) const {
1911  }
1912 
1913 };
1914 
1915 
1916 typedef enum {
1917  OIDTR_Removed, //Removed by calling any remove method or calling set method with 0 raw life time
1918  OIDTR_Set, //Removed by calling set or add method, data was overwritten. OIDTR_Set is also when MeshOIDTable is full and old item was overwritten.
1919  OIDTR_Validation, //Removed by validation.
1921 
1940 template <int16_t BufferSize>
1942  public MicroTable<MeshOIDTableRow, BufferSize>
1943 {
1944 public:
1945 
1950  MeshOIDTable(const uint32_t rowLife) :
1951  MicroTable<MeshOIDTableRow, BufferSize>(rowLife)
1952  {
1953 
1954  }
1955 
1965  bool set(uint8_t index, uint8_t id, uint8_t destination, SystemPacketType type, int16_t valid = -1) {
1966  return MicroTable<MeshOIDTableRow, BufferSize>::set(index, MeshOIDTableRow(id, destination, type), valid);
1967  }
1968 
1978  bool add(uint8_t id, uint8_t destination, SystemPacketType type, uint8_t rawLifeTime = 255) {
1979  int16_t index = getIndexOfID(id); //Searching, if same row does not exists yet
1980  if (index >= 0) {
1981  return set(index, id, destination, type, rawLifeTime);
1982  }
1983  else {
1984  //Creating new row, because it does not exists
1986  if (index >= 0) {
1987  return set(index, id, destination, type, rawLifeTime);
1988  }
1989  //Buffer is full, so we need to overwrite the oldest row.
1991  return set(index, id, destination, type, rawLifeTime);
1992  }
1993  }
1994 
2002  inline bool add(const MeshOIDTableRow& val, uint8_t rawLifeTime = 255) {
2003  return add(val.ID, val.Destination, val.Type);
2004  }
2005 
2011  bool removeID(uint8_t ID) {
2012  int16_t index = getIndexOfID(ID);
2013  if (index >= 0) {
2015  }
2016  return false;
2017  }
2018 
2024  int16_t removeByDestination(uint8_t destination) {
2025  int16_t cnt = 0;
2026  for (int16_t i = MicroTable<MeshOIDTableRow, BufferSize>::realUsedSize - 1; i >= 0; i--) {
2029  }
2030  }
2031  return cnt;
2032  }
2033 
2039  int16_t getIndexOfID(uint8_t id) const {
2040  for (int16_t i = 0; i < MicroTable<MeshOIDTableRow, BufferSize>::realUsedSize; i++) {
2042  return i;
2043  }
2044  }
2045  return -1;
2046  }
2047 
2048 
2054  bool existsID(uint8_t id) const {
2055  for (int16_t i = 0; i < MicroTable<MeshOIDTableRow, BufferSize>::realUsedSize; i++) {
2057  return true;
2058  }
2059  }
2060  return false;
2061  }
2062 
2069  bool existsDestAndSysPacketType(uint8_t destination, SystemPacketType type) const {
2070  for (int16_t i = 0; i < MicroTable<MeshOIDTableRow, BufferSize>::realUsedSize; i++) {
2071  if (MicroTable<MeshOIDTableRow, BufferSize>::buffer[i].Destination == destination
2074  return true;
2075  }
2076  }
2077  return false;
2078  }
2079 
2091  inline void setOnRemoveCallback(void(*callback)(MeshOIDTable<BufferSize>*, int16_t, const MeshOIDTableRow&, uint8_t, MeshOIDTableRemoveReason)) {
2092  onRemoveCallback = callback;
2093  }
2094 
2095 protected:
2105  void onSet(int16_t index, const MeshOIDTableRow& oldValue, uint8_t oldRawLifeTime, const MeshOIDTableRow& newValue, uint8_t newRawLifeTime) override {
2106  if (onRemoveCallback != NULL && oldValue.ID != newValue.ID) {
2107  onRemoveCallback(this, index, oldValue, oldRawLifeTime, OIDTR_Set);
2108  }
2109  }
2110 
2118  void onRemove(int16_t index, const MeshOIDTableRow& oldValue, uint8_t oldRawLifeTime, bool removedByValidation = false) override {
2119  if (onRemoveCallback != NULL) {
2120  onRemoveCallback(this, index, oldValue, oldRawLifeTime, ((removedByValidation)?OIDTR_Validation:OIDTR_Removed));
2121  }
2122  }
2123 
2124  void(*onRemoveCallback)(MeshOIDTable<BufferSize>*, int16_t, const MeshOIDTableRow&, uint8_t, MeshOIDTableRemoveReason) = NULL;
2125 };
2126 
2127 
2128 
2129 
2130 #endif /* INC_MESHTABLES_H_ */
MicroTable::ValidationInterval
const uint32_t ValidationInterval
Definition: meshTables.h:1141
MeshOIDTableRow::Type
SystemPacketType Type
Type of system message.
Definition: meshTables.h:267
MeshRouteTable::onCreate
void onCreate(int16_t index, const MeshRouteTableRow &newValue, uint8_t newRawLifeTime) override
This method is called when valid row is set to blank space. It is called after count calculation is d...
Definition: meshTables.h:1608
MeshMACTable
Mesh MAC table, is lookup table for node address and MAC address. It acts as DHCP table....
Definition: meshTables.h:1168
MicroTable::printRaw
virtual size_t printRaw(OSTREAM &stream, const char tableIdentifier[4]) const
Prints raw table data through stream. Those data can be decoded in PC or in another MCU.
Definition: meshTables.h:929
MeshOIDTableRow::Destination
uint8_t Destination
Message destination. If set to UNKNOWN_MESH_ADDRESS (253), no destination is specified.
Definition: meshTables.h:261
MicroTable::convertLifeTimeToRaw
uint8_t convertLifeTimeToRaw(uint32_t lifeTime) const
Converts life time in milliseconds to raw life time value. Value is rounded up.
Definition: meshTables.h:882
MeshOIDTable::add
bool add(uint8_t id, uint8_t destination, SystemPacketType type, uint8_t rawLifeTime=255)
Adds or overwrites data in row. If row already exists, it will be overwritten, else new row is added....
Definition: meshTables.h:1978
ITOA
#define ITOA
Definition: meshConfig.h:17
MeshOIDTable::existsDestAndSysPacketType
bool existsDestAndSysPacketType(uint8_t destination, SystemPacketType type) const
Checks if row with specified destination address and system packet type exists.
Definition: meshTables.h:2069
MeshMACTableRow::MAC
MeshMAC MAC
MAC address.
Definition: meshTables.h:32
MicroTable::operator[]
const RowT & operator[](int16_t index) const
Gets row from table by index.
Definition: meshTables.h:405
MeshRouteTable
Mesh route table contains all known routes. Source address column value has to be unique....
Definition: meshTables.h:1329
MicroTable::count
int16_t count() const
Gets number of used rows in buffer.
Definition: meshTables.h:774
MeshFIDTableRow
Structure, that acts as one row in MeshFIDTable.
Definition: meshTables.h:193
MicroTable::getRawDataSize
virtual size_t getRawDataSize() const
Calculates, how many bytes will be printed, when using command printRaw.
Definition: meshTables.h:901
MeshFIDTable::getIndexOfIDSourceAndBSSID
int16_t getIndexOfIDSourceAndBSSID(uint8_t id, uint8_t source, MeshMAC bssid) const
Gets index of row with specified ID and Source in table.
Definition: meshTables.h:1898
MeshRouteTable::set
bool set(int16_t index, uint8_t source, uint8_t neighbor, uint8_t hop, int16_t valid=-1)
Sets row values in table.
Definition: meshTables.h:1355
T_RIGHT
@ T_RIGHT
Definition: meshHelper.h:118
MeshIDTable::set
bool set(uint16_t index, uint8_t id, uint8_t source, int16_t valid=-1)
Sets row values in table.
Definition: meshTables.h:1714
MeshOIDTableRow
Structure, that contains one row with data from out ID table.
Definition: meshTables.h:249
MicroTable::onRowLifeChanged
virtual void onRowLifeChanged(int16_t index, uint8_t old_raw, uint8_t new_raw)
This method is called when table is cleared. It is called after cleaning is done, so all variables ar...
Definition: meshTables.h:1132
MicroTable::remove
bool remove(const RowT &rowRef)
Removes first row, which is equal to rowRef.
Definition: meshTables.h:533
MeshOIDTable::onSet
void onSet(int16_t index, const MeshOIDTableRow &oldValue, uint8_t oldRawLifeTime, const MeshOIDTableRow &newValue, uint8_t newRawLifeTime) override
This method is called when valid row is set to new value. It is called after count calculation is don...
Definition: meshTables.h:2105
MeshRouteTable::directNeighborCount
uint8_t directNeighborCount
Definition: meshTables.h:1669
MeshMACTable::setValidityChangeCallback
void setValidityChangeCallback(void(*callback)(MeshMACTable< BufferSize > *, int16_t, const MeshMACTableRow &, bool, bool))
Sets callback function, which is called when row validity has changed. There can be 3 states of valid...
Definition: meshTables.h:1291
MeshRouteTableRow::operator==
bool operator==(const MeshRouteTableRow &another) const
Definition: meshTables.h:127
MeshOIDTableRow::operator==
bool operator==(const MeshOIDTableRow &another) const
Definition: meshTables.h:292
MeshRouteTable::isRowDirectNeighbor
bool isRowDirectNeighbor(int16_t index) const
Checks if row contains record of direct neighbor (source number and neighbor number are equal).
Definition: meshTables.h:1512
MeshOIDTable
Mesh ID table stores IDs of transmitted messages, check status of sent messages. Size of table can be...
Definition: meshTables.h:1941
MicroTable::clear
void clear()
Removes all rows data.
Definition: meshTables.h:586
MicroTable::onRemove
virtual void onRemove(int16_t index, const RowT &oldValue, uint8_t oldRawLifeTime, bool removedByValidation=false)
This method is called when valid row is removed. It is called after count calculation is done,...
Definition: meshTables.h:1117
MeshIDTableRow::MeshIDTableRow
MeshIDTableRow()=default
MeshFIDTable::add
bool add(const MeshFIDTableRow &val)
Adds or overwrites data in row. If row already exists, it will be overwritten, else new row is added....
Definition: meshTables.h:1868
MeshRouteTableRow
Structure, that contains one row with data from route table.
Definition: meshTables.h:70
MeshFIDTableRow::printRow
size_t printRow(OSTREAM &stream) const
Definition: meshTables.cpp:101
MeshOIDTable::MeshOIDTable
MeshOIDTable(const uint32_t rowLife)
Constructor.
Definition: meshTables.h:1950
MeshRouteTable::set
int16_t set(const MeshRouteTableRow &row, int16_t valid=-1)
Sets row values in table. Row index is established using getIndexOfSource() method....
Definition: meshTables.h:1394
MeshIDTable::add
bool add(uint8_t id, uint8_t source)
Adds or overwrites data in row. If row already exists, it will be overwritten, else new row is added....
Definition: meshTables.h:1725
MicroTable::setRawRemainingLifeTime
bool setRawRemainingLifeTime(int16_t index, uint8_t rawLifeTime_=255)
Sets row life time. Valid counter for this rowcan be changed, only when row is still valid.
Definition: meshTables.h:673
MeshFIDTableRow::ID
uint8_t ID
ID of message.
Definition: meshTables.h:201
MicroTable::set
bool set(int16_t index, const RowT &row)
Sets row values in table. Row life time is set to maximum.
Definition: meshTables.h:424
OIDTR_Removed
@ OIDTR_Removed
Definition: meshTables.h:1917
MeshRouteTable::removeByNeighbor
int16_t removeByNeighbor(uint8_t neighbor)
Removes all rows with specified neighbor address.
Definition: meshTables.h:1481
MeshOIDTable::existsID
bool existsID(uint8_t id) const
Checks if row with specified ID exists in table.
Definition: meshTables.h:2054
MicroTable::validate
void validate()
Decreases all valid column values in specified interval (row lifetime). If valid value is 0,...
Definition: meshTables.h:611
MeshFIDTableRow::clear
void clear()
Removes all data from current row.
Definition: meshTables.h:214
MicroTable::usedBufferSize
int16_t usedBufferSize
Definition: meshTables.h:1139
MeshRouteTableRow::Hop
uint8_t Hop
Number of hops from current node to Source.
Definition: meshTables.h:86
MeshIDTable::add
bool add(const MeshIDTableRow &val)
Adds or overwrites data in row. If row already exists, it will be overwritten, else new row is added....
Definition: meshTables.h:1748
MeshRouteTableRow::isGateway
bool isGateway() const
Checks if row is route to gateway node.
Definition: meshTables.h:100
OIDTR_Set
@ OIDTR_Set
Definition: meshTables.h:1918
MicroTable::lifeTime
uint8_t lifeTime[RowsCount]
Definition: meshTables.h:1136
MicroTable::exists
bool exists(const RowT &rowRef) const
Checks if any row, which is equal to rowRef exists in table.
Definition: meshTables.h:749
MeshMACTable::set
bool set(uint8_t address, MeshMAC MAC, int16_t valid=-1)
Sets row values in table.
Definition: meshTables.h:1188
MicroTable::buffer
RowT buffer[RowsCount]
Definition: meshTables.h:1135
MeshMACTable::addressExists
bool addressExists(uint8_t address) const
Checks if node address exists in table.
Definition: meshTables.h:1258
MeshRouteTableRow::MeshRouteTableRow
MeshRouteTableRow()=default
MeshFIDTable
Mesh foreign packet's ID table stores IDs of received packets from another network,...
Definition: meshTables.h:1809
DHCPTABLE_ROW_RAW_LIFETIME_RESERVED
#define DHCPTABLE_ROW_RAW_LIFETIME_RESERVED
Definition: meshConfig.h:147
MeshRouteTable::MeshRouteTable
MeshRouteTable(const uint32_t rowLife)
Constructor.
Definition: meshTables.h:1338
MeshFIDTable::add
bool add(uint8_t id, uint8_t source, MeshMAC bssid)
Adds or overwrites data in row. If row already exists, it will be overwritten, else new row is added....
Definition: meshTables.h:1845
MeshRouteTable::add
bool add(uint8_t source, uint8_t neighbor, uint8_t hop)
Adds or overwrites data in row. This method works slightly different, because it implements part of m...
Definition: meshTables.h:1418
MeshRouteTable::onClear
void onClear() override
This method is called when table is cleared. It is called after cleaning is done, so all variables ar...
Definition: meshTables.h:1647
MicroTable::realUsedSize
int16_t realUsedSize
Definition: meshTables.h:1140
MicroTable::get
RowT get(int16_t index)
Gets row from table by index.
Definition: meshTables.h:396
MicroTable::getFirstBlankRowIndex
int16_t getFirstBlankRowIndex(int16_t startPos=0) const
Gets index of first blank row.
Definition: meshTables.h:708
MicroTable::getRowRemainingLifeTime
uint32_t getRowRemainingLifeTime(int16_t index) const
Gets selected row's remaining life time in milliseconds.
Definition: meshTables.h:843
MeshRouteTableRow::Neighbor
uint8_t Neighbor
Neighbor node address, that is connected (directly/indirectly) to source node.
Definition: meshTables.h:82
alignText
void alignText(char *text, int size, char fill, TextAlignment alignment)
Aligns text in char array.
Definition: meshHelper.cpp:97
MeshOIDTableRow::ID
uint8_t ID
ID of message.
Definition: meshTables.h:257
MeshMACTableRow::clear
void clear()
Removes all data from current row.
Definition: meshTables.h:37
MeshIDTableRow
Structure, that acts as one row in MeshIDTable.
Definition: meshTables.h:142
MeshFIDTable::exists
bool exists(uint8_t id, uint8_t source, MeshMAC bssid) const
Checks if row with specified ID and Source exists in table.
Definition: meshTables.h:1909
MeshOIDTable::add
bool add(const MeshOIDTableRow &val, uint8_t rawLifeTime=255)
Adds or overwrites data in row. If row already exists, it will be overwritten, else new row is added....
Definition: meshTables.h:2002
MicroTable::set
bool set(int16_t index, const RowT &row, int16_t rawLifeTime_)
Sets row values in table.
Definition: meshTables.h:465
MicroTable::getFragmentation
uint8_t getFragmentation() const
Calculates fragmentation in %. Fragmentation is calculated like this: (getRealUsedSize() - count())/g...
Definition: meshTables.h:798
MicroTable::convertRawToLifeTime
uint32_t convertRawToLifeTime(uint8_t rawLifeTime) const
Converts raw life time value to life time in milliseconds. Value is aproximate. To get accurate resul...
Definition: meshTables.h:893
MeshOIDTableRow::printHeader
static size_t printHeader(OSTREAM &stream)
Print header for table of rows.
Definition: meshTables.cpp:131
MeshRouteTable::getDirectNeighborCount
uint8_t getDirectNeighborCount() const
Gets number direct neighbors in buffer.
Definition: meshTables.h:1581
MeshOIDTable::removeID
bool removeID(uint8_t ID)
Removes row data by ID.
Definition: meshTables.h:2011
meshPacket.h
This file contains class which can be used to handling mesh packets.
MicroTable::exists
bool exists(int16_t index) const
Checks if row at specified index exists in table.
Definition: meshTables.h:740
MeshRouteTableRow::isDirectNeighbor
bool isDirectNeighbor() const
Checks if row is route to direct neighbor or not.
Definition: meshTables.h:92
T_LEFT
@ T_LEFT
Definition: meshHelper.h:116
MeshFIDTableRow::MeshFIDTableRow
MeshFIDTableRow()=default
MeshIDTable::getIndexOfIDAndSource
int16_t getIndexOfIDAndSource(uint8_t id, uint8_t source) const
Gets index of row with specified ID and Source in table.
Definition: meshTables.h:1776
MeshRouteTable::sourceExists
bool sourceExists(uint8_t source) const
Checks if source node exists in table.
Definition: meshTables.h:1521
MeshFIDTableRow::printHeader
static size_t printHeader(OSTREAM &stream)
Print header for table of rows.
Definition: meshTables.cpp:97
MicroTable::getRawRowRemainingLifeTime
uint8_t getRawRowRemainingLifeTime(int16_t index) const
Gets selected row's raw remaining life time.
Definition: meshTables.h:863
MicroTable::remove
bool remove(int16_t index)
Removes row at index.
Definition: meshTables.h:546
MeshRouteTableRow::printRow
size_t printRow(OSTREAM &stream) const
Definition: meshTables.cpp:36
MeshMACTable::getFreeAddress
int16_t getFreeAddress(uint8_t startFrom=MESH_GATEWAY_MAX_ADDRESS+1)
Gets first available address.
Definition: meshTables.h:1274
MeshIDTableRow::printRow
size_t printRow(OSTREAM &stream) const
Definition: meshTables.cpp:73
MeshIDTableRow::ID
uint8_t ID
ID of message.
Definition: meshTables.h:150
MeshOIDTable::setOnRemoveCallback
void setOnRemoveCallback(void(*callback)(MeshOIDTable< BufferSize > *, int16_t, const MeshOIDTableRow &, uint8_t, MeshOIDTableRemoveReason))
Sets callback function, which is called when any item is removed from this table. If table is cleared...
Definition: meshTables.h:2091
MeshOIDTableRow::MeshOIDTableRow
MeshOIDTableRow()=default
MeshRouteTable::getIndexOfSource
int16_t getIndexOfSource(uint8_t source) const
Gets index of source address.
Definition: meshTables.h:1552
MicroTable::onClear
virtual void onClear()
This method is called when table is cleared. It is called after cleaning is done, so all variables ar...
Definition: meshTables.h:1123
MeshMACTable::getAddressFromMAC
int16_t getAddressFromMAC(MeshMAC mac, int16_t startPos=0) const
Searches for node address, which is assinged to node MAC address.
Definition: meshTables.h:1229
HAS_MEM_FUNC
HAS_MEM_FUNC(printRowForChangeLog, has_printRowForChangeLog)
MeshMACTableRow::printRow
size_t printRow(OSTREAM &stream) const
Definition: meshTables.cpp:18
MeshOIDTable::onRemove
void onRemove(int16_t index, const MeshOIDTableRow &oldValue, uint8_t oldRawLifeTime, bool removedByValidation=false) override
This method is called when valid row is removed. It is called after count calculation is done,...
Definition: meshTables.h:2118
MeshFIDTable::removeByIDSourceAndBSSID
bool removeByIDSourceAndBSSID(uint8_t ID, uint8_t source, MeshMAC bssid)
Removes row data by source and ID.
Definition: meshTables.h:1883
MicroTable::onCreate
virtual void onCreate(int16_t index, const RowT &newValue, uint8_t newRawLifeTime)
This method is called when valid row is set to blank space. It is called after count calculation is d...
Definition: meshTables.h:1096
MeshRouteTableRow::printHeader
static size_t printHeader(OSTREAM &stream)
Print header for table of rows.
Definition: meshTables.cpp:32
MeshRouteTable::setNewCallback
void setNewCallback(void(*callback)(MeshRouteTable< BufferSize > *, int16_t, const MeshRouteTableRow &, uint8_t))
Sets callback function, which is called when new record was inserted to table. This callback is not c...
Definition: meshTables.h:1595
OSTREAM
#define OSTREAM
Definition: meshConfig.h:41
MicroTable::getIndexOf
virtual int16_t getIndexOf(const RowT &rowRef) const
Gets index of row which is equal to rowRef.
Definition: meshTables.h:694
MicroTable::size
int16_t size() const
Gets capacity of table in rows.
Definition: meshTables.h:766
SPT_DATA
typedef SPT_DATA
Definition: meshPacket.h:32
MicroTable::defragment
void defragment()
Removes blank spaces between rows. Call this to speed up searching when buffer is fragmented.
Definition: meshTables.h:808
MeshOIDTableRow::clear
void clear()
Removes all data from current row.
Definition: meshTables.h:272
MeshRouteTable::operator+=
void operator+=(const MeshRouteTableRow &val)
Definition: meshTables.h:1461
MicroTable::printTo
size_t printTo(Print &p) const override
Makes this class printable.
Definition: meshTables.h:1082
MeshFIDTable::operator+=
void operator+=(const MeshFIDTableRow &val)
Definition: meshTables.h:1872
MeshIDTable::exists
bool exists(uint8_t id, uint8_t source) const
Checks if row with specified ID and Source exists in table.
Definition: meshTables.h:1786
MeshIDTable::MeshIDTable
MeshIDTable(const uint32_t rowLife)
Constructor.
Definition: meshTables.h:1701
MeshIDTable
Mesh ID table stores IDs of received packets, to prevent receiving same packet multiple times....
Definition: meshTables.h:1691
MicroTable::operator[]
RowT operator[](int16_t index)
Gets row from table by index.
Definition: meshTables.h:414
MeshMACTableRow::operator==
bool operator==(const MeshMACTableRow &another) const
Definition: meshTables.h:55
MeshRouteTable::onRemove
void onRemove(int16_t index, const MeshRouteTableRow &oldValue, uint8_t oldRawLifeTime, bool removedByValidation=false) override
This method is called when valid row is set to new value. It is called after count calculation is don...
Definition: meshTables.h:1637
MeshIDTableRow::clear
void clear()
Removes all data from current row.
Definition: meshTables.h:159
MeshRouteTable::getOldestRowIndexNotGW
int16_t getOldestRowIndexNotGW() const
Gets index of first oldest row, except gateway nodes.
Definition: meshTables.h:1655
MicroTable::getRealUsedSize
int16_t getRealUsedSize() const
Gets real used count of rows in table. This value is calculated like this: last_used_row_index + 1.
Definition: meshTables.h:790
MicroTable::getLifeTimeResolution
uint32_t getLifeTimeResolution() const
Gets life time resolution in milliseconds.
Definition: meshTables.h:873
MeshMAC
Structure that represents physical MAC address used in MeshNEt protocol. MeshMAC address unlike MAC a...
Definition: meshHelper.h:207
MeshMACTable::MACExists
bool MACExists(MeshMAC mac) const
Checks if node MAC address exists in table.
Definition: meshTables.h:1265
MicroTable::MicroTable
MicroTable(const uint32_t rowLife)
Constructor.
Definition: meshTables.h:375
MeshFIDTableRow::operator==
bool operator==(const MeshFIDTableRow &another) const
Definition: meshTables.h:234
MicroTable::onSet
virtual void onSet(int16_t index, const RowT &oldValue, uint8_t oldRawLifeTime, const RowT &newValue, uint8_t newRawLifeTime)
This method is called when valid row is set to new value. It is called after count calculation is don...
Definition: meshTables.h:1107
MeshRouteTable::set
int16_t set(uint8_t source, uint8_t neighbor, uint8_t hop, int16_t valid=-1)
Sets row values in table. Row index is established using getIndexOfSource() method....
Definition: meshTables.h:1370
MicroTable::get
const RowT & get(int16_t index) const
Gets row from table by index.
Definition: meshTables.h:387
MeshRouteTable::removeBySource
bool removeBySource(uint8_t source)
Removes row, which contains specified source address.
Definition: meshTables.h:1470
MeshOIDTable::getIndexOfID
int16_t getIndexOfID(uint8_t id) const
Gets index of row with specified ID in table.
Definition: meshTables.h:2039
MicroTable::getOldestRowIndex
int16_t getOldestRowIndex() const
Gets index of first oldest row.
Definition: meshTables.h:721
MeshMACTable::MeshMACTable
MeshMACTable(const uint32_t rowLife)
Constructor.
Definition: meshTables.h:1176
MeshOIDTableRow::printRow
size_t printRow(OSTREAM &stream) const
Definition: meshTables.cpp:135
MeshRouteTable::neighborExists
bool neighborExists(uint8_t neighbor) const
Checks if neighbor node exists in table.
Definition: meshTables.h:1536
MicroTable::lastValidationTime
uint32_t lastValidationTime
Definition: meshTables.h:1138
MeshIDTableRow::operator==
bool operator==(const MeshIDTableRow &another) const
Definition: meshTables.h:178
MeshIDTable::operator+=
void operator+=(const MeshIDTableRow &val)
Definition: meshTables.h:1752
MeshMACTableRow
Structure, that contains one row with data from address to MAC lookup table. Designed for gateway nod...
Definition: meshTables.h:24
MeshRouteTableRow::clear
void clear()
Removes all data from current row.
Definition: meshTables.h:107
MicroTable::print
size_t print(OSTREAM &stream, bool showIndexes=true, bool doNotPrintBlank=true, bool showRemainingRowLifetime=true) const
Prints items from table to stream.
Definition: meshTables.h:994
MeshMACTable::onRowLifeChanged
void onRowLifeChanged(int16_t index, uint8_t old_raw, uint8_t new_raw) override
This method is called when table is cleared. It is called after cleaning is done, so all variables ar...
Definition: meshTables.h:1297
MeshOIDTable::removeByDestination
int16_t removeByDestination(uint8_t destination)
Removes row data by it's destination address.
Definition: meshTables.h:2024
MeshIDTableRow::Source
uint8_t Source
Source node number.
Definition: meshTables.h:154
MeshOIDTable::set
bool set(uint8_t index, uint8_t id, uint8_t destination, SystemPacketType type, int16_t valid=-1)
Sets row values in table.
Definition: meshTables.h:1965
MicroTable::isRowBlank
bool isRowBlank(int16_t index) const
Checks if row is blank or not. Row, that is not valid is blank.
Definition: meshTables.h:758
OIDTR_Validation
@ OIDTR_Validation
Definition: meshTables.h:1919
MeshIDTableRow::printHeader
static size_t printHeader(OSTREAM &stream)
Print header for table of rows.
Definition: meshTables.cpp:69
MeshOIDTableRemoveReason
MeshOIDTableRemoveReason
Definition: meshTables.h:1916
MeshMACTableRow::MeshMACTableRow
MeshMACTableRow()=default
MeshMACTable::add
int16_t add(MeshMAC mac, bool isGateway=false)
Adds MAC address to table at first free index.
Definition: meshTables.h:1199
MicroTable::RowLife
const uint32_t RowLife
Definition: meshTables.h:1142
MeshRouteTable::add
bool add(const MeshRouteTableRow &val)
Adds or overwrites data in row. This method works slightly different as basic add method,...
Definition: meshTables.h:1431
MeshRouteTable::removeByAddress
int16_t removeByAddress(uint8_t address)
Removes all rows which contains specified address in "Source" or "Neighbor" field.
Definition: meshTables.h:1497
MeshFIDTable::MeshFIDTable
MeshFIDTable(const uint32_t rowLife)
Constructor.
Definition: meshTables.h:1819
MeshRouteTableRow::Source
uint8_t Source
Source address.
Definition: meshTables.h:78
MeshRouteTable::getNeighborFromSource
int16_t getNeighborFromSource(int8_t source) const
Gets neighbor, which is connected (directly or indirectly) with source node.
Definition: meshTables.h:1566
MeshMACTable::getMACFromAddress
MeshMAC getMACFromAddress(uint8_t address) const
Gets node MAC address assigned to node address.
Definition: meshTables.h:1246
MeshFIDTableRow::Source
uint8_t Source
Source node number.
Definition: meshTables.h:205
MeshMACTableRow::printHeader
static size_t printHeader(OSTREAM &stream)
Print header for table of rows.
Definition: meshTables.cpp:14
MESH_GATEWAY_MAX_ADDRESS
#define MESH_GATEWAY_MAX_ADDRESS
Maximum address, which is reserved for gateway. Defaultly addressed 0,1,2 are reserved for gateway an...
Definition: meshConfig.h:69
MeshFIDTableRow::BSSID
MeshMAC BSSID
BSSID of network.
Definition: meshTables.h:209
MicroTable
This class emulates table storage. This table is created without dynamic allocation....
Definition: meshTables.h:351
MicroTable::getMaxRowLifeTime
uint8_t getMaxRowLifeTime() const
Gets the maximum row life time in millisseconds.
Definition: meshTables.h:782
MeshFIDTable::set
bool set(uint16_t index, uint8_t id, uint8_t source, MeshMAC bssid, int16_t valid=-1)
Sets row values in table.
Definition: meshTables.h:1833
MeshIDTable::removeByIDAndSource
bool removeByIDAndSource(uint8_t ID, uint8_t source)
Removes row data by source and ID.
Definition: meshTables.h:1762