伴隨著物聯網的大潮,無數的設備被安裝上WiFi模塊,接入到互聯網上。比如國內的家電巨頭海爾、美的、格力、海信等,已經在2014年推出了一系列帶WiFi的智能家電產品,包括空調、冰箱、洗衣機、熱水器、空氣凈化器、烤箱、電飯煲等等。等待了這么多年,智能家居終于開始成熟了。
相對于藍牙和ZigBee等其他無線網絡技術,WiFi最大的優(yōu)勢是無需依賴手機或者其他中間設備,通過WiFi路由器,就能夠連接到互聯網上,直接與云服務器連接或者進行遠程控制。而且目前的WiFi模塊功耗和價格已經下降得很多,很容易被嵌入到各種物聯網設備中,無需過多的擔心成本和功耗。
但是,將WiFi模塊用在物聯網設備中,也有一個麻煩,就是WiFi的初始設置。要讓這些設備連接上WiFi路由器,需要首先讓它們知道WiFi路由器的名稱(SSID)和密碼。但是不同于傳統的PC或者手機,大多數物聯網設備沒有按鍵或者觸摸屏這樣的輸入接口,因此需要其他的方法將路由器的SSID和密碼告知物聯網設備。因為這些物聯網設備大多有與之配套的手機APP,問題也就變成了如何將SSID和密碼從手機APP傳送給這些設備。從目前已知的方法來看,主要有以下兩種。
第一種是基于WiFi模塊的SoftAP模式。在WiFi協議中,設備可以工作在AP模式,也可以工作在Station模式。比如WiFi路由器就是典型的AP,而手機和PC就是典型的Station。物聯網設備在絕大多數情況下都是工作Station模式,但是為了支持初始配置,許多WiFi模塊支持AP模式,當然,不是全功能的AP模式,只是有限的功能,所以稱之為SoftAP。利用SoftAP進行WiFi初始配置的流程如下:
- 設備啟動時,如果發(fā)現WiFi沒有配置,則啟動SoftAP模式,自己變成一個WiFi熱點。
- 手機連接上SoftAP,打開APP,輸入WiFi路由器的SSID和密碼,傳送給SoftAP。
- SoftAP收到SSID和密碼后,切換到Station模式,連接指定的WiFi路由器,同時將SSID和密碼保存在本地。
- 下次設備啟動時,因為WiFi已經配置好了,設備之間進入Station模式,連接指定的WiFi路由器。
使用這種方式的智能設備很多,比如小K智能開關,第一次啟動后會產生一個OK_SP3的熱點,完成配置后就沒有了。
在具體APP的實現中,需要考慮Android和iOS的不同。比如WiFi路由器SSID一般是不用用戶輸入的,APP會提供一個周圍熱點的SSID列表,用戶選擇即可。但是iOS是不支持在APP中做WiFi掃描的,因此需要設備端先掃描一個SSID列表發(fā)給手機,然后用戶在APP里面選擇。另外iOS是不支持在APP中切換WiFi連接的,因此用戶需要先手工連接到SoftAP,完成配置后,再切換回來。而Android中是可以的。Android的APP中可以先自動連接SoftAP,配置完成后,再自動切換到原來的AP,而用戶可能感覺不到這個過程,從而改善了用戶體驗。
第二種是基于WiFi模塊的Sniffer模式。基于SoftAP的方式可以保證配置成功,但是用戶體驗不太好。因為它要求手機先連接到SoftAP上,無論是手工的(iOS)還是自動的(Android),配置完成后再切換回來。在此期間,手機因為離開了原先的WiFi路由器,因此失去了與互聯網的連接。這個是許多用戶感覺不爽的地方。而Sniffer模式不同。使用這種配置方式,用戶手機不需要斷開與當前WiFi路由器的連接,從而可以保持與互聯網的連接。這也是這種方式經常被稱為智能配置的原因。這種方式要求WiFi模塊支持Sniffer模式,也就是雜收模式(Promiscuous)。對無線通信熟悉的人都知道,無線通信本質上是一種廣播。理論上,一個WiFi設備可以收到空氣中的所有包,只不過正常工作時,底層將不需要的包過濾掉了。打開雜收模式,就是將底層收到的所有包,直接提交給上層處理。這樣,雖然WiFi模塊與路由器和手機之間沒有連接,但是它可以監(jiān)聽手機發(fā)出來的包,而手機APP也可以在這些包里面隱含配置信息,從而達到將配置信息傳送給WiFi模塊的目的。
手機發(fā)包時,是連接在WiFi路由器上的。如果WiFi路由器是加密的,比如WEP和WPA,那么WiFi模塊收到的包必然也是加密的,模塊無法直接獲得包里面的信息,那么手機與模塊之間怎么傳遞信息呢?這就要深入理解一下WiFi幀的結構。
![物聯網設備的WiFi快速配置](http://a.jx263.net/images/3f197dfba6754d2eab1f6169fafa92e7.png)
?圖1,通用的WiFi幀結構
從上圖可以看出,WiFi幀包括幀頭,幀體和校驗和三部分。其中幀頭是不加密的,幀體部分根據幀類型的不同,有加密的,也有不加密的,比如管理幀ProbeRequest中的幀體部分就是不加密的。
另外,WiFi幀的長度也是很有用的信息。不管幀怎樣加密,對于一定的加密方式(WEP,CCMP,TKIP),加密后的幀長度總是原始數據長度加上一個固定的偏移。這樣手機APP就可以通過控制數據包長度的方式來傳遞有用信息。
總結起來,目前的智能配置一般有下面三種方式:
1, 第一種方式通過WiFi幀的長度傳遞信息。比如要傳遞一個字符串”abc”,三個字符a、b、c對應的ASCII分別是97、98、99。手機APP可以生成數據包,控制其長度為97、98、99加上固定的偏移量。這樣WiFi模塊捕獲到包之后,就可以根據包長度提取有用的信息了。目前微信的airkiss就是使用這樣的方式。京東的通用智能家居APP也是使用的這樣的方式。
2, 第二種方式通過WiFi幀的MAC地址傳遞信息。WiFi幀頭雖然是不加密的,但是它的內容都是底層WiFi驅動填寫的,而手機APP處于應用層,是無法控制其中的內容的,但是有一個例外。就是手機APP發(fā)送UDP組播包時,組播包的目的IP地址的后23位會映射到WiFi幀目的MAC地址后23位,這樣手機APP可以通過修改UDP包的組播地址,達到傳遞信息的目的。比如傳遞“abc”,可以發(fā)送3個組播包,目的地址分別是229.0.0.97,239.0.0.98,239.0.0.99。這樣WiFi模塊捕獲到包之后,就可以從MAC地址中提取到有用的信息了。比如海爾的U+智能設備就是采用這樣的方式。
3, 第三種方式是通過管理幀的幀體部分傳遞信息,一般使用ProbeRequest,因為它是手機APP可以在應用層控制的。手機APP可以在應用層構造一個目標SSID,啟動掃描。比如傳遞”abc”,可以讓手機掃描名為“abc”的目標SSID。WiFi模塊捕捉到這樣的掃描幀之后,就可以從中提取出有用的信息了。
當然,上面說的只是原理,真正實現的時候,有許多細節(jié)需要考慮。比如WiFi模塊并不知道手機在哪個WiFi信道上發(fā)包,要捕捉到手機發(fā)出的包,首先要鎖定信道。這就需要一些技巧。另外,安全性也是一個問題。因為手機要把WiFi路由器的密碼傳送給WiFi模塊,如果是明文的,很容易就被截取了,從而給WiFi網絡帶來極大的安全隱患,這就需要對數據做擾碼,這就需要八仙過海、各顯神通了。
另外,SoftAP和智能配置也不是完全互斥的。智能配置雖然方便,但是在WiFi環(huán)境很復雜的時候,還是有一定的失敗概率,而SoftAP是可以保證成功的。所以很多智能設備都是先用智能方式配置,如果失敗就切換到SoftAP,比如海爾的U+智能家居設備。