軟件無(wú)線(xiàn)電(Software Defined Radio)以前往往以高(zhuang)大(bi)上(fan)的面目示人,是大公司或?qū)W校實(shí)驗(yàn)室的高級(jí)玩具,一套系統(tǒng)動(dòng)輒幾萬(wàn)甚至幾十萬(wàn),從來(lái)都是一個(gè)2B(2B = to business)的模式。自從一個(gè)芬蘭黑客(考證癖出來(lái)考證一下)破解了rtl2832芯片的電視棒之后(
http://sdr.osmocom.org/trac/wiki /rtl-sdr),SDR終于像樹(shù)莓派一樣普及了。你可以淘寶一個(gè)50或60RMB的電視棒,然后給妹子show off跟蹤飛機(jī),偷聽(tīng)空管說(shuō)話(huà),掃描GSM信號(hào),再然后在妹子崇拜的眼神里嚴(yán)辭拒絕出去吃飯的提議,潛心鉆研下一個(gè)可玩的無(wú)線(xiàn)電信號(hào)–LTE。
言歸正轉(zhuǎn)。
一、背景介紹
世界各地的SDR玩家們肯定不會(huì)放過(guò)前面提到的LTE。比如這個(gè)LTE小區(qū)搜索和跟蹤程序(
https://github.com/Evrytania/LTE-Cell-Scanner),它可以用前述的廉價(jià)電視棒掃描并解調(diào)LTE基站下行PBCH(物理廣播信道)信號(hào),獲取一些基本的小區(qū)信息。
后來(lái)中國(guó)也宣布上4G了,我想那就git clone下來(lái)試一下吧,從而一發(fā)而不可收了。先后為這個(gè)程序加入了TD-LTE支持(原來(lái)只支持FDD模式,居然無(wú)視我泱泱大國(guó)自主知識(shí)產(chǎn)權(quán)4G標(biāo)準(zhǔn)。獠縇NB/變頻器算法支持,OpenCL加速(單頻點(diǎn)掃描速度提高約20倍,縮減到半秒左右)等。以上改進(jìn)的整個(gè)歷程和程序在此:
https://github.com/JiaoXianjun/LTE-Cell-Scanner 。折騰歷程參見(jiàn)“HackRF 掃描LTE基站 支持中國(guó)的TDD-LTE”。
電視棒便宜又好玩,但局限性也很明顯:
1.頻率覆蓋范圍有限。E4K版本覆蓋到約2.2GHz(但高端頻率接收性能已嚴(yán)重下降),820t版本覆蓋到約1.76GHz。國(guó)內(nèi)目前開(kāi)通的LTE信號(hào)最 低也在1.8GHz以上,超出820t版的覆蓋范圍。雖然部分在E4K電視棒覆蓋范圍內(nèi),但E4K版的電視棒早已停產(chǎn),奇貨可居,手里有E4K電視棒的各 位且用且珍惜吧!顯然,電視棒也玩不了最熱鬧的2.4GHz頻段,除非外接MMDS-LNB或者其他變頻器進(jìn)行頻率擴(kuò)展。
2.帶寬和采樣率有限,也就最高2、3M的樣子,只能玩玩1、2M帶寬以下的信號(hào),對(duì)LTE和WiFi的信號(hào)帶寬就望塵莫及了。所幸按照LTE標(biāo)準(zhǔn),PBCH 信號(hào)(基站廣播的最基本信息)固定在中心1MHz左右?guī)拑?nèi),剛好還在電視棒的能力之內(nèi)。但是對(duì)于LTE基站廣播的更多信息(比如SIB)就無(wú)能為力了, 因?yàn)楦嘈畔⒕涂赡芊植荚诔鲋行?MHz帶寬范圍了。
3. 只能收不能發(fā)。
4. RF指標(biāo)一般。畢竟太廉價(jià),以及接收目標(biāo)是很強(qiáng)的電視廣播信號(hào)。
雖然電視棒有種種缺點(diǎn),但它實(shí)在太便宜,便宜到價(jià)格都快要忽略不計(jì)了。世界各地的人們玩的不亦樂(lè)乎。各種“打磨”“改裝”“提升”方案層出不窮。與 此同時(shí),各路大神悉數(shù)登場(chǎng),要為世人打造更強(qiáng)大的開(kāi)源SDR硬件,同時(shí)還要把以往的2B價(jià)格(比如USRP)降到2C范圍。這其中的明星產(chǎn)品就是 BladeRF和HackRF了,兩者都在kickstarter上成功募集到資金,前者已開(kāi)始交付用戶(hù)。后者HackRF據(jù)說(shuō)生產(chǎn)上遇到一些問(wèn)題,一再 跳票,還未開(kāi)始大規(guī)模交付kickstarter上交了錢(qián)的用戶(hù)。NB的是 hackrf.net 居然按照HackRF圖紙先造了出來(lái)并開(kāi)始銷(xiāo)售!于是就有了我將HackRF的支持加入LTE小區(qū)搜索程序的事情:
中華人民共和國(guó)二零一四年三月十五日,就是HFD硬件自由日清華站活動(dòng)在清華大學(xué)五教5102召開(kāi)講座的那一天,我獨(dú)自前往5102聆聽(tīng)大神們布 道,遇見(jiàn)王康,前來(lái)問(wèn)我道,“先生可曾用過(guò)HackRF沒(méi)有?”我說(shuō)“沒(méi)有”。他就正告我,“先生還是用一用罷;HackRF就是為先生這樣的人設(shè)計(jì)的!
二、對(duì)HackRF的初步試用感受
介紹具體細(xì)節(jié)之前,先給出一些直觀的試用感受。
先說(shuō)優(yōu)點(diǎn):
1. 覆蓋頻率范圍、支持的帶寬和采樣率自然是比電視棒高太多了,可玩的信號(hào)種類(lèi)更多,更重要的是比電視棒多了發(fā)射(友情提示,國(guó)家有法規(guī),發(fā)射需謹(jǐn)慎)。HackRF的配置和功能從電視棒的玩票性質(zhì)已經(jīng)進(jìn)入高大上的專(zhuān)業(yè)選手圈子。
2. 靈敏度比我珍藏的絕版E4K電視棒明顯的要好,在家里E4K電視棒搜到LTE信號(hào)要憑運(yùn)氣,但是用HackRF基本就每次都能搜到了。
3.功耗(或者是啟動(dòng)電流?)居然比E4K電視棒要低,這個(gè)有些出乎我的意料,畢竟HackRF的板子看起來(lái)比電視棒還是大不少,上面的芯片也多不 少。電視棒在ThinkpadT410筆記本上用的時(shí)候,如果不用筆記本底座(220V電源供電)上的USB口而直接用筆記本自帶的USB口,則經(jīng)常會(huì)驅(qū) 動(dòng)報(bào)錯(cuò)甚至導(dǎo)致筆記本死機(jī)(這個(gè)問(wèn)題困擾我好久,最后發(fā)現(xiàn)是供電不足),HackRF則直接用筆記本本身USB口,無(wú)需外接電源,就已經(jīng)運(yùn)行的很穩(wěn)定,這 樣我筆記本就不用插電源,可以到處跑了。
如果非要說(shuō)缺點(diǎn),HackRF價(jià)格比起電視棒當(dāng)然高了n倍。但對(duì)比專(zhuān)業(yè)設(shè)備和業(yè)余設(shè)備的價(jià)格本身就是沒(méi)意義的。我感覺(jué)HackRF應(yīng)該是專(zhuān)業(yè)選手里價(jià)格最低的了。
另一個(gè)美中不足(或者說(shuō)也是價(jià)格所限)是僅支持單天線(xiàn)和半雙工。單天線(xiàn)的話(huà)就玩不了MIMO和測(cè)向之類(lèi)的了。如果能像BladeRF那樣支持雙天線(xiàn),那么就不但可以提高解調(diào)信號(hào)的質(zhì)量,并且有可能找出信號(hào)的方向從而可能定位目標(biāo)的物理位置,豈不更有趣。
(按: HackRF有10MHz同步時(shí)鐘的輸入和輸出,理論上可以進(jìn)行多個(gè)HackRF的級(jí)聯(lián),從而完成上述的MIMO和測(cè)向應(yīng)用。詳見(jiàn)HackRF10MHz時(shí)鐘)
三、使用純C語(yǔ)言操作HackRF
羅嗦半天,終于要進(jìn)入正題了。
GNURadio,開(kāi)源SDR領(lǐng)域最大的生態(tài)系統(tǒng)。圖形界面,腳本語(yǔ)言,支持各種硬件(USRP,BladeRF,rtl- sdr,HackRF,etc),軟件資源極為豐富,上手快,深得愛(ài)好者、學(xué)校、研究人員的喜愛(ài)。幾句命令,幾下鼠標(biāo),搭個(gè)框圖便能玩弄空中的信號(hào)于掌股 之中。
但,今天我們不說(shuō)GNURadio。
說(shuō)說(shuō)如何用純C/C++程序直接調(diào)用HackRF(或者rtl-sdr電視棒以及其他基于USB的SDR硬件,都應(yīng)該是類(lèi)似的)。這樣你就可以在別 人用鼠標(biāo)搭框圖對(duì)各種采樣率變換焦頭爛額的時(shí)候,飛快的敲鍵盤(pán)用VI編寫(xiě)C/C++程序來(lái)使用HackRF,不經(jīng)意流露鄙視的眼神,深藏功與名。逼格頓時(shí) 提升幾個(gè)檔次。好(dan)牛(teng)!
以下介紹的都是在Linux下的一些工作。這里假設(shè)你對(duì)Linux比較熟悉(不太熟悉的,可以看這篇blog中的一些基礎(chǔ)操作介紹:
http://blog.sina.com.cn/s/blog_67cdafe201014odm.html)。
(前方“野程序員”預(yù)警!本人不是計(jì)算機(jī)專(zhuān)業(yè)科班出身,本文關(guān)于程序方面的內(nèi)容都是照貓畫(huà)虎或者頻繁試錯(cuò)的結(jié)果,未必最優(yōu)或者最正確,僅供參考,歡迎指正。大言不慚的說(shuō)本人其實(shí)是通信專(zhuān)業(yè)科班出身,咳咳。)
1)環(huán)境的建立
hackrf的程序包是一個(gè)典型的cmake包,可以從github上自由下載、編譯和安裝。以我在Ubuntu12.04系統(tǒng)下的操作為例。
祈禱你的系統(tǒng)已經(jīng)安裝了HackRF所需的其他程序包,以上過(guò)程會(huì)非常順暢和快速。否則cmake步驟和make步驟可能會(huì)給一些錯(cuò)誤提示,按照提示安裝所需的包即可。libusb是必須的,USB接口的SDR設(shè)備驅(qū)動(dòng)一般都是基于libusb構(gòu)建。
最后一步的安裝操作( sudo make install )會(huì)把其他程序進(jìn)行API調(diào)用所需的頭文件以及編譯好的二進(jìn)制庫(kù)文件放在一些預(yù)定義的位置:
頭文件: /usr/local/include/libhackrf/hackrf.h
庫(kù)文件:/usr/local/lib/libhackrf.a,libhackrf.so
其實(shí)HackRF源代碼包里已經(jīng)包含了一些有益的參考和例子:
host/libhackrf/src/下面是庫(kù)文件的源代碼:hackrf.h; hackrf.c,我們要調(diào)用的API的具體實(shí)現(xiàn)都在這里。
host/hackrf-tools/src/ 下面是附帶的一些小測(cè)試程序,比如我主要是通過(guò) hackrf_transfer.c 學(xué)習(xí)的如何通過(guò)C/C++使用HackRF。
你可以先玩玩這些小工具。至此,無(wú)需龐大的GNURadio,HackRF已經(jīng)可以玩起來(lái)了,是不是很簡(jiǎn)單?
2)如何使你的代碼編譯時(shí)找到HackRF庫(kù)
接下來(lái)你想讓自己的C/C++信號(hào)處理程序用上HackRF,那么首先就是如何讓你的代碼找到HackRF庫(kù)。
直接包含HackRF頭文件,并且鏈接HackRF庫(kù)當(dāng)然可以,對(duì)于Linuxer怎么弄都成。
如果你的代碼工程也是基于cmake構(gòu)建,也很容易寫(xiě)cmake腳本來(lái)使你的代碼編譯時(shí)自動(dòng)找到HackRF庫(kù)。以L(fǎng)TE小區(qū)搜索程序?yàn)槔ǹ梢詮?
https://github.com/JiaoXianjun/LTE-Cell-Scanner 下載),在 cmake/Modules/ 目錄下,寫(xiě)了一個(gè) FindHACKRF.cmake 的腳本,該腳本會(huì)搜索一些預(yù)定義的頭文件和庫(kù)文件位置來(lái)檢測(cè)HackRF庫(kù)的存在。如果你編譯時(shí)提示找不到 HackRF的庫(kù),可以看看你的HackRF庫(kù)是否沒(méi)有安裝在 FindHACKRF.cmake 搜索的幾個(gè)位置中,以下摘自 FindHACKRF.cmake :
在代碼cmake過(guò)程中,頂層腳本 CMakeLists.txt 會(huì)調(diào)用 FindHACKRF.cmake 并且執(zhí)行相應(yīng)的操作,比如告訴 src/CMakeLists.txt 去鏈接HackRF庫(kù)。
3)調(diào)用HackRF的API以及編寫(xiě)回調(diào)函數(shù)
好了,下面講解具體的,如何在你的C/C++信號(hào)處理代碼中調(diào)用HackRF,獲取空中的信號(hào)樣本。
首先介紹一下一般性的流程。
在你的程序中,需要先調(diào)用一些初始化API完成最初的設(shè)備open、初始化操作。之后調(diào)用LNA增益、VGA增益、射頻頻率、采樣率等API按照你的需要進(jìn)行相關(guān)的設(shè)置。(按: 這些增益可以參考這篇文章的解釋)
而后調(diào)用接收/發(fā)射API(也會(huì)把你寫(xiě)的回調(diào)函數(shù)作為參數(shù)告知該API)開(kāi)始接收/發(fā)射。以接收為例,當(dāng)HackRF驅(qū)動(dòng)接收到USB接口傳來(lái)的 I&Q采樣數(shù)據(jù)時(shí),會(huì)自動(dòng)調(diào)用你寫(xiě)的回調(diào)函數(shù),你的回調(diào)函數(shù)中會(huì)看到驅(qū)動(dòng)程序傳過(guò)來(lái)的一些信息(通過(guò)傳入回調(diào)函數(shù)的參數(shù)),比如本次接收到數(shù)據(jù)的 長(zhǎng)度、buffer的起始地址之類(lèi)的信息,根據(jù)這些信息,你可以進(jìn)行相應(yīng)的處理,比如告訴告訴前臺(tái)程序:數(shù)據(jù)來(lái)了,拿去處理!
仍舊以L(fǎng)TE小區(qū)搜索程序?yàn)槔M(jìn)行介紹。
在 src/CellSearch.cpp 中,函數(shù) config_hackrf() 完成初始化和初次信號(hào)接收的測(cè)試。依次調(diào)用的HackRF API有(這些API都定義在hackrf.h中,實(shí)現(xiàn)在hackrf.c中):
然后調(diào)用信號(hào)接收子函數(shù) capture_data() ,進(jìn)行初次接收測(cè)試。信號(hào)接收子函數(shù) capture_data() 實(shí)現(xiàn)在 src/capbuf.cpp 中。具體代碼:
本次接收至此完成,接收的 CAPLENGTH*2 數(shù)據(jù)存在全局?jǐn)?shù)組 hackrf_rx_buf 中了。程序可以進(jìn)一步處理接收到的數(shù)據(jù)了。數(shù)據(jù)格式很簡(jiǎn)單,就是I和Q交替存儲(chǔ),均為有符號(hào)8bit整數(shù)(因?yàn)镠ackRF目前最新的CPLD程序已經(jīng)做了
無(wú)符號(hào)有符號(hào)變換,因此我們?cè)趆ost程序里看到的已經(jīng)是處理完的有符號(hào)數(shù),信號(hào)處理可以直接用了。當(dāng)然其中可能有一些RF的非理想因素,比如DC offset, IQ imbalance之類(lèi)的,這些都是信號(hào)處理可以用算法去搞的了)
下面介紹回調(diào)函數(shù)。回調(diào)函數(shù)除了把接收數(shù)據(jù)總長(zhǎng)度更新到全局變量 hackrf_rx_count 中外,還會(huì)把接收數(shù)據(jù)存儲(chǔ)到全局?jǐn)?shù)組
中。回調(diào)函數(shù) capbuf_hackrf_callback(hackrf_transfer* transfer) 也實(shí)現(xiàn)在 src/capbuf.cpp 中。當(dāng)回調(diào)函數(shù)被驅(qū)動(dòng)自動(dòng)調(diào)用時(shí),驅(qū)動(dòng)本次接收數(shù)據(jù)的長(zhǎng)度會(huì)在 transfer->valid_length 中,而數(shù)據(jù)內(nèi)容會(huì)在 transfer->buffer 中。注意,回調(diào)函數(shù)不是驅(qū)動(dòng)的一部分,而是用戶(hù)自己根據(jù)需要寫(xiě)的用戶(hù)程序,然后通過(guò) hackrf_start_rx() 這個(gè)API告知驅(qū)動(dòng),每當(dāng)驅(qū)動(dòng)收到數(shù)據(jù)時(shí)就會(huì)自動(dòng)調(diào)用回調(diào)函數(shù)(你可以類(lèi)比中斷服務(wù)程序)。
回調(diào)函數(shù)介紹。
以上就是使用C/C++直接操作HackRF的方法。
當(dāng)然不能算是我完全原創(chuàng),只是照著之前的LTE小區(qū)搜索程序作者James Peroulas對(duì)rtl-sdr驅(qū)動(dòng)的調(diào)用方法,依葫蘆畫(huà)瓢做的。
和JamesPeroulas有過(guò)幾次交流,得知他居然還在深圳的中興工作過(guò)很長(zhǎng)時(shí)間,后來(lái)去了硅谷那邊的Intel,現(xiàn)在在那邊專(zhuān)門(mén)做SDR系統(tǒng)的range
network公司工作(據(jù)說(shuō)是做OpenBTS的人創(chuàng)建的,有興趣的可以考證一下)。在無(wú)線(xiàn)通信信號(hào)處理和編程方面都有非常非常豐富的經(jīng)驗(yàn)。通過(guò)學(xué)習(xí)和改進(jìn)他的代碼,真的學(xué)到了很多很多東西。所以,想深挖的,強(qiáng)烈推薦讀代碼并且寫(xiě)代碼做實(shí)驗(yàn)。
源自:FreebuF.COM