Beispiel #1
0
    # send the schedule to the nodes (let's use SF12)
    print("start with lora...")
    lora = LoRa(mode=LoRa.LORA,
                tx_iq=True,
                frequency=freqs[0],
                region=LoRa.EU868,
                power_mode=LoRa.ALWAYS_ON,
                bandwidth=my_bw,
                sf=12,
                tx_power=14)
    lora_sock = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
    lora_sock.setblocking(False)
    pkg = struct.pack(_LORA_PKG_FORMAT % len(data), MY_ID, len(data), data)
    print(pkg)
    while (lora.ischannel_free(-100) == False):
        time.sleep_ms(100)
    lora_sock.send(pkg)
    print("schedule sent!")
    time.sleep(1)
    while (lora.ischannel_free(-100) == False):
        time.sleep_ms(100)
    data = "init"
    pkg = struct.pack(_LORA_PKG_FORMAT % len(data), MY_ID, len(data), data)
    lora_sock.send(pkg)
    print("Init command sent!")
    my_data = list()
    time.sleep_ms(207)  # propagation time of init with SF12
    chrono = Timer.Chrono()
    chrono.start()
    start = chrono.read_ms()
Beispiel #2
0
class Lora_Link_Layer:

    def __init__(self, receive_msg_cb):
        print("Initializing Link Layer...")

        self.receive_msg_cb = receive_msg_cb
        self.msg_buffer_list = []

        self.incoming_cts_key = -1
        self.wait = False #Use other name, e.g. wait_for_channel
        self.wait_time = 0
        #use int instead of boolean. If multiple cts/rts arrive sum.

        self.lora = LoRa(mode=LoRa.LORA, region=LoRa.EU868)
        self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
        self.s.setblocking(False)
        self.lora.callback(trigger=(LoRa.RX_PACKET_EVENT | LoRa.TX_PACKET_EVENT), handler=self.lora_cb)

        self.lora_mac_address_b = binascii.hexlify(self.lora.mac())
        self.lora_mac_address = str(self.lora_mac_address_b, "utf-8")

        #_thread.start_new_thread(self.process_msg_pipeline, ())


    def get_lora_mac(self):
        return self.lora_mac_address


    def lora_cb(self, lora):
        events = lora.events()
        if events & LoRa.RX_PACKET_EVENT:

            msg = self.s.recv(250)
            #print(msg)
            #unpack message and pass meta information (like mac address or protocol) as parameter
            #meta, data = self.unpack_frame(msg.decode("utf-8"))
            #msg_utf8 = data
            #msg_1 = msg.decode("utf-8")
            #print('Link Layer: Lora packet received. ' + str(msg_utf8, "utf-8"))

            #if (msg_1.startswith("cts")):
            #    self.handle_incoming_cts(msg_1)

            #elif (msg_1.startswith("rts")):
            #    self.handle_incoming_rts(msg_1)
                #send cts. what if cts gets lost? Ignore? CSMA sending messages
                #only one rts at a time. identify rts if it is repeated.
            #else:
            print('Link Layer: Passing received data to Network Layer')
            self.receive_msg_cb(msg)

        #if events & LoRa.TX_PACKET_EVENT:
            #print('Lora packet sent')


    def append_msg_to_pipeline(self, msg, use_ca):
        #self.msg_buffer_list.append([msg, use_ca])
        self.lora_send_csma_ca(msg, use_ca)

        #Buffer Länge definieren und Nachrichten verwerfen oder auf Teilpackete aufteilen.
        #Time on air -> vielfaches (zufällig) warten, falls Kanal nicht frei.

    def process_msg_pipeline(self):
        while True:
            if (len(self.msg_buffer_list) > 0):
                msg_and_ca = self.msg_buffer_list.pop(0)
                msg = msg_and_ca[0]
                use_ca = msg_and_ca[1]

                self.lora_send_csma_ca(msg, use_ca)

                time.sleep(1)


    def lora_send_csma_ca(self, msg, use_ca):
        if (use_ca):
            print("Link Layer: using CA")

            #do not send rts if wait = true
            rts_random_key_b = binascii.hexlify(os.urandom(2))
            rts_random_key = str(rts_random_key_b, "utf-8")
            rts = "rts." + rts_random_key

            while not (rts_random_key == self.incoming_cts_key): #and not wait. Probably?
                #maximum repetition
                if not self.wait:
                    self.lora_send_csma(rts)
                    print("Link Layer: Waiting for cts. expected: " + str(rts_random_key) + " received: " + str(self.incoming_cts_key))
                else:
                    print("Link Layer: Waiting..." + str(self.wait_time))
                #change delay randomly/exponential
                #Wie lange warten? cts soll nicht mit nächstem rts versuch überlagert werden?
                time.sleep(2)

        else:
            print("Link Layer: NOT using CA")

        #blocking function
        self.lora_send_csma(msg)


    def lora_send_csma(self, msg):
        #Semtech LoRa: High sensitivity  -111 to -148dBm (Datasheet: https://semtech.my.salesforce.com/sfc/p/#E0000000JelG/a/2R0000001OKs/Bs97dmPXeatnbdoJNVMIDaKDlQz8q1N_gxDcgqi7g2o)
        while not self.lora.ischannel_free(-100,100):
            #max rep.
            print("Link Layer: channel not free")

        print("Link Layer: channel free (CSMA). Sending data...")
        self.lora_send(msg)


    def lora_send(self, msg):
        #frame = self.pack_frame("c", msg)
        frame = msg
        print("Link Layer | Sending data: " + str(frame))
        self.s.send(frame)


    def handle_incoming_cts(self, incoming_cts):
        print("Link Layer: CTS received. Key=" + incoming_cts)
        self.incoming_cts_key = str(incoming_cts.split(".")[1], "utf-8")
        #Important: Wait also if CTS is for other lora. Use MAC adress as identifier
        #Combine with incoming RTS


    def handle_incoming_rts(self, incoming_rts):
        incoming_rts_key = str(incoming_rts.split(".")[1], "utf-8")
        print("Link Layer: RTS received. Key=" + incoming_rts_key)
        #send cts. what if cts gets lost? Ignore? CSMA sending messages
        #only one rts at a time. identify rts if it is repeated.
        #check if rts is new. Problem: other lora did not receive cts. Important: Waiting time
        if (not self.wait):
            _thread.start_new_thread(self.wait_timer, (5,))
            print("Link Layer: CTS other lora. Waiting for other lora...")
            #save mac address of other lora and wait until packet from this lora arrived or max
            cts = "cts." + incoming_rts_key
            #self.lora_send_csma(cts.encode("utf-8"))
            self.lora_send_csma(cts)


    def wait_timer(self, wait_time):
        self.wait_time = wait_time
        self.wait = True
        print("Wait timer")

        while self.wait_time > 0:
            time.sleep(1)
            self.wait_time = self.wait_time - 1
            print(str(self.wait_time))

        self.wait = False


    #This field states whether the frame is a data frame or it is used for control functions like error and flow control or link management etc.
    def pack_frame(self, type, data):
        #Use single bits for control and 8 bytes for MAC without delimiters. character delimiters can cause problems and need much space.
        frame = type + "::" + self.get_lora_mac() + "::" + data
        print("Link Layer:" + frame)
        return frame


    def unpack_frame(self, frame):
        meta = [frame.split("::")[0], frame.split("::")[1]]
        data = frame.split("::")[2]
        return meta, data
Beispiel #3
0
            chrono.stop()
            chrono.reset()
            print(chrono3.read())
            chrono3.stop()
            chrono3.reset()
            print(' ')

    elif not channel_status :
        ########### Packet transmission detected and set to receive moode ##########################
        noise_found=True
        print('Receiving Data')
        time_now=chrono3.read()

        ########### Fast sleep optimization ##########################
        while chrono3.read()<(packet_gap_interval*1.1+time_now):
            cca_list.append(str(lora.ischannel_free(-100)))
            if cca_list.count('True')<=10 and chrono3.read()>(packet_gap_interval+time_now):
                print(cca_list.count('True'))
                print(chrono3.read())
                noise_found=False
                print('Noise Detected')
                noise_detected_counter+=1
                break
        lora = LoRa(power_mode=LoRa.ALWAYS_ON,region=LoRa.EU868)
        cca_list.clear()
        event=0
        while event !=1 and noise_found:
            event=lora.events()
            if chrono3.read() >= fast_sleep_threshold:
                fast_sleep_time_save+=wakeup_interval-fast_sleep_threshold
                break