LoRaMesher Library  0.0.5
A LoRa Mesh library for the IoT
LoraMesher.h
1#ifndef _LORAMESHER_H
2#define _LORAMESHER_H
3
4// LoRa libraries
5#include "RadioLib.h"
6
7// Logger
8#include <ArduinoLog.h>
9//#define DISABLE_LOGGING
10
11//Actual LoRaMesher Libraries
12#include "BuildOptions.h"
13
14#include "utilities/LinkedQueue.hpp"
15
16#include "services/PacketService.h"
17
18#include "services/RoutingTableService.h"
19
20#include "services/PacketQueueService.h"
21
22#include "services/WiFiService.h"
23
29
30public:
37 static LoraMesher instance;
38 return instance;
39 }
40
102 void begin(float freq = LM_BAND, float bw = LM_BANDWIDTH, uint8_t sf = LM_LORASF, uint8_t cr = LM_CODING_RATE, uint8_t syncWord = LM_SYNC_WORD, int8_t power = LM_POWER, uint16_t preambleLength = LM_PREAMBLE_LENGTH);
103
136 [[deprecated("Use begin(...) instead. Will be deleted permanently in v0.0.6.")]]
137 void init(void (*receiverFunction)(void*));
138
144 void start();
145
150 void standby();
151
156 ~LoraMesher();
157
163 void setFrequency(float freq) { radio->setFrequency(freq); recalculateMaxTimeOnAir(); }
164
170 void setBandwidth(float bw) { radio->setBandwidth(bw); recalculateMaxTimeOnAir(); }
171
177 void setSpreadingFactor(uint8_t sf) { radio->setSpreadingFactor(sf); recalculateMaxTimeOnAir(); }
178
184 void setCodingRate(uint8_t cr) { radio->setCodingRate(cr); recalculateMaxTimeOnAir(); }
185
193 void setOutputPower(int8_t power, bool useRfo = false) { radio->setOutputPower(power, useRfo); }
194
200 void setReceiveAppDataTaskHandle(TaskHandle_t ReceiveAppDataTaskHandle) { ReceiveAppData_TaskHandle = ReceiveAppDataTaskHandle; }
201
206 LM_LinkedList<RouteNode>* routingTableList() { return RoutingTableService::routingTableList; }
207
216 template <typename T>
217 void createPacketAndSend(uint16_t dst, T* payload, uint8_t payloadSize) {
218 //Cannot send an empty packet
219 if (payloadSize == 0)
220 return;
221
222 //Get the size of the payload in bytes
223 size_t payloadSizeInBytes = payloadSize * sizeof(T);
224
225 //Create a data packet with the payload
226 DataPacket* dPacket = PacketService::createDataPacket(dst, getLocalAddress(), DATA_P, reinterpret_cast<uint8_t*>(payload), payloadSizeInBytes);
227
228 //Create the packet and set it to the send queue
229 setPackedForSend(reinterpret_cast<Packet<uint8_t>*>(dPacket), DEFAULT_PRIORITY);
230 }
231
240 void sendReliablePacket(uint16_t dst, uint8_t* payload, uint32_t payloadSize);
241
250 template <typename T>
251 void sendReliable(uint16_t dst, T* payload, uint32_t payloadSize) {
252 sendReliablePacket(dst, reinterpret_cast<uint8_t*>(payload), sizeof(T) * payloadSize);
253 }
254
260 size_t getReceivedQueueSize();
261
267 size_t getSendQueueSize();
268
275 template<typename T>
277 ReceivedAppPackets->setInUse();
278 AppPacket<T>* appPacket = reinterpret_cast<AppPacket<T>*>(ReceivedAppPackets->Pop());
279 ReceivedAppPackets->releaseInUse();
280 return appPacket;
281 }
282
289 template <typename T>
290 static void deletePacket(AppPacket<T>* p) {
291 delete p;
292 }
293
299 int routingTableSize();
300
301
307 uint16_t getLocalAddress();
308
314 uint32_t getReceivedDataPacketsNum() { return receivedDataPacketsNum; }
315
321 uint32_t getSendPacketsNum() { return sendPacketsNum; }
322
328 uint32_t getReceivedHelloPacketsNum() { return receivedHelloPacketsNum; }
329
335 uint32_t getSentHelloPacketsNum() { return sentHelloPacketsNum; }
336
342 uint32_t getReceivedBroadcastPacketsNum() { return receivedBroadcastPacketsNum; }
343
349 uint32_t getForwardedPacketsNum() { return forwardedPacketsNum; }
350
356 uint32_t getDataPacketsForMeNum() { return dataPacketForMeNum; }
357
363 uint32_t getReceivedIAmViaNum() { return receivedIAmViaNum; }
364
370 uint32_t getDestinyUnreachableNum() { return sendPacketDestinyUnreachableNum; }
371
377 uint32_t getReceivedNotForMe() { return receivedPacketNotForMeNum; }
378
379
380private:
381
386 LoraMesher();
387
388 LM_LinkedList<AppPacket<uint8_t>>* ReceivedAppPackets = new LM_LinkedList<AppPacket<uint8_t>>();
389
390 LM_LinkedList<QueuePacket<Packet<uint8_t>>>* ReceivedPackets = new LM_LinkedList<QueuePacket<Packet<uint8_t>>>();
391
392 LM_LinkedList<QueuePacket<Packet<uint8_t>>>* ToSendPackets = new LM_LinkedList<QueuePacket<Packet<uint8_t>>>();
393
398 SX1276* radio;
399
404 Module* genericModule;
405
410 TaskHandle_t Hello_TaskHandle = nullptr;
411
417 TaskHandle_t ReceivePacket_TaskHandle = nullptr;
418
424 TaskHandle_t ReceiveData_TaskHandle = nullptr;
425
431 TaskHandle_t SendData_TaskHandle = nullptr;
432
438 TaskHandle_t ReceiveAppData_TaskHandle = nullptr;
439
444 TaskHandle_t PacketManager_TaskHandle = nullptr;
445
446 static void onReceive(void);
447
448 void receivingRoutine();
449
450 void initializeLoRa(float freq, float bw, uint8_t sf, uint8_t cr, uint8_t syncWord, int8_t power, uint16_t preambleLength);
451
452 void initializeSchedulers();
453
454 //TODO: Change message
455 [[deprecated("Create task and add it to the LoRaMesher using the function setReceiveAppDataTaskHandle(...). Will be deleted permanently in v0.0.6.")]]
456 void initializeReceivedUserDataTask(void (*func)(void*));
457
458 void sendHelloPacket();
459
460 void packetManager();
461
462
468 uint32_t receivedDataPacketsNum = 0;
469 void incReceivedDataPackets() { receivedDataPacketsNum++; }
470
471 uint32_t sendPacketsNum = 0;
472 void incSendPackets() { sendPacketsNum++; }
473
474 uint32_t receivedHelloPacketsNum = 0;
475 void incRecHelloPackets() { receivedHelloPacketsNum++; }
476
477 uint32_t sentHelloPacketsNum = 0;
478 void incSentHelloPackets() { sentHelloPacketsNum++; }
479
480 uint32_t receivedBroadcastPacketsNum = 0;
481 void incReceivedBroadcast() { receivedBroadcastPacketsNum++; }
482
483 uint32_t forwardedPacketsNum = 0;
484 void incForwardedPackets() { forwardedPacketsNum++; }
485
486 uint32_t dataPacketForMeNum = 0;
487 void incDataPacketForMe() { dataPacketForMeNum++; }
488
489 uint32_t receivedIAmViaNum = 0;
490 void incReceivedIAmVia() { receivedIAmViaNum++; }
491
492 uint32_t sendPacketDestinyUnreachableNum = 0;
493 void incDestinyUnreachable() { sendPacketDestinyUnreachableNum++; }
494
495 uint32_t receivedPacketNotForMeNum = 0;
496 void incReceivedNotForMe() { receivedPacketNotForMeNum++; }
497
503 void processPackets();
504
511 template <typename T>
512 static void deletePacket(Packet<T>* p) {
513 free(p);
514 }
515
522 void setPackedForSend(Packet<uint8_t>* p, uint8_t priority) {
523 Log.traceln(F("Adding packet to Q_SP"));
524 QueuePacket<Packet<uint8_t>>* send = PacketQueueService::createQueuePacket(p, priority);
525 Log.traceln(F("Created packet to Q_SP"));
526 addToSendOrderedAndNotify(send);
527 //TODO: Using vTaskDelay to kill the packet inside LoraMesher
528 }
529
535 void addToSendOrderedAndNotify(QueuePacket<Packet<uint8_t>>* qp);
536
542 void processDataPacket(QueuePacket<DataPacket>* pq);
543
549 void processDataPacketForMe(QueuePacket<DataPacket>* pq);
550
556 void notifyUserReceivedPacket(AppPacket<uint8_t>* appPq);
557
565 bool sendPacket(Packet<uint8_t>* p);
566
571 void sendPackets();
572
580 void sendStartSequencePackets(uint16_t destination, uint8_t seq_id, uint16_t num_packets);
581
582
591 QueuePacket<ControlPacket>* getStartSequencePacketQueue(uint16_t destination, uint8_t seq_id, uint16_t num_packets);
592
600 void sendAckPacket(uint16_t destination, uint8_t seq_id, uint16_t seq_num);
601
609 void sendLostPacket(uint16_t destination, uint8_t seq_id, uint16_t seq_num);
610
617 void printHeaderPacket(Packet<uint8_t>* p, String title);
618
626 bool processLargePayloadPacket(QueuePacket<ControlPacket>* pq);
627
635 void processSyncPacket(uint16_t source, uint8_t seq_id, uint16_t seq_num);
636
644 void addAck(uint16_t source, uint8_t seq_id, uint16_t seq_num);
645
650 uint8_t sequence_id = 0;
651
657 uint8_t getSequenceId();
658
663 void managerSendQueue();
664
669 void managerReceivedQueue();
670
675 struct sequencePacketConfig {
676 //Identification is Sequence Id and Source address
677 uint8_t seq_id; //Sequence Id
678 uint16_t source; //Source Address
679
680 uint16_t number{0}; //Number of packets of the sequence
681 uint8_t firstAckReceived{0}; //If this value is set to 0, there has not been received any ack.
682 uint16_t lastAck{0}; //Last ack received/send. 0 to n ACKs where n is the number of packets.
683 unsigned long timeout{0};; //Timeout of the sequence
684 uint8_t numberOfTimeouts{0}; //Number of timeouts that has been occurred
685 uint32_t RTT{0}; //Round Trip time
686
687 sequencePacketConfig(uint8_t seq_id, uint16_t source, uint16_t number) : seq_id(seq_id), source(source), number(number) {};
688 };
689
694 struct listConfiguration {
695 sequencePacketConfig* config;
696 LM_LinkedList<QueuePacket<ControlPacket>>* list;
697 };
698
704 void actualizeRTT(listConfiguration* config);
705
715 void processLostPacket(uint16_t destination, uint8_t seq_id, uint16_t seq_num);
716
725 bool sendPacketSequence(listConfiguration* lstConfig, uint16_t seq_num);
726
732 void joinPacketsAndNotifyUser(listConfiguration* listConfig);
733
741 void addTimeout(LM_LinkedList<listConfiguration>* queue, uint8_t seq_id, uint16_t source);
742
748 void resetTimeout(sequencePacketConfig* configPacket);
749
755 void addTimeout(sequencePacketConfig* configPacket);
756
762 void clearLinkedList(listConfiguration* listConfig);
763
770 void findAndClearLinkedList(LM_LinkedList<listConfiguration>* queue, listConfiguration* listConfig);
771
780 listConfiguration* findSequenceList(LM_LinkedList<listConfiguration>* queue, uint8_t seq_id, uint16_t source);
781
788 LM_LinkedList<listConfiguration>* q_WSP = new LM_LinkedList<listConfiguration>();
789
794 LM_LinkedList<listConfiguration>* q_WRP = new LM_LinkedList<listConfiguration>();
795
800 uint32_t maxTimeOnAir = 0;
801
806 uint8_t preambleReceivedWhenSending = 0;
807
813 void waitBeforeSend(uint8_t repeatedDetectPreambles);
814
819 void recalculateMaxTimeOnAir();
820
821};
822
823#endif
Application packet, it is used to send the packet to the application layer.
Definition: AppPacket.h:11
LoRaMesher Library.
Definition: LoraMesher.h:28
uint32_t getForwardedPacketsNum()
Get the Received Broadcast Packets Num.
Definition: LoraMesher.h:349
size_t getSendQueueSize()
Get the Send Queue Size. Packets that are waiting to be send.
Definition: LoraMesher.cpp:709
uint32_t getSendPacketsNum()
Get the Send Packets Num.
Definition: LoraMesher.h:321
void sendReliablePacket(uint16_t dst, uint8_t *payload, uint32_t payloadSize)
Send the payload reliable. It will wait for an ACK back from the destination to send the next packet.
Definition: LoraMesher.cpp:513
uint32_t getReceivedDataPacketsNum()
Get the Received Data Packets Num.
Definition: LoraMesher.h:314
uint16_t getLocalAddress()
Get the Local Address.
Definition: LoraMesher.cpp:287
uint32_t getReceivedIAmViaNum()
Get the Received I Am Via Num.
Definition: LoraMesher.h:363
void setReceiveAppDataTaskHandle(TaskHandle_t ReceiveAppDataTaskHandle)
Set the Receive App Data Task Handle, every time a received packet for this node is detected,...
Definition: LoraMesher.h:200
void setCodingRate(uint8_t cr)
Sets LoRa coding rate denominator. Allowed values range from 5 to 8.
Definition: LoraMesher.h:184
static void deletePacket(AppPacket< T > *p)
Delete the packet from memory.
Definition: LoraMesher.h:290
uint32_t getReceivedNotForMe()
Get the Received Not For Me.
Definition: LoraMesher.h:377
static LoraMesher & getInstance()
Get the Instance of the LoRaMesher.
Definition: LoraMesher.h:36
LM_LinkedList< RouteNode > * routingTableList()
Routing table List.
Definition: LoraMesher.h:206
uint32_t getReceivedHelloPacketsNum()
Get the Received Hello Packets Num.
Definition: LoraMesher.h:328
void setOutputPower(int8_t power, bool useRfo=false)
Sets transmission output power. Allowed values range from -3 to 15 dBm (RFO pin) or +2 to +17 dBm (PA...
Definition: LoraMesher.h:193
void setFrequency(float freq)
Set the Frequency. Allowed values range from 137.0 MHz to 525.0 MHz.
Definition: LoraMesher.h:163
AppPacket< T > * getNextAppPacket()
Get the Next Application Packet.
Definition: LoraMesher.h:276
uint32_t getDestinyUnreachableNum()
Get the Destiny Unreachable Num.
Definition: LoraMesher.h:370
int routingTableSize()
Returns the routing table size.
Definition: LoraMesher.cpp:692
void begin(float freq=LM_BAND, float bw=LM_BANDWIDTH, uint8_t sf=LM_LORASF, uint8_t cr=LM_CODING_RATE, uint8_t syncWord=LM_SYNC_WORD, int8_t power=LM_POWER, uint16_t preambleLength=LM_PREAMBLE_LENGTH)
LoRaMesh initialization method.
Definition: LoraMesher.cpp:5
void init(void(*receiverFunction)(void *))
Initialize the LoraMesher object.
Definition: LoraMesher.cpp:13
void standby()
Standby LoRaMesher. Including tasks and reception and send packets.
Definition: LoraMesher.cpp:27
uint32_t getReceivedBroadcastPacketsNum()
Get the Received Broadcast Packets Num.
Definition: LoraMesher.h:342
void createPacketAndSend(uint16_t dst, T *payload, uint8_t payloadSize)
Create a Packet And Send it.
Definition: LoraMesher.h:217
~LoraMesher()
Destroy the LoraMesher.
Definition: LoraMesher.cpp:77
uint32_t getDataPacketsForMeNum()
Get the Data Packets For Me Num.
Definition: LoraMesher.h:356
void setSpreadingFactor(uint8_t sf)
Sets LoRa spreading factor. Allowed values range from 6 to 12.
Definition: LoraMesher.h:177
void start()
Start/Resume LoRaMesher. After calling begin(...) or standby() you can Start/resume the LoRaMesher....
Definition: LoraMesher.cpp:52
uint32_t getSentHelloPacketsNum()
Get the Sent Hello Packets Num.
Definition: LoraMesher.h:335
size_t getReceivedQueueSize()
Returns the number of packets inside the received packets queue.
Definition: LoraMesher.cpp:705
void sendReliable(uint16_t dst, T *payload, uint32_t payloadSize)
Send the payload reliable. It will wait for an ack of the destination.
Definition: LoraMesher.h:251
void setBandwidth(float bw)
Sets LoRa bandwidth. Allowed values are 10.4, 15.6, 20.8, 31.25, 41.7, 62.5, 125, 250 and 500 kHz.
Definition: LoraMesher.h:170
static LM_LinkedList< RouteNode > * routingTableList
Routing table List.
Definition: RoutingTableService.h:32