您好,登錄后才能下訂單哦!
剛買回來一個智能音箱和博聯,需要給音箱和博聯配置聯網,音箱需要先打開藍牙,然后在手機app中填寫wifi的ssid和密碼,通過藍牙發送到音箱,音箱收到后連接到wifi。
博聯就比較奇怪,進入聯網模式以后,手機app上填寫wifi的ssid和密碼后,直接點配置按鈕后,博聯就連上了。要知道手機并沒有與這個設備建立連接,ssid和密碼不知道怎么就莫名其妙的被發送過去了。
仔細想了一下,應該是通過wifi信號發送的,wifi本質上是一種射頻信號,手機可以發送wifi信號,博聯上也有wifi芯片,理論上可以直接接受到手機的wifi信號而不需要經過路由器。但究竟是怎么發送過去就不得而知。
經過一番搜索后得知,這種技術叫做easyconfig或者smaterconfig、SmartConnect,不同的地方叫法不一樣,最早應該是TI公司提供給博聯的。
原理就是手機發送udp廣播或者組播。博聯的無線網卡支持混雜模式,可以接收到環境中所有的wifi數據包,這樣手機在發送udp報文后就會被博聯捕獲到,但由于和路由器直接通訊的數據是加密的,博聯能捕獲到也并沒有什么卵用,這種的技術關鍵就在于使用長度字段來傳遞ssid和密碼信息。只需要規定編碼方式。
知道原理后,是否可以在音箱上實現呢?
智能音箱是安卓系統,有root權限,并且知道使用的wifi芯片為ap6210(BCM43362)。
但并不知道音箱的wifi芯片是否可以可以接受到環境下所有的wifi數據。到博通(cypress.com)的網站上找了很久,發現有一個monitor模式,使用論壇上下載的wl工具可以開啟monitor模式,打開monitor后,使用tcpdump抓包就會收到很多數據。
所有如果要在音箱上也實現easyconfig就需要開啟monitor模式然后抓包,然后再根據包的長度通過某種規則傳遞ssid和wifi密碼。
開啟monitor模式可以通過執行wl指令(或者直接發送ioctl命令)。抓包可以使用開源的tcpdump,但是通過數據包長度編碼還沒有思路。
再查看easyconfig原理時,發現微信有一個airkiss工具,提供一個.a的靜態庫,開啟monitor模式或混雜模式后,將收到的數據包交給airkiss,airkiss會處理解析數據的工作,airkiss也提供手機端的發送程序。
因此要實現easyconfig只需要實現如下功能就可以:
1.打開/關閉無線網卡monitor模式
2.使用tcpdump(libpcap)抓包
3.講抓包后收到數據后再調用airkiss的函數
4.手機端實現發送ssid和密碼的app,可使用微信airkiss提供的app測試
5.實現應用層控制開啟/關閉,收到密碼后聯網,聯網成功后通知手機端等功能
由于安卓系統中并沒有monitor模式或混雜模式相關的函數,也無法實現抓包的功能,所有不能使用普通的安卓應用來實現這個功能,使用ndk也沒用,主要原因是android應用的進程最高只有system權限,而開啟monitor模式需要和驅動層通訊需要有root權限。
所以需要使用linux下的可執行程序實現,和ndk類似,只是不生成.so,編譯方法也需要做一些修改。另外這個程序還需要與應用層通訊,可以使用socket。
liunx下可執行程序。
眾所周知安卓是基于linux系統實現,但很少有人在安卓系統下開發linux程序,一般編譯系統是會設計到,相關應用也會編譯系統時一起編譯。
開發linux上的程序,需要用linux系統,使用gcc編譯,另外由于音箱是arm架構還需要使用交叉編譯,但使用通用的arm交叉編譯工具編譯的可執行程序并不能再音箱上運行,具體原因未知,查看資料后說要使用從ndk中的分離交叉編譯工具,下載linux下的ndk并分離出交叉編譯工具后可編譯生成在安裝系統上運行的可執行程序。
如果交叉編譯已經如何分離ndk中的編譯工具可自行百度。
app_process
之前寫過在如何在安卓上運行java程序,不是一個apk而是命令行程序,另外還有如果彈出一個非比尋常的窗體。
android下可以通過命令行運行java代碼,就像windows或者linux下使用java命令運行后綴為.jar的java程序,只是android上的命令不是java而是app_process jar包的格式為dex。
app_process是一個命令號工具,作用就是啟動jvm加載并執行dex文件。android系統啟動時根據傳入的參數會啟動zge進程zgz進程負責創建所有的安卓應用的進程。
最近又看了之前的博文,又有個新的發現,那就是這個程序是有root權限的。普通的安卓應用都是由zg fork出來的,最高只有system權限。system權限可以修改系統的設置,但無法與驅動層通訊。如果linux下可執行程序,運行程序時如果是root權限,那么這個進程也是root權限。使用app_process啟動的java程序時也是一樣。
所以也可以java來實現這樣的程序,因為java的語法比c簡單,如果程序比較復雜可以考慮使用java實現,由于一鍵配置的程序并不復雜所以并沒有用java是用c++實現的。
如果開啟無線網卡monitor模式
繼續上面實現easyconfig的步驟,首先需要開啟網卡的monitor模式。
查看資料linux下有相應的工具可以實現,但這些命令在android系統上并不存在,我也嘗試將工具移植到android系統上,但編譯不了,總各種各樣的問題。
因此我需要去找這個monitor模式究竟是在那里控制的。
一開始我認為對wifi數據的處理是在wifi驅動層實現的,音箱的wifi芯片默認情況會接受環境下所有的數據包,驅動程序會根據數據包的目的地址過濾不屬于自己的數據。
于是我就去看無線網卡驅動,根據芯片型號,找到一份liunx的源碼,bcmdhd就是wifi的網卡驅動,重新編譯后盡然可以運行,于是找到接受數據的地方,并添加打印函數,cat /proc/kmsg 可以看到驅動層的日志。 可惜的是,驅動層并沒有所有的wifi數據,只有他自己的數據。
對wifi數據的過濾是在wifi芯片中完成的,通過查看bcm43362的資料得知,wifi芯片中也有處理程序,建立連接數據加密等操作都是由wifi芯片處理的,驅動程序只負責與wifi芯片進行通訊將數據發送到上層。
實際上處理建立連接操作(過濾不屬于自己的數據)是mac層實現,mac層的實現方式有2中,softmac和fullmac,softmac就是我一開始所認為的那樣由驅動程序過濾不屬于自己的數據,驅動層可以捕獲到其他設備發送出去的數據。fullmac是由wifi芯片來實現mac層的功能。而bcm43362使用的是fullmac,不能在驅動層捕獲數據。
bcmdhd驅動會加載一個bin文件,這個bin文件就是wifi芯片里的程序,wifi芯片里有mcu就相當于一個嵌入式系統。我想是不是可以修改這個wifi里bin程序呢,這個bin文件又是從哪里來的。
通過搜索得知bcm有一個用于開發的sdk winced,于是我又去下載這個winced(博通的wifi業務已經買給了cypress要在cypress的網站上下載)。
但實際上這個winced并沒有什么卵用,這個是給嵌入式設備用的,跟wifi芯片里的mcu沒有關系,這個是esp8266不一樣。
幸運的是cypress的論壇上有linux/android下如何使用他的wifi模塊的內容,他們還提供用于調試的命令行工具名字叫wl,把這個wl push到音箱上是可以運行的,使用 "wl monitor on/off",可以開啟/關閉調試模式。
開啟monitor模式后,使用tcpdump抓包后可以看到有一堆數據出現,關閉后就沒有任何數據(音箱沒有聯網),這就表示第一步已經完成,無線網卡可以收到環境中所有的數據包。
那么接下來的問題就是如果抓包
其實抓包比較簡單,tcpdump是有源碼的,tcpdump是基于libpcap的,實際上使用pcap就可以了,下載pcap的源碼,交叉編譯可得到靜態文件libpcap.a,在應用中引入這個靜態文件 。調用libpcap中的函數就可以實現抓包。
理論上libpcap.a放到ndk中,打包的apk中,普通的apk程序也可以實現抓包,但由于權限的問題,libpcap的函數會執行失敗,如果可以讓安卓進程有root那樣就可以執行,前面說過普通的安卓應用最高只有system權限。
前面2步實現之后,后面就很容易,到這里再加入airkiss的靜態庫,將抓到的數據包傳入airkiss,再用airkiss提供的測試工具發送ssid和密碼,使用printf打印就可以看到,手機端發送過來的ssid和密碼。
現在智能音箱算是比較流行,也與一些賣開發板的,我知道的若琪的開發板也是采用博通的wifi芯片,一般給音箱配置聯網都是通過藍牙或者通過建立ap的方式,使用easyconfig的方式會更加方便。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。