Ejemplo n.º 1
0
 def create_simul(self):
     if self.simul_config is None:
         self.set_config(DEFAULT_SIMUL_CONFIG.copy())
     self.init_stat()
     Statsct.get_results()
     sim = net_sim_core.Simul(self.simul_config)
     self.sim = sim
Ejemplo n.º 2
0
    def finish(self, schc_packet, schc_frag):
        self.state = "DONE"
        dprint('state DONE -> {}'.format(self.state))
        #input('DONE')
        # decompression
        self.protocol.process_decompress(schc_packet,
                                         self.sender_L2addr,
                                         direction="UP")

        # ACK message
        schc_ack = frag_msg.frag_receiver_tx_all1_ack(schc_frag.rule,
                                                      schc_frag.dtag,
                                                      schc_frag.win,
                                                      cbit=1)
        dprint("ACK success sent:", schc_ack.__dict__)
        if enable_statsct:
            Statsct.set_msg_type("SCHC_ACK_OK")
        dprint(
            "----------------------- SCHC ACK OK SEND  -----------------------"
        )
        """
        Changement à corriger
        args = (schc_ack.packet.get_content(), self.context["devL2Addr"])
        """
        args = (schc_ack.packet.get_content(), '*')
        self.protocol.scheduler.add_event(0, self.protocol.layer2.send_packet,
                                          args)
        # XXX need to keep the ack message for the ack request.
        #the ack is build everytime
        self.schc_ack = schc_ack
Ejemplo n.º 3
0
 def cond_collision(self, frag_size):
     """Calculates if there is a collision"""
     frag_ToA = get_toa(frag_size, Statsct.SF)
     #check if there is a collision at the start of the packet
     dprint("current time: {}, position: {}, ToA fragment: {}".format(self.current_time,self.position,frag_ToA['t_packet']))
     dprint("background_traffic: {}".format(self.background_traffic[self.position]))
     while self.position < len(self.background_traffic) and self.current_time > self.background_traffic[self.position][0]:           
         self.position += 1
     dprint("position: {}, ".format(self.position))
     
     if self.position != len(self.background_traffic):
         if self.current_time == self.background_traffic[self.position][0]:
             #special case when both packet start time is the same
             dprint("Collision! -> packet start at same time as the next")
             self.current_time += frag_ToA['t_packet'] + Statsct.dc_time_off(frag_ToA['t_packet'],Statsct.dc)
             return True
         elif self.position != 0 and self.current_time < self.background_traffic[self.position-1][1]:
             dprint("Collision! -> packet start before the end of previous packet")
             self.current_time += frag_ToA['t_packet'] + Statsct.dc_time_off(frag_ToA['t_packet'],Statsct.dc)
             return True
         else:
             if self.current_time + frag_ToA['t_packet'] > self.background_traffic[self.position][0]:
                 dprint("Collision!-> packet ends after next has start")
                 self.current_time += frag_ToA['t_packet'] + Statsct.dc_time_off(frag_ToA['t_packet'],Statsct.dc)
                 return True
     self.current_time += frag_ToA['t_packet'] + Statsct.dc_time_off(frag_ToA['t_packet'],Statsct.dc)
     input('')
     return False    
Ejemplo n.º 4
0
    def event_inactive(self):
        """ event_inactive

        // TODO : Redaction (here is frag_recv.py)


        """
        #if the ack-ok was received, no ACK REQ will be received,
        #check for state == "DONE" and return, this means that the ack-ok
        #was send, before the system returns after sending the ack-ok, now it
        #waits for one inactivity timer before closing session
        if self.state == "DONE":
            return

        # sending sender abort.
        schc_frag = frag_msg.frag_receiver_tx_abort(self.rule, self.dtag)
        """
        Changement à corriger
        args = (schc_frag.packet.get_content(), self.context["devL2Addr"])
        """
        args = (schc_frag.packet.get_content(), '*')
        dprint("Sent Receiver-Abort.", schc_frag.__dict__)
        dprint(
            "----------------------- SCHC RECEIVER ABORT SEND  -----------------------"
        )

        if enable_statsct:
            Statsct.set_msg_type("SCHC_RECEIVER_ABORT")
            Statsct.set_header_size(frag_msg.get_sender_header_size(self.rule))
        self.state = "ABORT"
        self.protocol.scheduler.add_event(0, self.protocol.layer2.send_packet,
                                          args)
        # XXX needs to release all resources.
        return
Ejemplo n.º 5
0
    def create_ack_schc_ko(self, schc_frag):
        """Create schc_ack packet in case of wrong RCS (C=0)
            return schc_ack packet
        """
        bit_list = find_missing_tiles_mic_ko_yes_all_1(
            self.tile_list, self.rule[T_FRAG][T_FRAG_PROF][T_FRAG_FCN],
            frag_msg.get_fcn_all_1(self.rule))
        for tile in self.tile_list:
            dprint("w-num: {} t-num: {} nb_tiles:{}".format(
                tile['w-num'], tile['t-num'], tile['nb_tiles']))
            dprint("raw_tiles:{}".format(tile['raw_tiles']))
        dprint('send ack before done {}'.format(bit_list))
        assert bit_list is not None

        if bit_list:
            # Some tiles are actually missing, send ACK for first window with missing tiles
            dprint("missing wn={} bitmap={}".format(bit_list[0][0],
                                                    bit_list[0][1]))
            # XXX compress bitmap if needed.
            # ACK failure message
            schc_ack = frag_msg.frag_receiver_tx_all1_ack(
                schc_frag.rule,
                schc_frag.dtag,
                win=bit_list[0][0],
                cbit=0,
                bitmap=bit_list[0][1])
        elif not self.tile_list:
            dprint("No tile received before All-1, sending empty bitmap")
            # ACK failure message
            schc_ack = frag_msg.frag_receiver_tx_all1_ack(schc_frag.rule,
                                                          schc_frag.dtag,
                                                          win=0,
                                                          cbit=0,
                                                          bitmap=BitBuffer([]))
        else:
            window_list = make_bit_list_mic_ko(
                self.tile_list, self.rule[T_FRAG][T_FRAG_PROF][T_FRAG_FCN],
                frag_msg.get_fcn_all_1(self.rule))
            last_window = max(window_list.keys())

            # No tiles are detected missing, send ACK for last window
            dprint("No missing tiles, sending last window: wn={} bitmap={}".
                   format(last_window, BitBuffer(window_list[last_window])))
            # XXX compress bitmap if needed.
            # ACK failure message
            schc_ack = frag_msg.frag_receiver_tx_all1_ack(
                schc_frag.rule,
                schc_frag.dtag,
                win=last_window,
                cbit=0,
                bitmap=BitBuffer(window_list[last_window]))
        if enable_statsct:
            Statsct.set_msg_type("SCHC_ACK_KO")
        dprint(
            "----------------------- SCHC ACK KO SEND  -----------------------"
        )
        dprint("ACK failure sent:", schc_ack.__dict__)
        return schc_ack
Ejemplo n.º 6
0
    def send_receiver_abort(self):
        # sending Receiver abort.
        self.state = "ABORT"
        schc_frag = schcmsg.frag_receiver_tx_abort(self.rule, self.dtag)
        args = (schc_frag.packet.get_content(), self.context["devL2Addr"])
        print("Sent Receiver-Abort.", schc_frag.__dict__)
        print("----------------------- SCHC RECEIVER ABORT SEND  -----------------------")

        if enable_statsct:
            Statsct.set_msg_type("SCHC_RECEIVER_ABORT")
            #Statsct.set_header_size(schcmsg.get_sender_header_size(self.rule))
        self.protocol.scheduler.add_event(0,
                                    self.protocol.layer2.send_packet, args)
Ejemplo n.º 7
0
    def send_packet(self, packet, src_id, dst_id=None,
                    callback=None, callback_args=tuple() ):
        self._log("----------------------- SEND PACKET -----------------------")
        if not self.frame_loss.check(len(packet)):
            self._log("----------------------- OK -----------------------")
            self._log("send-packet {}->{} {}".format(src_id, dst_id, packet))
            if enable_statsct:
                Statsct.log("send-packet {}->{} {}".format(src_id, dst_id, packet))
                Statsct.add_packet_info(packet, src_id, dst_id, True)
            # if dst_id == None, it is a broadcast
            link_list = self.get_link_by_id(src_id, dst_id)
            count = 0
            for link in link_list:
                count += self.send_packet_on_link(link, packet)
        else:
            self._log("----------------------- KO -----------------------")
            self._log("packet was lost {}->{}".format(src_id, dst_id))
            if enable_statsct:
                Statsct.log("packet was lost {}->{} {}".format(src_id, dst_id, packet))            
                Statsct.add_packet_info(packet,src_id,dst_id, False)
            count = 0
        #
        if callback != None:
            args = callback_args+(count,) # XXX need to check. - CA:
            # [CA] the 'count' is now passed as 'status' in:
            #  SimulLayer2._event_sent_callback(self, transmit_callback, status
            # the idea is that is transmission fails, at least you can pass
            # count == 0 (status == 0), and you can do something there.
            # (in general case, some meta_information need to be sent)

            #args = callback_args
            callback(*args)
        return count
