Project logo

MESH NET

Sensory mesh network protocol designed for microcontrollers.


MeshNet v1.0.0

MeshNet is a sensory mesh network designed for microcontrollers with Arduino core. Nodes of the network are called MNodes. It isn't designed to transfer large amounts of data at high speed, but to collect data from sensor nodes. The code was optimized for microcontrollers with at least 20kB of RAM (tables and buffers cannot be further reduced :cry:) and at least 90kB of FLASH memory. It was tested on STM32L432KC microcontroller.

Features

  • Can be used with any radio, that supports broadcasting.
  • Contains at least one control node called Main Gateway Node (MGN).
  • Scalability up to 251 nodes of which 1 to 3 nodes are gateway nodes.
  • Data size of one packet from 1 to 512 bytes.
  • Supports acknowledgment of receipt of the packet by destination node in conjunction with packet timeout.
  • Supports multiple networks on same channel.
  • Self-forming (with dynamic addressing) and self-healing network.
  • Supports auto connect to specified network.
  • Supports ping.
  • Error reporting using callback functions.
  • Implements user interface using SerialConsole.
  • Routing protocol features:
    • type: flat hybrid single-route routing protocol with hop-by-hop routing.
    • route discovery method: link state -> whole network must be flooded. We want to improve this disadvantage.
    • metric: hop-count -> which is not ideal for wireless mesh networks, but improvements will be made.

How to view documentation

  1. Download and install doxygen to your device.
  2. When you use:
    • Windows - run makeDoc.bat file, it will create documentation to html directory and opens it. When you have already generated documentation directory (html), you can view it by opening index.html file in that directory.
    • Linux or Mac - run doxygen.exe in console in folder to generate documentation. Open file in html/index.html

Integration with STM32 project

  1. Download or clone this code to folder with name MeshNet.
  2. Open/create project in STM32CubeIDE.
  3. Right click to project > Convert to C++.
  4. Right click to project > New > Folder > Advanced and check radio button "Link to alternate location (Linked folder)", then click to Browse and select, where MeshNet folder is located. It is recommended to use variables in path.
  5. Right click to project > Properties > C/C++ General > Paths and symbols > Source Location. Click to "Add Folder..." button and select MeshNet folder, then click OK.
  6. Right click to project > Properties > C/C++ General > Paths and symbols > Includes. Click to Add button (check "Is a workspace path") and add those paths to GNU C and GNU C++ tab: /${ProjName}/MeshNet/Mesh/Inc /${ProjName}/MeshNet/RadioInterfaces/Inc
  7. Right click to project > Properties > C/C++ General > Paths and symbols > Symbols. Click to Add button and add this symbol to GNU C and GNU C++ tab:
    STM32
  8. Also check, if there is MCU type in symbols. For example, STM32L432kc type is STM32L432xx.

Interface with SerialConsole

SerialConsole is project, which allows easy implementation of console for microcontrollers using serial UART interface. With this console you can control and monitor MeshNet class using specified commands or using GUI. Project with application for windows and linux (with mono) is located here.

Creating interface for custom radio

Almost any radio can be used with this mesh network, but those requirements has to be met:

  • Broadcast transmission must be supported.
  • The radio must be able to send at least 24 bytes at once. The more bytes it can send, the better.
  • It must be possible to disable the auto acknowledgment and auto retransmit when ACK was not received. ACKs are handed by MeshNet.

Optional requirements for radio, which increases performance:

  • Radio should contain FIFO buffer for received frames. Its size should be at least 3 rows.
  • Radio may support hardware CRC calculation for each sent and received frame. If radio does not support CRC calculation, it must be done by software in radio driver and if it won't pass, frame must be discarded. At least CRC-16 must be used.
  • Radio should fire interrupt when frame is received.
  • Radio may be able to check if carriage wave is present. This is used for interference avoiding.
  • Radio may be able to check RSSI of received frame. This is used during path discovery, to determine link quality.
  • Radio should support low power modes.

