def receive_msg(self): while True: # receive from lower layer [message_id, message_data ] = yield self.sim_env.process(self.transp_lay.receive_msg()) # receiver information print("\n\nRECEIVER\nTime: " + str(self.sim_env.now) + "--Communication Layer: \nI am ECU " + self._ecu_id + "\nReceived message:\n - ID: " + str(message_id)) # Assume it takes 0.5 seconds to e.g. decrypt this message uid = uuid.uuid4() # BEFORE PROCESSING print("\nECU " + str(self._ecu_id) + "Time before message received: " + str(self.sim_env.now)) G().mon( self.monitor_list, MonitorInput([], "AUTH_RECEIVE_TIME_BEFORE_DECRYPTION", self._ecu_id, self.sim_env.now, 123, message_id, message_data.get(), message_data.padded_size, 432, uid)) ''' Perform asymmetric decryption of the incoming message using its public key, e.g. lasting 0.5 seconds''' # get the public key of the sender senders_public_key = PublicKeyManager().get_key( message_data.sender_id) # use this key for decryption - also checks if this key is still valid received_cipher_message = message_data.get() clear_message = encryption_tools.asy_decrypt( received_cipher_message, senders_public_key, self.sim_env.now) [received_timestamp, received_hashed_message, received_message] = clear_message yield self.sim_env.timeout(0.5) ''' Perform symmetric decryption, e.g. takes 0.02 seconds''' [received_symmetric_key, received_symmetrically_encrypted_message] = received_message received_clear_message = encryption_tools.sym_decrypt( received_symmetrically_encrypted_message, received_symmetric_key) yield self.sim_env.timeout(0.02) ''' Verify received hash of the message, e.g. takes 0.01 second ''' hashed_message = HashedMessage(str(received_message), HashMechEnum.MD5) is_same_hash = hashed_message.same_hash(received_hashed_message) yield self.sim_env.timeout(0.01) # AFTER PROCESSING print("\nECU " + str(self._ecu_id) + "Time after message received: " + str(self.sim_env.now)) G().mon( self.monitor_list, MonitorInput([], "AUTH_RECEIVE_TIME_AFTER_DECRYPTION", self._ecu_id, self.sim_env.now, 123, message_id, message_data.get(), message_data.padded_size, 432, uid)) # push to higher layer return [message_id, received_clear_message]
def monitor_update(self): ''' updates the monitor connected to this ecu Input: - Output: monitor_list RefList list of MonitorInputs ''' # register Monitoring tags to track #G().register_eventline_tags(self._tags) items_1 = len( self.transp_lay.datalink_lay.controller.receive_buffer.items) items_2 = self.transp_lay.datalink_lay.transmit_buffer_size G().mon( self.monitor_list, MonitorInput(items_1, MonitorTags.BT_ECU_RECEIVE_BUFFER, self._ecu_id, self.sim_env.now)) G().mon( self.monitor_list, MonitorInput(items_2, MonitorTags.BT_ECU_TRANSMIT_BUFFER, self._ecu_id, self.sim_env.now)) self.monitor_list.clear_on_access( ) # on the next access the list will be cleared return self.monitor_list.get()
def receive_msg(self): while True: # receive from lower layer [message_id, message_data] = yield self.sim_env.process(self.transp_lay.receive_msg()) # receiver information print("\n\nRECEIVER\nTime: "+str(self.sim_env.now)+"--Communication Layer: \nI am ECU " + self._ecu_id + "\nReceived message:\n - ID: " + str(message_id)) # Assume it takes 0.5 seconds to e.g. decrypt this message uid = uuid.uuid4() # BEFORE PROCESSING print("\nECU "+ str(self._ecu_id) +"Time before message received: "+ str(self.sim_env.now)) G().mon(self.monitor_list, MonitorInput([], "AUTH_RECEIVE_TIME_BEFORE_DECRYPTION", self._ecu_id, self.sim_env.now, 123, message_id, message_data.get(), message_data.padded_size, 432, uid)) ''' receive and verify certificate ''' [received_message, received_certificate] = message_data.get() # verify certificate - which works here as they all have the same CA authority that signed the certificate certificate_valid = encryption_tools.certificate_trustworthy(received_certificate, self.my_root_certificates, self.sim_env.now) # AFTER PROCESSING print("\nECU "+ str(self._ecu_id) +"Time after message received: "+ str(self.sim_env.now)) G().mon(self.monitor_list, MonitorInput([], "AUTH_RECEIVE_TIME_AFTER_DECRYPTION", self._ecu_id, self.sim_env.now, 123, message_id, message_data.get(), message_data.padded_size, 432, uid)) # push to higher layer return [message_id, message_data]
def c_t_tls_hand_dec_client_keyex_msg(self, pub_dec_alg, pub_dec_keylen, size_to_dec, pub_dec_alg_option): ''' time to decrypt the inner registration message -> So this is a private decryption with the sec module private key (after this was public encrypted) ''' try: # extract infos L().log(701, pub_dec_alg, pub_dec_keylen, size_to_dec) algorithm = EnumTrafor().to_value(pub_dec_alg) al_mode = EnumTrafor().to_value(pub_dec_alg_option) key_len = EnumTrafor().to_value(pub_dec_keylen) # DB Lookup if pub_dec_alg == AsymAuthMechEnum.ECC: db_val = TimingDBMap().lookup_interpol(lib=self.library_tags['t_tls_hand_dec_client_keyex_msg'], mode='DECRYPTION', \ param_len=key_len, alg=algorithm, data_size=size_to_dec, description='t_tls_hand_dec_client_keyex_msg') else: db_val = TimingDBMap().lookup_interpol(exp=al_mode, lib=self.library_tags['t_tls_hand_dec_client_keyex_msg'], mode='DECRYPTION', \ keylen=key_len, alg=algorithm, data_size=size_to_dec, description='t_tls_hand_dec_client_keyex_msg') # return result if db_val: return G().val_log_info(db_val, 602, db_val) else: logging.warn("Error: Could not find in DB the Value in 't_tls_hand_dec_client_keyex_msg' use 0.0...01\nUsed input: %s" % str([self.library_tags['t_tls_hand_dec_client_keyex_msg'], pub_dec_alg, pub_dec_keylen, size_to_dec, pub_dec_alg_option])) L().log(603, 't_tls_hand_dec_client_keyex_msg') return 0.01 # self.settings['t_tls_hand_dec_client_keyex_msg'] = 'ecuSW.app_lay.ecu_auth.SSMA_DECR_INNER_REG_MSG' except: logging.warn("Error: Could not find in DB the Value in 't_tls_hand_dec_client_keyex_msg' use 0.0...01\nUsed input: %s" % str([self.library_tags['t_tls_hand_dec_client_keyex_msg'], pub_dec_alg, pub_dec_keylen, size_to_dec, pub_dec_alg_option])) return 0.000000001
def c_t_tls_hand_enc_cert_verify_msg(self, enc_alg, enc_key_len, msg_size, alg_option): # Public encrypt try: # extract information L().log(604, enc_alg, enc_key_len, msg_size) algorithm = EnumTrafor().to_value(enc_alg) key_len = EnumTrafor().to_value(enc_key_len) # read Database if enc_alg == AsymAuthMechEnum.ECC: db_val = TimingDBMap().lookup_interpol(lib=self.library_tags['t_tls_hand_enc_cert_verify_msg'], mode='ENCRYPTION', param_len=key_len, alg=algorithm, \ data_size=msg_size, description='t_tls_hand_enc_cert_verify_msg') else: # RSA: have to slice the message and encrypt each of those if msg_size > ((float(key_len) / 8) - 11): size_to_enc_in = ceil((float(key_len) / 8) - 11) else: size_to_enc_in = msg_size db_val = TimingDBMap().lookup_interpol(lib=self.library_tags['t_tls_hand_enc_cert_verify_msg'], exp=alg_option, mode='ENCRYPTION', keylen=key_len, \ alg=algorithm, data_size=size_to_enc_in, description='t_tls_hand_enc_cert_verify_msg') # RSA: have to slice the message and encrypt each of those nr_chuncks = math.ceil(msg_size / ((float(key_len) / 8) - 11)) db_val = db_val * nr_chuncks # return result if db_val: return G().val_log_info(db_val, 602, db_val) else: L().log(603, 't_tls_hand_enc_cert_verify_msg') return 0.001 except: logging.error("Error: Could not calculate the Value in 't_tls_hand_enc_cert_verify_msg'") return 0.000000001
def _get_next_available(self): ''' returns the next element that was received as a whole Input: - Output: val object the message that was received ''' try: val = self._get_next_received() self.rec_msgs_expected_size.pop(self.buffer_receiver[str(val)], None) self.rec_msg.pop(self.buffer_receiver[str(val)], None) except: pass try: self.rec_msgs_expected_size.pop(self.buffer_receiver[str(val)], None) self.rec_len.pop(self.buffer_receiver[str(val)], None) del self.rec_len[self.buffer_receiver[str(val)]] except: pass try: # remove the element del self.buffer_receiver[str(val)] except: pass return G().val_log_info(val, 802, val)
def c_t_prf_for_key_legitimation(self, mac_alg, mac_keylen): ''' key generation with AES is a Random Function so same as a PRF''' try: # extract information algorithm = EnumTrafor().to_value(SymAuthMechEnum.AES) key_len = EnumTrafor().to_value(AuKeyLengthEnum.bit_192) # read Database db_val = TimingDBMap().lookup_interpol( lib=self.library_tags['t_prf_for_key_legitimation'], mode='KEYGEN', keylen=key_len, alg=algorithm) # return result if db_val: return G().val_log_info(db_val, 602, db_val) else: L().log(603, 't_prf_for_key_legitimation') return 0.001 except: logging.error( "Error: Could not calculate the Value in 't_prf_for_key_legitimation'" ) return 0.000000001
def c_t_reg_msg_hash(self, size_to_hash, hash_mech): try: # extract infos L().log(605, hash_mech, size_to_hash) algorithm = EnumTrafor().to_value(hash_mech) # DB Lookup db_val = TimingDBMap().lookup_interpol( lib=self.library_tags['t_reg_msg_hash'], mode='HASH', alg=algorithm, data_size=size_to_hash, description='t_reg_msg_hash') # return value if db_val: return G().val_log_info(db_val, 602, db_val) else: logging.warn( "Error: Could not find in DB the Value in 't_reg_msg_hash' use 0.0...01\nUsed input: %s" % str([ self.library_tags['t_reg_msg_hash'], size_to_hash, hash_mech ])) L().log(603, 't_reg_msg_hash') return 0.01 # self.settings['t_reg_msg_hash'] = 'ecuSW.comm_mod.authenticator.SCCM_ECU_HASH_REG_MSG' except: logging.warn( "Error: Could not find in DB the Value in 't_reg_msg_hash' use 0.0...01\nUsed input: %s" % str([ self.library_tags['t_reg_msg_hash'], size_to_hash, hash_mech ])) return 0.000000001
def c_t_generate_mac(self, input_size, mac_alg, mac_keylen): ''' generation of the comparison hash is a AES CMAC operation''' try: # extract infos L().log(605, mac_alg, input_size) algorithm = EnumTrafor().to_value(mac_alg) key_len = EnumTrafor().to_value(mac_keylen) alg_mode = "CMAC" # DB Lookup db_val = TimingDBMap().lookup_interpol( lib=self.library_tags['t_generate_compare_mac'], keylen=key_len, mode='ENCRYPTION', alg=algorithm, alg_mode=alg_mode, data_size=input_size) # return value if db_val: return G().val_log_info(db_val, 602, db_val) else: L().log(603, 't_generate_mac') return 0.01 # self.settings['t_reg_msg_hash'] = 'ecuSW.comm_mod.authenticator.SCCM_ECU_HASH_REG_MSG' except: logging.error( "Error: Could not calculate the Value in 't_generate_mac'") return 0.000000001 return 0
def make(self, class_id, constructor_in): ''' given the constructor parameters for the class with class_id the class with the specified id will be created and returned Input: class_id string Identifier of the class to be generated constructor_in list list of constructor parameters for this specific class Output: instance object instance of the specified class ''' try: # extract class GeneratedClass = self.create_dict[class_id] # @UnusedVariable # create constructor input in_str = "" for i in range(len(constructor_in)): in_str += "constructor_in[" + str(i) + "], " in_str = in_str[:-2] # return instance return eval('GeneratedClass(' + in_str + ')') except: L().log_traceback() return G().val_log_info(None, 201, class_id)
def c_t_ecu_auth_conf_msg_enc(self, size_to_enc, sym_enc_alg, sym_enc_keylen, sym_enc_alg_mode): ''' time to encrypt the conf. msg with the ecu key''' try: # extract infos L().log(703, sym_enc_alg, sym_enc_keylen, size_to_enc) algorithm = EnumTrafor().to_value(sym_enc_alg) algo_mode = EnumTrafor().to_value(sym_enc_alg_mode) key_len = EnumTrafor().to_value(sym_enc_keylen) # DB Lookup db_val = TimingDBMap().lookup_interpol(alg_mode=algo_mode, lib=self.library_tags['t_ecu_auth_conf_msg_enc'], mode='ENCRYPTION', \ keylen=key_len, alg=algorithm, data_size=size_to_enc, description='t_ecu_auth_conf_msg_enc') # return result if db_val: return G().val_log_info(db_val, 602, db_val) else: logging.warn( "Error: Could not find in DB the Value in 't_ecu_auth_conf_msg_enc' use 0.0...01\nUsed input: %s" % str([ self.library_tags['t_ecu_auth_conf_msg_enc'], size_to_enc, sym_enc_alg, sym_enc_keylen, sym_enc_alg_mode ])) L().log(603, 't_ecu_auth_conf_msg_enc') return 0.01 # self.settings['t_ecu_auth_reg_msg_outter_dec'] = 'ecuSW.app_lay.ecu_auth.SSMA_DECR_OUTTER_REG_MSG' except: logging.warn( "Error: Could not find in DB the Value in 't_ecu_auth_conf_msg_enc' use 0.0...01\nUsed input: %s" % str([ self.library_tags['t_ecu_auth_conf_msg_enc'], size_to_enc, sym_enc_alg, sym_enc_keylen, sym_enc_alg_mode ])) return 0.000000001
def put_msg(self, message): ''' puts the message into the buffer in a sorted way. Messages that arrived earlier and messaged that have a higher priority are further up front in the queue Input: message object message that should be send over the bus Output: - ''' # transmit buffer full size_after_add, size_before_add = self._extract_sizes(message) if size_after_add > size_before_add: return G().val_log_info(None, 801) # dummy if False: yield self.sim_env.timeout(0) # pritoriy is lower if 0 is sent: if isinstance(message.data.get(), str) and message.data.get().isdigit(): preval = 0.001 else: preval = 0 self._controller.transmit_buffer.put( QueueElement(message.message_identifier + preval, message)) # add message to buffer self.physical_lay.transceiver.connected_bus.add_willing(self) if len(self._controller.transmit_buffer.queue) == 1: self.physical_lay.transceiver.connected_bus.notify_bus()
def c_t_str_auth_enc_grant_msg(self, sym_enc_alg, sym_enc_keylen, size_to_enc, sym_enc_alg_mode): ''' time to encrypt the grant message''' try: # extract infos L().log(706, sym_enc_alg, sym_enc_keylen, size_to_enc) algorithm = EnumTrafor().to_value(sym_enc_alg) algo_mode = EnumTrafor().to_value(sym_enc_alg_mode) key_len = EnumTrafor().to_value(sym_enc_keylen) # DB Lookup db_val = TimingDBMap().lookup_interpol(alg_mode=algo_mode, lib=self.library_tags['t_str_auth_enc_grant_msg'], mode='ENCRYPTION', \ keylen=key_len, alg=algorithm, data_size=size_to_enc, description='t_str_auth_enc_grant_msg') # return values if db_val: return G().val_log_info(db_val, 602, db_val) else: logging.warn( "Error: Could not find in DB the Value in 't_str_auth_enc_grant_msg' use 0.0...01\nUsed input: %s" % str([ self.library_tags['t_str_auth_enc_grant_msg'], sym_enc_alg, sym_enc_keylen, size_to_enc, sym_enc_alg_mode ])) L().log(603, 't_str_auth_enc_grant_msg') return 0.01 # self.settings['t_str_auth_enc_grant_msg'] = 'ecuSW.app_lay.stream_auth.SSMA_STREAM_ENC_GRANT_MSG' except: logging.warn( "Error: Could not find in DB the Value in 't_str_auth_enc_grant_msg' use 0.0...01\nUsed input: %s" % str([ self.library_tags['t_str_auth_enc_grant_msg'], sym_enc_alg, sym_enc_keylen, size_to_enc, sym_enc_alg_mode ])) return 0.000000001
def _monitor_transmission_start(self): ''' notes the start time when this message was put on the bus Input: - Output: - ''' # extract information uid = uuid.uuid4() tag = MonitorTags.CB_PROCESSING_MESSAGE c_id = self.comp_id sender_id = self.current_message.sender_id msg_id = self.current_message.message_identifier msg_uid = self.current_message.data.unique_id data = self.current_message.data.get() # extract further information msg = self.current_message size = self.current_message_length_bit / 8 self.current_message.data.unique_id = msg_uid # send to monitor G().mon( self.monitor_list, MonitorInput(data, tag, c_id, self.sim_env.now, sender_id, msg_id, msg, size, msg_id, uid.hex)) return data, c_id, sender_id, msg_id, msg, size, uid
def c_t_key_exchange_decryption(self, msg_size, dec_alg, dec_key_len, alg_option): ''' Private decryption or alternatively symmetric encryption with master key''' try: # extract information L().log(604, dec_alg, dec_key_len, msg_size) algorithm = EnumTrafor().to_value(dec_alg) key_len = EnumTrafor().to_value(dec_key_len) alg_mode = EnumTrafor().to_value(alg_option) # Symmertic Encryption if isinstance(dec_alg, SymAuthMechEnum): db_val = TimingDBMap().lookup_interpol( lib=self.library_tags['t_key_exchange_encryption'], mode='DECRYPTION', keylen=key_len, alg=algorithm, alg_mode=alg_mode, data_size=msg_size) else: # read Database if dec_alg == AsymAuthMechEnum.ECC: db_val = TimingDBMap().lookup_interpol( lib=self.library_tags['t_key_exchange_decryption'], mode='DECRYPTION', param_len=key_len, alg=algorithm, data_size=msg_size) else: # RSA: have to slice the message and encrypt each of those if msg_size > ((float(key_len) / 8) - 11): size_to_enc_in = ceil((float(key_len) / 8) - 11) else: size_to_enc_in = msg_size db_val = TimingDBMap().lookup_interpol( lib=self.library_tags['t_key_exchange_decryption'], exp=alg_option, mode='DECRYPTION', keylen=key_len, alg=algorithm, data_size=size_to_enc_in) # RSA: have to slice the message and encrypt each of those nr_chuncks = math.ceil(msg_size / ((float(key_len) / 8) - 11)) db_val = db_val * nr_chuncks # return result if db_val: return G().val_log_info(db_val, 602, db_val) else: L().log(603, 't_key_exchange_decryption') return 0.001 except: logging.error( "Error: Could not calculate the Value in 't_key_exchange_decryption'" ) return 0.000000001
def _monitor_transmission_end(self, mon_out): ''' notes the end time when this message was put on the bus Input: - Output: - ''' G().mon(self.monitor_list, MonitorInput(mon_out[0], MonitorTags.CB_DONE_PROCESSING_MESSAGE, \ mon_out[1], self.sim_env.now, mon_out[2], mon_out[3], \ mon_out[4], mon_out[5], -1, mon_out[6].hex))
def c_t_ecu_auth_reg_msg_outter_dec(self, pub_dec_alg, pub_dec_keylen, size_to_dec, pub_dec_alg_option): ''' time to decrypt the outter registration message -> Verify == Public Decrypt! ''' try: # extract infos L().log(702, pub_dec_alg, pub_dec_keylen, size_to_dec) algorithm = EnumTrafor().to_value(pub_dec_alg) alg_opt = EnumTrafor().to_value(pub_dec_alg_option) key_len = EnumTrafor().to_value(pub_dec_keylen) # DB Lookup if pub_dec_alg == AsymAuthMechEnum.ECC: db_val = TimingDBMap().lookup_interpol(lib=self.library_tags['t_ecu_auth_reg_msg_outter_dec'], mode='VERIFY', param_len=key_len, \ alg=algorithm, data_size=size_to_dec, description='t_ecu_auth_reg_msg_outter_dec') if pub_dec_alg == AsymAuthMechEnum.RSA and self.library_tags[ 't_ecu_auth_reg_msg_outter_dec'] == "CyaSSL": if size_to_dec > ((float(key_len) / 8) - 11): size_to_dec_in = ceil((float(key_len) / 8) - 11) else: size_to_dec_in = size_to_dec db_val = TimingDBMap().lookup_interpol(lib=self.library_tags['t_ecu_auth_reg_msg_outter_dec'], exp=alg_opt, mode='ENCRYPTION', \ keylen=key_len, alg=algorithm, data_size=size_to_dec_in, description='t_ecu_auth_reg_msg_outter_dec') # in case of RSA have to slice the message and encrypt each of those nr_chuncks = math.ceil(size_to_dec / ((float(key_len) / 8) - 11)) db_val = db_val * nr_chuncks if pub_dec_alg == AsymAuthMechEnum.RSA and self.library_tags[ 't_ecu_auth_reg_msg_outter_dec'] in [ "Crypto_Lib_SW", "Crypto_Lib_HW" ]: db_val = TimingDBMap().lookup_interpol(lib=self.library_tags['t_ecu_auth_reg_msg_outter_dec'], exp=alg_opt, mode='VERIFY', \ keylen=key_len, alg=algorithm, data_size=size_to_dec, description='t_ecu_auth_reg_msg_outter_dec') # return result if db_val: return G().val_log_info(db_val, 602, db_val) else: logging.warn( "Error: Could not find in DB the Value in 't_ecu_auth_reg_msg_outter_dec' use 0.0...01\nUsed input: %s" % str([ self.library_tags['t_ecu_auth_reg_msg_outter_dec'], pub_dec_alg, pub_dec_keylen, size_to_dec, pub_dec_alg_option ])) L().log(603, 't_ecu_auth_reg_msg_outter_dec') return 0.01 # self.settings['t_ecu_auth_reg_msg_outter_dec'] = 'ecuSW.app_lay.ecu_auth.SSMA_DECR_OUTTER_REG_MSG' except: logging.warn( "Error: Could not find in DB the Value in 't_ecu_auth_reg_msg_outter_dec' use 0.0...01\nUsed input: %s" % str([ self.library_tags['t_ecu_auth_reg_msg_outter_dec'], pub_dec_alg, pub_dec_keylen, size_to_dec, pub_dec_alg_option ])) return 0.000000001
def avg_byte_time_with_stream(self): ''' returns the time one byte of Nutzdaten(!) of a message needs on average from the sender before encryption to the receiver after encryption So per Stream from CP_ECU_INTENT_SEND_SIMPLE_MESSAGE to CP_ECU_DECRYPTED_SIMPLE_MESSAGE ''' # per stream gather # check all times self._db_cur.execute( "SELECT * FROM Checkpoints WHERE MonitorTag = 'MonitorTags.CP_ECU_DECRYPTED_SIMPLE_MESSAGE'" ) end_data = self._db_cur.fetchall() # Avg Byte duration per stream dur_stream = {} for end_d in end_data: try: self._db_cur.execute( "SELECT * FROM Checkpoints WHERE MonitorTag = 'MonitorTags.CP_ECU_INTENT_SEND_SIMPLE_MESSAGE' AND UniqueId = '%s'" % end_d[8]) start_d = self._db_cur.fetchall() start_time = start_d[0][0] m_size = start_d[0][6] G().force_add_dict_list(dur_stream, end_d[7], (end_d[0] - start_time) / float(m_size)) except: pass # all Durations per stream avg_dur_stream = {} for msg_stream in dur_stream.keys(): # calc average try: avg_dur_stream[msg_stream] = sum( dur_stream[msg_stream]) / float(len( dur_stream[msg_stream])) except: pass # Average duration of all streams lst = [] for ky in avg_dur_stream.keys(): lst.append(avg_dur_stream[ky]) try: avg_all_streams = sum(lst) / float(len(lst)) except: avg_all_streams = -1 return [avg_all_streams, avg_dur_stream]
def _grab_highest_priority(self): ''' note the time it takes to select the message with the highest priority Input: - Output: - ''' if self.SCB_GRAB_PRIO_MSG != 0: G().to_t(self.sim_env, self.SCB_GRAB_PRIO_MSG, 'SCB_GRAB_PRIO_MSG', self.__class__.__name__, self) return True return False
def _wait_receive(self): ''' if the time to receive the message is zero this method is false. Otherwise it is true Input: - Output: bool boolean true if the time to receive the message is not zero ''' if self.STDDLL_RECEIVE_BUFFER != 0: G().to_t(self.sim_env, self.STDDLL_RECEIVE_BUFFER * self._jitter, 'STDDLL_RECEIVE_BUFFER', self.__class__.__name__, self) return True return False
def _need_time_message_priority(self): ''' true if the message priority estimation needs time else false Input: - Output: bool boolean true if the message priority estimation needs time ''' if self.STDDLL_GET_MSG_PRIO != 0: G().to_t(self.sim_env, self.STDDLL_GET_MSG_PRIO * self._jitter, 'STDDLL_GET_MSG_PRIO', self.__class__.__name__, self) return True return False
def _need_time_transmit(self): ''' true if the transmit buffer needs a sending time else false Input: - Output: bool boolean true if the transmit buffer needs a sending time ''' if self.STDDLL_TRANSMIT_BUFFER != 0: G().to_t(self.sim_env, self.STDDLL_TRANSMIT_BUFFER * self._jitter, 'STDDLL_TRANSMIT_BUFFER', self.__class__.__name__, self) return True return False
def _process_timeout_needed(self): ''' true if there is time needed to process this message on this layer Input: - Output: bool boolean True if there is time needed for processing ''' if self.STDTL_SEND_PROCESS != 0: G().to_t(self.sim_env, self.STDTL_SEND_PROCESS * self._jitter, 'STDTL_SEND_PROCESS', self.__class__.__name__, self) return True return False
def put_delayed_message(self, dll_layer, message): ''' this method puts the passed message on the passed data link layer after waiting the specified gateway delay Input: message CANFDSegMessage message that is forwarded Output: - ''' G().to_t(self.sim_env, self.GW_TRANSITION_PROCESS * self._jitter, 'GW_TRANSITION_PROCESS', self.__class__.__name__, self) yield self.sim_env.timeout(self.GW_TRANSITION_PROCESS * self._jitter) self.sim_env.process(dll_layer.put_msg(message))
def calc_overhead(self): ''' This method gets all sizes of the encrypted simple messages before and after encrytion Then the overhead due to encryption is calculated ''' # 1. per stream gather enc_sizes = { } # all start times when streams are sent: always one sender anyway clear_sizes = {} self._db_cur.execute( "SELECT * FROM Checkpoints WHERE MonitorTag = 'MonitorTags.CP_ECU_ENCRYPTED_SEND_SIMPLE_MESSAGE'" ) enc_data = self._db_cur.fetchall() for enc_dat in enc_data: try: self._db_cur.execute( "SELECT * FROM Checkpoints WHERE MonitorTag = 'MonitorTags.CP_ECU_INTENT_SEND_SIMPLE_MESSAGE' AND UniqueId = '%s'" % enc_dat[8]) start_d = self._db_cur.fetchall() G().force_add_dict_list(clear_sizes, start_d[0][7], start_d[0][6]) G().force_add_dict_list(enc_sizes, enc_dat[7], enc_dat[6]) except: pass lst_more = [] lst_clear = [] for ky in enc_sizes.keys(): try: lst_more.append( self._mean(enc_sizes[ky]) - self._mean(clear_sizes[ky])) lst_clear.append(self._mean(clear_sizes[ky])) except: pass return (self._mean(lst_more) / self._mean(lst_clear))
def receive_msg(self): while True: # receive from lower layer [message_id, message_data ] = yield self.sim_env.process(self.transp_lay.receive_msg()) # receiver information print("\n\nRECEIVER\nTime: " + str(self.sim_env.now) + "--Communication Layer: \nI am ECU " + self._ecu_id + "\nReceived message:\n - ID: " + str(message_id) + "\n - Content: " + message_data.get()) # Assume it takes 0.5 seconds to e.g. decrypt this message uid = uuid.uuid4() # BEFORE PROCESSING print("\nECU " + str(self._ecu_id) + "Time before message received: " + str(self.sim_env.now)) G().mon( self.monitor_list, MonitorInput([], "AUTH_RECEIVE_TIME_BEFORE_DECRYPTION", self._ecu_id, self.sim_env.now, 123, message_id, message_data.get(), message_data.padded_size, 432, uid)) yield self.sim_env.timeout(0.5) # AFTER PROCESSING print("\nECU " + str(self._ecu_id) + "Time after message received: " + str(self.sim_env.now)) G().mon( self.monitor_list, MonitorInput([], "AUTH_RECEIVE_TIME_AFTER_DECRYPTION", self._ecu_id, self.sim_env.now, 123, message_id, message_data.get(), message_data.padded_size, 432, uid)) # push to higher layer return [message_id, message_data]
def process(self): ''' this method processes all messages that are in the transmit buffer once a message is in the buffer the message with the highest priority in the buffer is selected and then sent Input: - Output: - ''' message = None while True: # send highest priority if (message == None): # grab message message = yield self.controller.transmit_buffer.get() message = self._get_next_high_prio(message) # wait if self._need_time_message_priority(): yield self.sim_env.timeout(self.STDDLL_GET_MSG_PRIO * self._jitter) # channel free if self.physical_lay.bus_free(): # try sending sending_ok = yield self.sim_env.process( self.physical_lay.put(message) ) # send message and check if sending was successful, else resend if sending_ok: self.transmit_buffer_size -= message.msg_length_in_bit / 8 message = None yield self.physical_lay.transceiver.connected_bus.sync_send.get( ) # bus busy sending else: continue else: # wait until free -> get notification from bus yield self.sim_env.process( self.physical_lay.wake_if_channel_free()) StdDatalinkLayer.CNT += 1 # wait backoff time backoff = time.call(self.STDDLL_BACKOFF_AFTER_COL, self.effective_bittime) G().to_t(self.sim_env, backoff, 'backoff', self.__class__.__name__, self) yield self.sim_env.timeout(backoff)
def send_msg(self, sender_id, message_id, message): ''' send the message that was passed by further pushing it to the next layer and adding a delay Input: sender_id string id of the sending component message_id integer message identifier of the message that will be sent message object Message that will be send on to the datalink layer Output: - ''' if self.STDCM_SEND_PROCESS != 0: G().to_t(self.sim_env, self.STDCM_SEND_PROCESS * self._jitter, 'STDCM_SEND_PROCESS', self.__class__.__name__) yield self.sim_env.timeout(self.STDCM_SEND_PROCESS * self._jitter) yield self.sim_env.process(self.transp_lay.send_msg(sender_id, message_id, message))
def put(self, msg): ''' this method puts a message to the connected bus Input: - Output: ok boolean true if putting was successful ''' if self.ST_PUT_ON_BUS != 0: G().to_t(self.sim_env, self.ST_PUT_ON_BUS * self._jitter, 'ST_PUT_ON_BUS', self.__class__.__name__, self) yield self.sim_env.timeout(self.ST_PUT_ON_BUS * self._jitter) ok = yield self.sim_env.process(self.connected_bus.put_message(msg)) return ok
def send_msg(self, sender_id, message_id, message): # Sender information print("\n\nSENDER - \nTime: " + str(self.sim_env.now) + "--Communication Layer: \nI am ECU " + sender_id + "\nSending message:\n - ID: " + str(message_id) + "\n - Content: " + message.get()) # Message to be send print("\nSize of the message we want to send: " + str(message.padded_size)) print("\nContent of the message: " + str(message.get())) # Assume it takes 0.2 seconds to e.g. encrypt this message uid = uuid.uuid4() # BEFORE PROCESSING print("\nECU " + str(self._ecu_id) + "Time before message sent: " + str(self.sim_env.now)) G().mon( self.monitor_list, MonitorInput([], "AUTH_SEND_TIME_BEFORE_ENCRYPTION", self._ecu_id, self.sim_env.now, 123, message_id, message.get(), message.padded_size, 432, uid)) yield self.sim_env.timeout(0.2) # AFTER PROCESSING G().mon( self.monitor_list, MonitorInput([], "AUTH_SEND_TIME_AFTER_ENCRYPTION", self._ecu_id, self.sim_env.now, 123, message_id, message.get(), message.padded_size, 432, uid)) print("\nECU " + str(self._ecu_id) + "Time after message sent: " + str(self.sim_env.now)) # Send message - here send your message with your message_id yield self.sim_env.process( self.transp_lay.send_msg(sender_id, message_id, message))