def _process_leader(self):
        print_debug(3, "Process Leader")
        """
        if state == self.mesh.STATE_LEADER_SINGLE:
            # no neighbors routers, so nothing left to do
            return
        """
        # cleanup old entries
        self.mesh.leader_dict_cleanup()

        if time.time() - self.leader_ts < self.LEADER_INTERVAL:
            return

        # ask each router
        self.leader_ts = time.time()
        router_list = self.mesh.routers_rloc_list(60)
        router_num = min(len(router_list), 5)
        idx = 0
        for router_pair in router_list[:router_num]:
            (age, router) = router_pair
            self.send_pack(self.PACK_LEADER_ASK_NEIGH, '', router)
            print_debug(3, "Leader inquire Router %s" % router)
            idx = idx + 1
            if idx < router_num:
                time.sleep(.5)
    def border_router(self, enable, prio=0, br_mess_cb=None):
        """ Disables/Enables the Border Router functionality, with priority and callback """
        net_list = self.mesh.mesh.border_router()
        print_debug(3, "State:" + str(enable) + "BR: " + str(net_list))

        if not enable:
            # disable all BR network registrations (possible multiple)
            self.br_handler = None
            for net in net_list:
                self.mesh.mesh.border_router_del(net.net)
            print_debug(3, "Done remove BR")
        else:
            self.br_handler = br_mess_cb
            # check if BR already added
            try:
                # print_debug(3, net[0].net)
                # print_debug(3, self.BR_NET_ADDRESS)
                # if net[0].net != self.BR_NET_ADDRESS:
                if not net_list[0].net.startswith(self.BR_NET_ADDRESS[0:-3]):
                    # enable BR
                    self.mesh.mesh.border_router(self.BR_NET_ADDRESS, prio)
                    print_debug(3, "Done add BR")
            except:
                # enable BR
                self.mesh.mesh.border_router(self.BR_NET_ADDRESS, prio)
                print_debug(3, "Force add BR")

        # print again the BR, to confirm
        net_list = self.mesh.mesh.border_router()
        print_debug(3, "BR: " + str(net_list))
        pass
Example #3
0
    def periodic_cb(self, alarm):
        # wait lock forever
        if self.lock.acquire():
            print_debug(2, "============ MESH THREAD >>>>>>>>>>> ")
            t0 = time.ticks_ms()

            self.mesh.process()
            if self.mesh.is_connected():
                # self.statistics.process()
                self.mesh.process_messages()

            # if Single Leader for 3 mins should reset
            # if self.mesh.mesh.state == self.mesh.mesh.STATE_LEADER and self.mesh.mesh.mesh.single():
            #     if self.single_leader_ts == 0:
            #         # first time Single Leader, record time
            #         self.single_leader_ts = time.time()
            #     print("Single Leader", self.mesh.mesh.state, self.mesh.mesh.mesh.single(),
            #         time.time() - self.single_leader_ts)

            #     if time.time() - self.single_leader_ts > 180:
            #         print("Single Leader, just reset")
            #         if self.sleep_function:
            #             self.sleep_function(1)
            # else:
            #     # print("Not Single Leader", self.mesh.mesh.state, self.mesh.mesh.mesh.single())
            #     self.single_leader_ts = 0

            self.lock.release()

            print_debug(
                2, ">>>>>>>>>>> DONE MESH THREAD ============ %d\n" %
                (time.ticks_ms() - t0))

        pass
Example #4
0
    def rcv_ack(self, data):
        """ just received an ACK for a previously sent message """
        message = Message()
        message.unpack_ack(data)

        # check if message was really in send buffer
        if message.mac in self.dict:
            self.dict[message.mac].state = Message.MESS_STATE_ACK

            if self.on_rcv_ack:
                self.on_rcv_ack(message)

            # check if message was about picture sending, to start actual file sending
            mess = self.dict[message.mac]
            if mess.payload == 'dog':
                print_debug(3, 'ACK from dog message, start picture sending')
                del self.dict[message.mac]
                self.send_message(message.mac, message.TYPE_IMAGE, 'dog.jpg', message.id, time.time())
                
                if self.on_rcv_message:
                    mess = Message((message.mac, message.TYPE_TEXT, 'Receiving the picture', message.id+1, time.time()))
                    self.on_rcv_message(mess)
        else:
            print_debug(3, str(message.mac) + str(self.dict))
        pass
    def br_send(self, data):
        """ if BR is available in whole Mesh, send some data """
        ret = False
        # first, make sure this node is not BR (BR data is sent directly)
        if len(self.mesh.mesh.border_router()) > 0:
            print_debug(3, "Node is BR, so shouldn't send data to another BR")
            return False

        # check if we have a BR network prefix in ipaddr
        for ip in self.mesh.ipaddr():
            if ip.startswith(self.BR_NET_ADDRESS[0:-4]):
                print_debug(3, "found BR address: %s" % ip)
                if time.time() - self.ext_mesh_ts >= 0:
                    ret = True
                    try:
                        ip = data['ip']
                        port = int(data['port'])
                        payload = data['b']
                    except:
                        print_debug(3,
                                    "Error parsing packet for Mesh-external")
                        ret = False
                    if ret:
                        self.send_pack(self.PACK_BR, payload, ip, port)
                        # self.send_pack(self.PACK_BR, self.debug_data(False), self.EXTERNAL_IP)
                        self.ext_mesh_ts = time.time()
                else:
                    print_debug(3, "BR sending too fast")
                    ret = False
        if not ret:
            print_debug(3, "no BR (mesh-external IPv6) found")
        return ret