To create custom radio interface first create inherited class from RFInterface and continue with those steps:

  1. In its constructor call constructor of base class RFInterface with all arguments. Some of those arguments describes radio features and behavior.
  2. Create destructor, where deInit() function is called.
  3. In init() function setup radio.
  4. In deInit() function disable or power off radio and unregister interrupt callback (set it to NULL) if set.
  5. Function hasError() has to return true, when radio has some error or is not connected to MCU.
  6. In send() function perform frame transmission. It must return true when frame was sent without any error. It has to be checked here, if radio is connected and if not, it has return false.
  7. In available() function check if any frame was received and return size of frame. If not, it must return 0.
  8. In recv() function read received bytes from radio buffer and write it to buffer specified in arguments. If it failed, return false. If RSSI cannot be established, set it to -60dBm.
  9. Create uint8_t array with same size as MaxMessageLength and in function getInternalTemporaryBuffer() return pointer to that array.
  10. From this step, other steps are optional.
  11. Implement sleep() and wakeUp() functions. As its name says, those functions should be able to temporary power off and power on radio. When the radio is in sleep mode, it may not be able to receive data. If not implemented, just return true in both functions.
  12. Implement checkInterference() function, which returns true, when carried wave is present.
  13. Implement setChannel() function to check specific channel. If channel cannot be changed, just return false.
  14. Implement setPower() function, which can set power mode. If power modes cannot be set, return false.
  15. Implement setFullSpeed() function, which has to be able to set low speed or full speed. Only two speed modes are supported. Return false if not implemented.
  16. Implement setReceiveInterruptCallback(), which registers callback function, that is called when interrupt is fired because frame was received. If not implemented, return false.
  17. Implement interruptHandle() function, which will be called in callback function from previous step. In this function flags in radio should be cleared.
  18. handle() function is periodically called. It may contain a code for radio handling, which must be called often.
  19. Function printDetails() may be able to print radio details in pretty form to specified stream. It is recommended to implement this function.
  20. Implement scanChannels() function, which checks carrier wave on each channel and returns best channel number with the smallest chance of an interference. If stream is specified, it must print chance of an interference for each scanned channel. Format of printed data is strictly specified:
    Retries: <number of retries for each channel>
    Channel span: <count of channels scanned at one retry, in most cases 1>
    Base frequency: <frequency of first channel (ch. 0) in kHz> kHz
    Channel width: <channel width in kHz> kHz
    <channel number>: <interfered retries>
    <channel number>: <interfered retries>
    ...

    Example for nRF24L01:

    Retries: 50
    Channel span: 1
    Base frequency: 2400000 kHz
    Channel width: 1000 kHz
    0: 2
    1: 12
    0: 0
  21. Implement scanChannelsWorking() function, which returns true if radio is busy, because scanning in progress.
  22. Implement getChannelsWidth() which returns width of channels in kHz.

Configuration

Behavior of MeshNet can be configured in meshConfig.h file with those macros:

Size configuration

Packet payload size

  • MESH_PACKET_PAYLOAD_SIZE_LIMIT - Size limit of packet payload. By default, set to 512 bytes, but can be set from 128 bytes to 1024 bytes. When changing this macro do not forget to change MESH_PACKET_PAYLOAD_SIZE_LIMIT_txt and MESH_PING_PAYLOAD_SIZE_LIMIT_txt macros.

Tables sizes and life times

  • ROUTETABLE_SIZE - count of rows in route table. By default, set to 64, but for gateway node it is recommended to set higher value. When changing this macro do not forget to change ROUTETABLE_SIZE_txt and ROUTETABLE_MAX_IND_txt macros.
  • ROUTETABLE_ROW_LIFETIME - maximum lifetime of each row in route table in milliseconds. By default, set to 30 minutes.
  • IDTABLE_SIZE - count of rows in IDTable. By default, set to 64, but for gateway node it is recommended to set higher value. When changing this macro do not forget to change IDTABLE_SIZE_txt and IDTABLE_MAX_IND_txt macros.
  • IDTABLE_ROW_LIFETIME - maximum lifetime of each row in IDTable in milliseconds. By default, set to 5 minutes.
  • FIDTABLE_SIZE - count of rows in FIDTable. By default, set to 8, but for gateway node it is recommended to set higher value. When changing this macro do not forget to change FIDTABLE_SIZE_txt and FIDTABLE_MAX_IND_txt macros.
  • FIDTABLE_ROW_LIFETIME - maximum lifetime of each row in FIDTable in milliseconds. By default, set to 5 minutes.
  • OIDTABLE_SIZE - count of rows in OIDTable. By default, set to 64, but for gateway node it is recommended to set higher value. When changing this macro do not forget to change OIDTABLE_SIZE_txt and OIDTABLE_MAX_IND_txt macros.
  • DHCPTABLE_VALID_ROW_LIFETIME - lifetime of each row in DHCP table in milliseconds. By default, set to one day. After this time, row stays in DHCP table for same time as life time, but is marked as reserved.

