Exemple #1
0
 def set_packet(self, packet_bbuf):
     super().set_packet(packet_bbuf)
     self.all_tiles = TileList(self.rule, packet_bbuf)
     # XXX
     # check whether the size of the last tile is less than L2 word
     # AND the tile number is zero
     # because draft-17 doesn't specify how to handle it.
     a = self.all_tiles.get_all_tiles()
     if (a[-1]["t-num"] == 0 and
             a[-1]["tile"].count_added_bits() < self.rule["L2WordSize"]):
         raise ValueError(
             "The size of the last tile with the tile number 0 must be equal to or greater than L2 word size."
         )
     # make the bitmap
     #self.bit_list = make_bit_list(self.all_tiles.get_all_tiles(),
     #                              self.rule["FCNSize"],
     #                              schcmsg.get_fcn_all_1(self.rule))
     self.bit_list = make_bit_list(self.all_tiles.get_all_tiles(),
                                   self.rule["FCNSize"], self.rule["WSize"])
     print("bit_list:", self.bit_list)
     for tile in self.all_tiles.get_all_tiles():
         print("w: {}, t: {}, sent: {}".format(tile['w-num'], tile['t-num'],
                                               tile['sent']))
     self.all1_send = False
     self.num_of_windows = 0
     for pos in self.bit_list:
         print("bitmap: {}, length:{}".format(self.bit_list[pos],
                                              len(self.bit_list[pos])))
         if len(self.bit_list[pos]) is not 0:
             self.num_of_windows += 1
     print("number of windows = {}".format(self.num_of_windows))
Exemple #2
0
 def set_packet(self, packet_bbuf):
     super().set_packet(packet_bbuf)
     self.all_tiles = TileList(self.rule, packet_bbuf)
     #print('all tils : ')
     #print(self.all_tiles.get_all_tiles())
     # XXX
     # check whether the size of the last tile is less than L2 word
     # AND the tile number is zero
     # because draft-17 doesn't specify how to handle it.
     #print('set_packet RULE: ',self.rule)
     profile = self.rule["profile"]
     L2WordSize = profile["L2WordSize"]
     print('L2WordSize: ', L2WordSize)
     a = self.all_tiles.get_all_tiles()
     #print('all tiles: ', a)
     if (a[-1]["t-num"] == 0
             and a[-1]["tile"].count_added_bits() < L2WordSize):
         raise ValueError(
             "The size of the last tile with the tile number 0 must be equal to or greater than L2 word size."
         )
     # make the bitmap
     frag = self.rule["fragmentation"]
     Mode = frag["FRModeProfile"]
     FCNSize = Mode["FCNSize"]
     self.bit_list = make_bit_list(self.all_tiles.get_all_tiles(), FCNSize,
                                   schcmsg.get_fcn_all_1(self.rule))
Exemple #3
0
 def set_packet(self, packet_bbuf):
     super().set_packet(packet_bbuf)
     self.all_tiles = TileList(self.rule, packet_bbuf)
     # XXX
     # check whether the size of the last tile is less than L2 word
     # AND the tile number is zero
     # because draft-17 doesn't specify how to handle it.
     a = self.all_tiles.get_all_tiles()
     if (a[-1]["t-num"] == 0 and
             a[-1]["tile"].count_added_bits() < self.rule["L2WordSize"]):
         raise ValueError(
             "The size of the last tile with the tile number 0 must be equal to or greater than L2 word size."
         )
     # make the bitmap
     self.bit_list = make_bit_list(self.all_tiles.get_all_tiles(),
                                   self.rule["FCNSize"],
                                   schcmsg.get_fcn_all_1(self.rule))
     print("bit_list:", self.bit_list)