Example #6
0
 def get_connections_pack(self):
     connections = self.get_mesh_connections()
     print_debug(3, "Connections " + str(connections))
     data = pack('!H', len(connections))
     for record in connections:
         (mac1, mac2, rssi) = record
         data = data + pack('!HHb', mac1, mac2, rssi)
     return data
Example #7
0
 def set_location(latitude, longitude):
     dlat = str(type(latitude))
     dlon = str(type(longitude))
     if dlat == dlon == "<class 'float'>":
         Gps.lat = latitude
         Gps.lon = longitude
         is_set = True
     else:
         print_debug(3, "Error parsing ", latitude, longitude)
Example #8
0
    def write_config(pymesh_config, force_restart=False):
        cf = open(PymeshConfig.CONFIG_FILENAME, 'w')
        cf.write(json.dumps(pymesh_config))
        cf.close()

        if force_restart:
            print_debug(3, "write_config force restart")
            time.sleep(1)
            machine.deepsleep(1000)
Example #9
0
 def node_info_mac_pack(self, mac):
     node, role = self.node_info_mac(mac)
     if node is None:
         print_debug(3, "Node is None %d" % mac)
         return bytes()
     # pack type: RouterData or Child (basically NeighborData)
     data = pack('!B', role)
     data = data + node.pack()
     return data
Example #10
0
 def send_message(self, mac, msg_type, payload, id, ts):
     """ send a new message """
     already = self.dict.get(mac, None)
     if already:
         print_debug(3, 'old message deleted for %X' % mac)
     message = Message((mac, msg_type, payload, id, ts))
     self.dict[mac] = message
     print_debug(3, "Added new message for %X: %s" % (mac, str(payload)))
     
     return True
Example #11
0
 def send_message(self, message, answer=None):
     """ actual sending of a message on socket """
     payload = message.pack(self.MAC, answer)
     pack_type = self.PACK_MESSAGE
     # if message.type == message.TYPE_IMAGE:
     #     pack_type = self.PACK_FILE_SEND
     if payload:
         print_debug(4, "Send message " + str(payload))
         self.send_pack(pack_type, payload, message.ip)
     pass
Example #12
0
 def file_transfer_done(self, rcv_data):
     message = Message(rcv_data)
     message.payload = 'Picture was received'
     print_debug(3, 'Picture done receiving from %d', message.mac)
     message.id = message.id + 1
     if self.on_rcv_message:
         self.on_rcv_message(message)
     
     self.send_message(message.mac, message.TYPE_TEXT, 'Picture was received', message.id+1, time.time())
     
     pass
    def __init__(self, config):
        """ Constructor """
        self.config = config
        config_lora = config.get('LoRa')
        self.lora = LoRa(mode=LoRa.LORA,
                         region=config_lora.get("region"),
                         frequency=config_lora.get("freq"),
                         bandwidth=config_lora.get("bandwidth"),
                         sf=config_lora.get("sf"))
        self.mesh = self.lora.Mesh()  #start Mesh

        # get Lora MAC address
        #self.MAC = str(ubinascii.hexlify(lora.mac()))[2:-1]
        self.MAC = int(str(ubinascii.hexlify(self.lora.mac()))[2:-1], 16)

        #last 2 letters from MAC, as integer
        self.mac_short = self.MAC & 0xFFFF  #int(self.MAC[-4:], 16)
        print_debug(
            5, "LoRa MAC: %s, short: %s" % (hex(self.MAC), self.mac_short))

        self.rloc16 = 0
        self.rloc = ''
        self.net_addr = ''
        self.ip_eid = ''
        self.ip_link = ''
        self.state = STATE_DISABLED

        # a dictionary with all direct neighbors
        # key is MAC for each neighbor
        # value is pair (age, mac, rloc16, role, rssi)
        #self.neigh_dict = {}
        self.router_data = RouterData()
        self.router_data.mac = self.MAC

        # a dictionary with all routers direct neighbors
        # key is MAC for each router
        # value is pair (age, rloc, neigh_num, (age, mac, rloc16, role, rssi))
        #self.leader_dict = {}
        self.leader_data = LeaderData()
        self.leader_data.mac = self.MAC

        # set of all MACS from whole current Mesh Network
        self.macs = set()
        self.macs_ts = -65535  # very old

        # list of all pairs (direct radio connections) inside Mesh
        self.connections = list()
        self.connections_ts = -65535  # very old

        # set a new unicast address
        self.unique_ip_prefix = "fdde:ad00:beef:0::"
        command = "ipaddr add " + self.ip_mac_unique(self.mac_short)
        self.mesh.cli(command)
Example #14
0
 def mesage_was_ack(self, mac, id):
     """ return True/False if a message was ACK """
     done = False
     try:
         message = self.dict[mac]
         if id == message.id:
             if message.state == Message.MESS_STATE_ACK:
                 done = True
     except:
         pass
     print_debug(3, "ACK? mac %x, id %d => %d" % (mac, id, done))
     return done