Ejemplo n.º 8
0
 def init_stat(self):
     # Statistic module
     radio_config = self.simul_config["radio"]
     Statsct.initialize(init_time=0)
     Statsct.log("Statsct test")
     Statsct.set_packet_size(radio_config["data_size"])
     Statsct.set_SF(radio_config["SF"])
Ejemplo n.º 9
0
 def update_stat(self, node1, rm0, rm1, node0):
     # ---------------------------------
     # Information about the devices
     dprint(32 * "-" + " SCHC device------------------------")
     dprint("SCHC device L3={} L2={} RM={}".format(node0.layer3.L3addr,
                                                   node0.id, rm0.__dict__))
     dprint(32 * "-" + " SCHC gw ---------------------------")
     dprint("SCHC gw     L3={} L2={} RM={}".format(node1.layer3.L3addr,
                                                   node1.id, rm1.__dict__))
     dprint(32 * "-" + " Rules -----------------------------")
     dprint("rules -> {}, {}".format(rm0.__dict__, rm1.__dict__))
     dprint("")
     # ----------------------------------
     # Statistic configuration
     Statsct.setSourceAddress(node0.id)
     Statsct.setDestinationAddress(node1.id)
Ejemplo n.º 10
0
    def generate_background_traffic(self, G, background_frag_size):
        self.background_traffic
        T = get_toa(background_frag_size, Statsct.SF)
        g = G / T['t_packet']
        print("g: {}, G:{}, T:{}".format(g, G, T['t_packet']))
        for i in range(1000):
            #aleatoire = machine.rng()
            #aleatoire2 = aleatoire/(2**24-1)

            aleatoire = urandom.getrandbits(8) / 256
            aleatoire2 = aleatoire / (2**24 - 1)
            #print(aleatoire2)
            if aleatoire2 != 0:
                test = -1 * math.log(aleatoire2) / 1 / g
                self.background_traffic.append((test, test + T['t_packet']))
        if enable_statsct:
            Statsct.set_background_traffic(self.background_traffic)
Ejemplo n.º 11
0
    def show_stat(self):
        dprint(32 * '-' + ' Simulation ended -----------------------|')
        # Results
        dprint("")
        dprint("")
        dprint(32 * "-" + " Statistics -----------------------------")

        dprint('---- Sender Packet list ')
        Statsct.print_packet_list(Statsct.sender_packets)
        dprint('')

        dprint('---- Receiver Packet list ')
        Statsct.print_packet_list(Statsct.receiver_packets)
        dprint('')

        dprint('---- Packet lost Results ' +
               '(Status -> True = Received, False = Failed) ')
        Statsct.print_ordered_packets()
        dprint('')

        dprint('---- Performance metrics')
        params = Statsct.calculate_tx_parameters()
        dprint('')

        dprint("---- General result of the simulation {}".format(params))
Ejemplo n.º 12
0
    def send_packetX(self, packet, src_id, dst_id=None, callback=None, callback_args=tuple()):
        """send a message to another device in a client - server Simulation"""
        self._log("----------------------- SEND PACKET -----------------------")
        if not self.frame_loss.check(packet):
            self._log("----------------------- OK -----------------------")
            self._log("send-packet {}->{} {}".format(src_id, dst_id, packet))
            if enable_statsct:
                Statsct.log("send-packet {}->{} {}".format(src_id, dst_id, packet))
                Statsct.add_packet_info(packet,src_id,dst_id, True)
            # if dst_id == None, it is a broadcast
            # link_list = self.get_link_by_id(src_id, dst_id)
            count = 1
            # for link in link_list:
            #     count += self.send_packet_on_link(link, packet)
            note_table_list = list(self.node_table.items())[-1][1]
            #self.node_table[0].protocol.layer2.clientSend.send(packet)

            note_table_list.protocol.layer2.roleSend.send(packet)

            try:
                number_tiles_send = \
                    note_table_list.protocol.fragment_session.session_list[0]["session"].current_number_tiles_sent()
                state = note_table_list.protocol.fragment_session.session_list[0]["session"].state
                print("STATE : ", state)
                print("Lenght queue", len(self.scheduler.queue))
                if (state == self.SEND_ALL_1 or state == self.ACK_FAILURE or state == self.ACK_TIMEOUT) \
                        and number_tiles_send == 0:
                    print("------------------------------- RECEIVE PACKET ------------------------------")
                    message = note_table_list.protocol.layer2.roleSend.Receive()
                    print("Message from Server", message)
                    note_table_list.protocol.layer2.event_receive_packet(note_table_list.id, message)
                    # note_table_list.protocol.fragment_session.session_list[0]["session"].state = 'START'
            except:
                print("Not fragment state")
        else:
            self._log("----------------------- KO -----------------------")
            self._log("packet was lost {}->{}".format(src_id, dst_id))
            if enable_statsct:
                Statsct.log("packet was lost {}->{} {}".format(src_id, dst_id, packet))
                Statsct.add_packet_info(packet,src_id,dst_id, False)
            count = 0
        #
        if callback != None:
            args = callback_args + (count,) # XXX need to check. - CA:
            # [CA] the 'count' is now passed as 'status' in:
            #  SimulLayer2._event_sent_callback(self, transmit_callback, status
            # the idea is that is transmission fails, at least you can pass
            # count == 0 (status == 0), and you can do something there.
            # (in general case, some meta_information need to be sent)

            #args = callback_args
            callback(*args)
        return count
