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], 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 bit_list: # Some tiles are actually missing, send ACK for first window with missing tiles print("missing wn={} bitmap={}".format(bit_list[0][0], bit_list[0][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[0][0], cbit=0, bitmap=bit_list[0][1]) else: window_list = make_bit_list_mic_ko( self.tile_list, self.rule[T_FRAG][T_FRAG_PROF][T_FRAG_FCN], schcmsg.get_fcn_all_1(self.rule)) last_window = max(window_list.keys()) # No tiles are detected missing, send ACK for last window print("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 = schcmsg.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") print( "----------------------- SCHC ACK KO SEND -----------------------" ) print("ACK failure sent:", schc_ack.__dict__) return schc_ack
def finish(self, schc_packet, schc_frag): self.state = "DONE" print('state DONE -> {}'.format(self.state)) #input('DONE') # decompression self.protocol.process_decompress(schc_packet, self.sender_L2addr, direction="UP") # 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 -----------------------") """ 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
def finish(self, schc_packet, schc_frag): self.state = "DONE" # decompression self.protocol.process_decompress(self.context, self.sender_L2addr, schc_packet) # 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__) args = (schc_ack.packet.get_content(), self.context["devL2Addr"]) self.protocol.scheduler.add_event(0, self.protocol.layer2.send_packet, args)
def receive_frag(self, bbuf, dtag): 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 schc_frag.abort == True: print("Received Sender-Abort.") # XXX needs to release all resources. return if self.state == "DONE": print("XXX need sending ACK back.") return # 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. 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"]) 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.mic_received = schc_frag.mic schc_packet, mic_calced = self.get_mic_from_tiles_received() if schc_frag.mic == mic_calced: self.finish(schc_packet, schc_frag) return else: print("ERROR: MIC mismatched. packet {} != result {}".format( schc_frag.mic, mic_calced)) bit_list = find_missing_tiles(self.tile_list, self.rule["FCNSize"], schcmsg.get_fcn_all_1(self.rule)) assert bit_list is not None 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]) 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. # set inactive timer. self.event_id_inactive_timer = self.protocol.scheduler.add_event( self.inactive_timer, self.event_inactive, tuple()) print("---", schc_frag.fcn)
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[T_FRAG][T_FRAG_PROF][T_FRAG_FCN], schcmsg.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: 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[T_FRAG][T_FRAG_PROF][T_FRAG_FCN], 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[T_FRAG][T_FRAG_PROF][T_FRAG_FCN], 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[T_FRAG][T_FRAG_PROF][T_FRAG_FCN], 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__) """ 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)
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)
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)