Example #15
0
    def get_type(self, data):

        (pack_type, len1) = unpack(self.PACK_HEADER_FMT,
                                   data[:calcsize(self.PACK_HEADER_FMT)])
        data = data[calcsize(self.PACK_HEADER_FMT):]

        len2 = len(data)
        if len1 != len2:
            print_debug(3, "PACK_HEADER length not ok %d %d" % (len1, len2))
            print_debug(3, str(data))
            return

        return (pack_type, data)
Example #16
0
    def node_info_set(self, data):
        (role, ) = unpack('!B', data)

        if role is self.STATE_ROUTER:
            router = RouterData(data[1:])
            self.leader_data.add_router(router)
            print_debug(3, "Added as router %s" % router.to_string())
        elif role is self.STATE_CHILD:
            node = NeighborData(data[1:])
            router = RouterData(node)
            self.leader_data.add_router(router)
            print_debug(3, "Added as Router-Neigh %s" % router.to_string())
        pass
Example #17
0
    def read_config(MAC):
        file = PymeshConfig.CONFIG_FILENAME
        pymesh_config = {}
        error_file = True

        try:
            import json
            f = open(file, 'r')
            jfile = f.read()
            f.close()
            try:
                pymesh_config = json.loads(jfile.strip())
                # pymesh_config['cfg_msg'] = "Pymesh configuration read from {}".format(file)
                error_file = False
            except Exception as ex:
                print_debug(
                    1,
                    "Error reading {} file!\n Exception: {}".format(file, ex))
        except Exception as ex:
            print_debug(
                1, "Final error reading {} file!\n Exception: {}".format(
                    file, ex))

        if error_file:
            # config file can't be read, so it needs to be created and saved
            pymesh_config = {}
            print_debug(
                3, "Can't find" + str(file) +
                ", or can't be parsed as json; Set default settings and reset")
            # don't write MAC, just to use the hardware one
            pymesh_config['LoRa'] = {
                "region": PymeshConfig.LORA_REGION,
                "freq": PymeshConfig.LORA_FREQ,
                "bandwidth": PymeshConfig.LORA_BW,
                "sf": PymeshConfig.LORA_SF
            }
            pymesh_config['Pymesh'] = {"key": PymeshConfig.KEY}
            pymesh_config['autostart'] = PymeshConfig.AUTOSTART
            pymesh_config['debug'] = PymeshConfig.DEBUG_LEVEL
            pymesh_config['ble_api'] = PymeshConfig.BLE_API
            pymesh_config['ble_name_prefix'] = PymeshConfig.BLE_NAME_PREFIX
            pymesh_config['br_ena'] = PymeshConfig.BR_ENABLE
            pymesh_config['br_prio'] = PymeshConfig.BR_PRIORITY

            PymeshConfig.check_mac(pymesh_config, MAC)
            print_debug(3, "Default settings:" + str(pymesh_config))
            PymeshConfig.write_config(pymesh_config, True)

        PymeshConfig.check_mac(pymesh_config, MAC)
        print_debug(3, "Settings:" + str(pymesh_config))
        return pymesh_config
    def neighbors_update(self):
        """ update neigh_dict from cli:'neighbor table' """
        """ >>> print(lora.cli("neighbor table"))
        | Role | RLOC16 | Age | Avg RSSI | Last RSSI |R|S|D|N| Extended MAC     |
        +------+--------+-----+----------+-----------+-+-+-+-+------------------+
        |   C  | 0x2801 | 219 |        0 |         0 |1|1|1|1| 0000000000000005 |
        |   R  | 0x7400 |   9 |        0 |         0 |1|0|1|1| 0000000000000002 |

        """
        x = self.mesh.neighbors()
        print_debug(3, "Neighbors Table: %s" % x)

        if x is None:
            # bad read, just keep previous neigbors
            return

        # clear all pre-existing neigbors
        self.router_data = RouterData()
        self.router_data.mac = self.MAC
        self.router_data.rloc16 = self.rloc16
        self.router_data.role = self.state
        self.router_data.ts = time.time()
        self.router_data.coord = Gps.get_location()

        for nei_rec in x:
            # nei_rec = (role=3, rloc16=10240, rssi=0, age=28, mac=5)
            age = nei_rec.age
            if age > 300:
                continue  # shouln't add neighbors too old
            role = nei_rec.role
            rloc16 = nei_rec.rloc16
            # maybe we shouldn't add Leader (because this info is already available at Leader)
            # if rloc16 == self.leader_rloc():
            #   continue
            rssi = nei_rec.rssi
            mac = nei_rec.mac
            neighbor = NeighborData((
                mac,
                age,
                rloc16,
                role,
                rssi,
            ))
            self.router_data.add_neighbor(neighbor)
            #print("new Neighbor: %s"%(neighbor.to_string()))
            #except:
            #    pass
        # add own info in dict
        #self.neigh_dict[self.MAC] = (0, self.rloc16, self.state, 0)
        print_debug(3, "Neighbors: %s" % (self.router_data.to_string()))
        return
