AlLoRa 1.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. AlLoRa-1.1.0/AlLoRa/Connectors/Connector.py +111 -0
  2. AlLoRa-1.1.0/AlLoRa/Connectors/LoPy4_connector.py +76 -0
  3. AlLoRa-1.1.0/AlLoRa/Connectors/SX127x_connector.py +63 -0
  4. AlLoRa-1.1.0/AlLoRa/Connectors/Serial_connector.py +49 -0
  5. AlLoRa-1.1.0/AlLoRa/Connectors/Wifi_connector.py +67 -0
  6. AlLoRa-1.1.0/AlLoRa/Connectors/__init__.py +0 -0
  7. AlLoRa-1.1.0/AlLoRa/DataSource.py +115 -0
  8. AlLoRa-1.1.0/AlLoRa/Digital_Endpoint.py +105 -0
  9. AlLoRa-1.1.0/AlLoRa/File.py +113 -0
  10. AlLoRa-1.1.0/AlLoRa/Interfaces/Interface.py +18 -0
  11. AlLoRa-1.1.0/AlLoRa/Interfaces/Serial_interface.py +62 -0
  12. AlLoRa-1.1.0/AlLoRa/Interfaces/Wifi_client.py +109 -0
  13. AlLoRa-1.1.0/AlLoRa/Interfaces/Wifi_hotspot.py +73 -0
  14. AlLoRa-1.1.0/AlLoRa/Interfaces/__init__.py +0 -0
  15. AlLoRa-1.1.0/AlLoRa/Nodes/Adapter.py +44 -0
  16. AlLoRa-1.1.0/AlLoRa/Nodes/Gateway.py +56 -0
  17. AlLoRa-1.1.0/AlLoRa/Nodes/Node.py +107 -0
  18. AlLoRa-1.1.0/AlLoRa/Nodes/Receiver.py +141 -0
  19. AlLoRa-1.1.0/AlLoRa/Nodes/Sender.py +212 -0
  20. AlLoRa-1.1.0/AlLoRa/Nodes/__init__.py +0 -0
  21. AlLoRa-1.1.0/AlLoRa/Packet.py +339 -0
  22. AlLoRa-1.1.0/AlLoRa/__init__.py +0 -0
  23. AlLoRa-1.1.0/AlLoRa.egg-info/PKG-INFO +634 -0
  24. AlLoRa-1.1.0/AlLoRa.egg-info/SOURCES.txt +45 -0
  25. AlLoRa-1.1.0/AlLoRa.egg-info/dependency_links.txt +1 -0
  26. AlLoRa-1.1.0/AlLoRa.egg-info/top_level.txt +2 -0
  27. AlLoRa-1.1.0/LICENSE +674 -0
  28. AlLoRa-1.1.0/PKG-INFO +634 -0
  29. AlLoRa-1.1.0/README.md +615 -0
  30. AlLoRa-1.1.0/examples/Adapters/Serial_adapter/__init__.py +0 -0
  31. AlLoRa-1.1.0/examples/Adapters/Serial_adapter/main.py +15 -0
  32. AlLoRa-1.1.0/examples/Adapters/WiFi_adapters/__init__.py +0 -0
  33. AlLoRa-1.1.0/examples/Adapters/__init__.py +0 -0
  34. AlLoRa-1.1.0/examples/LoPyReceiver/__init__.py +0 -0
  35. AlLoRa-1.1.0/examples/LoPyReceiver/boot.py +11 -0
  36. AlLoRa-1.1.0/examples/LoPyReceiver/main.py +27 -0
  37. AlLoRa-1.1.0/examples/LoPySender/__init__.py +0 -0
  38. AlLoRa-1.1.0/examples/LoPySender/boot.py +11 -0
  39. AlLoRa-1.1.0/examples/LoPySender/main.py +64 -0
  40. AlLoRa-1.1.0/examples/RaspberryGateway/Serial_Gateway/__init__.py +0 -0
  41. AlLoRa-1.1.0/examples/RaspberryGateway/Serial_Gateway/main.py +17 -0
  42. AlLoRa-1.1.0/examples/RaspberryGateway/Wifi_Gateway/__init__.py +0 -0
  43. AlLoRa-1.1.0/examples/RaspberryGateway/Wifi_Gateway/main.py +16 -0
  44. AlLoRa-1.1.0/examples/RaspberryGateway/__init__.py +0 -0
  45. AlLoRa-1.1.0/examples/__init__.py +0 -0
  46. AlLoRa-1.1.0/setup.cfg +4 -0
  47. AlLoRa-1.1.0/setup.py +35 -0
