示例#1
0
    def __init__(self, rule_id, window_size, tiles, tile_size, fragmenter):
        self.current_state = self.STATE_TX_INIT
        self.current_window = 0
        # self.current_data_rate = 2  # Spread Factor 12
        self.tiles_dic = tiles
        self.tile_size = tile_size
        self.current_tiles_pointer = 0
        self.rule_id = rule_id
        self.window_size = window_size
        self.schc_message = SCHC_Message()
        self.schc_fragmenter = fragmenter
        self.current_fcn = window_size - 1
        self.total_len_tiles = len(tiles)

        self.n_windows = math.ceil(len(tiles) / window_size)

        tiles_list = list(tiles.values())
        pointer = 0
        for x in range(0, self.n_windows):
            self.tiles_array.insert(x,
                                    tiles_list[pointer:pointer + window_size])
            pointer = pointer + window_size

        print("***** Sending {0} bytes in {1} tiles *******\n".format(
            int(len(tiles) * tile_size / 8), len(tiles)))

        self.chrono = Timer.Chrono()
        self.chrono.start()
        self.chrono_var
        self.is_first_msg = True
        self.is_first_window = True
        self.sent_frag_counter = 0
        self.failed_frag_counter = 0
        self.times_array = {}
    def process_request(self, buffer, downlink_url, dev_id, rule_id):
        logging.debug("Entering to process_request...")
        session = None
        if len(buffer) > 0:
            # Get the session
            dtag = SCHC_Message.get_dtag(buffer)
            if rule_id == 20:
                session = self.get_uplink_session(rule_id, dtag)
                session.set_downlink_url(downlink_url)
                session.set_dev_id(dev_id)
                session.set_lorawan_port(rule_id)
            elif rule_id == 21:
                session = self.get_downlink_session(rule_id, dtag)
                session.set_downlink_url(downlink_url)
            else:
                logging.error("Rule ID not correct!!!!")
                return

            # Sending message to State Machine
            session.execute(buffer)
            # hilo = threading.Thread(target=session.sm.execute, args=(buffer,))
            # hilo.start()
            # logging.warning("Thread Active Count: %d" % threading.active_count())

            if session.sm.current_state == session.sm.STATE_RX_TERMINATE_ALL:
                logging.info("Reception complete. Deleting session ID: %d" % id(session))
                self.terminate_uplink_session(rule_id, dtag)
                print("")
                print("")
                print("")

            logging.debug("Leaving to process_request...")
 def __init__(self, rule_id, window_size, tiles, tile_size):
     self.current_state = self.STATE_TX_INIT
     self.current_window = 0
     self.current_fcn = window_size
     self.rule_id = rule_id
     self.schc_message = SCHC_Message()
     self.tiles = tiles
     self.tile_size = tile_size
    def RX_END_recv_ack_req(self, buffer):
        logging.debug("Calling to RX_END_recv_ack_req")
        (msg_type, w, fcn, rcs,
         schc_payload) = SCHC_Message().decode_schc_msg(buffer, self.rule_id)

        if msg_type == SCHC_Message.SCHC_ACK_REQ_MSG:
            logging.info("Receiving a SCHC ACK Request")
            logging.info("|--- ACK REQ, W={0:1d} ---->|".format(w))
            msg = self.last_ack_sended
            body_dic = self.last_body_dic

            fragmenter = self.schc_fragmenter
            fragmenter.lpwan_send_function(body_dic,
                                           self.session.get_downlink_url())
            logging.info("Resending a SCHC ACK Msg")
            logging.info("|<-- ACK, -------------|")
            logging.info(
                "Changing STATE - From STATE_RX_END --> STATE_RX_TERMINATE_ALL"
            )
            self.current_state = self.STATE_RX_TERMINATE_ALL
示例#5
0
    def execute(self, buffer=None, rule_id=None):
        #print("Calling execute()")

        if buffer != None:
            (msg_type, w, c, rest,
             schc_payload) = SCHC_Message.decode_schc_msg(buffer, rule_id)
            if self.current_state is self.STATE_TX_WAIT_x_ACK and msg_type == SCHC_Message.SCHC_ACK_MSG and w > self.current_window:
                print(
                    "Discarting Message. The SCHC ACK does not match the session"
                )
            elif self.current_state is self.STATE_TX_WAIT_x_ACK:
                self.TX_WAIT_x_ACK_received_ack(buffer)

        else:
            if self.current_state is self.STATE_TX_INIT:
                self.TX_INIT_send_fragment()
            elif self.current_state is self.STATE_TX_SEND:
                self.TX_SEND_send_fragment()
            elif self.current_state is self.STATE_TX_WAIT_x_ACK:
                self.TX_WAIT_x_ACK_received_ack(buffer)
            else:
                print("Wrong STATE")

        return