Example #19
0
    def add_rcv_message(self, message):
        """ received a new message """
        message.ts = time.time()
        self.rcv_dict[message.mac] = message
        self.rcv_mess_new = message

        if message.payload == b'dog':#🐕':
            message.payload = 'Picture started receiving'
            print_debug(3, 'Rcv mess about dog, so we start receiving picture')
        # else:
        #     print_debug(3, 'payload is not dog')

        if self.on_rcv_message:
            self.on_rcv_message(message)

        return True
Example #20
0
    def __init__(self, config):
        """ Constructor """
        self.config_lora = config.get('LoRa')
        self._lora_init()

        # get Lora MAC address
        #self.MAC = str(ubinascii.hexlify(lora.mac()))[2:-1]
        self.MAC = int(str(ubinascii.hexlify(self.lora.mac()))[2:-1], 16)

        #last 2 letters from MAC, as integer
        self.mac_short = self.MAC & 0xFFFF  #int(self.MAC[-4:], 16)
        print_debug(
            5, "LoRa MAC: %s, short: %s" % (hex(self.MAC), self.mac_short))

        self.rloc16 = 0
        self.rloc = ''
        self.net_addr = ''
        self.ip_eid = ''
        self.ip_link = ''
        self.state = STATE_DISABLED

        # a dictionary with all direct neighbors
        # key is MAC for each neighbor
        # value is pair (age, mac, rloc16, role, rssi)
        #self.neigh_dict = {}
        self.router_data = RouterData()
        self.router_data.mac = self.MAC

        # a dictionary with all routers direct neighbors
        # key is MAC for each router
        # value is pair (age, rloc, neigh_num, (age, mac, rloc16, role, rssi))
        #self.leader_dict = {}
        self.leader_data = LeaderData()
        self.leader_data.mac = self.MAC

        # set of all MACS from whole current Mesh Network
        self.macs = set()
        self.macs_ts = -65535  # very old

        # list of all pairs (direct radio connections) inside Mesh
        self.connections = list()
        self.connections_ts = -65535  # very old

        # set a new unicast address
        self._add_ipv6_unicast()
Example #21
0
    def __init__(self, filename):
        self.packsize = 400 # packsize
        self.buffer = bytearray(self.packsize)
        self.mv = memoryview(self.buffer)
        #self.ip = 0 # ip
        self.chunk = 0
        self.filename = filename
        try:
            self.file = open(filename, "rb")
        except:
            print_debug(3, "File %s can't be opened !!!!"%filename)
            self.state = DONE
            return
        self.size = 0
        

        self.start = time.time()
        self.state = INIT
    def periodic_cb(self, alarm):
        # wait lock forever
        gc.collect()
        if self.lock.acquire():
            print_debug(2, "============ MESH THREAD >>>>>>>>>>> ")
            t0 = time.ticks_ms()

            self.mesh.process()
            if self.mesh.is_connected():
                # self.statistics.process()
                self.mesh.process_messages()

            # if Single Leader for 5 mins should reset
            if self.mesh.mesh.state == self.mesh.mesh.STATE_LEADER and self.mesh.mesh.mesh.single(
            ):
                if self.single_leader_ts == 0:
                    # first time Single Leader, record time
                    self.single_leader_ts = time.time()
                print("Single Leader", self.mesh.mesh.state,
                      self.mesh.mesh.mesh.single(),
                      time.time() - self.single_leader_ts)

                if time.time() - self.single_leader_ts > 300:
                    print("Single Leader, just reset")
                    self.mesh.mesh.mesh.deinit()
                    # machine.reset() this might be causing nodes to boot loop
                    if self.sleep_function:
                        self.sleep_function(1)
                    else:
                        machine.reset()
            else:
                # print("Not Single Leader", self.mesh.mesh.state, self.mesh.mesh.mesh.single())
                self.single_leader_ts = 0

            self.lock.release()

            print_debug(
                2, ">>>>>>>>>>> DONE MESH THREAD ============ %d\n" %
                (time.ticks_ms() - t0))

        pass
Example #23
0
    def send_pack(self, pack_type, data, ip, port=PORT_MESH_INTERNAL):
        if self.sock is None:
            return False

        print_debug(3, "Send pack: 0x%X to IP %s" % (pack_type, ip))

        # check not to send same (packet, destination) too often
        # if not self._check_to_send(pack_type, ip):
        #     print_debug(3, "NO send")
        #     return False

        sent_ok = True
        header = pack('!BH', pack_type, len(data))

        try:
            self.sock.sendto(header + data, (ip, port))
            #self.mesh.blink(2, .1)
        except Exception as ex:
            print_debug(3, "Socket.sendto exception: {}".format(ex))
            sent_ok = False
        return sent_ok
