Skip to content

Commit f6cd5e4

Browse files
author
Catalin Ioana
committed
lib/lora_mesh: added Border Router example
1 parent 309c729 commit f6cd5e4

File tree

2 files changed

+105
-3
lines changed

2 files changed

+105
-3
lines changed

lib/lora_mesh/loramesh.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def __init__(self, lora=None):
3939
self.ip_link = ''
4040
self.single = True
4141
self.state = STATE_DISABLED
42+
self.ip_others = []
4243

4344
def _state_update(self):
4445
""" Returns the Thread role """
@@ -54,6 +55,7 @@ def _rloc_ip_net_addr(self):
5455

5556
def _update_ips(self):
5657
""" Updates all the unicast IPv6 of the Thread interface """
58+
self.ip_others = []
5759
ips = self.mesh.ipaddr()
5860
self.rloc16 = self.mesh.rloc()
5961
for line in ips:
@@ -73,6 +75,8 @@ def _update_ips(self):
7375
elif line.startswith('fe80'):
7476
# Link-Local
7577
self.ip_link = line
78+
else:
79+
self.ip_others.append(line)
7680

7781
def is_connected(self):
7882
""" Returns true if it is connected as either Child, Router or Leader """
@@ -89,10 +93,18 @@ def led_state(self):
8993
else:
9094
pycom.rgbled(self.RGBLED[self.state])
9195

92-
def ip(self):
96+
# returns the IP ML-EID or the ip having this prefix
97+
def ip(self, prefix = None):
9398
""" Returns the IPv6 RLOC """
94-
self._update_ips()
95-
return self.rloc
99+
ip = self._update_ips()
100+
if prefix is None:
101+
return self.ip_eid
102+
# we need to check al IPs from self.ip_others that may start with prefix
103+
p = prefix.split("::")[0]
104+
for ip in self.ip_others:
105+
if ip.startswith(p):
106+
return ip
107+
return None
96108

97109
def neighbors(self):
98110
""" Returns a list with all properties of the neighbors """
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
from network import LoRa
2+
import ubinascii
3+
from loramesh import Loramesh
4+
import pycom
5+
import time
6+
import socket
7+
import struct
8+
9+
BORDER_ROUTER_HEADER_FORMAT = '!BHHHHHHHHH'
10+
11+
pycom.wifi_on_boot(False)
12+
pycom.heartbeat(False)
13+
border_router_net = "2001:dead:beef:caff::/64"
14+
15+
lora = LoRa(mode=LoRa.LORA, region=LoRa.EU868, bandwidth=LoRa.BW_125KHZ, sf=7)
16+
#mesh = lora.Mesh()
17+
MAC = str(ubinascii.hexlify(lora.mac()))[2:-1]
18+
print("LoRa MAC: %s"%MAC)
19+
20+
mesh = Loramesh(lora)
21+
22+
# waiting until it connected to Mesh network
23+
while True:
24+
mesh.led_state()
25+
print("%d: State %s, single %s"%(time.time(), mesh.cli('state'), mesh.cli('singleton')))
26+
time.sleep(2)
27+
if not mesh.is_connected():
28+
continue
29+
30+
print('Neighbors found: %s'%mesh.neighbors())
31+
print('IPs: %s'%mesh.mesh.ipaddr())
32+
print('BRs: %s'%mesh.mesh.border_router())
33+
break
34+
35+
#add BR
36+
if int(MAC, 16) == 8:
37+
if len(mesh.mesh.border_router()) == 0:
38+
mesh.mesh.border_router(border_router_net, 1)
39+
print("Set Border Router with prefix %s"%border_router_net)
40+
41+
# create UDP socket for Border Router interface
42+
br_socket = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
43+
myport = 1234
44+
print("Please wait until BR gets propagated to the Leader ...")
45+
while True:
46+
ip = mesh.ip(border_router_net)
47+
#ip = mesh.ip()
48+
if ip is not None:
49+
br_socket.bind((ip, myport))
50+
#s.bind(myport)
51+
print("Created socked for (%s, %d)"%(ip, myport))
52+
break
53+
time.sleep(1)
54+
55+
eid_sock = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
56+
myport = 1235
57+
ip = mesh.ip()# ipv6 EID
58+
if ip is not None:
59+
eid_sock.bind((ip, myport))
60+
#s.bind(myport)
61+
print("Created socked for (%s, %d)"%(ip, myport))
62+
63+
# handler responisble for receiving packets on UDP Pymesh socket
64+
def receive_pack(dummy):
65+
# listen for incomming packets
66+
sock = eid_sock
67+
while True:
68+
rcv_data, rcv_addr = sock.recvfrom(128)
69+
if len(rcv_data) == 0:
70+
rcv_data, rcv_addr = br_socket.recvfrom(128)
71+
if len(rcv_data) == 0:
72+
break
73+
print("Data from Border Router socket")
74+
sock = br_socket
75+
rcv_ip = rcv_addr[0]
76+
rcv_port = rcv_addr[1]
77+
print('Incomming %d bytes from %s (port %d)'%(len(rcv_data), rcv_ip, rcv_port))
78+
if sock == br_socket and len(rcv_data) >= struct.calcsize(BORDER_ROUTER_HEADER_FORMAT):
79+
br_header = struct.unpack(BORDER_ROUTER_HEADER_FORMAT, rcv_data)
80+
print("IP dest: %X:%X:%X:%X:%X:%X:%X:%X (port %d)"%(
81+
br_header[1],br_header[2],br_header[3],br_header[4],
82+
br_header[5],br_header[6],br_header[7],br_header[8], br_header[9]))
83+
print(rcv_data[struct.calcsize(BORDER_ROUTER_HEADER_FORMAT):])
84+
else:
85+
print(rcv_data)
86+
if not rcv_data.startswith("ACK"):
87+
print("Sent ACK back")
88+
sock.sendto('ACK', (rcv_ip, rcv_port))
89+
90+
mesh.mesh.rx_cb(receive_pack, None)

0 commit comments

Comments
 (0)