Buffers sizes

  • MESH_OFIFO_HIGH_SIZE - size of high priority part (Route and Unicast packets) of output FIFO. By default, set to 3.
  • MESH_OFIFO_LOW_SIZE - size of low priority part (Flood and Broadcast packets) of output FIFO. By default, set to 4.
  • MESH_WFIFO_SIZE - size of waitingFIFO buffer. By default, set to 8.

Miscellaneous

  • MESH_INST_ARRAY_SIZE - size of instance array. This array stores all created instances of current class. Number of created instances of MeshNet in this program cannot exceed this number. By default, set to 2, but can be set to higher value if multiple instances are defined on one MCU.

Timing

Frame receive timing

  • MESH_NEXT_FRAME_TIMEOUT - timeout in milliseconds. If header frame was received and next frame is expected, until this timeout all other frames are ignored. By default, set to 40ms.

Frame send timing

  • MESH_ROUTE_RETR_TIME - after this time in milliseconds routed frame (Type: Route or Unicast) can be retransmitted when ACK was not received. By default, set to 50ms.
  • MESH_FRAME_SEND_DELAY - after this time in milliseconds from last frame send, broadcasted frame (Type: Flood or Broadcast) can be sent. By default, set to 15ms.

Clear to send time

  • MESH_ACK_CTS_TIME - this time in microseconds is added to CTS time, when ACK is expected. By default, set to 15ms.
  • MESH_FRAME_CTS_TIME - this time in microseconds is added to CTS time, when another frame is expected. By default, set to 20ms.

    Clear to send random time

  • MESH_RANDOM_ROUTED_CTS_TIME - random value between 0 and this time in microseconds is added to CTS time, when routed frame (Type: Route or Unicast) was received. By default, set to 5ms.
  • MESH_RANDOM_UNROUTED_CTS_TIME - random value between 0 and this time in microseconds is added to CTS time, when broadcasted frame (Type: Flood or Broadcast) was received. By default, set to 10ms.

Miscellaneous

  • MESH_PATH_DISC_TIMEOUT - timeout in milliseconds for path discovery. By default, set to 5 seconds.

Settings

Packet relaying limit

  • MESH_HOP_RELAY_LIMIT - maximum count of hops, that can one packet do. After exceeding this limit, packet is discarded. By default, set to 25.

Retransmissions limits

  • MESH_ROUTE_RETR_CNT - maximum count of routed frame (Type: Route or Unicast) retransmission when ACK was not received. When this limit exceeds, node is marked as inacessible. By default, set to 4, so frame can be sent in worst case 5 times.
  • MESH_FLOOD_RETR_CNT - count of guaranteed retransmittments for every broadcasted frame (Type: Flood or Broadcast). Those frames are broadcasted multiple times, because there is higher chance, that they will be received by all neighbor nodes. This is by default set to 1, so broadcasted frame will be sent 2 times. Set to 0 to disable retransmittment of broadcasted frames.

RSSI threshold

  • MESH_RSSI_THRESHOLD - RSSI threshold. If RSSI of any frame (excepts ACK) exceeds this threshold it is ignored. RSSI threshold is by default set to -70dBm.

Connection settings

  • MESH_SYS_NET_SCAN_TIMEOUT - system network scan timeout in milliseconds. By default, set to 1.5ms.
  • MESH_CONNECT_TIMEOUT - connect process timeout including system network scan before connection in milliseconds. By default, set to 7.5s.

Disconnection settings

  • MESH_DISCONNECT_TIMEOUT - after this time in milliseconds node is definitely disconnected from network and all packets in FIFO for that network are cleared. By default, set to 5s.
  • MESH_REQ_DISCONNECT_TIMEOUT - until this time in milliseconds, node, the gateway requested disconnection, must respond with disconnect packet, which says, it is disconnecting. By default, set to 7.5s.