Example #24
0
    def process(self):
        self.mesh.update_internals()
        self.mesh.led_state()
        print_debug(3, "%d: MAC %s(%d), State %s, Single %s" % (time.time(),
            hex(self.MAC), self.MAC, self.mesh.state_string(), str(self.mesh.mesh.single())))
        print_debug(3, self.mesh.ipaddr())
        leader = self.mesh.mesh.leader()
        if leader is not None:
            print_debug(3,"Leader: mac %s, rloc %s, net: %s" %
                  (hex(leader.mac), hex(leader.rloc16), hex(leader.part_id)))
        if not self.mesh.is_connected():
            return  # nothing to do

        # create socket
        if self.sock is None:
            self.create_socket()

        if not self.rx_cb_registered:
            self.rx_cb_registered = True
            self.mesh.mesh.rx_cb(self.receive_all_data, None)

        # update internal neighbor table
        self.mesh.neighbors_update()

        self.mesh.leader_add_own_neigh()

        # # if file to be sent
        # if self.send_f is not None:
        #     data, ip = self.send_f.process(None)
        #     if len(data) > 0:
        #         self.send_pack(self.PACK_FILE_SEND, data, ip)

        # if self.mesh.state == self.mesh.STATE_LEADER:
        #     self._process_leader()
        return
Example #25
0
    def process(self, last_response):
        if self.state == INIT:
            self.chunk = self.file.readinto(self.buffer)
            self.state = WAIT_ACK
            self.retries = 0
            self.size = self.chunk
            self.start = time.time()

        elif self.state == WAIT_ACK:
            if last_response is not None:
                # got ACK, send next chunk
                self.chunk = self.file.readinto(self.buffer)
                self.size = self.size + self.chunk
                print_debug(3, "%d Bytes sent, time: %4d sec" % (self.size, time.time() - self.start))
                if self.chunk == 0:
                    self._end_transfer()

                self.retries = 0
            else:
                print_debug(3, "No answer, so retry?")
                if time.time() - self.last_ts < 5:
                    #if we just sent the retry, don't resend anything, still wait for answer
                    print_debug(3, "No retry, too soon")
                    return ''
                self.retries = self.retries + 1

            if self.retries > RETRIES_MAX:
                self._end_transfer()

        elif self.state == DONE:
            self.chunk = 0

        self.last_ts = time.time()
        return self.mv[:self.chunk]
Example #26
0
    def routers_rloc_list(self, age_min, resolve_mac=None):
        """ return list of all routers IPv6 RLOC16
            if mac parameter is present, then returns just the RLOC16 of that mac, if found
        """
        mac_ip = None
        data = self.mesh.routers()
        print_debug(3, "Routers Table: " + str(data))
        '''>>> print_debug(3, lora.cli('router table'))
        | ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
        +----+--------+----------+-----------+-------+--------+-----+------------------+
        | 12 | 0x3000 |       63 |         0 |     0 |      0 |   0 | 0000000000000002 |'''

        if data is None:
            # bad read
            return ()

        net_addr = self.net_addr
        routers_list = []
        for line in data:
            # line = (mac=123456, rloc16=20480, id=20, path_cost=0, age=7)
            age = line.age
            if age > 300:
                continue  # shouldn't add/resolve very old Routers
            rloc16 = line.rloc16

            # check if it's own rloc16
            if rloc16 == self.rloc16:
                continue

            if resolve_mac is not None:
                if resolve_mac == line.mac:
                    mac_ip = rloc16
                    break

            # look for this router in Leader Data
            # if doesn't exist, add it to routers_list with max ts
            # if it exists, just add it with its ts
            last_ts = self.leader_data.get_mac_ts(line.mac)
            if time.time() - last_ts < age_min:
                continue  # shouldn't add/resolve very "recent" Routers

            ipv6 = net_addr + hex(rloc16)[2:]
            routers_list.append((last_ts, ipv6))

        if resolve_mac is not None:
            print_debug(3, "Mac found in Router %s" % str(mac_ip))
            return mac_ip

        # sort the list in the ascending values of timestamp
        routers_list.sort()

        print_debug(3, "Routers list %s" % str(routers_list))
        return routers_list
Example #27
0
    def check_mac(pymesh_config, MAC):
        if pymesh_config.get('MAC') is None:
            # if MAC config unspecified, set it to LoRa MAC
            print_debug(3, "Set MAC in config file as " + str(MAC))
            pymesh_config['MAC'] = MAC
            PymeshConfig.write_config(pymesh_config, False)
        else:
            mac_from_config = pymesh_config.get('MAC')
            if mac_from_config != MAC:
                print_debug(3,
                            "MAC different" + str(mac_from_config) + str(MAC))
                pymesh_config['MAC'] = MAC
                # if MAC in config different than LoRa MAC, set LoRa MAC as in config file
                fo = open("/flash/sys/lpwan.mac", "wb")
                mac_write = bytes([(MAC >> 56) & 0xFF, (MAC >> 48) & 0xFF,
                                   (MAC >> 40) & 0xFF, (MAC >> 32) & 0xFF,
                                   (MAC >> 24) & 0xFF, (MAC >> 16) & 0xFF,
                                   (MAC >> 8) & 0xFF, MAC & 0xFF])
                fo.write(mac_write)
                fo.close()
                # print_debug(3, "reset")
                PymeshConfig.write_config(pymesh_config, False)

        print_debug(3, "MAC ok" + str(MAC))
Example #28
0
 def create_socket(self):
     """ create UDP socket """
     self.sock = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
     self.sock.bind(self.PORT_MESH_INTERNAL)
     print_debug(5, "Socket created on port %d" % self.PORT_MESH_INTERNAL)