Exemple #4
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)
Exemple #5
0
class FragmentAckOnError(FragmentBase):
    def set_packet(self, packet_bbuf):
        super().set_packet(packet_bbuf)
        self.all_tiles = TileList(self.rule, packet_bbuf)
        # XXX
        # check whether the size of the last tile is less than L2 word
        # AND the tile number is zero
        # because draft-17 doesn't specify how to handle it.
        a = self.all_tiles.get_all_tiles()
        if (a[-1]["t-num"] == 0 and
                a[-1]["tile"].count_added_bits() < self.rule["L2WordSize"]):
            raise ValueError(
                "The size of the last tile with the tile number 0 must be equal to or greater than L2 word size."
            )
        # make the bitmap
        #self.bit_list = make_bit_list(self.all_tiles.get_all_tiles(),
        #                              self.rule["FCNSize"],
        #                              schcmsg.get_fcn_all_1(self.rule))
        self.bit_list = make_bit_list(self.all_tiles.get_all_tiles(),
                                      self.rule["FCNSize"], self.rule["WSize"])
        print("bit_list:", self.bit_list)
        for tile in self.all_tiles.get_all_tiles():
            print("w: {}, t: {}, sent: {}".format(tile['w-num'], tile['t-num'],
                                                  tile['sent']))
        self.all1_send = False
        self.num_of_windows = 0
        for pos in self.bit_list:
            print("bitmap: {}, length:{}".format(self.bit_list[pos],
                                                 len(self.bit_list[pos])))
            if len(self.bit_list[pos]) is not 0:
                self.num_of_windows += 1
        print("number of windows = {}".format(self.num_of_windows))
        #input("")
    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)

    def cancel_ack_wait_timer(self):
        # don't assert here because the receiver sends ACK back anytime.
        #assert self.event_id_ack_wait_timer is not None
        print(
            '----------------------- cancel_ack_wait_timer -----------------------'
        )
        self.protocol.scheduler.cancel_event(self.event_id_ack_wait_timer)
        self.event_id_ack_wait_timer = None

    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 """
        """
        self.number_of_ack_waits += 1
        print("number_of_ack_waits -> {}".format(self.number_of_ack_waits))
        if self.number_of_ack_waits > self.num_of_windows:
            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__)
            # if enable_statsct:
            #     Statsct.set_msg_type("SCHC_FRAG")
            #     Statsct.set_header_size(schcmsg.get_sender_header_size(self.rule))
            self.protocol.scheduler.add_event(0, self.protocol.layer2.send_packet,
                                            args)
            self.number_of_ack_waits = 0
            
        else:
            print("Do no send ACK REQ, waiting for more ACKS")        #the idea is that if the ack did not arrive, to send a SCHC ACK REQ
        """

    def event_sent_frag(self, status):  # status == nb actually sent (for now)
        print("EVENT SEND FRAG")
        self.send_frag()

    def receive_frag(self, bbuf, dtag):
        # the ack timer can be cancelled here, because it's been done whether
        # both rule_id and dtag in the fragment are matched to this session
        # at process_received_packet().
        self.cancel_ack_wait_timer(
        )  # the timeout is canceled but has to be set
        # when an ack should be received
        self.resend = False
        #
        schc_frag = schcmsg.frag_sender_rx(self.rule, bbuf)
        print(
            "-----------------------  sender frag received -----------------------"
        )
        print("fragment received -> {}".format(schc_frag.__dict__))
        if ((self.rule["WSize"] is None
             or schc_frag.win == schcmsg.get_win_all_1(self.rule))
                and schc_frag.cbit == 1
                and schc_frag.remaining.allones() == True):
            print(
                "-----------------------  Receiver Abort rid={} dtag={} -----------------------"
                .format(self.rule.ruleID, self.dtag))
            #self.resend = False
            self.state = self.RECEIVER_ABORT

            return
        if schc_frag.cbit == 1:
            print(
                "----------------------- ACK Success rid={} dtag={} -----------------------"
                .format(self.rule.ruleID, self.dtag))
            #self.resend = False
            self.state = self.ACK_SUCCESS
            return
        if schc_frag.cbit == 0:
            print(
                "----------------------- ACK Failure rid={} dtag={} -----------------------"
                .format(self.rule.ruleID, self.dtag))
            #self.resend = False
            #self.all1_send = False
            self.state = self.ACK_FAILURE
            self.resend_frag(schc_frag)
            return

    def resend_frag(self, schc_frag):
        self.resend = True
        print("recv bitmap:", (schc_frag.win, schc_frag.bitmap.to_bit_list()))
        print("sent bitmap:", (schc_frag.win, self.bit_list[schc_frag.win]))
        self.all_tiles.unset_sent_flag(schc_frag.win,
                                       schc_frag.bitmap.to_bit_list())
        self.send_frag()
Exemple #6
0
 def send_frag(self):
     # 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: ', window_tiles)
     #print('**********nb_remaining_tiles: ', nb_remaining_tiles)
     #print('**********remaining_size: ', remaining_size)
     if window_tiles is not None:
         # even when mic is sent, it comes here in the retransmission.
         if (nb_remaining_tiles == 0 and len(window_tiles) == 1
                 and remaining_size >= schcmsg.get_mic_size(self.rule)):
             #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))
             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:
             # regular fragment.
             fcn = window_tiles[0]["t-num"]
             mic = None
         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:
             # set ack waiting timer
             args = (
                 schc_frag,
                 window_tiles[0]["w-num"],
             )
             self.event_id_ack_wait_timer = self.protocol.scheduler.add_event(
                 self.ack_wait_timer, self.ack_timeout, args)
         # save the last window tiles.
         self.last_window_tiles = window_tiles
     elif self.mic_sent is not None:
         # it looks that all fragments have been sent.
         print("xxx looks all tiles have been sent.", window_tiles,
               nb_remaining_tiles, remaining_size)
         schc_frag = None
         return
     else:
         # 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,
         )
         self.event_id_ack_wait_timer = self.protocol.scheduler.add_event(
             self.ack_wait_timer, self.ack_timeout, args)
     # send a SCHC fragment
     args = (schc_frag.packet.get_content(), self.protocol.layer2.mac_id,
             None, self.event_sent_frag, True)
     print("frag sent:", schc_frag.__dict__)
     self.protocol.scheduler.add_event(0, self.protocol.layer2.send_packet,
                                       args)
Exemple #7
0
class FragmentAckOnError(FragmentBase):
    def set_packet(self, packet_bbuf):
        super().set_packet(packet_bbuf)
        self.all_tiles = TileList(self.rule, packet_bbuf)
        #print('all tils : ')
        #print(self.all_tiles.get_all_tiles())
        # XXX
        # check whether the size of the last tile is less than L2 word
        # AND the tile number is zero
        # because draft-17 doesn't specify how to handle it.
        #print('set_packet RULE: ',self.rule)
        profile = self.rule["profile"]
        L2WordSize = profile["L2WordSize"]
        print('L2WordSize: ', L2WordSize)
        a = self.all_tiles.get_all_tiles()
        #print('all tiles: ', a)
        if (a[-1]["t-num"] == 0
                and a[-1]["tile"].count_added_bits() < L2WordSize):
            raise ValueError(
                "The size of the last tile with the tile number 0 must be equal to or greater than L2 word size."
            )
        # make the bitmap
        frag = self.rule["fragmentation"]
        Mode = frag["FRModeProfile"]
        FCNSize = Mode["FCNSize"]
        self.bit_list = make_bit_list(self.all_tiles.get_all_tiles(), FCNSize,
                                      schcmsg.get_fcn_all_1(self.rule))
        #print("bit_list:", self.bit_list)

    def send_frag(self):
        # 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: ', window_tiles)
        #print('**********nb_remaining_tiles: ', nb_remaining_tiles)
        #print('**********remaining_size: ', remaining_size)
        if window_tiles is not None:
            # even when mic is sent, it comes here in the retransmission.
            if (nb_remaining_tiles == 0 and len(window_tiles) == 1
                    and remaining_size >= schcmsg.get_mic_size(self.rule)):
                #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))
                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:
                # regular fragment.
                fcn = window_tiles[0]["t-num"]
                mic = None
            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:
                # set ack waiting timer
                args = (
                    schc_frag,
                    window_tiles[0]["w-num"],
                )
                self.event_id_ack_wait_timer = self.protocol.scheduler.add_event(
                    self.ack_wait_timer, self.ack_timeout, args)
            # save the last window tiles.
            self.last_window_tiles = window_tiles
        elif self.mic_sent is not None:
            # it looks that all fragments have been sent.
            print("xxx looks all tiles have been sent.", window_tiles,
                  nb_remaining_tiles, remaining_size)
            schc_frag = None
            return
        else:
            # 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,
            )
            self.event_id_ack_wait_timer = self.protocol.scheduler.add_event(
                self.ack_wait_timer, self.ack_timeout, args)
        # send a SCHC fragment
        args = (schc_frag.packet.get_content(), self.protocol.layer2.mac_id,
                None, self.event_sent_frag, True)
        print("frag sent:", schc_frag.__dict__)
        self.protocol.scheduler.add_event(0, self.protocol.layer2.send_packet,
                                          args)

    def cancel_ack_wait_timer(self):
        # don't assert here because the receiver sends ACK back anytime.
        #assert self.event_id_ack_wait_timer is not None
        self.protocol.scheduler.cancel_event(self.event_id_ack_wait_timer)
        self.event_id_ack_wait_timer = None

    def ack_timeout(self, *args):
        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
        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.protocol.layer2.mac_id, None, None, False)
            print("Sent Sender-Abort.", schc_frag.__dict__)
            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)
        # retransmit MIC.
        args = (schc_frag.packet.get_content(), self.protocol.layer2.mac_id,
                None, self.event_sent_frag, True)
        print("Retransmitted frag:", schc_frag.__dict__)
        self.protocol.scheduler.add_event(0, self.protocol.layer2.send_packet,
                                          args)

    def event_sent_frag(self, status):  # status == nb actually sent (for now)
        self.send_frag()

    def receive_frag(self, bbuf, dtag):
        # the ack timer can be cancelled here, because it's been done whether
        # both rule_id and dtag in the fragment are matched to this session
        # at process_received_packet().
        self.cancel_ack_wait_timer()
        #
        schc_frag = schcmsg.frag_sender_rx(self.rule, bbuf)
        print("sender frag received:", schc_frag.__dict__)
        if ((self.rule["WSize"] is None
             or schc_frag.win == schcmsg.get_win_all_1(self.rule))
                and schc_frag.cbit == 1
                and schc_frag.remaining.allones() == True):
            print("Receiver Abort rid={} dtag={}".format(
                self.rule.ruleID, self.dtag))
            return
        if schc_frag.cbit == 1:
            print("ACK Success rid={} dtag={}".format(self.rule.ruleID,
                                                      self.dtag))
            return
        if schc_frag.cbit == 0:
            print("ACK Failure rid={} dtag={}".format(self.rule.ruleID,
                                                      self.dtag))
            self.resend_frag(schc_frag)
            return

    def resend_frag(self, schc_frag):
        print("recv bitmap:", (schc_frag.win, schc_frag.bitmap.to_bit_list()))
        print("sent bitmap:", (schc_frag.win, self.bit_list[schc_frag.win]))
        self.all_tiles.unset_sent_flag(schc_frag.win,
                                       schc_frag.bitmap.to_bit_list())
        self.send_frag()