Miscellaneous

  • MESH_IMPL_CONSOLE_ITEM - if set to 0, SerialConsole interface won't be implemented to MeshNet. This setting can significantly reduce FLASH memory usage. By default, set to 1.
  • MESH_NO_STATISTICS - if uncommented, statistics will not be recorded. This setting can slightly reduce RAM memory usage. By default, commented out.

File list

  • Folder Mesh:
    • mesh.h - Main file with the MeshNet class. This file must be included to use MeshNet.
    • meshNetGateway.h - Main file with the MeshNetGateway class, which is inherited from the MeshNet class and implements functionality of MGN.
    • meshBuffers.h - File, which contains implementations of all used buffers in mesh protocol.
    • meshTables.h - File, which contains implementations of all used tables in mesh protocol.
    • meshFrame.h - Contains class MeshFrame, which represents frames to be sent or received. Frames data part is dynamically allocated.
    • meshPacket.h - Contains class MeshPacket, which represents packet, that are split to multiple frames, which are sent. Payload is dynamically allocated, same as MeshFrame and its length can be up to 512B.
    • meshPacketBuilder.h - Contains class MeshPacketBuilder, which builds packet from multiple received frames.
    • meshPacketSplitter.h - Contains class MeshPacketSplitter, which splits packet to multiple frames, that are sent.
    • meshPacketDecoders - Contains functions, that decodes or encodes system packets fields.
    • meshPacketFlags - Contains structures, that represents flags in MeshPacket or MeshFrame headers and other flags used in code.
    • meshConfig.h - Configuration file.
    • meshHelper.h - File, which contains helper function or classes for MeshNet. For example, MeshMAC is located here.
    • meshVariableArray.h - File, which contains class, that behaves as dynamically allocated array. This array can be used to create packet payload to be send. Best performance can be achieved when using send() method in conjunction with std::move and MeshVariableArray with payload data.
  • Folder RadioInterfaces:
    • RFInterface.h - Contains abstract class, that act as interface with almost any radio.
    • NRF24L01_interface.h - Contains class inherited from the RFInterface. This class acts as interface with nRF24L01 or nRF24L01+ radio.
    • Simulation_interface.h - Contains class inherited from the RFInterface. This class acts as interface with virtual radio, which is used with MeshProtocolSimulator.

Examples

Simple example of basic node with nRF24L01+, which sends data over network:

Macro MESH_IMPL_CONSOLE_ITEM in meshConfig.h must be set to 0


//Includes for STM32
#include "wirish.h" //On STM32 arduino core (framework) must be included
#include "HardwareSPI.h"
//Includes for Arduino
//#include <SPI.h>

include "mesh.h"

include "NRF24L01_interface.h"

//On STM32 in STM32CubeIDE hspi1 is imported from main.c and enabled in .ioc file //On arduino comment out next two lines extern SPI_HandleTypeDef hspi1; HardwareSPI SPI(hspi1);

RF24 radio(5, 3); //Creating nRF24L01+ driver instance NRF24L01_RFI intf(radio, SPI); //Creating wrapper instance MeshNet mesh; //Creating MeshNet instance

//Called in main.c before infinity loop void setup(){ SPI.begin(); //Enabling SPI needed for nRF24L01+ mesh.setChannel(76); //Setting custom channel //Starting node with MeshMAC address 00-00-00-05 mesh.begin(MeshMAC(5), intf); //Setting auto connect to network with BSSID 00-00-00-01 //with retry every 30 seconds mesh.setAutoConnect(MeshMAC(1), 30000); }

uint32_t nextGreetingTime = 0;

//Called in main.c inside infinity loop void loop(){ //Sending data only if connected if(mesh.isConnected() && nextGreetingTime < millis()){ const uint8_t data[5] = {'H', 'e', 'l', 'l', 'o'}; mesh.send(0, data, 5); //Sending data to gateway node with address 0 nextGreetingTime = millis() + 10000; //Wait 10 seconds } mesh.handle(); //Handling mesh node code }