@@ -0,0 +1,111 @@
1
+ from AlLoRa.Packet import Packet
2
+ try:
3
+ from utime import sleep, ticks_ms as time
4
+ from uos import urandom
5
+ import gc
6
+ except:
7
+ from time import sleep, time
8
+ from os import urandom
9
+
10
+ class Connector:
11
+ MAX_LENGTH_MESSAGE = 255
12
+
13
+ def __init__(self):
14
+ self.MAC = "00000000"
15
+
16
+ def config(self, name="N", frequency = 868, sf=7, mesh_mode=False, debug=False, min_timeout = 0.5, max_timeout = 6):
17
+ self.name = name
18
+ self.frequency = frequency
19
+ self.sf = sf
20
+ self.mesh_mode = mesh_mode
21
+
22
+ self.debug = debug
23
+
24
+ self.min_timeout = min_timeout
25
+ self.max_timeout = max_timeout
26
+ self.adaptive_timeout = self.min_timeout
27
+ self.backup_timeout = self.adaptive_timeout
28
+
29
+ self.sf_backup = self.sf
30
+
31
+ def backup_config(self):
32
+ return {"freq": self.frequency,
33
+ "sf": self.sf,
34
+ "min_timeout": self.min_timeout,
35
+ "max_timeout": self.max_timeout
36
+ }
37
+
38
+ def get_mac(self):
39
+ return self.MAC
40
+
41
+ def set_sf(self, sf):
42
+ pass
43
+
44
+ def backup_sf(self):
45
+ self.sf_backup = self.sf
46
+
47
+ def restore_sf(self):
48
+ self.set_sf(self.sf_backup)
49
+
50
+ def set_mesh_mode(self, mesh_mode=False):
51
+ self.mesh_mode = mesh_mode
52
+
53
+ def send(self, packet: Packet):
54
+ return None
55
+
56
+ def recv(self, focus_time=12):
57
+ return None
58
+
59
+ def send_and_wait_response(self, packet):
60
+ packet.set_source(self.get_mac()) # Adding mac address to packet
61
+ focus_time = self.adaptive_timeout
62
+ send_success = self.send(packet)
63
+ #if not send_success:
64
+ #return None
65
+
66
+ while focus_time > 0:
67
+ t0 = time()
68
+ received_data = self.recv(focus_time)
69
+ td = (time() - t0)/1000
70
+ if not received_data:
71
+ random_factor = int.from_bytes(urandom(2), "little") / 2**16
72
+ self.adaptive_timeout = min(self.adaptive_timeout * (1 + random_factor),
73
+ self.max_timeout) #random exponential backoff.
74
+ gc.collect()
75
+ return None
76
+ response_packet = Packet(self.mesh_mode)
77
+ if self.debug:
78
+ self.signal_estimation()
79
+ print("WAIT_RESPONSE({}) || sender_reply: {}".format(self.adaptive_timeout, received_data))
80
+ try:
81
+ response_packet.load(received_data)
82
+ if response_packet.get_source() == packet.get_destination() and response_packet.get_destination() == self.get_mac():
83
+ if len(received_data) > response_packet.HEADER_SIZE + 60: # Hardcoded for only chunks
84
+ self.adaptive_timeout = max(self.adaptive_timeout * 0.8 + td * 0.21, self.min_timeout)
85
+ if response_packet.get_debug_hops():
86
+ response_packet.add_hop(self.name, self.get_rssi(), 0)
87
+ if response_packet.get_change_sf():
88
+ print("OK and changing sf")
89
+ new_sf = int(response_packet.get_payload().decode().split('"')[1])
90
+ print(new_sf)
91
+ self.set_sf(new_sf)
92
+ gc.collect()
93
+ return response_packet
94
+ except Exception as e:
95
+ print("Corrupted packet received", e, received_data)
96
+ focus_time = self.adaptive_timeout - td
97
+
98
+ """ This function returns the RSSI of the last received packet"""
99
+ def get_rssi(self):
100
+ return 0
101
+
102
+ def signal_estimation(self):
103
+ percentage = 0
104
+ rssi = self.get_rssi()
105
+ if (rssi >= -50):
106
+ percentage = 100
107
+ elif (rssi <= -50) and (rssi >= -100):
108
+ percentage = 2 * (rssi + 100)
109
+ elif (rssi < 100):
110
+ percentage = 0
111
+ print('SIGNAL STRENGTH', percentage, '%')
@@ -0,0 +1,76 @@
1
+ from time import sleep
2
+
3
+ from AlLoRa.Packet import Packet
4
+ from AlLoRa.Connectors.Connector import Connector
5
+ from network import LoRa
6
+ import socket
7
+ import binascii
8
+
9
+ import pycom
10
+
11
+ class LoPy4_connector(Connector):
12
+
13
+ def __init__(self):
14
+ super().__init__()
15
+ self.MAC = binascii.hexlify(LoRa().mac()).decode('utf-8')[-8:]
16
+
17
+ def config(self, name = "L", frequency = 868, sf=7,
18
+ mesh_mode=False, debug=False, min_timeout = 0.5, max_timeout = 6): #max_timeout = 100
19
+ super().config(name, frequency, sf, mesh_mode, debug, min_timeout, max_timeout)
20
+ self.lora = LoRa(mode=LoRa.LORA, frequency=self.frequency*1000000,
21
+ region=LoRa.EU868, sf = self.sf)
22
+ self.lora_socket = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
23
+
24
+ def set_sf(self, sf):
25
+ if self.sf != sf:
26
+ self.lora.sf(sf)
27
+ self.sf = sf
28
+ if self.debug:
29
+ print("SF Changed to: ", self.sf)
30
+
31
+ def get_stats(self):
32
+ stats = self.lora.stats()
33
+ if self.debug:
34
+ print("rx_timestamp {0}, rssi {1}, snr {2}, sftx {3}, sfrx {4}, tx_trials {5}, tx_power {6}, tx_time_on_air {7}, tx_counter {8}, tx_frequency {9}".format(stats[0],
35
+ stats[1], stats[2], stats[3], stats[4], stats[5], stats[6], stats[7], stats[8], stats[9]))
36
+ return stats
37
+
38
+ def get_rssi(self):
39
+ return self.lora.stats()[1]
40
+
41
+ def send(self, packet):
42
+ if packet.get_length() <= Connector.MAX_LENGTH_MESSAGE:
43
+ if self.debug:
44
+ print("SEND_PACKET(SF: {}) || packet: {}".format(self.sf, packet.get_content()))
45
+ if packet.get_mesh():
46
+ pycom.rgbled(0xb19cd8) # purple
47
+ else:
48
+ pycom.rgbled(0x007f00) # green
49
+ try:
50
+ self.lora_socket.send(packet.get_content()) #.encode()
51
+ if self.debug:
52
+ pycom.rgbled(0) # off
53
+ return True
54
+ except:
55
+ if self.debug:
56
+ pycom.rgbled(0) # off
57
+ return False
58
+ else:
59
+ if self.debug:
60
+ print("Error: Packet too big")
61
+ return False
62
+
63
+ def recv(self, focus_time=12):
64
+ try:
65
+ self.lora_socket.settimeout(focus_time)
66
+ data = self.lora_socket.recv(Connector.MAX_LENGTH_MESSAGE)
67
+ self.lora_socket.setblocking(False)
68
+ if self.debug:
69
+ self.get_stats()
70
+ return data
71
+ except Exception as e:
72
+ if self.debug:
73
+ print("Error receiving: ", e)
74
+
75
+ def send_and_wait_response(self, packet):
76
+ return super().send_and_wait_response(packet)
@@ -0,0 +1,63 @@
1
+ import time
2
+ import ubinascii
3
+ import network
4
+
5
+ from AlLoRa.Packet import Packet
6
+ from AlLoRa.Connectors.Connector import Connector
7
+
8
+ # Requires PyLora_SX127x_extensions to be installed
9
+ # https://github.com/GRCDEV/PyLora_SX127x_extensions
10
+ from PyLora_SX127x_extensions.pyLora import pyLora
11
+
12
+ class SX127x_connector(Connector):
13
+
14
+ def __init__(self): #max_timeout = 10
15
+ super().__init__()
16
+
17
+ wlan_sta = network.WLAN(network.STA_IF)
18
+ wlan_sta.active(True)
19
+ wlan_mac = wlan_sta.config('mac')
20
+ self.MAC = ubinascii.hexlify(wlan_mac).decode()[-8:]
21
+ wlan_sta.active(False)
22
+
23
+ def config(self, name = "S", frequency = 868, sf=7, mesh_mode=False, debug=False, min_timeout = 0.5, max_timeout = 6): #max_timeout = 10
24
+ super().config(name, frequency, sf, mesh_mode, debug, min_timeout, max_timeout)
25
+ self.lora = pyLora(freq = self.frequency,
26
+ sf=self.sf, verbose= self.debug)
27
+ self.lora.setblocking(False)
28
+
29
+ def set_sf(self, sf):
30
+ if self.sf != sf:
31
+ self.lora.sf(sf)
32
+ self.sf = sf
33
+ if self.debug:
34
+ print("SF Changed to: ", self.sf)
35
+
36
+ def get_rssi(self):
37
+ return self.lora.get_rssi()
38
+
39
+ def send(self, packet):
40
+ if self.debug:
41
+ print("SEND_PACKET() || packet: {}".format(packet.get_content()))
42
+ if packet.get_length() <= Connector.MAX_LENGTH_MESSAGE:
43
+ try:
44
+ self.lora.setblocking(True)
45
+ self.lora.send(packet.get_content()) # .encode()
46
+ self.lora.setblocking(False)
47
+ return True
48
+ except:
49
+ self.lora.setblocking(False)
50
+ return False
51
+ else:
52
+ if self.debug:
53
+ print("Error: Packet too big")
54
+ return False
55
+
56
+ def recv(self, focus_time=12):
57
+ try:
58
+ self.lora.settimeout(focus_time)
59
+ data = self.lora.recv(Connector.MAX_LENGTH_MESSAGE)
60
+ return data
61
+ except:
62
+ if self.debug:
63
+ print("nothing received or error")
@@ -0,0 +1,49 @@
1
+ import serial, struct
2
+ from time import sleep, time
3
+
4
+
5
+ from AlLoRa.Packet import Packet
6
+ from AlLoRa.Connectors.Connector import Connector
7
+
8
+ class Serial_connector(Connector):
9
+
10
+ def __init__(self, serial_port = "/dev/ttyAMA3", baud = 9600, timeout = 1):
11
+ super().__init__()
12
+ self.SERIAL_PORT = serial_port
13
+ self.BAUD_RATE = baud
14
+ self.timeout = timeout
15
+ self.serial = serial.Serial(self.SERIAL_PORT, self.BAUD_RATE, timeout=self.timeout)
16
+
17
+
18
+ def send_and_wait_response(self, packet: Packet) -> Packet:
19
+ if self.debug:
20
+ print("send and wait")
21
+ retry = True
22
+ max_retries = 1
23
+ response_packet = Packet(self.mesh_mode)
24
+ while max_retries > 0 and retry:
25
+ try:
26
+ content = packet.get_content()
27
+ if self.debug:
28
+ print("Sending: ", content)
29
+
30
+ self.serial.write(content)
31
+ sleep(1)
32
+ received_data = self.serial.read(255)
33
+
34
+ if received_data:
35
+ response_packet = Packet(self.mesh_mode)
36
+ check = response_packet.load(received_data)
37
+ if check:
38
+ if self.debug:
39
+ print("Receiving: ", response_packet.get_content())
40
+ retry = False
41
+
42
+ except Exception as e:
43
+ retry = True
44
+ if self.debug:
45
+ print("Error S&W: ", e)
46
+ finally:
47
+ max_retries -= 1
48
+
49
+ return response_packet
@@ -0,0 +1,67 @@
1
+ import socket
2
+ import json
3
+ import select
4
+ from time import sleep, time
5
+
6
+ from AlLoRa.Packet import Packet
7
+ from AlLoRa.Connectors.Connector import Connector
8
+
9
+ class WiFi_connector(Connector):
10
+
11
+ def __init__(self, RECEIVER_API_HOST, RECEIVER_API_PORT, SOCKET_TIMEOUT=10,
12
+ SOCKET_RECV_SIZE=10000, PACKET_RETRY_SLEEP=0.5, logger_error=None):
13
+ super().__init__()
14
+ self.SOCKET_TIMEOUT = SOCKET_TIMEOUT
15
+ self.RECEIVER_API_HOST = RECEIVER_API_HOST
16
+ self.RECEIVER_API_PORT = RECEIVER_API_PORT
17
+ self.SOCKET_RECV_SIZE = SOCKET_RECV_SIZE
18
+ self.logger_error = logger_error
19
+ self.PACKET_RETRY_SLEEP = PACKET_RETRY_SLEEP
20
+
21
+ def send_and_wait_response(self, packet: Packet) -> Packet:
22
+ json_response = None
23
+ retry = True
24
+ max_retries = 1
25
+ response_packet = Packet(self.mesh_mode)
26
+ while max_retries > 0 and retry:
27
+ try:
28
+ s = socket.socket()
29
+ s.setblocking(True)
30
+ addr = socket.getaddrinfo(self.RECEIVER_API_HOST, self.RECEIVER_API_PORT)[0][-1]
31
+ s.settimeout(self.SOCKET_TIMEOUT)
32
+ s.connect(addr)
33
+
34
+ content_str = packet.get_dict()
35
+ content = json.dumps({"packet": content_str})
36
+
37
+ httpreq = 'POST {} HTTP/1.1\r\nHost: {}\r\nConnection: close\r\nAccept: */*\r\nContent-Type: application/json\r\nContent-Length: {}\r\n\r\n{}'.format(
38
+ "/send-packet", self.RECEIVER_API_HOST, len(content), content).encode('utf-8')
39
+
40
+ ready_to_read, ready_to_write, in_error = select.select([],
41
+ [s],
42
+ [],
43
+ 15)
44
+ s.send(httpreq)
45
+ ready_to_read, ready_to_write, in_error = select.select([s],
46
+ [],
47
+ [s],
48
+ 15)
49
+ response = s.recv(self.SOCKET_RECV_SIZE)
50
+
51
+ retry = False
52
+ try:
53
+ extracted_response = response.decode('utf-8').split('\r\n\r\n')[1]
54
+ json_response = json.loads(extracted_response)
55
+ response_packet.load_dict(json_response['response_packet'])
56
+ except Exception as e:
57
+ #print("Error in load: ", e)
58
+ pass # It fails when response is empty
59
+
60
+ except Exception as e:
61
+ #self.logger_error.error("Allowed Exception (Network connection was interrupted by some reason, but will keep trying to reconnect): {}".format(e))
62
+ sleep(self.PACKET_RETRY_SLEEP)
63
+ retry = True
64
+ finally:
65
+ max_retries -= 1
66
+
67
+ return response_packet
File without changes
@@ -0,0 +1,115 @@
1
+ import _thread
2
+ import utime
3
+ import os
4
+
5
+ from AlLoRa.File import CTP_File
6
+
7
+ # Do not instanciate this class as pretends to be an abstract one
8
+ class DataSource:
9
+
10
+
11
+ def __init__(self, file_chunk_size: int, file_queue_size=25, sleep_between_readings=60):
12
+
13
+ self.STOP_THREAD = True
14
+ self.IS_STARTED = False
15
+
16
+ self.file_queue = []
17
+ self.file_queue_size = file_queue_size
18
+ self.file_chunk_size = file_chunk_size
19
+
20
+ self.SECONDS_BETWEEN_READINGS = sleep_between_readings
21
+
22
+ self.backup_file = None
23
+
24
+
25
+ def get_file_chunk_size(self):
26
+ return self.file_chunk_size
27
+
28
+
29
+ def add_to_queue(self, file: CTP_File):
30
+ if len(self.file_queue) >= self.file_queue_size:
31
+ self.file_queue.pop(0)
32
+ repeated = False
33
+ for f in self.file_queue:
34
+ if f.get_name() == file.get_name():
35
+ repeated = True
36
+ break
37
+ if repeated is False:
38
+ self.file_queue.append(file)
39
+
40
+
41
+ def read(self):
42
+ while self.STOP_THREAD is False:
43
+ try:
44
+ file = self.read_datasource()
45
+ if file is not None:
46
+ self.add_to_queue(file=file)
47
+ else:
48
+ print("skipped file, it is None")
49
+ utime.sleep(self.SECONDS_BETWEEN_READINGS)
50
+ except KeyboardInterrupt as e:
51
+ self.stop()
52
+ self.IS_STARTED = False
53
+ print(self.STOP_THREAD)
54
+
55
+
56
+ def read_datasource(self) -> CTP_File:
57
+ pass
58
+
59
+
60
+ def prepare(self):
61
+ pass
62
+
63
+ def start(self):
64
+ self.prepare()
65
+ self.STOP_THREAD = False
66
+ self.IS_STARTED = True
67
+ _thread.start_new_thread(self.read, ())
68
+
69
+
70
+ def stop(self):
71
+ self.STOP_THREAD = True
72
+ print(self.STOP_THREAD)
73
+
74
+ def is_started(self):
75
+ return self.IS_STARTED
76
+
77
+ '''
78
+ Everytime this function is called, it assumes the file is already consumed, so a deleting is performed.
79
+ '''
80
+ def get_next_file(self):
81
+ try:
82
+ backup_file = self.file_queue.pop(0)
83
+ self.backup(file=backup_file)
84
+ return backup_file
85
+ except IndexError as e:
86
+ return None
87
+
88
+
89
+ def get_backup(self):
90
+ try:
91
+ filename = ""
92
+ with open("./filename-backup.txt", "r") as f:
93
+ filename = f.read()
94
+
95
+ content = None
96
+ with open("./content-backup", "r") as f:
97
+ content = f.read()
98
+ rescued_file = CTP_File(name='{}'.format(filename), content=bytearray(content), chunk_size=self.file_chunk_size)
99
+ return rescued_file
100
+ except OSError as e:
101
+ print("The backup could not be restored", e)
102
+
103
+
104
+ def backup(self, file: CTP_File):
105
+ try:
106
+ os.remove("./filename-backup.txt")
107
+ os.remove("./content-backup")
108
+ except OSError:
109
+ pass
110
+
111
+ with open("./filename-backup.txt", "w") as f:
112
+ f.write(file.get_name())
113
+
114
+ with open("./content-backup", "w") as f:
115
+ f.write(file.get_content())
@@ -0,0 +1,105 @@
1
+ from AlLoRa.File import CTP_File
2
+
3
+ class Digital_Endpoint:
4
+
5
+ REQUEST_DATA_STATE = "REQUEST_DATA_STATE"
6
+ PROCESS_CHUNK_STATE = "PROCESS_CHUNK_STATE"
7
+ OK = "OK"
8
+
9
+ def __init__(self, name: str, mac_address: str, active: bool = True, sleep_mesh: bool = True,
10
+ MAX_RETRANSMISSIONS_BEFORE_MESH: int = 10):
11
+ self.name = name
12
+ self.mac_address = mac_address[-8:]
13
+ self.active = active
14
+ self.current_file = None
15
+
16
+ self.state = Digital_Endpoint.OK
17
+
18
+ self.mesh = False
19
+ self.sleep_mesh = sleep_mesh
20
+ self.retransmission_counter = 0
21
+ self.MAX_RETRANSMISSIONS_BEFORE_MESH = MAX_RETRANSMISSIONS_BEFORE_MESH
22
+
23
+ def get_name(self):
24
+ return self.name
25
+
26
+ def get_mac_address(self):
27
+ return self.mac_address
28
+
29
+ def get_mesh(self):
30
+ return self.mesh
31
+
32
+ def is_active(self):
33
+ return self.active
34
+
35
+ def enable_mesh(self):
36
+ self.mesh = True
37
+ print("Node {}: ENABLING MESH".format(self.name))
38
+
39
+ def disable_mesh(self):
40
+ self.mesh = False
41
+ self.retransmission_counter = 0
42
+ print("Node {}: DISABLING MESH".format(self.name))
43
+
44
+ def get_sleep(self):
45
+ return self.sleep_mesh
46
+
47
+ def count_retransmission(self):
48
+ if not self.get_mesh():
49
+ self.retransmission_counter += 1
50
+ if self.retransmission_counter >= self.MAX_RETRANSMISSIONS_BEFORE_MESH:
51
+ self.enable_mesh()
52
+
53
+ def reset_retransmission_counter(self, hop): #packet
54
+ if not self.get_mesh(): # If mesh mode is deactivated and I receive a message from this node
55
+ self.retransmission_counter = 0 # Reset counter, going well...
56
+ else:
57
+ if not hop:
58
+ self.disable_mesh()
59
+
60
+ def set_current_file(self, file: CTP_File):
61
+ self.current_file = file
62
+
63
+ def get_current_file(self):
64
+ return self.current_file
65
+
66
+ def connected(self, ok, hop, mesh_mode):
67
+ if ok:
68
+ if mesh_mode:
69
+ self.reset_retransmission_counter(hop)
70
+ self.state = Digital_Endpoint.REQUEST_DATA_STATE
71
+ else:
72
+ if mesh_mode:
73
+ self.count_retransmission()
74
+
75
+ def set_metadata(self, metadata, hop, mesh_mode):
76
+ if metadata:
77
+ new_file = CTP_File(name = metadata[1], length = metadata[0])
78
+ self.set_current_file(new_file)
79
+ if mesh_mode:
80
+ self.reset_retransmission_counter(hop)
81
+
82
+ self.state = Digital_Endpoint.PROCESS_CHUNK_STATE
83
+ else:
84
+ if mesh_mode:
85
+ self.count_retransmission()
86
+
87
+ def get_next_chunk(self):
88
+ try:
89
+ self.current_chunk = self.current_file.get_missing_chunks()[0]
90
+ return self.current_chunk
91
+ except:
92
+ return None
93
+
94
+ def set_data(self, data, hop, mesh_mode):
95
+ if data:
96
+ self.current_file.add_chunk(self.current_chunk, data)
97
+ if mesh_mode:
98
+ self.reset_retransmission_counter(hop)
99
+ else:
100
+ if mesh_mode:
101
+ self.count_retransmission()
102
+
103
+ if len(self.current_file.get_missing_chunks()) <= 0:
104
+ self.state = Digital_Endpoint.OK
105
+ return self.current_file