大家好,又见面了,我是你们的朋友全栈君。
QXDM抓取log为isf格式,需要用QCAT打开进行分析,如果需要自动分析QXDM抓取的log,一个可行的方法为调用QCAT的COM接口打开isf文件并进行分析。
QCAT 6.X支持基于COM的接口调用,允许用户通过Perl、VBScript、JavaScript、Python等脚本语言调用应用。具体调用方法在QCAT安装后的《QCAT User Guide》用户手册中,第六章Scripting with QCAT (Windows Only) 详述了QCAT COM编程可用的接口。
如果要进行com编程需要安装pywin32模块才能进行COM调用
pip install pywin32
import win32com.client qcatApp = win32com.client.Dispatch("QCAT6.Application") except : QMessageBox.warning(self, '', 'QCAT打开失败,请检查QCAT') sys.exit(1)
self.TargetLogId = 0xB0C0 SIBFilter = qcatApp.PacketFilter SIBFilter.SetAll(False) #设置过滤所有的消息类型 SIBFilter.Set(self.TargetLogId, True) #只显示类型为0xB0C0的log,可以设置多次filter显示不同类型LOG SIBFilter.Commit()
if qcatApp.OpenLog(winfilepath) != 1: #winfilepath为需要打开的文档路径 print("Open Log Error") exit() print("file open ok")
QcatPacket = qcatApp.FirstPacket #第一包 QcatPacket.Next() #下一包,如果已经是最后一包则该方法返回FALSE QcatPacket.text #获取QCAT解码的内容
由于调用QcatPacket.text获取QCAT解码的内容,然后通过文本处理的方式对log进行处理,语法上是对str进行处理,但是由于协议兼容性,有很多地方需要注意。
1、注意可选信元和信令
很多信元是可选的,因此需要先设置信元的默认值,然后判断需要解析的信元是否存在,如果没有解析出来则说明为默认值。
有些信令比如SIB2~8需要根据SIB1来判断是否存在,如果不存在则无需等待收集齐后处理。
对于SIB3、SIB5和SIB6等SIB处理,都含有cellReselectionPriority,需要判断每个cellReselectionPriority对应的频点,不可混淆,特别多个SIB在同一个周期调度时更需要注意。
2、兼容不同版本协议
比如同频重选门限对于R8为”s-IntraSearch “,对于R9为”s-IntraSearchP-r9″,由于”s-IntraSearchP-r9″包含了”s-IntraSearch”,为了避免R8和R9的参数混合了,这里需要在”s-IntraSearch”后面加一个空格,判断如果含有”s-IntraSearch “则为R8,如果含有”s-IntraSearchP-r9″则为R9。
自定义的内部信元更需要注意,比如“0xB193 LTE ML1 Serving Cell Meas Response”中,较早的终端SINR显示为“SINR Rx[0]”,有些较新的终端则显示为“SNR Rx[0]”,处理时统一根据“NR Rx[0]”来判断。
3、注意数据转换
有些信元的取值范围可以是数字,也可以是invalid或者infinity等,如果简单将str转换为int,会出现转化失败的情况,因此需要先通过str.isdigit()判断是否能转换为数字,然后再转换。
4、pywin32与多线程
用com调用QCAT处理log时,一开始单线程没有问题,一到多线程程序就崩溃,查到下面这篇文档。
http://irootlee.com/python_pywin32_thread/
因为COM对象属于一个线程,该线程与当前的线程无法正常通信,所以导致在多线程中调用Dispatch函数会报错。
我们需要Windows提供的函数Coinitialize来创建一个套间,使得他们可以正常关联和执行,具体方法就是在多线程中调用COM对象代码前面加上 python com.CoInitialize(),最后在COM对象调用结束后加上pythoncom.CoUninitialize()释放资源。
查看QXDM User Guide,python也可以通过COM接口调用QXDM获取终端log。
#初始化 import win32com.client app = win32com.client.Dispatch("QXDM.QXDMAutoApplication") qxdm = app.GetAutomationWindow() #查看QXDM版本 version = qxdm.AppVersion #加载.dmc配置文件,根据配置文件抓取终端log qxdm.LoadConfig('XXXXXX.dmc') #设置终端的调试端口,连接终端 response = qxdm.SetComPort(XX) #获取当前已经抓到的log的数量