Simple example of main gateway node with nRF24L01+, which received data from network:
> Macro `MESH_IMPL_CONSOLE_ITEM` in `meshConfig.h` must be set to 0
```c++
#include "wirish.h" //On STM32 arduino core (framework) must be included
#include "HardwareSPI.h"
#include "HardwareSerial.h"
//Includes for Arduino
//#include <SPI.h>
//#include <Serial.h>

#include "meshNetGateway.h"
#include "NRF24L01_interface.h"

//On STM32 in STM32CubeIDE hspi1 and huart1 are imported from main.c and enabled in .ioc file
//On arduino comment out next four lines
extern SPI_HandleTypeDef hspi1;
HardwareSPI SPI(hspi1);
extern UART_HandleTypeDef huart1;
HardwareSerial Serial(huart1);

RF24 radio(5, 3); //Creating nRF24L01+ driver instance
NRF24L01_RFI intf(radio, SPI); //Creating wrapper instance
MeshNetGateway mesh; //Creating MeshNetGateway instance

void onReceive(MeshNet* mesh, MeshPacket& packet){
    //Reporting, that packet was received
    Serial.print("Received packet from ");
    Serial.print((int)packet.PacketHeader.Source);
    Serial.print(" with payload: ");
    Serial.write(packet.p_ptr(), packet.Length());
    Serial.println();
}

//Called in main.c before infinity loop
void setup(){
    SPI.begin(); //Enabling SPI needed for nRF24L01+
    Serial.begin(115200); //Enabling UART for printing
    mesh.setChannel(76); //Setting custom channel
    //Starting gateway node with MeshMAC address
    //and BSSID 00-00-00-01
    //and with SSID "My network"
    mesh.begin(MeshMAC(1), intf, "My network");
    //Setting callback function, that is called when packet is received
    mesh.setOnReceive(onReceive);
}

//Called in main.c inside infinity loop
void loop(){
    mesh.handle(); //Handling mesh node code
}

Simple example of basic node with nRF24L01+, which is controlled using SerialConsole interface through serial port:

Macro MESH_IMPL_CONSOLE_ITEM in meshConfig.h must be set to 1

//Includes for STM32
#include "wirish.h" //On STM32 arduino core (framework) must be included
#include "HardwareSPI.h"
#include "HardwareSerial.h"
//Includes for Arduino
//#include <SPI.h>
//#include <Serial.h>

#include "SerialConsole.h"
#include "mesh.h"
#include "NRF24L01_interface.h"

//On STM32 in STM32CubeIDE hspi1 and huart1 are imported from main.c and enabled in .ioc file
//On arduino comment out next four lines
extern SPI_HandleTypeDef hspi1;
HardwareSPI SPI(hspi1);
extern UART_HandleTypeDef huart1;
HardwareSerial Serial(huart1);

RF24 radio(5, 3); //Creating nRF24L01+ driver instance
NRF24L01_RFI intf(radio, SPI); //Creating wrapper instance
MeshNet mesh; //Creating MeshNet instance
SerialConsole console(Serial, "My console"); //Creating SerialConsole

//Called in main.c before infinity loop
void setup(){
    SPI.begin(); //Enabling SPI needed for nRF24L01+
    mesh.setChannel(76); //Setting custom channel
    //Starting node with MeshMAC address 00-00-00-05
    mesh.begin(MeshMAC(5), intf);
    console.begin(); //Enabling SerialConsole
    console.addConsoleItem(mesh); //Adding mesh as ConsoleItem to the SerialConsole
    //Setting auto connect to network with BSSID 00-00-00-01
    //with retry every 30 seconds
    mesh.setAutoConnect(MeshMAC(1), 30000);
}

uint32_t nextGreetingTime = 0;

//Called in main.c inside infinity loop
void loop(){
    console.handle(); //Handling SerialConsole code
    mesh.handle(); //Handling mesh node code
}

License

Copyright 2022 Matej Fitoš

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Author

Created by Matej Fitoš

Copyright © 2022 Matej Fitoš

                             Apache License
                       Version 2.0, January 2004
                    http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.

    "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."

    "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and

    (b) You must cause any modified files to carry prominent notices stating that You changed the files; and

    (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

    You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

    END OF TERMS AND CONDITIONS

    APPENDIX: How to apply the Apache License to your work.

    To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.

    Copyright 2022 Matej Fitoš

    Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Contributors 2

Matej Fitoš 97.78%

Juraj Ďuďák 2.22%


Links

Languages

  • C++ 99.99%
  • Batchfile 0.01%
  • Makefile 0%

  • Application
    Last update

    2022-05-05 22:21:33

    Created at

    19.12.2021