Example #29
0
    def process(self, arg1, arg2):
        last_mesh_pairs = []
        last_mesh_mac_list = []
        last_mesh_node_info = {}

        try:
            while True:
                time.sleep(.1)
                cmd = input('>')

                if cmd == 'ip':
                    print(self.mesh.ip())

                elif cmd == 'mac':
                    # read/write LoRa MAC address
                    try:
                        id = int(
                            input('(new LoRa MAC (0-64k) [Enter for read])<'))
                    except:
                        print(self.mesh.mesh.mesh.MAC)
                        continue
                    id = id & 0xFFFF  # just 2B value
                    # it's actually set in main.py (main thread)
                    print("LoRa MAC set to", id)
                    self.sleep(1, id)  # force restart

                elif cmd == 'mml':
                    mesh_mac_list = self.mesh.get_mesh_mac_list()
                    if len(mesh_mac_list) > 0:
                        last_mesh_mac_list = mesh_mac_list
                    print('mesh_mac_list ', json.dumps(last_mesh_mac_list))

                elif cmd == 'self':
                    node_info = self.mesh.get_node_info()
                    print("self info:", node_info)

                elif cmd == 'mni':
                    for mac in last_mesh_mac_list:
                        node_info = self.mesh.get_node_info(mac)
                        time.sleep(.5)
                        if len(node_info) > 0:
                            last_mesh_node_info[mac] = node_info
                    print('last_mesh_node_info',
                          json.dumps(last_mesh_node_info))

                elif cmd == 'mp':
                    mesh_pairs = self.mesh.get_mesh_pairs()
                    if len(mesh_pairs) > 0:
                        last_mesh_pairs = mesh_pairs
                    print('last_mesh_pairs', json.dumps(last_mesh_pairs))

                elif cmd == 's':
                    try:
                        to = int(input('(to)<'))
                        # typ = input('(type, 0=text, 1=file, Enter for text)<')
                        # if not typ:
                        #     typ = 0
                        # else:
                        #     typ = int(typ)
                        txt = input('(message)<')
                    except:
                        continue
                    data = {
                        'to': to,
                        # 'ty': 0,
                        'b': txt,
                        'id': 12345,
                        'ts': int(time.time()),
                    }
                    print(self.mesh.send_message(data))

                elif cmd == 'ws':
                    to = int(input('(to)<'))
                    try:
                        id = int(input('(id, default 12345)<'))
                    except:
                        id = 12345
                    print(self.mesh.mesage_was_ack(to, id))

                elif cmd == 'rm':
                    print(self.mesh.get_rcv_message())

                elif cmd == 'gps':
                    try:
                        lat = float(input('(lat [Enter for read])<'))
                        lon = float(input('(lon)<'))
                    except:
                        print("Gps:", (Gps.lat, Gps.lon))
                        continue

                    Gps.set_location(lat, lon)
                    print("Gps:", (Gps.lat, Gps.lon))

                elif cmd == 'sleep':
                    try:
                        timeout = int(input('(time[sec])<'))
                    except:
                        continue
                    if self.sleep:
                        self.sleep(timeout)

                # elif cmd == "ble":
                #     # reset BLE connection
                #     self.ble_comm.restart()

                # elif cmd == "stat":
                #     # do some statistics
                #     # data = []
                #     # data[0] = {'mac':6, 'n':3, 't':30, 's1':0, 's2':0}
                #     # data[0] = {'mac':6, 'n':3, 't':30, 's1':5, 's2':10}
                #     # data[2] = {'mac':6, 'n':30, 't':60, 's1':10, 's2':45}
                #     # for line in data:
                #     #     print()
                #     # print("1 = {'mac':6, 'n':30, 't':60, 's1':10, 's2':45}<'")
                #     # print("2 = {'mac':6, 'n':30, 't':60, 's1':10, 's2':45}<'")
                #     # print("3 = {'mac':6, 'n':30, 't':60, 's1':10, 's2':45}<'")
                #     # id = int(input('(choice 1-..)<'))
                #     data = {'mac':6, 'n':3, 't':60, 's1':3, 's2':8}
                #     res = self.mesh.statistics_start(data)
                #     print("ok? ", res)

                # elif cmd == "stat?":
                #     try:
                #         id = int(input('(id [Enter for all])<'))
                #     except:
                #         id = 0
                #     res = self.mesh.statistics_get(id)
                #     print("ok? ", res)

                elif cmd == "rst":
                    print("Mesh Reset NVM settings ... ")
                    self.mesh.mesh.mesh.mesh.deinit()
                    if self.sleep:
                        self.sleep(1)

                # elif cmd == "pyb":
                #     # print("Pybytes debug menu, Pybytes connection is ", Pybytes_wrap.is_connected())
                #     state = 1
                #     timeout = 120
                #     try:
                #         state = int(input('(Debug 0=stop, 1=start [Default start])<'))
                #     except:
                #         pass
                #     try:
                #         timeout = int(input('(Pybytes timeout [Default 120 sec])<'))
                #     except:
                #         pass
                #     self.mesh.pybytes_config((state == 1), timeout)

                elif cmd == "br":
                    state = 2  # default display BR
                    try:
                        state = int(
                            input(
                                '(state 0=Disable, 1=Enable, 2=Display [Default Display])<'
                            ))
                    except:
                        pass

                    if state == 2:
                        print("Border Router state: ",
                              self.mesh.mesh.mesh.mesh.border_router())
                    elif state == 1:
                        # Enable BR
                        prio = 0  # default normal priority
                        try:
                            prio = int(
                                input(
                                    '(priority -1=Low, 0=Normal or 1=High [Default Normal])<'
                                ))
                        except:
                            pass
                        self.mesh.br_set(True, prio, self.new_br_message_cb)
                    else:
                        # disable BR function
                        self.mesh.br_set(False)

                elif cmd == "brs":
                    """ send data to BR """
                    ip_default = "1:2:3::4"
                    port = 5555
                    try:
                        payload = input("(message<)")
                        ip = input(
                            "(IP destination, Mesh-external [Default: 1:2:3::4])<"
                        )
                        if len(ip) == 0:
                            ip = ip_default
                        port = int(
                            input("(port destination [Default: 5555])<"))
                    except:
                        pass
                    data = {'ip': ip, 'port': port, 'b': payload}
                    print("Send BR message:", data)
                    self.mesh.send_message(data)

                elif cmd == "buf":
                    print("Buffer info:",
                          self.mesh.mesh.mesh.mesh.cli("bufferinfo"))

                elif cmd == "ot":
                    cli = input('(openthread cli)<')
                    print(self.mesh.mesh.mesh.mesh.cli(cli))

                elif cmd == "debug":
                    ret = input('(debug level[0-5])<')
                    try:
                        level = int(ret)
                        self.mesh.debug_level(level)
                    except:
                        print_debug(1, "error parsing")

                elif cmd == "config":
                    print(self.mesh.config)

                else:
                    print("List of available commands")
                    print("ip - display current IPv6 unicast addresses")
                    print("mac - set or display the current LoRa MAC address")
                    print("self - display all info about current node")
                    print(
                        "mml - display the Mesh Mac List (MAC of all nodes inside this Mesh), also inquires Leader"
                    )
                    print(
                        "mp - display the Mesh Pairs (Pairs of all nodes connections), also inquires Leader"
                    )
                    print("s - send message")
                    print("ws - verifies if message sent was acknowledged")
                    print("rm - verifies if any message was received")
                    print("sleep - deep-sleep")
                    # print("stat - start statistics")
                    # print("stat? - display statistics")
                    print(
                        "br - enable/disable or display the current Border Router functionality"
                    )
                    print("brs - send packet for Mesh-external, to BR, if any")
                    print("rst - reset NOW, including NVM Pymesh IPv6")
                    print("buf - display buffer info")
                    print("ot - sends command to openthread internal CLI")
                    print("debug - set debug level")
                    print("config - print config file contents")
                    print("gps - get/set location coordinates")

        except KeyboardInterrupt:
            print('cli Got Ctrl-C')
        except Exception as e:
            sys.print_exception(e)
        finally:
            print('cli finally')
            self.sleep(0)