示例#6
0
class LoRaWAN_ACK_On_Error_TX:

    STATE_TX_INIT = 0
    STATE_TX_SEND = 1
    STATE_TX_WAIT_x_ACK = 2
    STATE_TX_RESEND_MISSING_FRAG = 3
    STATE_TX_ERROR = 4
    STATE_TX_END = 5

    current_state = None
    session = None
    current_window = None
    current_fcn = None
    rule_id = None
    window_size = None
    n_windows = None

    schc_message = None

    # LoRaWAN parameters
    current_data_rate = None
    tile_size = None

    tiles_dic = None
    total_len_tiles = None
    current_tiles_pointer = None
    tiles_array = []

    schc_fragmenter = None

    ack_received = False

    chrono = None
    start_tx = None
    chrono_var = None
    end_first_msg = None

    times_array = {}

    def __init__(self, rule_id, window_size, tiles, tile_size, fragmenter):
        self.current_state = self.STATE_TX_INIT
        self.current_window = 0
        # self.current_data_rate = 2  # Spread Factor 12
        self.tiles_dic = tiles
        self.tile_size = tile_size
        self.current_tiles_pointer = 0
        self.rule_id = rule_id
        self.window_size = window_size
        self.schc_message = SCHC_Message()
        self.schc_fragmenter = fragmenter
        self.current_fcn = window_size - 1
        self.total_len_tiles = len(tiles)

        self.n_windows = math.ceil(len(tiles) / window_size)

        tiles_list = list(tiles.values())
        pointer = 0
        for x in range(0, self.n_windows):
            self.tiles_array.insert(x,
                                    tiles_list[pointer:pointer + window_size])
            pointer = pointer + window_size

        print("***** Sending {0} bytes in {1} tiles *******\n".format(
            int(len(tiles) * tile_size / 8), len(tiles)))

        self.chrono = Timer.Chrono()
        self.chrono.start()
        self.chrono_var
        self.is_first_msg = True
        self.is_first_window = True
        self.sent_frag_counter = 0
        self.failed_frag_counter = 0
        self.times_array = {}

    def execute(self, buffer=None, rule_id=None):
        #print("Calling execute()")

        if buffer != None:
            (msg_type, w, c, rest,
             schc_payload) = SCHC_Message.decode_schc_msg(buffer, rule_id)
            if self.current_state is self.STATE_TX_WAIT_x_ACK and msg_type == SCHC_Message.SCHC_ACK_MSG and w > self.current_window:
                print(
                    "Discarting Message. The SCHC ACK does not match the session"
                )
            elif self.current_state is self.STATE_TX_WAIT_x_ACK:
                self.TX_WAIT_x_ACK_received_ack(buffer)

        else:
            if self.current_state is self.STATE_TX_INIT:
                self.TX_INIT_send_fragment()
            elif self.current_state is self.STATE_TX_SEND:
                self.TX_SEND_send_fragment()
            elif self.current_state is self.STATE_TX_WAIT_x_ACK:
                self.TX_WAIT_x_ACK_received_ack(buffer)
            else:
                print("Wrong STATE")

        return

    def TX_INIT_send_fragment(self):
        print("")
        print("Calling TX_INIT_send_fragment")
        self.current_state = self.STATE_TX_SEND
        print("Changing STATE - From STATE_TX_INIT --> STATE_TX_SEND")
        self.execute()

    def TX_SEND_send_fragment(self):
        while True:
            # Given a data rate, the MTU of the LoRaWAN channel is obtained
            header_size_available, payload_size_available = self.schc_message.get_schc_payload_size_available(
                self.schc_fragmenter.data_rate)
            print("payload_size_available: " + str(payload_size_available))

            # Given the MTU and the Size of a tile, how many tiles can be sent in a SCHC Regular Message is obtained
            tiles_x_payload = math.floor(payload_size_available /
                                         self.tile_size)

            # Set counters
            fcn = self.current_fcn
            current_window = self.current_window

            # From the array of tiles, the tiles that will be sent in the SCHC Message are obtained
            window_length_in_tiles = len(self.tiles_array[self.current_window])
            payload = self.tiles_array[self.current_window][
                self.current_tiles_pointer:self.current_tiles_pointer +
                tiles_x_payload]
            self.current_tiles_pointer = self.current_tiles_pointer + tiles_x_payload

            if (self.current_tiles_pointer >= window_length_in_tiles) and (
                    self.current_window < self.n_windows - 1):
                # len(payload) < tiles_x_payload: Cuando len(payload) < tiles_x_payload se enviarám los ultimos tiles de la ventana actual.
                # self.current_tiles_pointer >= self.window_size: Significa que se estan enviando los ultimos tiles correspondientes a la actual ventana
                # self.current_window < self.n_windows-1: Con esto nos aseguramos que aun no nos hemos cambiado de ventana.
                # Evitamos asi enviar los tiles de la siguiente ventana
                # EN RESUMEN: Se estan enviando los ultimos tiles de la ventana (no es la ultima ventana)
                print("Sending last tiles for the window with ID: %d" %
                      self.current_window)

                print("Sending %d tiles in a Regular SCHC Message" %
                      len(payload))
                msg = self.schc_message.create_regular_schc_fragment(
                    self.rule_id, 0, current_window, fcn, payload,
                    self.tile_size)

                if self.is_first_msg:
                    self.chrono_var = self.chrono.read_ms()

                self.schc_fragmenter.lpwan_send_function(
                    self.schc_fragmenter.get_socket_lorawan(), msg,
                    self.rule_id)

                if self.is_first_msg:
                    self.end_first_msg = self.chrono.read_ms()
                    self.start_tx = self.chrono_var
                    self.times_array['iteracion'] = self.schc_fragmenter.index
                    self.times_array[
                        'tf'] = self.end_first_msg - self.start_tx - 2000 - 100.352
                    self.is_first_msg = False

                if self.is_first_window:
                    self.sent_frag_counter = self.sent_frag_counter + 1

                self.current_state = self.STATE_TX_WAIT_x_ACK
                print(
                    "Changing STATE - From STATE_TX_SEND --> STATE_TX_WAIT_x_ACK"
                )

                print("Sending SCHC ACK Request")
                msg = self.schc_message.create_schc_ack_request(
                    self.rule_id, self.current_window)
                self.schc_fragmenter.lpwan_send_function(
                    self.schc_fragmenter.get_socket_lorawan(), msg,
                    self.rule_id)

                return

            elif (self.current_tiles_pointer >= window_length_in_tiles) and (
                    self.current_window == self.n_windows - 1):
                # len(payload) < tiles_x_payload: Cuando len(payload) < tiles_x_payload se enviarám los ultimos tiles de la ventana actual.
                # self.current_tiles_pointer >= self.window_size: Significa que se estan enviando los ultimos tiles correspondientes a la actual ventana
                # self.current_window == self.n_windows-1: Con esto nos aseguramos que se envian los tiles de la ULTIMA ventana
                # EN RESUMEN: Se estan enviando los ULTIMOS tiles de la ULTIMA ventana
                print(
                    "Sending last tiles of SCHC packet for LAST window with ID: %d"
                    % self.current_window)

                if len(payload) - 1 != 0:
                    print("Sending %d tiles in a Regular SCHC Message" %
                          len(payload[0:len(payload) - 1]))
                    msg = self.schc_message.create_regular_schc_fragment(
                        self.rule_id, 0, current_window, fcn,
                        payload[0:len(payload) - 1], self.tile_size)

                    if self.is_first_msg:
                        self.chrono_var = self.chrono.read_ms()

                    self.schc_fragmenter.lpwan_send_function(
                        self.schc_fragmenter.get_socket_lorawan(), msg,
                        self.rule_id)

                    if self.is_first_msg:
                        self.end_first_msg = self.chrono.read_ms()
                        self.start_tx = self.chrono_var
                        self.times_array[
                            'iteracion'] = self.schc_fragmenter.index
                        self.times_array[
                            'tf'] = self.end_first_msg - self.start_tx - 2000 - 100.352
                        self.is_first_msg = False

                    if self.is_first_window:
                        self.sent_frag_counter = self.sent_frag_counter + 1

                    print("Sending %d tiles in a All-1 SCHC Message" %
                          len(payload[len(payload) - 1:len(payload)]))
                    msg = self.schc_message.create_all_1_schc_fragment(
                        self.rule_id, 0, current_window, 63,
                        payload[len(payload) - 1:len(payload)])
                    self.schc_fragmenter.lpwan_send_function(
                        self.schc_fragmenter.get_socket_lorawan(), msg,
                        self.rule_id)
                else:
                    print("Sending %d tiles in a All-1 SCHC Message" %
                          len(payload[len(payload) - 1:len(payload)]))
                    msg = self.schc_message.create_all_1_schc_fragment(
                        self.rule_id, 0, current_window, 63,
                        payload[len(payload) - 1:len(payload)])

                    if self.is_first_msg:
                        self.chrono_var = self.chrono.read_ms()

                    self.schc_fragmenter.lpwan_send_function(
                        self.schc_fragmenter.get_socket_lorawan(), msg,
                        self.rule_id)

                    if self.is_first_msg:
                        self.end_first_msg = self.chrono.read_ms()
                        self.start_tx = self.chrono_var
                        self.times_array[
                            'iteracion'] = self.schc_fragmenter.index
                        self.times_array[
                            'tf'] = self.end_first_msg - self.start_tx - 2000 - 100.352
                        self.is_first_msg = False

                    if self.is_first_window:
                        self.sent_frag_counter = self.sent_frag_counter + 1

                self.current_state = self.STATE_TX_WAIT_x_ACK
                print(
                    "Changing STATE - From STATE_TX_SEND --> STATE_TX_WAIT_x_ACK"
                )

                print("Sending SCHC ACK Request")
                msg = self.schc_message.create_schc_ack_request(
                    self.rule_id, self.current_window)
                self.schc_fragmenter.lpwan_send_function(
                    self.schc_fragmenter.get_socket_lorawan(), msg,
                    self.rule_id)

                return

            elif len(payload) != 0:
                print("Sending %d tiles in a Regular SCHC Message" %
                      len(payload))
                msg = self.schc_message.create_regular_schc_fragment(
                    self.rule_id, 0, current_window, fcn, payload,
                    self.tile_size)
                self.current_fcn = self.current_fcn - tiles_x_payload
                self.current_state = self.STATE_TX_SEND

                if self.is_first_msg:
                    self.chrono_var = self.chrono.read_ms()

                ### **************** Para generar error forzado *******************
                #if fcn != 62:
                self.schc_fragmenter.lpwan_send_function(
                    self.schc_fragmenter.get_socket_lorawan(), msg,
                    self.rule_id)
                ### **************** Para generar error forzado *******************

                if self.is_first_msg:
                    self.end_first_msg = self.chrono.read_ms()
                    self.start_tx = self.chrono_var
                    self.times_array['iteracion'] = self.schc_fragmenter.index
                    self.times_array[
                        'tf'] = self.end_first_msg - self.start_tx - 2000 - 100.352
                    self.is_first_msg = False

                if self.is_first_window:
                    self.sent_frag_counter = self.sent_frag_counter + 1

    def TX_WAIT_x_ACK_received_ack(self, buffer):
        print("")
        #print("Calling TX_WAIT_x_ACK_received_ack()")

        (w, c,
         bitmap_list) = SCHC_Message.decode_schc_ack(buffer, self.window_size)
        print("SCHC ACK received for window ID: " + str(w) + "!!!")

        if w != self.current_window:
            print(
                "The received SCHC ACK window does not match the current SCHC ACK window. SCHC ACK discarded"
            )
            return
        elif self.ack_received:
            print("Resending missing fragments in process. SCHC ACK discarded")
            return

        self.ack_received = True
        if self.current_window is w and c is 0:
            tiles_failed_array = []
            tiles_failed_array_reversed = []
            for x in range(0, len(bitmap_list)):
                if bitmap_list[x] == '0':
                    tiles_failed_array.append(
                        (self.window_size - 1 - x,
                         [self.tiles_array[self.current_window][x]]))

            if len(tiles_failed_array) == 0:
                if self.is_first_window:
                    end_time_for_window = self.chrono.read_ms()
                    self.times_array[
                        'total_time_for_window'] = end_time_for_window - self.start_tx
                    self.is_first_window = False

                print("All tiles received OK for windows ID: " +
                      str(self.current_window))
                self.current_window = self.current_window + 1
                self.current_tiles_pointer = 0
                self.current_fcn = self.window_size - 1
                self.current_state = self.STATE_TX_SEND
                print(
                    "Changing STATE - From STATE_TX_WAIT_x_ACK --> STATE_TX_SEND"
                )
                print("")
                self.ack_received = False
                self.execute()
            else:
                #print("****** tiles_failed_array ****: " + str(tiles_failed_array))
                while len(tiles_failed_array) != 0:
                    # Given a data rate, the MTU of the LoRaWAN channel is obtained
                    header_size_available, payload_size_available = self.schc_message.get_schc_payload_size_available(
                        self.schc_fragmenter.data_rate)

                    # Given the MTU and the Size of a tile, how many tiles can be sent in a SCHC Regular Message is obtained
                    tiles_x_payload = math.floor(payload_size_available /
                                                 self.tile_size)

                    consecutive_tiles = SCHC_Message.get_consecutive_filed_tiles(
                        tiles_failed_array)

                    if consecutive_tiles > tiles_x_payload:
                        consecutive_tiles = tiles_x_payload

                    failed_tiles = []
                    first_fcn, first_tile = tiles_failed_array[0]
                    for x in range(0, consecutive_tiles):
                        fcn, tile = tiles_failed_array.pop()
                        failed_tiles.append(tile[0])

                    print("Re-Sending %d tiles in a Regular SCHC Message" %
                          len(failed_tiles))
                    msg = self.schc_message.create_regular_schc_fragment(
                        self.rule_id, 0, self.current_window, first_fcn,
                        failed_tiles, self.tile_size)
                    self.schc_fragmenter.lpwan_send_function(
                        self.schc_fragmenter.get_socket_lorawan(), msg,
                        self.rule_id)

                    if self.is_first_window:
                        self.failed_frag_counter = self.failed_frag_counter + 1

                self.ack_received = False
                print("Sending SCHC ACK Request")
                msg = self.schc_message.create_schc_ack_request(
                    self.rule_id, self.current_window)
                self.schc_fragmenter.lpwan_send_function(
                    self.schc_fragmenter.get_socket_lorawan(), msg,
                    self.rule_id)

        elif self.current_window is w and c is 1:
            print("All tiles received OK for SCHC Packet")
            self.current_state = self.STATE_TX_END
            print("Changing STATE - From STATE_TX_WAIT_x_ACK --> STATE_TX_END")
            end_time = self.chrono.read_ms()

            if self.is_first_window:
                self.times_array[
                    'total_time_for_window'] = end_time - self.start_tx
                self.is_first_window = False

            self.times_array[
                'total_time_for_schc_packet'] = end_time - self.start_tx
            self.times_array['failed_fragments'] = self.failed_frag_counter
            self.times_array['sent_fragments'] = self.sent_frag_counter
            self.schc_fragmenter.total_times.append(self.times_array)

        return
