一、原理
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編程可用的接口。
二、關鍵步驟
1、安裝pywin32模塊
如果要進行com編程需要安裝pywin32模塊才能進行COM調用
pip install pywin32
2、通過COM接口打開QCAT
import win32com.client
try:
qcatApp = win32com.client.Dispatch("QCAT6.Application")
except :
QMessageBox.warning(self, '', 'QCAT打開失敗,請檢查QCAT')
sys.exit(1)
3、設置過濾器
self.TargetLogId = 0xB0C0
SIBFilter = qcatApp.PacketFilter
SIBFilter.SetAll(False) #設置過濾所有的消息類型
SIBFilter.Set(self.TargetLogId, True) #只顯示類型爲0xB0C0的log,可以設置多次filter顯示不同類型LOG
SIBFilter.Commit()
4、打開UE LOG文件
if qcatApp.OpenLog(winfilepath) != 1: #winfilepath爲需要打開的文檔路徑
print("Open Log Error")
exit()
print("file open ok")
5、遍歷UE LOG過濾後內容
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對象代碼前面加上pythoncom.CoInitialize(),最後在COM對象調用結束後加上pythoncom.CoUninitialize()釋放資源。