def activate_channel(self, port_handle, accessmask, bus_type): XL_ACTIVATE_NONE = 0 XL_ERR_INVALID_PORT = 118 status = self.dll.xlActivateChannel(port_handle, accessmask, bus_type, XL_ACTIVATE_NONE) rfic_info("activate status:", status) return status
def get_required_message(self, source, target, service_id, method_id): ''' 检索期望消息 ''' srcIP = self.ethAppChannel[source]["ip"] srcPort = self.ethAppChannel[source]["port"] dstIP = self.ethAppChannel[target]["ip"] dstPort = self.ethAppChannel[target]["port"] while True: try: msg_list = MessageRecorder.get_tmp_message_list((srcIP, dstIP, srcPort, dstPort)) for msg in msg_list[::-1]: target_params = msg # 只关注最后一条 try: raw = SOMEIP(target_params['raw']) # raw.show() msg_service_id = raw.srv_id msg_method_id = raw.method_id if msg_service_id == service_id and msg_method_id == method_id: rfic_info("检索到期望消息", target_params) MessageRecorder.clear_tmp_message_list() # 清空临时消息,缩短消息检索时间 time.sleep(0.03) # 等待消息流程完成 return True, target_params except: pass except: pass
def open_port(self, app_name, port_handle, accessmask, permissionmask, bus_type): status = self.dll.xlOpenPort( byref(port_handle), app_name, accessmask, byref(permissionmask), 8 * 1024 * 1024, ChannelBasedConstants.XL_INTERFACE_VERSION_V4, bus_type) rfic_info("open port:", status, port_handle)
def fota_get_log_upload_url_resp(): """ FOTA_GetLogUploadURLResp 请求方向:IAM->ICC :return: 返回解析出来的消息 """ rfic_info("等待IAM发送FOTA_GetLogUploadURLResp。。。") return True, ""
def fota_report_upload_log_result_req(): """ FOTA_ReportUploadLogResultReq 请求方向:ICC->IAM :return: 返回解析出来的消息 """ rfic_info("等待ICC发送FOTA_ReportUploadLogResultReq。。。") return True, ""
def fota_hmi_status(): """ FOTA_HMIStatus 请求方向:ICC->ICM :return: 返回解析出来的消息 """ rfic_info("等待ICC发送FOTA_HMIStatus。。。") return True, ""
def fota_hmi_update_progress(): """ FOTA_HMIUpdateProgress 请求方向:ICC->ICM :return: 返回解析出来的消息 """ rfic_info("等待ICC发送FOTA_HMIUpdateProgress。。。") return True, ""
def set_can_channel_transceiver(self, port_handle, accessmask): transceiver_type = ChannelBasedConstants.XL_TRANSCEIVER_TYPE_CAN_252 line_mode = ChannelBasedConstants.XL_TRANSCEIVER_LINEMODE_NORMAL res_net = 0 # reserved for future use, Set to 0. status = self.dll.xlCanSetChannelTransceiver(port_handle, accessmask, transceiver_type, line_mode, res_net) rfic_info("set can channel transceiver:", status)
def fota_report_upload_log_result_resp(): """ FOTA_ReportUploadLogResultResp 请求方向:IAM->ICC :return: 返回解析出来的消息 """ rfic_info("等待IAM发送FOTA_ReportUploadLogResultResp。。。") return True, ""
def set_can_channel_bitrate(self, port_handle, accessmask, bitrate=500000): """ 指定比特率 """ bitrate = c_ulong(bitrate) status = self.dll.xlCanSetChannelBitrate(port_handle, accessmask, bitrate) rfic_info("set can channel bitrate:", status)
def fota_get_log_upload_url_req(): """ FOTA_GetLogUploadURLReq 请求方向:ICC->IAM :return: 返回解析出来的消息 """ rfic_info("等待ICC发送FOTA_GetLogUploadURLReq。。。") return True, ""
def generate_tx_data(self, target_params, flags="PA", matrix=None): rfic_info(target_params) txData = T_XL_ETH_DATAFRAME_TX() if flags == "PA": srcIp = target_params["srcIp"] # 本端:'192.168.0.101' dstIp = target_params["dstIp"] # 对端:'192.168.0.100' srcPort = target_params["srcPort"] dstPort = target_params["dstPort"] window = target_params["window"] seq = target_params["seq"] ack = target_params["ack"] srcMAC = target_params["srcMAC"] dstMAC = target_params["dstMAC"] elif flags == "A": srcIp = target_params["dstIp"] # 本端:'192.168.0.101' dstIp = target_params["srcIp"] # 对端:'192.168.0.100' srcPort = target_params["dstPort"] dstPort = target_params["srcPort"] window = target_params["window"] seq = target_params["ack"] ack = target_params["seq"] + target_params["payload_len"] srcMAC = target_params["dstMAC"] dstMAC = target_params["srcMAC"] else: srcIp = target_params["srcIp"] # 本端:'192.168.0.101' dstIp = target_params["dstIp"] # 对端:'192.168.0.100' srcPort = target_params["srcPort"] dstPort = target_params["dstPort"] window = target_params["window"] seq = target_params["seq"] ack = target_params["ack"] srcMAC = target_params["srcMAC"] dstMAC = target_params["dstMAC"] for i in range(len(srcMAC)): txData.sourceMAC[i] = srcMAC[i] txData.destMAC[i] = dstMAC[i] txData.frameIdentifier = 0 txData.flags = XLDefine.XLethernet_TX_Flags.XL_ETH_DATAFRAME_FLAGS_USE_SOURCE_MAC payload_length, combine_payload = self.generate_someip_based_tcp(srcIp, dstIp, srcPort, dstPort, seq, ack, flags, matrix) txData.dataLen = payload_length + 2 # min. 46 bytes + 2 bytes for etherType if txData.dataLen < 46: txData.dataLen = 46 + 2 # 数据位长度最小是 46+2 eth_tp_v = self.host2network_order(0x0800) # 本地字节序转成网络字节序 IPv4 ethTp = c_ushort() ethTp.value = int(eth_tp_v, 16) txData.frameData.ethFrame.etherType = ethTp.value # 设置字节序的类型 for i in range(len(combine_payload)): txData.frameData.ethFrame.payload[i] = int(combine_payload[i], 16) return txData
def ril_print(*args, **kwargs): rfic_info("[Func Call] <%s>开始执行..." % func.__name__, log=False) res = func(*args, **kwargs) args = "" if len(args) == 0 else args kwargs = "" if len(kwargs) == 0 else kwargs rfic_info("[Func Call] <%s>%s%s------>%s" % (func.__name__, str(args), str(kwargs), res), log=False) return res
def set_can_channel_params(self, port_handle, accessmask): """ 使用给定参数初始化accessMask定义的通道 如果要调用此函数,端口必须具有init access访问权限 """ pChipParams = XLchipParams() status = self.dll.xlCanSetChannelParams(port_handle, accessmask, byref(pChipParams)) rfic_info("set can channel params:", status)
def eth_send(self, target, txData): ethSendStatus = self.dll.xlEthTransmit(self.ethPortHandle, self.ethAppChannel[target]["accessChannelMask"], self.ethUserHandle, byref(txData)) rfic_info("xlEthTransmit:%s" % ethSendStatus) time.sleep(0.05) # 报文发送之后,等待对端响应response if ethSendStatus == 0: return True else: return False
def fota_update_status_resp(): """ FOTA_UpdateStatusResp 云端反馈收到任务上报状态信息 请求方向:云->车 :return: """ rfic_info("等待OTA后台发送FOTA_UpdateStatusResp。。。") return True, ""
def cleanup(self): ''' 关闭端口和驱动 :return: ''' self.deactive_channel(self.ethPortHandle, self.ethAccessMask) status = self.dll.xlClosePort(self.ethPortHandle) rfic_info("close port:", status) status = self.dll.xlCloseDriver() rfic_info("close driver:", status)
def start(self, params=None): # 所有用例开始执行之前的初始化动作 rfic_info("开始执行测试用例...") # 生成测试报告文件夹 -s Constants.REPORT_DIR = os.path.join( Constants.REPORT_BASE_DIR, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')) if not os.path.exists(Constants.REPORT_DIR): os.makedirs(Constants.REPORT_DIR)
def set_can_channel_output( self, port_handle, accessmask, mode=ChannelBasedConstants.XL_OUTPUT_MODE_NORMAL): """ 如果mode=XL_OUTPUT_MODE_SILENT,当收到CAN消息后,CANchip不会生成任何acknowledges 在静默模式下,不能发送消息,但是可以接收消息 如果没有调用该方法,那么默认的模式是:normal模式(有acknowledges) """ status = self.dll.xlCanSetChannelOutput(port_handle, accessmask, mode) rfic_info("set can channel output:", status)
def set_appl_config(self, app_name, app_channels, bus_type): ''' 为Application设置applicationName 指定该applicationName对应的哪个VN5640设备,以及该VN5640的总线类型 当前仅支持 1 个VN5640 e.g. AppName1:VN5640 1 AppName2:VN5640 2 ''' status_list = [] for ethName, value_dict in app_channels.items(): status = self.dll.xlSetApplConfig(app_name, value_dict["appChannel"], self.hwType, self.hwIndex, value_dict["hwChannel"], bus_type) status_list.append(status) rfic_info("xlSetApplConfig:", str(status_list))
def fota_update_status_req(times=1, timeout=1): """ FOTA_UpdateStatusReq 车端上报升级任务状态 请求方向:车->云 :return: 返回解析出来的消息 """ rfic_info("等待ICC发送FOTA_UpdateStatusReq。。。") res_list = [] for _ in range(times): # 连续检测times次, rfic_info("等待ICC发送FOTA_UpdateStatusReq。。。") # 检测并解析报文 current_time = time.time() # 开始检测的时间点 res = False while time.time() - current_time <= timeout: # 检测报文 requestInfo = {} triggerInfo = {} # 明确消息 requestInfo.requestMethod="FOTA_CheckVersionReq" condition1 = requestInfo.get( "requestMethod") == "FOTA_UpdateStatusReq" # 检测到报文 if condition1: res = True break res_list.append(res) # 列表中的True的次数应该与times相等 -s true_cnt = 0 for ele in res_list: if ele: true_cnt += 1 # 列表中的True的次数应该与times相等 -e if true_cnt == times: return True, "" else: return False, "超时[%ss]未检测到车端报文[%s/%s]:FOTA_UpdateStatusReq" % ( str(timeout), true_cnt, times)
def send_msg_as_method(self, source, target, matrix): ''' 发送(TCP)method消息,需要等待对端回复 A->B:PSH+ACK B->A:PSH+ACK A->B:ACK :param source: 源ECU :param target: 目的ECU :param matrix: 通信矩阵,包含service_id,method_id,msg_type :return: ''' # 监听本端给对端发的ACK消息 srcIP = self.ethAppChannel[source]["ip"] srcPort = self.ethAppChannel[source]["port"] dstIP = self.ethAppChannel[target]["ip"] dstPort = self.ethAppChannel[target]["port"] msg_list = MessageRecorder.get_message_list((srcIP, dstIP, srcPort, dstPort)) while len(msg_list) == 0: msg_list = MessageRecorder.get_message_list((srcIP, dstIP, srcPort, dstPort)) target_params = msg_list[-1] # 只关注最后一条 # 本端发送PSH+ACK消息 tx_data = self.generate_tx_data(target_params, "PA", matrix) self.eth_send(target, tx_data) # 监听对端给本端发的PSH+ACK消息 msg_list = MessageRecorder.get_message_list((dstIP, srcIP, dstPort, srcPort)) while len(msg_list) == 0: # 没有消息的时候,不停的收 msg_list = MessageRecorder.get_message_list((dstIP, srcIP, dstPort, srcPort)) target_params = msg_list[-1] # 只关注最后一条 raw_info = SOMEIP(target_params['raw']).show(dump=True) rfic_info(raw_info) # 本端发送ACK消息 tx_data = self.generate_tx_data(target_params, "A") return self.eth_send(target, tx_data)
def tearDown(self): # 停止消息监测 rfic_info("停止消息监测") # self.xldriver_eth_handle.terminate_monitor() # xldriver恢复初始设置 rfic_info("重置Vn5640") # self.xldriver_eth_handle.recovery() # 台架下电 rfic_info("台架下电") return True
def setUp(self): # VN5640初始化 rfic_info("初始化VN5640") if not debug: self.xldriver_eth_handle.reset() # 开启消息监测 rfic_info("开始消息流监听") if not debug: self.xldriver_eth_handle.eth_recv_monitor() # 台架上电 rfic_info("台架上电") return True
def can_send(self, canMask, xlEvent): pEventCount = c_uint(1) status = self.dll.xlCanTransmit(self.canPortHandle, canMask, byref(pEventCount), byref(xlEvent)) rfic_info("can transmit:", status)
def run(self): src, dst = "device100", "device102" # src, dst = "device102", "device100" # 等待具体的消息过来后,开始进行消息的仿真发送 rfic_info("等待指定的ABC消息。。。") if not debug: status, target_params = self.xldriver_eth_handle.get_required_message( src, dst, 0x0100, 0x3b) rfic_info("收到期望消息:", str(target_params)) rfic_info("断开原始通信链路") if not debug: self.xldriver_eth_handle.set_bypass_inactive_mode(src, dst) rfic_info("开始组包...") # 消息仿真与发送 -s req_data = [ "FE", "FF", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "01", "00", "00" ] matrix = { "srv_id": 0x0100, "method_id": 0x3b, "session_id": 1, "msg_type": SOMEIP.TYPE_REQUEST, "req_data": req_data } rfic_info("消息构造:srv_id=%s,method_id=%s" % (hex(matrix["srv_id"]), hex(matrix["method_id"]))) rfic_info("消息发送指向:%s-->%s" % (src, dst)) if not debug: status = self.xldriver_eth_handle.send_msg_as_method( src, dst, matrix) result_msg = "passed" if status else "failed" rfic_info("消息发送完成", result_msg) rfic_info("打开原始通信链路") if not debug: self.xldriver_eth_handle.set_bypass_mac_mode(src, dst) # 消息仿真与发送 -e return True
def teardown(): rfic_info("------teardown------") Constants.clean() # 重置全局变量
def start(): """ 所有测试用例执行之前执行的功能 :return: """ rfic_info("------start------")
def stop(self, params=None): # 所有用例执行完成后执行的动作 rfic_info("测试用例执行完成...") Reporter.generate_html() # 汇总每条测试用例生成的json文件,最终生成html测试报告
def show_logo(self): with open("logo.info") as f: data = f.readlines() for line in data: rfic_info(line.replace("\n", ""))