Ejemplo n.º 13
0
    def ack_timeout(self, *args):
        self.cancel_ack_wait_timer()
        print("----------------------- ACK timeout -----------------------  ")
        assert len(args) == 2
        assert isinstance(args[0], schcmsg.frag_sender_tx)
        assert isinstance(args[1], int)
        schc_frag = args[0]
        win = args[1]
        self.ack_requests_counter += 1
        print("ack_requests_counter -> {}".format(self.ack_requests_counter))
        if self.ack_requests_counter > max_ack_requests:
            # sending sender abort.
            schc_frag = schcmsg.frag_sender_tx_abort(self.rule, self.dtag, win)
            args = (schc_frag.packet.get_content(), self.context["devL2Addr"])
            print("Sent Sender-Abort.", schc_frag.__dict__)
            if enable_statsct:
                Statsct.set_msg_type("SCHC_SENDER_ABORT")
                #Statsct.set_header_size(schcmsg.get_sender_header_size(self.rule))

            self.protocol.scheduler.add_event(0,
                                              self.protocol.layer2.send_packet,
                                              args)
            return
        # set ack waiting timer
        self.event_id_ack_wait_timer = self.protocol.scheduler.add_event(
            self.ack_wait_timer, self.ack_timeout, args)
        print("*******event id {}".format(self.event_id_ack_wait_timer))

        schc_frag = schcmsg.frag_sender_ack_req(self.rule, self.dtag, win)
        if enable_statsct:
            Statsct.set_msg_type("SCHC_ACK_REQ")
        # # retransmit MIC.
        args = (schc_frag.packet.get_content(), self.context["devL2Addr"],
                self.event_sent_frag)
        print("SCHC ACK REQ frag:", schc_frag.__dict__)
        self.protocol.scheduler.add_event(0, self.protocol.layer2.send_packet,
                                          args)
        """ waits for all the acks before sending the ack request """
        """
Ejemplo n.º 14
0
 def init_collision(self, G, background_frag_size):
     """ Init the collision table"""
     if enable_statsct:
         if Statsct.get_background_traffic() is not None:
             self.background_traffic = Statsct.get_background_traffic()
         else:
             self.generate_background_traffic(G, background_frag_size)
         if Statsct.get_current_time is not None:
             self.current_time = Statsct.get_current_time()
         if Statsct.get_position is not None:
             self.position = Statsct.get_position()
     else:
         self.generate_background_traffic(G, background_frag_size)
     print("background_frag_size: {}".format(background_frag_size))
     #y = 0
     #calculate the background traffic, one packet each 5000ms of 500ms ToA
     #for i in range(10):
     #    self.background_traffic.append((y,y+500))
     #   y += 500000
     #The first fragment will be sent after a random time (10 seconds)
     #make sure the table is begin enough to transmitt the packet
     self.current_time = 10000 * urandom.getrandbits(8) / 256
     input('')
Ejemplo n.º 15
0
    def deliver_packet(self, packet, src_id, dst_id=None,
                    callback=None, callback_args=tuple(), with_hack=False):
        self._log("----------------------- SEND PACKET -----------------------")
        lost = self.frame_loss.is_lost(len(packet))
        if not lost:
            self._log("----------------------- OK -----------------------")
            self._log("send-packet {}->{} {}".format(src_id, dst_id, packet))
            if enable_statsct:
                Statsct.log("send-packet {}->{} {}".format(src_id, dst_id, packet))
                clock = self.scheduler.get_clock()
                Statsct.add_packet_info(clock, packet, src_id, dst_id, True)
            # if dst_id == None, it is a broadcast
            link_list = self.get_link_by_id(src_id, dst_id)
            if not with_hack:
                count = 0
                for link in link_list:
                    count += self.send_packet_on_link(link, packet)
            else:
                count = 1
                self._send_packetX_hack() # [CA] should be removed
        else:
            self._log("----------------------- KO -----------------------")
            self._log("packet was lost {}->{}".format(src_id, dst_id))
            if enable_statsct:
                Statsct.log("packet was lost {}->{} {}".format(src_id, dst_id, packet))
                clock = self.scheduler.get_clock()
                Statsct.add_packet_info(clock, packet, src_id, dst_id, False)
            count = 0
        #
        if self.observer is not None:
            info = {"src":src_id, "dst":dst_id, "packet":packet,
                    "clock": clock, "count":count, "lost":lost,
                    "event-id": self.scheduler._get_event_id() }
            self.observer.record_packet(info)

        if callback != None: #XXX: should called by channel after delay
            args = callback_args+(count,) # XXX need to check. - CA:
            # [CA] the 'count' is now passed as 'status' in:
            #  SimulLayer2._event_sent_callback(self, transmit_callback, status
            # the idea is that is transmission fails, at least you can pass
            # count == 0 (status == 0), and you can do something there.
            # (in general case, some meta_information need to be sent)

            #args = callback_args
            callback(*args)
        return count
Ejemplo n.º 16
0
    def receive_frag(self, bbuf, dtag):
        self._last_receive_info = []
        dprint('state: {}, recieved fragment -> {}, rule-> {}'.format(
            self.state, bbuf, self.rule))

        schc_frag = frag_msg.frag_receiver_rx(self.rule, bbuf)
        dprint("receiver frag received:", schc_frag.__dict__)
        # XXX how to authenticate the message from the peer. without
        # authentication, any nodes can cancel the invactive timer.
        self.cancel_inactive_timer()
        if self.state == "ABORT":
            self._last_receive_info = [("state-abort", )]
            self.send_receiver_abort()
            return
        #
        # input("")
        if schc_frag.abort == True:
            dprint(
                "----------------------- Sender-Abort ---------------------------"
            )
            # Statsct.set_msg_type("SCHC_SENDER_ABORT")
            # XXX needs to release all resources.
            self._last_receive_info = [("abort", )]
            return

        if schc_frag.ack_request == True:
            dprint("Received ACK-REQ")
            self._last_receive_info = [("ack-req", )]
            # if self.state != "DONE":
            #     #this can happen when the ALL-1 is not received, so the state is
            #     #not done and the sender is requesting an ACK.
            #     # sending Receiver abort.
            #     schc_frag = frag_msg.frag_receiver_tx_abort(self.rule, self.dtag)
            #     args = (schc_frag.packet.get_content(), self.context["devL2Addr"])
            #     dprint("Sent Receiver-Abort.", schc_frag.__dict__)
            #     dprint("----------------------- SCHC RECEIVER ABORT SEND  -----------------------")

            #     if enable_statsct:
            #         Statsct.set_msg_type("SCHC_RECEIVER_ABORT")
            #         #Statsct.set_header_size(frag_msg.get_sender_header_size(self.rule))
            #     self.protocol.scheduler.add_event(0,
            #                                 self.protocol.layer2.send_packet, args)
            #     # XXX needs to release all resources.
            #     return
            dprint("XXX need sending ACK back.")
            self.state = 'ACK_REQ'
            # input('')
            self.resend_ack(schc_frag)
            return

        info = self._last_receive_info
        self.fragment_received = True
        # append the payload to the tile list.
        # padding truncation is done later. see below.
        # nb_tiles = schc_frag.payload.count_added_bits()//self.rule["tileSize"]
        tile_size = self.rule[T_FRAG][T_FRAG_PROF][T_FRAG_TILE]
        nb_tiles, last_tile_size = (schc_frag.payload.count_added_bits() //
                                    tile_size,
                                    schc_frag.payload.count_added_bits() %
                                    tile_size)
        info.append(("tile-info", {
            "nb-tiles": nb_tiles,
            "tile-size": tile_size,
            "last-tile-size": last_tile_size
        }))
        dprint("---------nb_tiles: ", nb_tiles, " -----last_tile_size ",
               last_tile_size)
        tiles = [
            schc_frag.payload.get_bits_as_buffer(tile_size)
            for _ in range(nb_tiles)
        ]
        dprint("---------tiles: ", tiles)

        # Note that nb_tiles is the number of tiles which is exact number of the
        # size of the tile.  the tile of which the size is less than the size
        # is not included.
        # The tile that is less than a tile size must be included, so a 1 can be added
        # in the bitmap when there is a tile in the all-1 message

        win = schc_frag.win
        fcn = schc_frag.fcn
        for tile_in_tiles in tiles:
            idx = tiles.index(tile_in_tiles)
            if tile_in_tiles.count_added_bits() % tile_size != 0:
                # tile found that is smaller than a normal tile
                dprint("tile found that is smaller than a normal tile")
                # nb_tiles = 1
            # tile should only be append if it is not in the list
            tile_in_list = False
            for tile in self.tile_list:
                if tile["w-num"] == win:
                    if tile["t-num"] == fcn - idx:
                        dprint("tile is already in tile list")
                        tile_in_list = True
                        info.append(("known-tile", idx, tile))
            if not tile_in_list:
                new_tile = ({
                    "w-num": win,
                    "t-num": fcn - idx,
                    "nb_tiles": 1,
                    "raw_tiles": tile_in_tiles
                })
                self.tile_list.append(new_tile)
                info.append(("new-tile", idx, new_tile))
                self.tile_list = sort_tile_list(
                    self.tile_list, self.rule[T_FRAG][T_FRAG_PROF][T_FRAG_FCN])
            if (fcn - idx) == 0:
                win += 1
                fcn = self.rule[T_FRAG][T_FRAG_PROF][T_FRAG_FCN] << 1
                tiles = tiles[(idx + 1):]

        # !IMPORTANT: it's neccesary to change this condition for one more exact which consider the last tile size cases
        if last_tile_size > 8:
            last_tile = schc_frag.payload.get_bits_as_buffer(last_tile_size)
            dprint('---------tile:', last_tile)
            info.append(("last-tile", last_tile))
            tile_in_list = False
            for tile in self.tile_list:
                if tile["w-num"] == win:
                    if tile["t-num"] == 7:  # XXX: why 7?
                        dprint("tile is already in tile list")
                        tile_in_list = True
                        info.append(("known-last-tile", None, tile))
            if not tile_in_list:
                new_tile = ({
                    "w-num": win,
                    "t-num": 7,
                    "nb_tiles": 1,
                    "raw_tiles": last_tile
                })
                self.tile_list.append(new_tile)
                info.append(("new-last-tile", None, tile))
                self.tile_list = sort_tile_list(
                    self.tile_list, self.rule[T_FRAG][T_FRAG_PROF][T_FRAG_FCN])

        # if schc_frag.payload.count_added_bits()%self.rule["tileSize"] != 0:
        #     #tile found that is smaller than a normal tile
        #     dprint("tile found that is smaller than a normal tile")
        #     #nb_tiles = 1
        # #tile should only be append if it is not in the list
        # tile_in_list = False
        # for tile in self.tile_list:
        #     if tile["w-num"] == schc_frag.win:
        #         if tile["t-num"] == schc_frag.fcn:
        #             dprint("tile is already in tile list")
        #             tile_in_list = True
        # if not tile_in_list:
        #     self.tile_list.append({
        #             "w-num": schc_frag.win,
        #             "t-num": schc_frag.fcn,
        #             "nb_tiles": nb_tiles,
        #             "raw_tiles":schc_frag.payload})
        #     self.tile_list = sort_tile_list(self.tile_list, self.rule["FCNSize"])
        for tile in self.tile_list:
            dprint("w-num: {} t-num: {} nb_tiles:{}".format(
                tile['w-num'], tile['t-num'], tile['nb_tiles']))
        dprint("")
        # dprint("raw_tiles:{}".format(tile['raw_tiles']))
        # self.tile_list = sort_tile_list(self.tile_list, self.rule["WSize"])

        # self.tile_list.append({
        #         "w-num": schc_frag.win,
        #         "t-num": schc_frag.fcn,
        #         "nb_tiles": nb_tiles,
        #         "raw_tiles":schc_frag.payload})
        # self.tile_list = sort_tile_list(self.tile_list, self.rule["FCNSize"])
        # self.tile_list = sort_tile_list(self.tile_list, self.rule["WSize"])

        should_send_ack = False
        if self.mic_received is not None:
            schc_packet, mic_calced = self.get_mic_from_tiles_received()
            if self.mic_received == mic_calced:
                info.append("mic-ok")
                self.finish(schc_packet, schc_frag)
                return
            else:
                # XXX waiting for the fragments requested by ACK.
                # during MAX_ACK_REQUESTS
                info.append("mic-not-ok")
                dprint("waiting for more fragments.")
                # XXX: do that only when necessary (one per window):
                #should_send_ack = True
        elif schc_frag.fcn == frag_msg.get_fcn_all_1(self.rule):
            # XXX: what if you receive two MICs?
            dprint(
                "----------------------- ALL1 received -----------------------"
            )
            self.all1_received = True
            Statsct.set_msg_type("SCHC_ALL_1")
            self.mic_received = schc_frag.mic
            schc_packet, mic_calced = self.get_mic_from_tiles_received()
            dprint("schc_frag.mic: {}, mic_calced: {}".format(
                schc_frag.mic, mic_calced))
            info.append(("mic-received", schc_frag.mic, mic_calced))
            if schc_frag.mic == mic_calced:
                dprint("SUCCESS: MIC matched. packet {} == result {}".format(
                    schc_frag.mic, mic_calced))
                info.append("mic-ok")
                self.mic_missmatched = False
                self.finish(schc_packet, schc_frag)
                return
            else:
                self.mic_missmatched = True
                self.state = 'ERROR_MIC'
                info.append("mic-not-ok")  # XXX: how do you leave ERROR state?
                dprint("----------------------- ERROR -----------------------")
                dprint("ERROR: MIC mismatched. packet {} != result {}".format(
                    schc_frag.mic, mic_calced))
                should_send_ack = True

        if should_send_ack:
            bit_list = find_missing_tiles(
                self.tile_list, self.rule[T_FRAG][T_FRAG_PROF][T_FRAG_FCN],
                frag_msg.get_fcn_all_1(self.rule))

            assert bit_list is not None
            schc_ack = self.create_ack_schc_ko(schc_frag)
            info.append(("mic-ack", bit_list))
            """
                Changement à corriger
                args = (schc_ack.packet.get_content(), self.context["devL2Addr"])
                """
            args = (schc_ack.packet.get_content(), '*')
            self.protocol.scheduler.add_event(0,
                                              self.protocol.layer2.send_packet,
                                              args)
            # XXX need to keep the ack message for the ack request.

        # XXX: maybe set timer in all cases (there are 'return's above)
        # set inactive timer.
        self.event_id_inactive_timer = self.protocol.scheduler.add_event(
            self.inactive_timer, self.event_inactive, tuple())
        dprint("---", schc_frag.fcn)
Ejemplo n.º 17
0
    def send_frag(self):
        # XXX
        # because No-ACK mode supports variable MTU,
        # sender can't know the fact that it can't send all fragments
        # before it reachs to send the last fragment (All-1).
        #
        #     The All-1 fragment MUST be formed like below.
        #
        #     | header | MIC |    last tile     |
        #                    |<- L2 word size ->|
        #                                       |<- L2 Word
        #
        #     if the size of header+MIC+tile doesn't fit the L2 Word,
        #
        #     | header | MIC |     last tile    |    padding    |
        #                    |<- L2 word size ->|<- less than ->|
        #                                         L2 word size
        #                                                       |<- L2 Word
        payload_size = (self.protocol.layer2.get_mtu_size() -
                        frag_msg.get_sender_header_size(self.rule))
        remaining_data_size = self.packet_bbuf.count_remaining_bits()
        if remaining_data_size >= payload_size:
            dprint(
                "----------------------- Fragmentation process -----------------------"
            )
            # put remaining_size of bits of packet into the tile.
            tile = self.packet_bbuf.get_bits_as_buffer(payload_size)
            transmit_callback = self.event_sent_frag
            fcn = 0
            self.mic_sent = None

            if enable_statsct:
                Statsct.set_msg_type("SCHC_FRAG")
                Statsct.set_header_size(
                    frag_msg.get_sender_header_size(self.rule))
        elif remaining_data_size < payload_size:
            dprint(
                "----------------------- Fragmentation process -----------------------"
            )
            if remaining_data_size <= (payload_size -
                                       frag_msg.get_mic_size(self.rule)):
                tile = None
                if remaining_data_size > 0:
                    tile = self.packet_bbuf.get_bits_as_buffer()
                # make All-1 frag.
                assert self.mic_sent is None
                last_frag_base_size = 0
                if tile is not None:
                    last_frag_base_size += (
                        frag_msg.get_sender_header_size(self.rule) +
                        frag_msg.get_mic_size(self.rule) + remaining_data_size)
                self.mic_sent = self.get_mic(self.mic_base,
                                             last_frag_base_size)
                # callback doesn't need in No-ACK mode.
                transmit_callback = None
                fcn = frag_msg.get_fcn_all_1(self.rule)
                if enable_statsct:
                    Statsct.set_msg_type("SCHC_ALL_1 ")
                    Statsct.set_header_size(
                        frag_msg.get_sender_header_size(self.rule) +
                        frag_msg.get_mic_size(self.rule))
            else:
                # put the size of the complements of the header to L2 Word.
                tile_size = (remaining_data_size -
                             (frag_msg.get_sender_header_size(self.rule) +
                              remaining_data_size) % self.l2word)
                tile = self.packet_bbuf.get_bits_as_buffer(tile_size)
                transmit_callback = self.event_sent_frag
                fcn = 0
                self.mic_sent = None
                if enable_statsct:
                    Statsct.set_msg_type("SCHC_FRAG")
                    Statsct.set_header_size(
                        frag_msg.get_sender_header_size(self.rule))
        schc_frag = frag_msg.frag_sender_tx(self.rule,
                                            dtag=self.dtag,
                                            win=None,
                                            fcn=fcn,
                                            mic=self.mic_sent,
                                            payload=tile)

        # send a SCHC fragment
        args = (schc_frag.packet.get_content(), self._session_id[0],
                transmit_callback)
        dprint("frag sent:", schc_frag.__dict__)
        if self.rule[T_FRAG][T_FRAG_PROF][T_FRAG_DTAG] == 0:
            w_dtag = '-'
        else:
            w_dtag = schc_frag.dtag

        if self.rule[T_FRAG][T_FRAG_PROF][T_FRAG_W] == 0:
            w_w = '-'
        else:
            w_w = schc_frag.win

        all1 = 2**self.rule[T_FRAG][T_FRAG_PROF][T_FRAG_FCN] - 1
        if schc_frag.fcn == all1:
            w_fcn = "All-1"
        elif schc_frag.fcn == 0:
            w_fcn = "All-0"
        else:
            w_fcn = schc_frag.fcn

        dtrace("r:{}/{} (noA) DTAG={} W={} FCN={}".format(
            self.rule[T_RULEID], self.rule[T_RULEIDLENGTH], w_dtag, w_w,
            w_fcn))
        dtrace("|----{:3}------------->".format(len(
            schc_frag.packet._content)))

        self.protocol.scheduler.add_event(0, self.protocol.layer2.send_packet,
                                          args)
min_packet_size = 250  #60

max_packet_size = 1290  #bytes
#packet_sizes = [80,160,320,640,1280]
#packet_sizes = [320]
#packet_sizes = [320,640,1280]
packet_sizes = [80, 160, 320, 640]
packet_sizes = [80]

tile_size = 49
#tile_size = 240
payload_ack_always = tile_size * 2
ack_on_error = True
#---------------------------------------------------------------------------
""" Init stastct module """
Statsct.initialize()
Statsct.log("Statsct test")
Statsct.set_packet_size(data_size)
Statsct.set_SF(SF)
#---------------------------------------------------------------------------

#no-ack
rm0 = RuleManager()
rm0.add_context(rule_context, compress_rule, frag_rule3, frag_rule4)

rm1 = RuleManager()
rm1.add_context(rule_context, compress_rule, frag_rule4, frag_rule3)
#ack-on-error
if ack_on_error:
    rm0 = RuleManager()
    rm0.add_context(rule_context, compress_rule, frag_rule1, frag_rule2)
Ejemplo n.º 19
0
    def receive_frag(self, bbuf, dtag):
        
        print('state: {}, recieved fragment -> {}, rule-> {}'.format(self.state,
                                bbuf, self.rule))
        
        schc_frag = schcmsg.frag_receiver_rx(self.rule, bbuf)
        print("receiver frag received:", schc_frag.__dict__)
        # XXX how to authenticate the message from the peer. without
        # authentication, any nodes can cancel the invactive timer.
        self.cancel_inactive_timer()
        if self.state == "ABORT":
            self.send_receiver_abort()
            return
        #
        #input("")
        if schc_frag.abort == True:
            print("Received Sender-Abort.")
            #Statsct.set_msg_type("SCHC_SENDER_ABORT")
            # XXX needs to release all resources.
            return
          
        if schc_frag.ack_request == True:
            print("Received ACK-REQ")
            # if self.state != "DONE":
            #     #this can happen when the ALL-1 is not received, so the state is
            #     #not done and the sender is requesting an ACK.
            #     # sending Receiver abort.
            #     schc_frag = schcmsg.frag_receiver_tx_abort(self.rule, self.dtag)
            #     args = (schc_frag.packet.get_content(), self.context["devL2Addr"])
            #     print("Sent Receiver-Abort.", schc_frag.__dict__)
            #     print("----------------------- SCHC RECEIVER ABORT SEND  -----------------------")

            #     if enable_statsct:
            #         Statsct.set_msg_type("SCHC_RECEIVER_ABORT")
            #         #Statsct.set_header_size(schcmsg.get_sender_header_size(self.rule))
            #     self.protocol.scheduler.add_event(0,
            #                                 self.protocol.layer2.send_packet, args)
            #     # XXX needs to release all resources.
            #     return
            print("XXX need sending ACK back.")
            #input('')
            self.resend_ack(schc_frag)
            return
        
        self.fragment_received = True
        # append the payload to the tile list.
        # padding truncation is done later. see below.
        nb_tiles = schc_frag.payload.count_added_bits()//self.rule["tileSize"]
        # Note that nb_tiles is the number of tiles which is exact number of the
        # size of the tile.  the tile of which the size is less than the size
        # is not included.
        # The tile that is less than a tile size must be included, so a 1 can be added
        # in the bitmap when there is a tile in the all-1 message
        if schc_frag.payload.count_added_bits()%self.rule["tileSize"] != 0:
            #tile found that is smaller than a normal tile
            print("tile found that is smaller than a normal tile")
            nb_tiles = 1
        #tile should only be append if it is not in the list
        tile_in_list = False
        for tile in self.tile_list:
            if tile["w-num"] == schc_frag.win:
                if tile["t-num"] == schc_frag.fcn:
                    print("tile is already in tile list")
                    tile_in_list = True
        if not tile_in_list:
            self.tile_list.append({
                    "w-num": schc_frag.win,
                    "t-num": schc_frag.fcn,
                    "nb_tiles": nb_tiles,
                    "raw_tiles":schc_frag.payload})
            self.tile_list = sort_tile_list(self.tile_list, self.rule["FCNSize"])
        for tile in self.tile_list:
            print("w-num: {} t-num: {} nb_tiles:{}".format(
                    tile['w-num'],tile['t-num'],tile['nb_tiles']))
            #print("raw_tiles:{}".format(tile['raw_tiles']))
        #self.tile_list = sort_tile_list(self.tile_list, self.rule["WSize"])

        # self.tile_list.append({
        #         "w-num": schc_frag.win,
        #         "t-num": schc_frag.fcn,
        #         "nb_tiles": nb_tiles,
        #         "raw_tiles":schc_frag.payload})
        # self.tile_list = sort_tile_list(self.tile_list, self.rule["FCNSize"])
        #self.tile_list = sort_tile_list(self.tile_list, self.rule["WSize"])

        if self.mic_received is not None:
            schc_packet, mic_calced = self.get_mic_from_tiles_received()
            if self.mic_received == mic_calced:
                self.finish(schc_packet, schc_frag)
                return
            else:
                # XXX waiting for the fragments requested by ACK.
                # during MAX_ACK_REQUESTS
                print("waiting for more fragments.")
        elif schc_frag.fcn == schcmsg.get_fcn_all_1(self.rule):
            print("----------------------- ALL1 received -----------------------")
            self.all1_received = True
            #Statsct.set_msg_type("SCHC_ALL_1")
            self.mic_received = schc_frag.mic
            schc_packet, mic_calced = self.get_mic_from_tiles_received()
            print("schc_frag.mic: {}, mic_calced: {}".format(schc_frag.mic,mic_calced))
            if schc_frag.mic == mic_calced:
                self.mic_missmatched = False
                self.finish(schc_packet, schc_frag)
                return
            else:
                self.mic_missmatched = True
                print("----------------------- ERROR -----------------------")
                print("ERROR: MIC mismatched. packet {} != result {}".format(
                        schc_frag.mic, mic_calced))
                bit_list = find_missing_tiles_mic_ko_yes_all_1(self.tile_list,
                                              self.rule["FCNSize"],
                                              schcmsg.get_fcn_all_1(self.rule))
                
                assert bit_list is not None
                if len(bit_list) == 0:
                    #When the find_missing_tiles functions returns an empty array
                    #but we know something is missing because the MIC calculation is wrong
                    #this can happen when the first fragments are lost for example
                    print("bit list empty but the mic missmatched")
                    #if tiles are missing, then the packet is larger, should send a bitmap
                    #that considers the max_fcn and the tiles received
                    bit_list = find_missing_tiles_mic_ko_yes_all_1(self.tile_list,
                                                self.rule["FCNSize"],
                                                schcmsg.get_fcn_all_1(self.rule))
                    #print("new bit list, should it work???")
                    #input("")
                for bl_index in range(len(bit_list)):
                    print("missing wn={} bitmap={}".format(bit_list[bl_index][0],
                                                           bit_list[bl_index][1]))
                    # XXX compress bitmap if needed.
                    # ACK failure message
                    schc_ack = schcmsg.frag_receiver_tx_all1_ack(
                            schc_frag.rule,
                            schc_frag.dtag,
                            win=bit_list[bl_index][0],
                            cbit=0,
                            bitmap=bit_list[bl_index][1])
                    if enable_statsct:
                        Statsct.set_msg_type("SCHC_ACK_KO")
                    print("----------------------- SCHC ACK KO SEND  -----------------------")

                    print("ACK failure sent:", schc_ack.__dict__)
                    args = (schc_ack.packet.get_content(),
                            self.context["devL2Addr"])
                    self.protocol.scheduler.add_event(
                            0, self.protocol.layer2.send_packet, args)
                    # XXX need to keep the ack message for the ack request.
                    break
        # set inactive timer.
        self.event_id_inactive_timer = self.protocol.scheduler.add_event(
                self.inactive_timer, self.event_inactive, tuple())
        print("---", schc_frag.fcn)
Ejemplo n.º 20
0
    def send_frag(self):
        print("{} send_frag!!!!!!!!!!!!!!!!!".format(utime.time()))
        print("all1_send-> {}, resend -> {}, state -> {}".format(
            self.all1_send, self.resend, self.state))
        print("all tiles unsend -> {}".format(self.all_tiles))
        for tile in self.all_tiles.get_all_tiles():
            print("w: {}, t: {}, sent: {}".format(tile['w-num'], tile['t-num'],
                                                  tile['sent']))
        if self.state == self.ACK_SUCCESS:
            return

        # if self.state == self.ACK_FAILURE and self.num_of_windows != 1 and self.number_of_ack_waits <= self.num_of_windows:
        #     #waiting for the acks of the others windows
        #     self.number_of_ack_waits += 1 #wait depends on the number of windows
        #     #set ack_time_out_timer
        #     print("waiting for more acks: {}".format(self.number_of_ack_waits))
        #     return

        # get contiguous tiles as many as possible fit in MTU.
        mtu_size = self.protocol.layer2.get_mtu_size()
        window_tiles, nb_remaining_tiles, remaining_size = self.all_tiles.get_tiles(
            mtu_size)
        print("window tiles: {}, nb_remaining_tiles: {}, remaining_size: {}".
              format(window_tiles, nb_remaining_tiles, remaining_size))
        if window_tiles is None and self.resend:
            print("no more tiles to resend")
            #how to identify that all tiles are resend and that the ack timeout should be set
            #to wait for tha last ok. It should be set after retransmission of the last fragment
            if self.state == self.ACK_FAILURE and self.event_id_ack_wait_timer is None:
                win = self.last_window_tiles[0][
                    "w-num"] if self.last_window_tiles[0][
                        "w-num"] is not None else 0
                if self.last_window_tiles[0]["t-num"] == 0:
                    win += 1
                schc_frag = schcmsg.frag_sender_tx(self.rule,
                                                   dtag=self.dtag,
                                                   win=win,
                                                   fcn=schcmsg.get_fcn_all_1(
                                                       self.rule),
                                                   mic=self.mic_sent)
                #set ack waiting timer
                args = (
                    schc_frag,
                    win,
                )
                self.event_id_ack_wait_timer = self.protocol.scheduler.add_event(
                    self.ack_wait_timer, self.ack_timeout, args)
                print("*******event id {}".format(
                    self.event_id_ack_wait_timer))
            # if self.all1_send and self.state == self.ACK_FAILURE:
            #     #case when with the bitmap is not possible to identify the missing tile,
            #     #resend ALL-1 messages
            #     # send a SCHC fragment
            #     args = (self.schc_all_1.packet.get_content(), self.context["devL2Addr"],
            #     self.event_sent_frag)
            #     print("frag sent:", self.schc_all_1.__dict__)
            #     if enable_statsct:
            #         Statsct.set_msg_type("SCHC_ALL_1")
            #         Statsct.set_header_size(schcmsg.get_sender_header_size(self.rule) +
            #             schcmsg.get_mic_size(self.rule))
            #     self.protocol.scheduler.add_event(0, self.protocol.layer2.send_packet,
            #                                     args)
            #     print("Sending all-1 beacuse there is an ACK FaILURE but cannot find the missing tiles")
            #     input("")

            # win = self.last_window_tiles[0]["w-num"] if self.last_window_tiles[0]["w-num"] is not None else 0
            # if self.last_window_tiles[0]["t-num"] == 0:
            #     win += 1
            # schc_frag = schcmsg.frag_sender_tx(
            #         self.rule, dtag=self.dtag, win=win,
            #         fcn=schcmsg.get_fcn_all_1(self.rule),
            #         mic=self.mic_sent)
            # set ack waiting timer
            #args = (schc_frag, win,)
            #self.event_id_ack_wait_timer = self.protocol.scheduler.add_event(
            #        self.ack_wait_timer, self.ack_timeout, args)
            #print("*******event id {}".format(self.event_id_ack_wait_timer))

        #if window_tiles is not None and not self.all1_send and not self.resend:
        if window_tiles is not None:

            print("window_tiles is not None -> {}, resend -> {}".format(
                self.all1_send, self.resend))
            # even when mic is sent, it comes here in the retransmission.
            if self.all1_send and self.state != self.ACK_FAILURE:
                #when there is a retransmission, the all-1 is send again and is send before
                #the ACK-OK is received. One option is not set the timer after the last
                #retransmission, but i don´t know how to idenfy that all missing fragments
                #have been send. Also the ALL-1 is not retransmisted (dont know if this should
                # be like this. For example, if the ALL-1s is lost, the receiver timer expires
                # and a receiver abort is send. If it arrives, there is not need to retransmit
                # the message after the retransmission of the missing fragments)
                #FIX, all-1 is resend
                print('All-1 ones already send')
                #cancel timer when there is success
                # if self.event_id_ack_wait_timer and self.state == self.ACK_SUCCESS:
                #     self.cancel_ack_wait_timer()
                #else:
                #    print("how to add a timer without sending a message")
                # fcn = schcmsg.get_fcn_all_1(self.rule)
                # args = (schc_frag, window_tiles[0]["w-num"],)
                # elf.event_id_ack_wait_timer = self.protocol.scheduler.add_event(
                # self.ack_wait_timer, self.ack_timeout, args)
                #fcn = schcmsg.get_fcn_all_1(self.rule)
                return
            elif (nb_remaining_tiles == 0 and len(window_tiles) == 1
                  and remaining_size >= schcmsg.get_mic_size(self.rule)):
                print("ALL-1 prepared")

                # make the All-1 frag with this tile.
                # the All-1 fragment can carry only one tile of which the size
                # is less than L2 word size.
                fcn = schcmsg.get_fcn_all_1(self.rule)
                last_frag_base_size = (
                    schcmsg.get_sender_header_size(self.rule) +
                    schcmsg.get_mic_size(self.rule) +
                    TileList.get_tile_size(window_tiles))
                #check if mic exists, no need no created again
                if self.mic_sent is None:
                    mic = self.get_mic(self.mic_base, last_frag_base_size)
                    # store the mic in order to know all-1 has been sent.
                    self.mic_sent = mic
                else:
                    mic = self.mic_sent
                print("mic_sent -> {}".format(self.mic_sent))
                if enable_statsct:
                    Statsct.set_msg_type("SCHC_ALL_1")
                    Statsct.set_header_size(
                        schcmsg.get_sender_header_size(self.rule) +
                        schcmsg.get_mic_size(self.rule))
                self.all1_send = True
                self.state = self.SEND_ALL_1
            else:
                print("regular SCHC frag")
                # regular fragment.
                fcn = window_tiles[0]["t-num"]
                mic = None

                if enable_statsct:
                    Statsct.set_msg_type("SCHC_FRAG")
                    Statsct.set_header_size(
                        schcmsg.get_sender_header_size(self.rule))
            schc_frag = schcmsg.frag_sender_tx(
                self.rule,
                dtag=self.dtag,
                win=window_tiles[0]["w-num"],
                fcn=fcn,
                mic=mic,
                payload=TileList.concat(window_tiles))

            if mic is not None:

                print("mic is not None")
                # set ack waiting timer
                #if enable_statsct:
                #    Statsct.set_msg_type("SCHC_FRAG")
                #    Statsct.set_header_size(schcmsg.get_sender_header_size(self.rule))
                args = (
                    schc_frag,
                    window_tiles[0]["w-num"],
                )
                print("all ones")
                self.schc_all_1 = schc_frag
                self.event_id_ack_wait_timer = self.protocol.scheduler.add_event(
                    self.ack_wait_timer, self.ack_timeout, args)
                print("*******event id {}".format(
                    self.event_id_ack_wait_timer))
            # save the last window tiles.
            self.last_window_tiles = window_tiles
            print("self.last_window_tiles -> {}".format(
                self.last_window_tiles))
        elif self.mic_sent is not None or self.all1_send:
            print("self.mic_sent is not None state -> {}".format(self.state))
            # it looks that all fragments have been sent.
            print(
                "----------------------- all tiles have been sent -----------------------",
                window_tiles, nb_remaining_tiles, remaining_size)
            schc_frag = None
            self.all1_send = True
            if self.event_id_ack_wait_timer and self.state == self.ACK_SUCCESS:
                self.cancel_ack_wait_timer()
            return
        else:
            print("only mic all tiles send")
            # Here, only MIC will be sent since all tiles has been sent.
            assert self.last_window_tiles is not None
            # As the MTU would be changed anytime AND the size of the
            # significant padding bits would be changed, therefore the MIC
            # calculation may be needed again.
            # XXX maybe it's better to check whether the size of MTU is change
            # or not when the previous MIC was calculated..
            last_frag_base_size = (
                schcmsg.get_sender_header_size(self.rule) +
                TileList.get_tile_size(self.last_window_tiles))
            self.mic_sent = self.get_mic(self.mic_base, last_frag_base_size)
            # check the win number.
            # XXX if the last tile number is zero, here window number has to be
            # incremented.
            win = self.last_window_tiles[0]["w-num"]
            if self.last_window_tiles[0]["t-num"] == 0:
                win += 1
            schc_frag = schcmsg.frag_sender_tx(self.rule,
                                               dtag=self.dtag,
                                               win=win,
                                               fcn=schcmsg.get_fcn_all_1(
                                                   self.rule),
                                               mic=self.mic_sent)
            # set ack waiting timer
            args = (
                schc_frag,
                win,
            )
            if enable_statsct:
                Statsct.set_msg_type("SCHC_ALL_1")
                Statsct.set_header_size(
                    schcmsg.get_sender_header_size(self.rule) +
                    schcmsg.get_mic_size(self.rule))
            self.schc_all_1 = schc_frag
            self.event_id_ack_wait_timer = self.protocol.scheduler.add_event(
                self.ack_wait_timer, self.ack_timeout, args)
            print("*******event id {}".format(self.event_id_ack_wait_timer))

        # send a SCHC fragment
        args = (schc_frag.packet.get_content(), self.context["devL2Addr"],
                self.event_sent_frag)
        print("frag sent:", schc_frag.__dict__)
        self.protocol.scheduler.add_event(0, self.protocol.layer2.send_packet,
                                          args)
Ejemplo n.º 21
0
    def send_frag(self):
        # XXX
        # because No-ACK mode supports variable MTU,
        # sender can't know the fact that it can't send all fragments
        # before it reachs to send the last fragment (All-1).
        #
        #     The All-1 fragment MUST be formed like below.
        #
        #     | header | MIC |    last tile     |
        #                    |<- L2 word size ->|
        #                                       |<- L2 Word
        #
        #     if the size of header+MIC+tile doesn't fit the L2 Word,
        #
        #     | header | MIC |     last tile    |    padding    |
        #                    |<- L2 word size ->|<- less than ->|
        #                                         L2 word size
        #                                                       |<- L2 Word
        payload_size = (self.protocol.layer2.get_mtu_size() -
                        schcmsg.get_sender_header_size(self.rule))
        remaining_data_size = self.packet_bbuf.count_remaining_bits()
        if remaining_data_size >= payload_size:
            # put remaining_size of bits of packet into the tile.
            tile = self.packet_bbuf.get_bits_as_buffer(payload_size)
            transmit_callback = self.event_sent_frag
            fcn = 0
            self.mic_sent = None
            if enable_statsct:
                Statsct.set_msg_type("SCHC_FRAG")
                Statsct.set_header_size(
                    schcmsg.get_sender_header_size(self.rule))
        elif remaining_data_size < payload_size:
            if remaining_data_size <= (payload_size -
                                       schcmsg.get_mic_size(self.rule)):
                tile = None
                if remaining_data_size > 0:
                    tile = self.packet_bbuf.get_bits_as_buffer()
                # make All-1 frag.
                assert self.mic_sent is None
                last_frag_base_size = 0
                if tile is not None:
                    last_frag_base_size += (
                        schcmsg.get_sender_header_size(self.rule) +
                        schcmsg.get_mic_size(self.rule) + remaining_data_size)
                self.mic_sent = self.get_mic(self.mic_base,
                                             last_frag_base_size)
                # callback doesn't need in No-ACK mode.
                transmit_callback = None
                fcn = schcmsg.get_fcn_all_1(self.rule)
                if enable_statsct:
                    Statsct.set_msg_type("SCHC_ALL_1")
                    Statsct.set_header_size(
                        schcmsg.get_sender_header_size(self.rule) +
                        schcmsg.get_mic_size(self.rule))
            else:
                # put the size of the complements of the header to L2 Word.
                tile_size = (remaining_data_size -
                             (schcmsg.get_sender_header_size(self.rule) +
                              remaining_data_size) % self.rule["L2WordSize"])
                tile = self.packet_bbuf.get_bits_as_buffer(tile_size)
                transmit_callback = self.event_sent_frag
                fcn = 0
                self.mic_sent = None
                if enable_statsct:
                    Statsct.set_msg_type("SCHC_FRAG")
                    Statsct.set_header_size(
                        schcmsg.get_sender_header_size(self.rule))
        schc_frag = schcmsg.frag_sender_tx(self.rule,
                                           dtag=self.dtag,
                                           win=None,
                                           fcn=fcn,
                                           mic=self.mic_sent,
                                           payload=tile)

        # send a SCHC fragment
        args = (schc_frag.packet.get_content(), self.context["devL2Addr"],
                transmit_callback)
        print("frag sent:", schc_frag.__dict__)
        self.protocol.scheduler.add_event(0, self.protocol.layer2.send_packet,
                                          args)
Ejemplo n.º 22
0
#---------------------------------------------------------------------------


def make_node(sim, rule_manager, devaddr, extra_config={}):
    node = simul.SimulSCHCNode(sim, extra_config)
    node.protocol.set_rulemanager(rule_manager)
    node.layer2.set_devaddr(devaddr)
    return node


#---------------------------------------------------------------------------

#---------------------------------------------------------------------------
""" Init stastct module """
Statsct.initialize()
Statsct.log("Statsct test")
#---------------------------------------------------------------------------

rule = []
for k in [
        opt.context_file, opt.rule_comp_file, opt.rule_fragin_file,
        opt.rule_fragout_file
]:
    with open(k) as fd:
        rule.append(json.loads(fd.read()))

rm0 = RuleManager()
rm0.add_context(rule[0], rule[1], rule[2], rule[3])

rm1 = RuleManager()
Ejemplo n.º 23
0
def frag_generic(rules_filename, packet_loss):
    # --------------------------------------------------
    # General configuration

    l2_mtu = 72  # bits
    data_size = 14  # bytes
    SF = 12

    simul_config = {
        "log": True,
    }

    # ---------------------------------------------------------------------------
    # Configuration packets loss

    if packet_loss:
        # Configuration with packet loss in noAck and ack-on-error
        loss_rate = 15  # in %
        collision_lambda = 0.1
        background_frag_size = 54
        loss_config = {"mode": "rate", "cycle": loss_rate}
        # loss_config = {"mode":"collision", "G":collision_lambda, "background_frag_size":background_frag_size}
    else:
        # Configuration without packet loss in noAck and ack-on-error
        loss_rate = None
        loss_config = None

    # ---------------------------------------------------------------------------
    # Init packet loss
    if loss_config is not None:
        simul_config["loss"] = loss_config

    # ---------------------------------------------------------------------------

    def make_node(sim, rule_manager, devaddr=None, extra_config={}, role=None):
        extra_config["unique-peer"] = True
        node = net_sim_core.SimulSCHCNode(sim, extra_config, role)
        node.protocol.set_rulemanager(rule_manager)
        if devaddr is None:
            devaddr = node.id
        node.layer2.set_devaddr(devaddr)
        return node

    # ---------------------------------------------------------------------------
    # Statistic module
    Statsct.initialize()
    Statsct.log("Statsct test")
    Statsct.set_packet_size(data_size)
    Statsct.set_SF(SF)
    # ---------------------------------------------------------------------------
    devaddr1 = b"\xaa\xbb\xcc\xdd"
    devaddr2 = b"\xaa\xbb\xcc\xee"
    dprint("---------Rules Device -----------")
    rm0 = RuleManager()
    # rm0.add_context(rule_context, compress_rule1, frag_rule3, frag_rule4)
    rm0.Add(device=devaddr1, file=rules_filename)
    rm0.Print()

    dprint("---------Rules gw -----------")
    rm1 = RuleManager()
    # rm1.add_context(rule_context, compress_rule1, frag_rule4, frag_rule3)
    rm1.Add(device=devaddr2, file=rules_filename)
    rm1.Print()

    # ---------------------------------------------------------------------------
    # Configuration of the simulation
    Statsct.get_results()
    sim = net_sim_core.Simul(simul_config)

    node0 = make_node(sim, rm0, devaddr1, role="device")  # SCHC device
    node1 = make_node(sim, rm1, devaddr2, role="core-server")  # SCHC gw
    sim.add_sym_link(node0, node1)
    node0.layer2.set_mtu(l2_mtu)
    node1.layer2.set_mtu(l2_mtu)

    # ---------------------------------------------------------------------------
    # Information about the devices

    dprint(
        "-------------------------------- SCHC device------------------------")
    dprint("SCHC device L3={} L2={} RM={}".format(node0.layer3.L3addr,
                                                  node0.id, rm0.__dict__))
    dprint(
        "-------------------------------- SCHC gw ---------------------------")
    dprint("SCHC gw     L3={} L2={} RM={}".format(node1.layer3.L3addr,
                                                  node1.id, rm1.__dict__))
    dprint(
        "-------------------------------- Rules -----------------------------")
    dprint("rules -> {}, {}".format(rm0.__dict__, rm1.__dict__))
    dprint("")

    # ---------------------------------------------------------------------------
    # Statistic configuration

    Statsct.setSourceAddress(node0.id)
    Statsct.setDestinationAddress(node1.id)

    # --------------------------------------------------
    # Message

    coap = bytearray(b"`\x12\x34\x56\x00\x1e\x11\x1e\xfe\x80\x00" +
                     b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" +
                     b"\x00\x00\x01\xfe\x80\x00\x00\x00\x00\x00" +
                     b"\x00\x00\x00\x00\x00\x00\x00\x00\x02\x16" +
                     b"2\x163\x00\x1e\x00\x00A\x02\x00\x01\n\xb3" +
                     b"foo\x03bar\x06ABCD==Fk=eth0\xff\x84\x01" +
                     b"\x82  &Ehello")

    # ---------------------------------------------------------------------------
    # Simnulation

    node0.protocol.layer3.send_later(1, None, node1.layer3.L3addr, coap)

    old_stdout = sys.stdout
    set_debug_output(True)
    sys.stdout = io.StringIO()
    sim.run()
    simulation_output = sys.stdout.getvalue()
    sys.stdout = old_stdout
    set_debug_output(False)

    print(simulation_output)
    return simulation_output
Ejemplo n.º 24
0
    def resend_ack(self, schc_frag):
        print("resend ack method")
        print(schc_frag.__dict__)
        if self.mic_received is not None:
            schc_packet, mic_calced = self.get_mic_from_tiles_received()
            print("schc_frag.mic: {}, mic_calced: {}".format(self.mic_received,mic_calced))
            if self.mic_received == mic_calced:
                self.state = "DONE"
        if self.state == "DONE":
            # ACK message
            schc_ack = schcmsg.frag_receiver_tx_all1_ack(
                schc_frag.rule,
                schc_frag.dtag,
                schc_frag.win,
                cbit=1)
            print("ACK success sent:", schc_ack.__dict__)
            if enable_statsct:
                Statsct.set_msg_type("SCHC_ACK_OK")
            print("----------------------- SCHC ACK OK SEND  -----------------------")
        else:
            if self.all1_received:
                print("all-1 received, building ACK")
                print('send ack before done {},{},{}'.format(self.tile_list,
                            self.rule["FCNSize"], schcmsg.get_fcn_all_1(self.rule)))
                bit_list = find_missing_tiles_mic_ko_yes_all_1(self.tile_list,
                                                self.rule["FCNSize"],
                                                schcmsg.get_fcn_all_1(self.rule))
                for tile in self.tile_list:
                    print("w-num: {} t-num: {} nb_tiles:{}".format(
                        tile['w-num'],tile['t-num'],tile['nb_tiles']))
                    print("raw_tiles:{}".format(tile['raw_tiles']))
                print('send ack before done {}'.format(bit_list))
                assert bit_list is not None
                if len(bit_list) == 0:
                    #When the find_missing_tiles functions returns an empty array
                    #but we know something is missing because the MIC calculation is wrong
                    #this can happen when the first fragments are lost
                    print("bit list empty")
                    bit_list = find_missing_tiles_mic_ko_yes_all_1(self.tile_list,
                                                self.rule["FCNSize"],
                                                schcmsg.get_fcn_all_1(self.rule))
                    print("new bit list, should it work???")

                for bl_index in range(len(bit_list)):
                    print("missing wn={} bitmap={}".format(bit_list[bl_index][0],
                                                            bit_list[bl_index][1]))
                    # XXX compress bitmap if needed.
                    # ACK failure message
                    schc_ack = schcmsg.frag_receiver_tx_all1_ack(
                            schc_frag.rule,
                            schc_frag.dtag,
                            win=bit_list[bl_index][0],
                            cbit=0,
                            bitmap=bit_list[bl_index][1])
                    if enable_statsct:
                        Statsct.set_msg_type("SCHC_ACK_KO")
                    print("----------------------- SCHC ACK KO SEND  -----------------------")

                    print("ACK failure sent:", schc_ack.__dict__)
                    break
            else:
                #special case when the ALL-1 message is lost: 2 cases:
                #1) the all-1 carries a tile (bit in bitmap)
                #2) the all-1 only carries the MIC (no bit in bitmap)
                if self.fragment_received is False:
                    print("no fragments received yet, abort")
                    self.send_receiver_abort()
                
                    return
                print("all-1 not received, building ACK")
                print('send ack before done {},{},{}'.format(self.tile_list,
                            self.rule["FCNSize"], schcmsg.get_fcn_all_1(self.rule)))
                for tile in self.tile_list:
                    print("w-num: {} t-num: {} nb_tiles:{}".format(
                        tile['w-num'],tile['t-num'],tile['nb_tiles']))
                    print("raw_tiles:{}".format(tile['raw_tiles']))
                
                
                bit_list = find_missing_tiles_no_all_1(self.tile_list,
                                                self.rule["FCNSize"],
                                                schcmsg.get_fcn_all_1(self.rule))
                print('send ack before done {}'.format(bit_list))
                assert bit_list is not None
                if len(bit_list) == 0:
                    bit_list = find_missing_tiles_no_all_1(self.tile_list,
                                                self.rule["FCNSize"],
                                                schcmsg.get_fcn_all_1(self.rule))
                for bl_index in range(len(bit_list)):
                    print("missing wn={} bitmap={}".format(bit_list[bl_index][0],
                                                            bit_list[bl_index][1]))
                    # XXX compress bitmap if needed.
                    # ACK failure message
                    schc_ack = schcmsg.frag_receiver_tx_all1_ack(
                            schc_frag.rule,
                            schc_frag.dtag,
                            win=bit_list[bl_index][0],
                            cbit=0,
                            bitmap=bit_list[bl_index][1])
                    if enable_statsct:
                        Statsct.set_msg_type("SCHC_ACK_KO")
                    print("----------------------- SCHC ACK KO SEND  -----------------------")

                    print("ACK failure sent:", schc_ack.__dict__)
                    break



        args = (schc_ack.packet.get_content(), self.context["devL2Addr"])
        self.protocol.scheduler.add_event(0,
                                            self.protocol.layer2.send_packet,
                                            args)
Ejemplo n.º 25
0
# ---------------------------------------------------------------------------


def make_node(sim, rule_manager, devaddr=None, extra_config={}):
    node = net_sim_core.SimulSCHCNode(sim, extra_config)
    node.protocol.set_rulemanager(rule_manager)
    if devaddr is None:
        devaddr = node.id
    node.layer2.set_devaddr(devaddr)
    return node


# ---------------------------------------------------------------------------
# Statistic module
Statsct.initialize()
Statsct.log("Statsct test")
Statsct.set_packet_size(data_size)
Statsct.set_SF(SF)
# ---------------------------------------------------------------------------
devaddr1 = b"\xaa\xbb\xcc\xdd"
devaddr2 = b"\xaa\xbb\xcc\xee"
dprint("---------Rules Device -----------")
rm0 = RuleManager()
# rm0.add_context(rule_context, compress_rule1, frag_rule3, frag_rule4)
rm0.Add(device=devaddr1, file="../examples/configs/rule1.json")
rm0.Print()

dprint("---------Rules gw -----------")
rm1 = RuleManager()
# rm1.add_context(rule_context, compress_rule1, frag_rule4, frag_rule3)
Ejemplo n.º 26
0
 def _set_protocol(self, protocol):
     self.protocol = protocol
     Statsct.addInfo('protocol', protocol.__dict__)
Ejemplo n.º 27
0
    def resend_ack(self, schc_frag):
        dprint("resend ack method")
        dprint(schc_frag.__dict__)
        if self.mic_received is not None:
            schc_packet, mic_calced = self.get_mic_from_tiles_received()
            dprint("schc_frag.mic: {}, mic_calced: {}".format(
                self.mic_received, mic_calced))
            if self.mic_received == mic_calced:
                self.state = "DONE"
        if self.state == "DONE":
            # ACK message
            schc_ack = frag_msg.frag_receiver_tx_all1_ack(schc_frag.rule,
                                                          schc_frag.dtag,
                                                          schc_frag.win,
                                                          cbit=1)
            dprint("ACK success sent:", schc_ack.__dict__)
            if enable_statsct:
                Statsct.set_msg_type("SCHC_ACK_OK")
            dprint(
                "----------------------- SCHC ACK OK SEND  -----------------------"
            )
        else:
            if self.all1_received:
                dprint("all-1 received, building ACK")
                dprint('send ack before done {},{},{}'.format(
                    self.tile_list, self.rule[T_FRAG][T_FRAG_PROF][T_FRAG_FCN],
                    frag_msg.get_fcn_all_1(self.rule)))
                schc_ack = self.create_ack_schc_ko(schc_frag)
            else:
                #special case when the ALL-1 message is lost: 2 cases:
                #1) the all-1 carries a tile (bit in bitmap)
                #2) the all-1 only carries the MIC (no bit in bitmap)
                if self.fragment_received is False:
                    dprint("no fragments received yet, abort")
                    self.send_receiver_abort()

                    return
                dprint("all-1 not received, building ACK")
                dprint('send ack before done {},{},{}'.format(
                    self.tile_list, self.rule[T_FRAG][T_FRAG_PROF][T_FRAG_FCN],
                    frag_msg.get_fcn_all_1(self.rule)))
                for tile in self.tile_list:
                    dprint("w-num: {} t-num: {} nb_tiles:{}".format(
                        tile['w-num'], tile['t-num'], tile['nb_tiles']))
                    dprint("raw_tiles:{}".format(tile['raw_tiles']))

                bit_list = find_missing_tiles_no_all_1(
                    self.tile_list, self.rule[T_FRAG][T_FRAG_PROF][T_FRAG_FCN],
                    frag_msg.get_fcn_all_1(self.rule))
                dprint('send ack before done {}'.format(bit_list))
                assert bit_list is not None
                if len(bit_list) == 0:
                    bit_list = find_missing_tiles_no_all_1(
                        self.tile_list,
                        self.rule[T_FRAG][T_FRAG_PROF][T_FRAG_FCN],
                        frag_msg.get_fcn_all_1(self.rule))
                for bl_index in range(len(bit_list)):
                    dprint("missing wn={} bitmap={}".format(
                        bit_list[bl_index][0], bit_list[bl_index][1]))
                    # XXX compress bitmap if needed.
                    # ACK failure message
                    schc_ack = frag_msg.frag_receiver_tx_all1_ack(
                        schc_frag.rule,
                        schc_frag.dtag,
                        win=bit_list[bl_index][0],
                        cbit=0,
                        bitmap=bit_list[bl_index][1])
                    if enable_statsct:
                        Statsct.set_msg_type("SCHC_ACK_KO")
                    dprint(
                        "----------------------- SCHC ACK KO SEND  -----------------------"
                    )

                    dprint("ACK failure sent:", schc_ack.__dict__)
        """
        Changement à corriger
        args = (schc_ack.packet.get_content(), self.context["devL2Addr"])
        """
        args = (schc_ack.packet.get_content(), "*")
        self.protocol.scheduler.add_event(0, self.protocol.layer2.send_packet,
                                          args)