示例#7
0
    def TX_WAIT_x_ACK_received_ack(self, buffer):
        print("")
        #print("Calling TX_WAIT_x_ACK_received_ack()")

        (w, c,
         bitmap_list) = SCHC_Message.decode_schc_ack(buffer, self.window_size)
        print("SCHC ACK received for window ID: " + str(w) + "!!!")

        if w != self.current_window:
            print(
                "The received SCHC ACK window does not match the current SCHC ACK window. SCHC ACK discarded"
            )
            return
        elif self.ack_received:
            print("Resending missing fragments in process. SCHC ACK discarded")
            return

        self.ack_received = True
        if self.current_window is w and c is 0:
            tiles_failed_array = []
            tiles_failed_array_reversed = []
            for x in range(0, len(bitmap_list)):
                if bitmap_list[x] == '0':
                    tiles_failed_array.append(
                        (self.window_size - 1 - x,
                         [self.tiles_array[self.current_window][x]]))

            if len(tiles_failed_array) == 0:
                if self.is_first_window:
                    end_time_for_window = self.chrono.read_ms()
                    self.times_array[
                        'total_time_for_window'] = end_time_for_window - self.start_tx
                    self.is_first_window = False

                print("All tiles received OK for windows ID: " +
                      str(self.current_window))
                self.current_window = self.current_window + 1
                self.current_tiles_pointer = 0
                self.current_fcn = self.window_size - 1
                self.current_state = self.STATE_TX_SEND
                print(
                    "Changing STATE - From STATE_TX_WAIT_x_ACK --> STATE_TX_SEND"
                )
                print("")
                self.ack_received = False
                self.execute()
            else:
                #print("****** tiles_failed_array ****: " + str(tiles_failed_array))
                while len(tiles_failed_array) != 0:
                    # Given a data rate, the MTU of the LoRaWAN channel is obtained
                    header_size_available, payload_size_available = self.schc_message.get_schc_payload_size_available(
                        self.schc_fragmenter.data_rate)

                    # Given the MTU and the Size of a tile, how many tiles can be sent in a SCHC Regular Message is obtained
                    tiles_x_payload = math.floor(payload_size_available /
                                                 self.tile_size)

                    consecutive_tiles = SCHC_Message.get_consecutive_filed_tiles(
                        tiles_failed_array)

                    if consecutive_tiles > tiles_x_payload:
                        consecutive_tiles = tiles_x_payload

                    failed_tiles = []
                    first_fcn, first_tile = tiles_failed_array[0]
                    for x in range(0, consecutive_tiles):
                        fcn, tile = tiles_failed_array.pop()
                        failed_tiles.append(tile[0])

                    print("Re-Sending %d tiles in a Regular SCHC Message" %
                          len(failed_tiles))
                    msg = self.schc_message.create_regular_schc_fragment(
                        self.rule_id, 0, self.current_window, first_fcn,
                        failed_tiles, self.tile_size)
                    self.schc_fragmenter.lpwan_send_function(
                        self.schc_fragmenter.get_socket_lorawan(), msg,
                        self.rule_id)

                    if self.is_first_window:
                        self.failed_frag_counter = self.failed_frag_counter + 1

                self.ack_received = False
                print("Sending SCHC ACK Request")
                msg = self.schc_message.create_schc_ack_request(
                    self.rule_id, self.current_window)
                self.schc_fragmenter.lpwan_send_function(
                    self.schc_fragmenter.get_socket_lorawan(), msg,
                    self.rule_id)

        elif self.current_window is w and c is 1:
            print("All tiles received OK for SCHC Packet")
            self.current_state = self.STATE_TX_END
            print("Changing STATE - From STATE_TX_WAIT_x_ACK --> STATE_TX_END")
            end_time = self.chrono.read_ms()

            if self.is_first_window:
                self.times_array[
                    'total_time_for_window'] = end_time - self.start_tx
                self.is_first_window = False

            self.times_array[
                'total_time_for_schc_packet'] = end_time - self.start_tx
            self.times_array['failed_fragments'] = self.failed_frag_counter
            self.times_array['sent_fragments'] = self.sent_frag_counter
            self.schc_fragmenter.total_times.append(self.times_array)

        return
    def RX_RCV_WINDOW_recv_fragment(self, buffer):
        logging.debug("Entering to RX_RCV_WINDOW_recv_fragment")
        (msg_type, w, fcn, rcs,
         schc_payload) = SCHC_Message().decode_schc_msg(buffer, self.rule_id)

        if msg_type == SCHC_Message.SCHC_ACK_REQ_MSG:
            logging.info("Receiving a SCHC ACK Request")
            logging.info("|--- ACK REQ, W={0:1d} ---->|".format(w))
            msg = self.last_ack_sended
            body_dic = self.last_body_dic

            fragmenter = self.schc_fragmenter
            fragmenter.lpwan_send_function(body_dic,
                                           self.session.get_downlink_url())
            logging.info("Resending a SCHC ACK Msg")
            logging.info("|<-- ACK, -------------|")

        elif msg_type == SCHC_Message.SCHC_FRAGMENT_MSG and fcn == self.window_size and rcs is not None:
            logging.info("Receiving a All-1 SCHC Fragment")
            # Receiving fragments that are not the last fragments of the SCHC packet
            tiles_in_payload = int(len(schc_payload) / self.tile_size_bytes)
            dic_pointer = (self.window_size - 1) - fcn
            logging.info(
                "|-----W={0:1d}, FCN={1:2d}----->| {2:2d} tiles recv".format(
                    w, fcn, tiles_in_payload))

            for i in range(tiles_in_payload):
                pointer = i * self.tile_size_bytes
                self.tiles_array[self.current_window][
                    dic_pointer] = schc_payload[pointer:pointer +
                                                self.tile_size_bytes]
                self.bitmap[self.current_window][dic_pointer] = '1'
                dic_pointer = dic_pointer + 1

            if SCHC_Message.integrity_check(self.tiles_array, rcs):
                logging.info(
                    "Sending a SCHC ACK Msg with Integrity Check success")
                c = 1
                msg = SCHC_Message.create_schc_ack(
                    self.rule_id, 0, self.current_window, c,
                    self.bitmap[self.current_window])
                logging.info("|<-- ACK, W={0:1d}, C={1:1d} ----|".format(w, c))
                logging.info(
                    "Changing STATE - From STATE_RX_RCV_WINDOW --> STATE_RX_END"
                )
                self.current_state = self.STATE_RX_END
            else:
                logging.info(
                    "Sending a SCHC ACK Msg with Integrity Check failure")
                c = 0
                msg = SCHC_Message.create_schc_ack(
                    self.rule_id, 0, self.current_window, c,
                    self.bitmap[self.current_window])
                logging.info(
                    "|<-- ACK, W={0:1d}, C={1:1d} ----| {2:2s} (bitmap)".
                    format(w, c, ''.join(self.bitmap[self.current_window])))

            body_dic = {}
            body_dic['payload_raw'] = base64.b64encode(msg).decode("utf-8")
            body_dic['dev_id'] = self.session.get_dev_id()
            body_dic['port'] = self.session.get_lorawan_port()
            body_dic['confirmed'] = False
            self.last_ack_sended = msg
            self.last_body_dic = body_dic

            fragmenter = self.schc_fragmenter
            fragmenter.lpwan_send_function(body_dic,
                                           self.session.get_downlink_url())

            # aux = []
            # for x in self.tiles_array:
            #     for y in x:
            #         if y != None:
            #             for j in y:
            #                 if j != None:
            #                     aux.append(hex(j)[2:])
            # schc_packet = ''.join(aux)

        elif msg_type == SCHC_Message.SCHC_FRAGMENT_MSG:
            logging.info("Receiving a Regular SCHC Fragment")
            # Receiving fragments that are not the last fragments of the SCHC packet
            tiles_in_payload = int(len(schc_payload) / self.tile_size_bytes)
            dic_pointer = (self.window_size - 1) - fcn
            self.all_1_pointer = dic_pointer + tiles_in_payload
            logging.info(
                "|-----W={0:1d}, FCN={1:2d}----->| {2:2d} tiles recv".format(
                    w, fcn, tiles_in_payload))

            for i in range(tiles_in_payload):
                pointer = i * self.tile_size_bytes
                try:
                    self.tiles_array[self.current_window][
                        dic_pointer] = schc_payload[pointer:pointer +
                                                    self.tile_size_bytes]
                except:
                    logging.error("self.current_window: " +
                                  str(self.current_window))
                    logging.error("dic_pointer: " + str(dic_pointer))
                    logging.error("pointer: " + str(pointer))
                    logging.error("self.tile_size_bytes: " +
                                  str(self.tile_size_bytes))

                self.bitmap[self.current_window][dic_pointer] = '1'
                dic_pointer = dic_pointer + 1

            if dic_pointer >= self.window_size:
                logging.info("Sending a SCHC ACK Msg")
                c = 0  # No se ha realizado integrity Check
                msg = SCHC_Message.create_schc_ack(
                    self.rule_id, 0, self.current_window, c,
                    self.bitmap[self.current_window])

                body_dic = {}
                body_dic['payload_raw'] = base64.b64encode(msg).decode("utf-8")
                body_dic['dev_id'] = self.session.get_dev_id()
                body_dic['port'] = self.session.get_lorawan_port()
                body_dic['confirmed'] = False
                self.last_ack_sended = msg
                self.last_body_dic = body_dic

                fragmenter = self.schc_fragmenter
                fragmenter.lpwan_send_function(body_dic,
                                               self.session.get_downlink_url())
                bitmap = ''.join(self.bitmap[self.current_window])
                logging.info(
                    "|<-- ACK, W={0:1d}, C={1:1d} ----| {2:2s} (bitmap)".
                    format(w, c, bitmap))

                if bitmap.find('0') != -1:
                    logging.debug(
                        "There are errors in the SCHC Fragments received")
                    logging.info(
                        "Changing STATE - From STATE_RX_RCV_WINDOW --> STATE_RX_WAIT_x_MISSING_FRAGS"
                    )
                    self.current_state = self.STATE_RX_WAIT_x_MISSING_FRAGS
                else:
                    self.current_window = self.current_window + 1

        else:
            logging.error("Receiving a Incompatibility Message ")

        return
    def RX_WAIT_x_MISSING_FRAGS_recv_fragment(self, buffer):
        logging.debug("Calling to RX_WAIT_x_MISSING_FRAGS_recv_fragment")
        (msg_type, w, fcn, rcs,
         schc_payload) = SCHC_Message().decode_schc_msg(buffer, self.rule_id)

        if msg_type == SCHC_Message.SCHC_ACK_REQ_MSG:
            logging.info("Receiving a SCHC ACK Request")
            logging.info("|--- ACK REQ, W={0:1d} ---->|".format(w))
            msg = self.last_ack_sended
            body_dic = self.last_body_dic

            fragmenter = self.schc_fragmenter
            fragmenter.lpwan_send_function(body_dic,
                                           self.session.get_downlink_url())
            logging.info("Resending a SCHC ACK Msg")
            logging.info("|<-- ACK, -------------|")
        else:
            logging.info("Receiving a Regular SCHC Fragment")
            # Receiving fragments that are not the last fragments of the SCHC packet
            tiles_in_payload = int(len(schc_payload) / self.tile_size_bytes)
            dic_pointer = (self.window_size - 1) - fcn
            self.all_1_pointer = dic_pointer + tiles_in_payload
            logging.info(
                "|-----W={0:1d}, FCN={1:2d}----->| {2:2d} tiles recv".format(
                    w, fcn, tiles_in_payload))

            for i in range(tiles_in_payload):
                pointer = i * self.tile_size_bytes
                self.tiles_array[self.current_window][
                    dic_pointer] = schc_payload[pointer:pointer +
                                                self.tile_size_bytes]
                self.bitmap[self.current_window][dic_pointer] = '1'
                dic_pointer = dic_pointer + 1

                bitmap_str = ''.join(self.bitmap[self.current_window])

            if bitmap_str.find('0') == -1:
                logging.info("Sending a SCHC ACK Msg")
                c = 0  # No se ha realizado integrity Check
                msg = SCHC_Message.create_schc_ack(
                    self.rule_id, 0, self.current_window, c,
                    self.bitmap[self.current_window])

                body_dic = {}
                body_dic['payload_raw'] = base64.b64encode(msg).decode("utf-8")
                body_dic['dev_id'] = self.session.get_dev_id()
                body_dic['port'] = self.session.get_lorawan_port()
                body_dic['confirmed'] = False
                self.last_ack_sended = msg
                self.last_body_dic = body_dic

                fragmenter = self.schc_fragmenter
                fragmenter.lpwan_send_function(body_dic,
                                               self.session.get_downlink_url())
                bitmap = ''.join(self.bitmap[self.current_window])
                logging.info(
                    "|<-- ACK, W={0:1d}, C={1:1d} ----| {2:2s} (bitmap)".
                    format(w, c, bitmap))

                if bitmap.find('0') != -1:
                    logging.debug(
                        "There are errors in the SCHC Fragments received")
                else:
                    logging.info(
                        "Changing STATE - From STATE_RX_WAIT_x_MISSING_FRAGS --> STATE_RX_RCV_WINDOW"
                    )
                    self.current_state = self.STATE_RX_RCV_WINDOW
                    self.current_window = self.current_window + 1
示例#10
0
 def __init__(self, session, rule_id, window_size, tiles, tile_size, fragmenter):
     self.current_state = self.STATE_TX_INIT
     self.current_window = 0
     self.current_fcn = window_size
     self.rule_id = rule_id
     self.schc_message = SCHC_Message()