Example #30
0
    def receive_all_data(self, arg):
        """ receives all packages on socket """

        while True:
            rcv_data, rcv_addr = self.sock.recvfrom(1024)
            if len(rcv_data) == 0:
                break  # out of while, no packet
            rcv_ip = rcv_addr[0]
            rcv_port = rcv_addr[1]
            print_debug(
                4, 'Incoming %d bytes from %s (port %d):' %
                (len(rcv_data), rcv_ip, rcv_port))
            # print_debug(3, rcv_data)
            print_debug(5, str(self.mesh.lora.stats()))

            # check if Node is BR
            if self.br_handler:
                #check if data is for the external of the Pymesh (for Pybytes)
                if rcv_data[0] == self.BR_MAGIC_BYTE and len(
                        rcv_data) >= calcsize(self.BR_HEADER_FMT):
                    br_header = unpack(self.BR_HEADER_FMT, rcv_data)
                    print_debug(
                        3,
                        "BR pack, IP dest: %x:%x:%x:%x:%x:%x:%x:%x (port %d)" %
                        (br_header[1], br_header[2], br_header[3],
                         br_header[4], br_header[5], br_header[6],
                         br_header[7], br_header[8], br_header[9]))
                    rcv_data = rcv_data[calcsize(self.BR_HEADER_FMT):]

                    dest_ip = "%x:%x:%x:%x:%x:%x:%x:%x" % (
                        br_header[1], br_header[2], br_header[3], br_header[4],
                        br_header[5], br_header[6], br_header[7], br_header[8])

                    dest_port = br_header[9]

                    print_debug(3, rcv_data)
                    (type, rcv_data) = self.get_type(rcv_data)
                    print_debug(3, rcv_data)

                    self.br_handler(rcv_ip, rcv_port, rcv_data, dest_ip,
                                    dest_port)
                    return  # done, no more parsing as this pack was for BR

            # check packet type
            (type, rcv_data) = self.get_type(rcv_data)
            # LEADER
            if type == self.PACK_ROUTER_NEIGHBORS:
                print_debug(3, "PACK_ROUTER_NEIGHBORS received")
                self.mesh.routers_neigh_update(rcv_data)
                # no answer
            # elif type == self.PACK_ROUTER_ASK_LEADER_DATA:
            #     print_debug(3, "PACK_ROUTER_ASK_LEADER_DATA received")
            #     # send answer with Leader data
            #     pack = self.mesh.leader_data_pack()
            #     self.send_pack(self.PACK_LEADER_DATA, pack, rcv_ip)

            # ROUTER
            elif type == self.PACK_LEADER_ASK_NEIGH:
                print_debug(3, "PACK_LEADER_ASK_NEIGH received")
                payload = self.mesh.neighbors_pack()
                #time.sleep(.2)
                self.send_pack(self.PACK_ROUTER_NEIGHBORS, payload, rcv_ip)
            # elif type == self.PACK_LEADER_DATA:
            #     print_debug(3, "PACK_LEADER_DATA received")
            #     if self.mesh.leader_data_unpack(rcv_data):
            #         self.interrogate_leader_ts = time.time()

            # ALL NODES
            elif type == self.PACK_MESSAGE:
                print_debug(3, "PACK_MESSAGE received")
                # add new pack received
                message = Message(rcv_data)
                # print_debug(3, message.payload)
                message.ip = rcv_ip
                self.messages.add_rcv_message(message)

                # send back ACK
                self.send_pack(self.PACK_MESSAGE_ACK,
                               message.pack_ack(self.MAC), rcv_ip)

                # forward message to user-application layer
                if self.message_cb:
                    self.message_cb(rcv_ip, rcv_port, message.payload)

            elif type == self.PACK_MESSAGE_ACK:
                print_debug(3, "PACK_MESSAGE_ACK received")
                # mark message as received
                self.messages.rcv_ack(rcv_data)

            elif type == self.PACK_ROUTER_ASK_MACS:
                print_debug(3, "PACK_ROUTER_ASK_MACS received")
                payload = self.mesh.leader_data.get_macs_pack()
                self.send_pack(self.PACK_LEADER_MACS, payload, rcv_ip)

            elif type == self.PACK_LEADER_MACS:
                print_debug(3, "PACK_LEADER_MACS received")
                self.mesh.macs_set(rcv_data)

            elif type == self.PACK_ROUTER_ASK_CONNECTIONS:
                print_debug(3, "PACK_ROUTER_ASK_CONNECTIONS received")
                payload = self.mesh.leader_data.get_connections_pack()
                self.send_pack(self.PACK_LEADER_CONNECTIONS, payload, rcv_ip)

            elif type == self.PACK_LEADER_CONNECTIONS:
                print_debug(3, "PACK_LEADER_CONNECTIONS received")
                self.mesh.connections_set(rcv_data)

            elif type == self.PACK_ROUTER_ASK_MAC_DETAILS:
                print_debug(3, "PACK_ROUTER_ASK_MAC_DETAILS received")
                (mac_req, ) = unpack('!H', rcv_data)
                print_debug(3, str(mac_req))
                payload = self.mesh.leader_data.node_info_mac_pack(mac_req)
                if len(payload) > 0:
                    self.send_pack(self.PACK_LEADER_MAC_DETAILS, payload,
                                   rcv_ip)
                else:
                    print_debug(3, "No info found about MAC %d" % mac_req)

            elif type == self.PACK_LEADER_MAC_DETAILS:
                print_debug(3, "PACK_LEADER_MAC_DETAILS received")
                self.mesh.node_info_set(rcv_data)

            # elif type == self.PACK_FILE_SEND:
            #     print_debug(3, "PACK_FILE_SEND received")
            #     payload = pack("!Q", self.MAC)
            #     self.send_pack(self.PACK_FILE_SEND_ACK, payload, rcv_ip)
            #     # rcv data contains '!QHH' as header
            #     chunk = len(rcv_data) -12
            #     self.file_size += chunk
            #     print_debug(3, "size: %d, chunk %d" % (self.file_size, chunk))
            #     file_handler = "ab" # append, by default
            #     if chunk > self.file_packsize:
            #         # started receiving a new file
            #         print_debug(3, "started receiving a new image")
            #         file_handler = "wb" # write/create new file
            #         self.file_packsize = chunk
            #     elif chunk < self.file_packsize:
            #         print_debug(3, "DONE receiving the image")
            #         # done receiving the file
            #         self.file_packsize = 0
            #         self.file_size = 0
            #         self.messages.file_transfer_done(rcv_data[:12])
            #     # else:
            #     #     #middle of the file, just write data
            #     #     self.file.write(rcv_data)
            #     with open('/flash/dog_rcv.jpg', file_handler) as file:
            #         file.write(rcv_data[12:])
            #         print_debug(3, "writing the image")

            # elif type == self.PACK_FILE_SEND_ACK:
            #     mac_rcv = unpack("!Q", rcv_data)
            #     print_debug(3, "PACK_FILE_SEND_ACK received from MAC %d"%mac_rcv)
            #     mac_rcv = 6
            #     message = self.messages.dict.get(mac_rcv, None)
            #     if message:
            #         print_debug(3, "message found")
            #         self.send_message(message, rcv_data)
            #     else:
            #         print_debug(3, "message NOT found ", mac_rcv, self.messages.dict)

            else:
                print_debug(3, "Unknown packet, type: 0x%X" % (type))
                print_debug(3, str(rcv_data))

        pass