2017年10月30日 星期一

WiFi direct—深入理解Wi-Fi P2P

原文網址:https://read01.com/dx0yPo.html



本章主要內容:
  • 介紹Wi-Fi P2P相關知識;
  • 介紹AndroidWifiP2pServicewpa_supplicant的相關代碼。

7.1 概述
承接第6章介紹的WSC,本章將繼續介紹Wi-Fi AllianceWi-Fi聯盟)推出的另外一項重要技術規範Wi-Fi P2P。該規範的商品名為Wi-Fi Direct,它支持多個Wi-Fi設備在沒有AP的情況下相互連接。
Android平台的Wi-Fi相關模塊中,P2P的功能點主要集中在:
  • Android Framework中的WifiP2pService,其功能和WifiService類似,用於處理和P2P相關的工作。
  • wpa_supplicant中的P2P模塊。
WSC一樣,本章的分析擬採用如下方法:
  • 首先將介紹P2P所涉及的基礎知識。
  • 然後再分析和P2P相關的模塊,包括SettingsWifiP2pService以及WPAS
下面,先來認識一下P2P

7.2 P2P基礎知識介紹 WFA定義的P2P協議文檔全名為「Wi-Fi Peer-to-PeerP2PTechnical Specification」,目前的版本為1.1,全長160頁。P2P技術使得多個Wi-Fi設備在沒有AP的情況下也能構成一個網絡(P2P Network,也被稱之為P2P Group)並相互通信。 
Wi-Fi P2P技術是Wi-Fi Display(也稱之為Miracast,詳情請參考作者的一篇博文)的基礎。在Miracast應用場景中,一台支持P2P的智慧型手機可直接連接上一台支持P2P的智能電視,智慧型手機隨後將自己的螢幕,或者媒體資源傳送給電視機去顯示或播放。顯然,藉助P2P技術,Wi-Fi設備之間的直接相連將極大拓展Wi-Fi技術的使用場景。
注意:根據筆者自己的判斷,隨著支持越來越多的設備支持P2PMiracast,智能終端設備之間的多屏共享和互動功能將很快得以實現。另外,恰逢本章撰寫之際,Google發布了Android 4.3。在這次發布盛會上,Google推出了ChromeCast設備。目前,ChromeCast的技術實現細節還不清楚,據說有可能是Google自己定義的Google cast協議(可參考developers.google.com/cast)。
下面先簡單介紹一下P2P的架構。

7.2.1 P2P架構介紹[1]

P2P架構中定義了三個組件,筆者將其稱之為一個設備,兩種角色。這三個組件分別是:
  • P2P Device:它是P2P架構中角色的實體,讀者可把它當做一個Wi-Fi設備。
  • P2P Group OwnerGroup Owner(簡稱GO)是一種角色,其作用類似於Infrastructure BSS中的AP
  • P2P Client:另外一種角色,其作用類似於Infrastructure BSS中的STA
相信對本書的讀者對上面這三個組件的概念並不陌生。實際上,P2P技術模仿了Infrastructure BSS網絡結構:
  • 在組建P2P Group(即P2P Network)之前,智能終端都是一個一個的P2P Device
  • 當這些P2P Device設備之間完成P2P協商後,那麼其中將有一個並且只能有一個[1]Device來扮演GO的角色(即充當AP),而其他Device來扮演Client的角色。
最終構成的這個P2P Group組織結構如圖7-1所示:

7-1 P2P Group示意圖
7-1展示了一個典型P2P Group的構成,其中:
  • 和一個Infrastructure BSS類似,一個P2P Group中只能有一個GO。一個GO可以支持1個或多個(即圖中的1:nClients連接。
  • 由於GO的功能類似於AP,所以周圍那些不支持P2P功能的STA也能發現並關聯到GO。這些STA被稱之為Legacy Clients
注意:「不支持P2P功能」更準確的定義是指不能處理P2P協議。在P2P網絡中,GO等同於AP,所以Legacy Clients也能搜索到GO並關聯上它。不過,由於Legacy Clients不能處理P2P協議,所以P2P一些特有功能在這些Legacy Clients中無法實現。
通過上述介紹讀者會進一步發現P2P GroupInfrastructure BSS的相似性:
  • P2P Device在構建P2P Group時,它將首先通過WSC來獲取安全信息。
  • 然後,Client將利用協商好的安全設置信息去關聯[2]GO(即P2P Group中的AP)。
這部分內容和Infrastructure BSSSTA利用WSC先協商安全信息然後再關聯至AP的流程完全一樣。正是這種相似性,使得P2P能充分利用現有的一些技術規範。圖7-2所示為P2P及其依賴的技術項:

 


7-2 P2P及其依賴的技術項
  • 為了保證一定的傳輸速率,P2P要求P2P Device必須支持802.11g及以上的規範。其中,安全部分必須支持WPA2。由於P2P技術一個主要的應用場景就是設備之間共享媒體數據(例如前面提到的Miracast應用場景),所以P2P Device還必須支持WMMWi-Fi Multimedia的縮寫,它是一種源自802.11eQoS服務,主要針對實時視音頻數據的傳輸)。
  • P2P Client關聯到GO之前,需要先通過WSC來協商安全信息,所以WSC也是P2P的依賴技術項。
  • 在上述技術基礎上,P2P規範定義了一些特有的技術項,圖7-2列出了其中三種必須實現的技術項,它們分別是P2P DiscoveryP2P Group Operation以及P2P PowerManagerment。除了這三個必選技術項外,P2P規範還定義了一個可選技術項,名為Managed P2P Device Operation(該技術項定義了如何在企業級環境中由對應的IT部門來統一配置和管理P2P設備)。
在如圖7-2所示的技術項中,P2P DiscoveryP2P所特有的,也是其核心。本章將主要圍繞它進行介紹。首先來看P2P Discovery
提示:
1P2P Group Operation講得是GO如何管理一個Group,也就是GO的工作職責。這部分內容請讀者自行學習參考資料[2]一節。
2P2P PowerManagementP2P設備的電源管理有關,用於節省不必要的電力損耗。由於篇幅關係,本章不擬討論它。請感興趣的讀者自行學習參考資料[3]

7.2.2 P2P Discovery介紹[4]

P2P Discovery的目的很簡單,就是使得多個P2P Device能夠互相發現並構建一個Group。根據規範,它包括四個主要技術子項:
  • Device Discovery:用於P2P設備搜索周圍其他支持P2P的設備。
  • Service Discovery:該Device Discovery基礎上,P2P還支持搜索指定的服務。這部分功能屬於可選項,筆者覺得它和第二章2.2.5.1Apple Bonjour技術介紹」中提到的Bonjour類似。
  • Group Formation:用於決定兩個P2P Device誰來扮演GO,誰來扮演Client
  • P2P Invitation:用於激活一個Persistent Group(見下文解釋),或者用於邀請一個Client加入一個當前已存在的Group
提示:GroupPersistent(永久性)GroupTemporary(臨時性)Group兩種。我們舉二個簡單例子來說明二者的區別:
Temporary Group:當你有份文件要傳給一個同事時,雙方打開手機的Wi-Fi P2P功能,建立一個Group,然後傳輸文件,最後關閉Wi-Fi P2P。在這個過程中,GOClient的角色分配由Group Formation來決定,這一次的GO可能是你的設備,下一次則可能是其他人的設備。對於這種Group,在建立Group過程中所涉及的安全配置信息以及和Group相關的信息(以後我們會見到它)都是臨時的,即下一次再組建Group時,這些安全配置信息都將發生變化。
Persistent Group:在這種Group中,GO由指定設備來扮演,而且安全配置信息及Group相關信息一旦生成,後續就不會再發生變化(除非用戶重新設置)。Persistent Group中的GO多見於固定用途的設備,例如印表機等。如此,除了第一次通過P2P連接到印表機時相對麻煩一點(需要利用WSC協商安全配置信息)外,後續使用的話,由於P2P設備將保存這些安全信息,所以下一次再使用印表機時就能利用這些信息直接和印表機進行關聯了。
由於篇幅關係,本章將僅介紹上述四個知識點中最為基礎的Device DiscoveryGroup Formation,而Service DiscoveryP2P Invitation的內容請讀者學習完本章後再仔細研讀P2P規範。

1. P2P Device Discovery介紹

P2P Device Discovery雖然也是利用802.11中的Probe RequestProbe Response幀來搜索周圍的P2P設備,但其步驟卻比Infrastructure BSS中的無線網絡搜索要複雜。舉一個簡單的例子,一個P2P Device除了自己要發送Probe Request幀外,還得接收來自其他設備的Probe Request幀並回復Probe Response幀。而在Infrastructure BSS中,只有AP會發送Probe Response幀。
為了加快搜索速度,P2PDevice Discovery定義了兩個狀態和兩個階段。
1Device Discovery工作流程介紹 P2P Device Discovery的工作流程包含兩個狀態和兩個階段。先來看兩個狀態,它們分別是:
  • Search State:在該狀態中,P2P Device將在2.4GHz1,6,11頻段上分別發送Probe Request幀。這幾個頻段被稱為Social Channels。為了區別非P2PProbe Request幀,P2P Device Discovery要求必須在Probe Request幀中包含P2P IE
  • Listen State:在該狀態下,P2P Device將隨機選擇在1,6,11頻段中的一個頻段(被選中的頻段被稱為Listen Channel)監聽Probe Request幀並回復Probe Response幀。值得指出的是,Listen Channel一旦選擇好後,在整個P2P Discovery階段就不能更改。另外,在這個階段中,P2P Device只處理那些包含了P2P IE信息的Probe Request幀。
再來看兩個階段,它們分別是:
Scan Phase:掃描階段。這一階段和前面章節介紹的無線網絡掃描一樣,P2P Device會在各個頻段上發送Probe Request幀(主動掃描)。P2P Device在這一階段中不會處理來自其他設備的Probe Request幀。這一階段過後,P2P Device將進入下一個階段,即Find Phase
Find Phase:雖然從中文翻譯來看,ScanFind意思比較接近,但P2PFind Phase卻和Scan Phase大不相同。在這一階段中,P2P Device將在Search StateListen State之間來回切換。Search State中,P2P Device將發送Probe Request幀,而Listen State中,它將接收其他設備的Probe Request幀並回復Probe Response幀。
7-3所示為P2P Device Discovery的流程示意圖。

7-3 P2P Device Discovery流程示意圖
7-3所示為兩個P2P DeviceDiscovery流程,其中:
Discovery啟動後,Device首先進入Scan Phase。在這一階段,P2P設備在其支持的所有頻段上都會發送Probe Request幀。
Scan Phase完成後,DeviceFind Phase。在這一階段中,Device將在ListenSearch State中切換。根據前面的介紹,每一個設備的Listen ChannelDiscovery開始前就已確定。例如,圖7-3Device 1Listen Channel1,而Device 2Listen Channel6
Find Phase中,P2P規範對Device處於Listen State的時間也有所規定,其時間是100TU的整數倍,倍數值是一個隨機數,位於minDiscoverableIntervalmaxDiscoverableInterval之間。這兩個值默認為13,而廠商可以修改。選擇隨機倍數的原因是為了防止兩個Device進入所謂的Lock-Step怪圈,即兩個Device同時進入Listen State,等待相同的時間後又同時進入Search State。如此,雙方都無法處理對方的Probe Request信息(Search State中,Device只發送Probe Request)。圖7-3中,Device 1第一次在Listen State中待了2100TU,而第二次在Listen State中待了1100TU
Device處於Find Phase中的Search State時,它將在1,6,11頻段上發送Probe Request幀。注意,只有當兩個設備處於同一頻段時,一方發送的幀才能被對方接收到。
提示:P2P規範對兩個狀態及兩個階段的描述非常細緻,甚至於對每個狀態能幹什麼和不能幹什麼都有詳細說明。不過,從如何快速掌握P2P框架的角度來看,筆者覺得這些內容過於囉嗦。
了解了Device Discovery的大體工作流程後,下面我們將通過實例來看看P2P使用到的Probe RequestProbe Response幀。
[2]注意,此處的關聯指得是RSNA,其工作流程包括包括4-WayHandshake
略略略略略略略略==========

7.4 wpa_supplicant中的P2P介紹 在第55.2.3中「WifiNative介紹」一節中曾介紹了wpa_supplicant的啟動,在那一節中,讀者會發現wpa_supplicant進程由WifiStateMachine啟動。在Android官方代碼中,雖然Java層有WifiServiceWifiP2pService兩個幾乎完全不同的Wifi服務,但二者都只和Native層的唯一一個wpa_supplicant進程交互。簡單點說,Android原生代碼中,一個wpa_supplicant進程將同時支持WifiServiceWifiP2pService
上述這種設計方法使得wpa_supplicant負擔較重,所以,一些手機廠商會為WifiServiceWifiP2pService各創建一個wpa_supplicant進程,使得它們能各司其職而互不干擾。以筆者的Galaxy Note2為例,它的,WifiService將和wpa_supplicant進程交互,而WifiP2pService將和一個名為p2p_supplicant(經過筆者測試,p2p_supplicant實際上就是wpa_supplicant,只不過名字不同罷了)的進程交互。
7-26所示為Galaxy Note2 init配置文件中關於p2p_supplicant服務的示意圖:

7-26 Galaxy Note2p2p_supplicant服務配置項
由圖7-26可知:
  • init配置文件定義了一個名為p2p_supplicant的服務,該服務啟動的進程為p2p_supplicant。根據筆者的測試,p2p_supplicant其實就是wpa_supplicant,只不過換了一個名字而已。
  • p2p_supplicant使用的配置文件名為/data/misc/wifi/p2p_supplicant.conf文件,其內容如圖7-27所示。

7-27 p2p_supplicant.conf內容
提示:關於init配置文件中wpa_supplicant服務的說明,請讀者參考第44.3wpa_supplicant初始化流程分析」一節。
7-27中,p2p_supplicant對於的ctrl_iface路徑為/data/misc/wifi/sockets。所以,如果要使用wpa_clip2p_supplicant交互的話,必須指定正確的ctrl_iface路徑。圖7-28所示為筆者用wpa_cli測試p2p_supplicant時的示例截圖:

7-28 wpa_clip2p_supplicant交互
下面來分析wpa_supplicant中和P2P相關的代碼。
注意:以Galaxy Note2為例,p2p_supplicant就是wpa_supplicant,只是編譯時打開了P2P相關的選項。下面的分析將以wpa_supplicant中和P2P相關的代碼及工作流程為主。

7.4.1 P2P模塊初始化

首先來看WPASP2P相關模塊的初始化。該初始化工作我們在第44.3.4中「wpa_supplicant_init_iface分析之五」曾提到過,其對應的函數wpas_p2p_init,馬上來看它
[p2p_supplicant.c::wpas_p2p_init]
int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
{
structp2p_configp2p; //p2p變量指向一個p2p_config對象,代表P2P模塊的配置信息
unsigned int r; int i;
//①WPA_DRIVER_FLAGS_P2P_CAPABLE:代表Wifi驅動對P2P支持的能力,詳情見下文解釋
if (!(wpa_s->drv_flags&WPA_DRIVER_FLAGS_P2P_CAPABLE)) return 0;
if (global->p2p) return 0;
//如果wifi driver能完成P2P功能,就不用勞駕WPAS了
if (wpa_s->drv_flags &WPA_DRIVER_FLAGS_P2P_MGMT) {......}
//②初始化並設置p2p_config對象
os_memset(&p2p, 0, sizeof(p2p));
p2p.msg_ctx= wpa_s; p2p.cb_ctx= wpa_s;
p2p.p2p_scan=wpas_p2p_scan; //P2P對應的掃描函數
.......//設置一些回調函數
p2p.get_noa = wpas_get_noa; p2p.go_connected = wpas_go_connected;
//設置P2P Device address。
os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
os_memcpy(p2p.dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN);
//設置P2P模塊配置信息,包括device name,model name,uuid等
p2p.dev_name = wpa_s->conf->device_name;
p2p.manufacturer = wpa_s->conf->manufacturer;
p2p.model_name = wpa_s->conf->model_name;
p2p.model_number = wpa_s->conf->model_number;
p2p.serial_number = wpa_s->conf->serial_number;
if (wpa_s->wps) {
os_memcpy(p2p.uuid, wpa_s->wps->uuid, 16);
p2p.config_methods = wpa_s->wps->config_methods;
}
//設置Operation Channel信息和listen channel信息
if (wpa_s->conf->p2p_listen_reg_class &&
wpa_s->conf->p2p_listen_channel) {
p2p.reg_class = wpa_s->conf->p2p_listen_reg_class;
p2p.channel = wpa_s->conf->p2p_listen_channel;
} else {......//設置默認值}
......
//設置國家碼
if (wpa_s->conf->country[0] && wpa_s->conf->country[1]) {
os_memcpy(p2p.country, wpa_s->conf->country, 2);
p2p.country[2] = 0x04;
} else//配置文件中沒有設置國家,所以取值為"XX\x04"
os_memcpy(p2p.country, "XX\x04", 3);//讀者可回顧圖7-7
//判斷wifi 驅動是否支持配置文件中設置的operationg channel和listen channel
if (wpas_p2p_setup_channels(wpa_s, &p2p.channels)) {......}
os_memcpy(p2p.pri_dev_type, wpa_s->conf->device_type,WPS_DEV_TYPE_LEN);
p2p.num_sec_dev_types = wpa_s->conf->num_sec_device_types;
os_memcpy(p2p.sec_dev_type, wpa_s->conf->sec_device_type,
p2p.num_sec_dev_types * WPS_DEV_TYPE_LEN);
//是否支持concurrent operation
p2p.concurrent_operations = !!(wpa_s->drv_flags&WPA_DRIVER_FLAGS_P2P_CONCURRENT);
p2p.max_peers = 100;//最多能保存100個對端P2P Device信息
//配置文件中沒有設置p2p_ssid_postfix,但P2pStateMachine在initializeP2pSettings函數中
//將設置P2P SSID後綴。以筆者的Galaxy Note2為例,其P2P SSID後綴為「Android_4aa9」
if (wpa_s->conf->p2p_ssid_postfix) {......}
p2p.p2p_intra_bss = wpa_s->conf->p2p_intra_bss;
//③global->p2p指向一個p2p_data結構體,它是WPAS中P2P模塊的代表
global->p2p =p2p_init(&p2p);
......
for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) {//拷貝vendor廠商特定的WSC屬性信息
if (wpa_s->conf->wps_vendor_ext[i] == NULL) continue;
p2p_add_wps_vendor_extension(global->p2p, wpa_s->conf->wps_vendor_ext[i]);
}
return 0;
}
由上述代碼可知,wpas_p2p_init的工作非常簡單,主要內容包括:
  • 初始化一個p2p_config對象,然後根據p2p_supplicant.conf文件的信息來設置其中的內容,同時還需要為P2P模塊設置一些回調函數。
  • 調用p2p_init函數以初始化P2P模塊。
下面來介紹上述代碼中涉及到的一些知識。

1. Driver Flags和重要數據結構介紹

先來看上述代碼中提到的drv_flags變量。WPAS中,Wifi驅動對P2P功能的支持情況就是由它來表達的。筆者的Galaxy Note2中該變量取值為0x2EAC0,其表達的含義如下:
[-->driver.h]
#define WPA_DRIVER_FLAGS_AP 0x00000040 //Wifi driver支持AP。它使得P2P設備能扮演GO
/*
標誌標明association成功後,kernel driver需要設置WEP key
這個標誌出現的原因是由於kernel API發生了變動,使得只能在關聯成功後才能設置key
*/
#define WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC_DONE 0x00000080
#define WPA_DRIVER_FLAGS_P2P_CONCURRENT 0x00000200 //Wifi驅動支持STA和P2P的並發運行
#define WPA_DRIVER_FLAGS_P2P_CAPABLE 0x00000800 //Wifi驅動支持P2P
/*
7.2.2.1.2「Probe Request幀設置」一節曾提到過說P2P包含Device Address和Interface Address
兩種類型的地址。在實際實現過程中,這兩個地址分別代表兩個virtual interface。顯然,P2P中第一個和一直
存在的是擁有Device Address的vitural interface。下面這個標誌表示該virtual interface可以參與
P2P管理(除P2P Group Operation之外的工作)工作以及非P2P相關的工作(例如利用這個virtual
interface 加入到一個BSS)
*/
#define WPA_DRIVER_FLAGS_P2P_MGMT_AND_NON_P2P 0x00002000
/*
該標誌主要針對associate操作。當關聯操作失敗後,如果driver支持該選項,則表明driver能處理失敗之
後的各種收尾工作(Key、timeout等工作)。否則,WPAS需要自己處理這些事情
*/
#define WPA_DRIVER_FLAGS_SANE_ERROR_CODES 0x00004000
//下面這個標誌和off channel機制有關。讀者可參考第4章4.3.4中「capability介紹」一節。當802.11
//MAC幀通過off channel發送的話,下面這個標誌表示driver會反饋一個發送情況(TX Report)消息給WPAS
#define WPA_DRIVER_FLAGS_OFFCHANNEL_TX 0x00008000
//下面這兩個標誌表示kernel中的driver是否能反饋Deauthentication/Disassociation幀
//發送情況(TX Report)
#define WPA_DRIVER_FLAGS_DEAUTH_TX_STATUS 0x00020000
下面來看wpas_p2p_init中出現的幾個重要數據結構,首先是p2p_configp2p_data,它們的成員如圖7-29所示:

7-29 p2p_configp2p_data結構示意圖
7-29展示了p2p_configp2p_data兩個數據結構中一些重要的成員。其中:
  • p2p_config定義了20個回調函數。這些回調函數定義了P2P模塊和外界交互的接口。在wpas_p2p_init中,這些回調函數均指向p2p_supplicant.c中對應的函數,例如p2p_scan指向wpas_p2p_scandev_lost指向wpas_dev_lost。另外,由於回調函數的參數比較複雜,所以圖中均省略了參數信息。
  • p2p_data指向一個p2p_config對象。
下面來看另外幾個重要數據結構的內容,如圖7-30所示:

7-30 p2p_device及其他數據結構示意圖
7-30展示了五種數據結構,其中:
  • p2p_device代表一個P2P設備。其中一些諸如設備名,Device CapabilityBitmap等信息保存在一個類型為p2p_peer_info的對象中。
  • p2p_group代表一個P2P Group的信息,其內部包含一個p2p_group_config對象和一個p2p_group_member鍊表。p2p_group_config表示該Group的配置信息,p2p_group_member代表Group MemberP2P Client的信息。
提示:WPAS中定義了非常多的數據結構類型,這極大增加了初學者的學習難度。根據筆者自己的經驗,建議讀者在學習過程中先簡單了解這些數據結構的名字及作用,然後在具體代碼分析時再結合代碼邏輯來了解這些數據結構及其內部各個成員變量的具體作用。
7.5 本章總結和參考資料說明

7.5.1 本章總結

本章對Wi-Fi P2P進行了詳細介紹,主要內容包括:
  • P2P理論知識。從完整性來說,本章介紹的內容只是P2P規範中最基礎的部分。但對於初學者而言,這部分的難度也不算小。就筆者自己的學習經歷而言,這部分內容需要反覆琢磨和研究,有時候還需要結合代碼分析才能真正掌握其精髓。
  • 在學習完P2P理論知識後,我們對WifiP2pSettings以及WifiP2pService進行了介紹。這部分內容比較簡單,讀者可輕鬆掌握相關知識。
  • 最後,我們對WPAS中的P2P模塊及運行機制進行了介紹。就所涉及到的知識而言,這些內容並不複雜,但由於P2P以及和wifi driver在具體實現時有諸多考慮(例如off channel的情況,TX Report的處理),所以其工作流程反倒顯得比較繁瑣。
最後,希望讀者在本章的基礎上,完成下列的一些任務:
  • 通讀P2P規範,了解Group OperationInvitationDevice Discoverability以及P2P Power Management相關知識。
  • 繼續研究wpas_start_wps_go代碼,掌握WPASWSC Registrar以及AP的工作流程。

7.5.2 參考資料說明

P2P基礎知識介紹

本章參考資料主要是Wifi P2P規範1.1版,讀者可從上下載協議全文。

P2P架構介紹

[1] WiFi P2P2節「Architectural Overview
[2] WiFi P2P3.2節「P2P Group Operation
[3] WiFi P2P3.3節「P2P Power Management

P2P Device DiscoveryGroup Formation

[4] WiFi P2P3.1節「P2P Discovery
[5] Part11:Wireless LAN Medium Access Control(MAC) and Phsyical Layer(PHY) Specifications附錄JCountry information element and regulatory classes
該文檔下載地址為。附錄J詳細描述了國家碼和管制信息方面的內容
[6] WiFi P2P4.2節「Management Frames
[7] 802.11-20128.4.1.11節「Action Field
該節介紹了ActionCategory欄位的取值情況
[8] WiFi P2P4.1節「P2P Information Elements
[9] WiFi P2P附錄AP2P State Machine

fatal: empty ident name (for ) not allowed

Issue
-----
    yulin@AIG:/work/yulin/w9250$ repo init -u git@172.16.201.30:mdm9650/manifests.git --config-name -b master -m UMC-9250W.xml
   
    Traceback (most recent call last):
      File "/work/yulin/w9250/.repo/repo/main.py", line 531, in
        _Main(sys.argv[1:])
      File "/work/yulin/w9250/.repo/repo/main.py", line 507, in _Main
        result = repo._Run(argv) or 0
      File "/work/yulin/w9250/.repo/repo/main.py", line 180, in _Run
        result = cmd.Execute(copts, cargs)
      File "/work/yulin/w9250/.repo/repo/subcmds/init.py", line 404, in Execute
        self._ConfigureUser()
      File "/work/yulin/w9250/.repo/repo/subcmds/init.py", line 298, in _ConfigureUser
        name  = self._Prompt('Your Name', mp.UserName)
      File "/work/yulin/w9250/.repo/repo/project.py", line 784, in UserName
        self._LoadUserIdentity()
      File "/work/yulin/w9250/.repo/repo/project.py", line 797, in _LoadUserIdentity
        u = self.bare_git.var('GIT_COMMITTER_IDENT')
      File "/work/yulin/w9250/.repo/repo/project.py", line 2747, in runner
        (self._project.name, name, p.stderr))
    error.GitError: manifests var:
    *** Please tell me who you are.
   
    Run
   
      git config --global user.email "you@example.com"
      git config --global user.name "Your Name"
   
    to set your account's default identity.
    Omit --global to set the identity only in this repository.
   
    fatal: empty ident name (for ) not allowed

Solution
--------
    Do below before 'repo init ...'
        git config --global user.email "you@example.com"
        git config --global user.name "Your Name"

2017年10月27日 星期五

Wi-Fi無線網路的認證與加密方式簡介

原文 http://mic1491.pixnet.net/blog/post/30237227-wi-fi%E7%84%A1%E7%B7%9A%E7%B6%B2%E8%B7%AF%E7%9A%84%E8%AA%8D%E8%AD%89%E8%88%87%E5%8A%A0%E5%AF%86%E6%96%B9%E5%BC%8F%E7%B0%A1%E4%BB%8B

Wi-Fi無線網路的認證與加密方式簡介


Wi-Fi (IEEE 802.11b, IEEE 802.11g, IEEE 802.11n)無線網路的認證與加密方式,有Open System, WEP, WPA, WPA2, MAC ACL, Web Redirection幾種。
所謂「認證(Authentication)」,就是用來確定無線上網者的身分,身分可以是使用者的帳號/密碼、數位憑證(Digital Certificate)、或是無線網卡的MAC (Media Access Control)位址,MAC位址也可稱為實體位址(Physical Address)。在Windows中,打開「命令提示字元」,輸入ipconfig /all,再按下Enter,就可以看到網卡的Physical Address,例如00-0C-6E-10-AD-7F。
所謂「加密(Encryption)」,就是網路封包(Packet)資料在空氣中無線傳輸時,被加密鎖碼(Encrypted)保護,因此就算有第三者截聽到封包,也無法解譯出裡面的資料內容。
無線網路啟用認証,以確定連上無線基地台的人,都是合法的無線網路使用者,來防止無線網路遭人盜用。無線網路啟用加密,以防止在空氣中傳輸的資料,被人竊聽。
以下進一步解釋無線網路的幾種認証與加密方式:
Open System: 完全不認證也不加密,任何人都可以連到無線基地台使用網路。採取這種方式,大多對無線網路安全性的問題不了解、不在意,或是不知道如何設定無線基地台與筆記型電腦。
WEP (Wired Equivalent Privacy): 無線網路基地台設定有 WEP金鑰(Key),筆記型電腦也必須設定相同的WEP Key,才可以連上無線基地台。WEP可以用在認證或是加密,例如認證使用Open System,而加密使用WEP;或者認証與加密都使用WEP。WEP加密現在已經有軟體可以輕易破解,因此不是很安全。
WPA (Wi-Fi Protected Access): 由Wi-Fi Alliance (http://www.wi-fi.com/)所提出的無線安全標準,有分成家用的WPA-PSK (Pre-Shared Key)與企業用的IEEE 802.1x Port-Based Network Access Control版本。WPA-PSK的設定方式與WEP相同,無線基地台與筆記型電腦必須設定相同的Key,電腦才可以連入基地台。因為WPA-PSK運用了TKIP (Temporal Key Integrity Protocol)技術,因此比WEP難被破解而更加安全。採用IEEE 802.1x則需要有另一台儲存無線使用者帳戶資料的RADIUS (Remote Authentication Dial-In User Service)伺服器,當筆記型電腦連入無線基地台時,無線基地台會要求使用者輸入帳號密碼、或是自動向筆記型電腦索取儲存在電腦硬碟的使用者數位憑證,然後向RADIUS伺服器確認使用者的身分。而用來加密無線封包的加密金鑰(Key),也是在認証的過程中自動產生,並且每一次連線所產生的金鑰都不同(專業術語稱為Session Key),因此非常難被破解。IEEE 802.1x的設定非常複雜,因此只適用於對無線安全要求很高的企業。
WPA2: WPA2顧名思義就是WPA的加強版,也就是IEEE 802.11i無線網路標準。同樣有家用的PSK版本與企業的IEEE 802.1x版本。WPA2與WPA的差別在於,它使用更安全的加密技術AES (Advanced Encryption Standard),因此比WPA更難被破解、更安全。
MAC ACL (Access Control List): MAC ACL只能用於認証而不能用於加密。在無線基地台輸入允許被連入的無線網卡MAC位址,不在此清單的無線網卡無法連入無線基地台。
Web Redirection: 這種方式是WISP (Wireless Internet Service Provider,例如統一安源WiFly)最常用的方式。無線基地台設定成Open System,但是另外在後台利用存取控制閘道器(Access Control Gateway, ACG),攔截筆記型電腦發出的Web封包(開啟瀏覽器嘗試上網),並強制重導到認證網頁要求輸入帳號密碼,然後ACG向RADIUS認證伺服器來確認使用者的身分,認證通過才可以自由到其它的網站。
在家裡裝設無線網路,除非你完全不在乎頻寬與鄰居分享或讓人偷用,否則最好還是啟用WEP或是WPA-PSK。
咖啡店家們應該也要注意到無線網路的認證問題,因為設定成Open System,不只是來電消費的客人,其實左鄰右舍也在使用你的無線網路,你只是不知道而已。如果你希望確定只有來電消費的客人可以使用無線網路,那就需要一台支援Web Redirection的進階無線基地台,並且有無線網路認證代管服務公司(例如Qon http://www.qon.com.tw/),來協助你控管無線網路。
關於如何設定無線安全設定,Microsoft的技術文件「為居家或小型企業設定 Windows XP IEEE 802.11 無線網路」,有非常詳細的步驟說明。


2017年10月26日 星期四

linux 使用 wake on lan

來源 http://yumax1012.blogspot.tw/2008/01/linux-wake-on-lan.html

可以試建立
/etc/init.d/halt.local

~~~內容如下
# script with local commands to be executed from init on system shutdown
#
# Here you should add things, that should happen directly before shuting
# down.
#
# enable WOL for magic packet (g) and broadcast (b)
#wol pumbagsd...
# Set Wake-on-LAN options. Not all devices support this. The
# argument to this option is a string of characters specifying
# which options to enable.
# p Wake on phy activity
# u Wake on unicast messages
# m Wake on multicast messages
# b Wake on broadcast messages
# a Wake on ARP
# g Wake on MagicPacket(tm)
# s Enable SecureOn(tm) password for MagicPacket(tm)
# d Disable (wake on nothing). This option clears all previous
# options.
/sbin/ifup eth0
/usr/sbin/ethtool -s eth0 wol g
#/usr/sbin/ethtool eth0

沒有ethtool 要先安裝 ethtool 套件:
apt-get install ethtool
執行 ethtool:
$ ethtool eth0
Settings for eth0:
Supports Wake-on: g
Wake-on: d
Link detected: yes

主要要看 Wake-on 這一項,要設成 g:

$ ethtool -s eth0 wol g

在執行一次 ethtool 確認有設定好:

$ ethtool eth0
Settings for eth0:
Supports Wake-on: g
Wake-on: g
Link detected: yes

由於這是在電腦開機前動作,
被喚醒的電腦只需要有 BIOS 及硬體有支援即可!
這樣就 ok 了。

2 則留言:

Jason Tseng 提到...
不好意思增加一些建議:
修改 : /etc/network/interfaces
iface eth0 inet dhcp
post-up /usr/sbin/ethtool -s $IFACE wol g
post-down /usr/sbin/ethtool -s $IFACE wol g

可每次開機自動設定好
http://wiki.debian.org/WakeOnLan
小麥 提到...
謝謝您的建議!!

移植 WG7833 最新 driver 至 kernel 3.14.49

原文 http://onlybernie.blogspot.tw/2015/10/



http://processors.wiki.ti.com/index.php/WL18xx_System_Build_Scripts

上面是 wl18xx 的 build code script,TI 說最簡單的方法就是使用它們....,但是因為我的

 filesystem 以及 toolchain 不是用官方的....,所以不能一次 build 完所有 wifi 所需要的 tool 和

 library。對我來說還滿麻煩的,因為我 libnl 、iw、openssl、wpa_supplicant 必須額外抓

 source code 來移植到板子上。

  iw - 3.15
  iw 使用的 libnl-3.2.24
  wpa_supplicant - 2.0
  wpa_supplicant 使用的 openssl-1.0.1h
  wpa_supplicant 使用的? (網路上好像沒說需要 libnl) libnl-1.1.4

  =====================================================================

1  用 TI build script 來 build 出 wifi modules: compat.ko、cfg80211.ko、mac80211、
    wlcore.ko、wl18xx.ko 以及 wlcore_sdio.ko。

    mkdir wl18xx
    cd wl18xx
    git clone git://git.ti.com/wilink8-wlan/build-utilites.git
    cp setup-env.sample setup-env
    vim setup-env

             export TOOLCHAIN_PATH=/opt/poky/1.8/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi
             export ROOTFS=/opt/poky/1.8/sysroots/cortexa8hf-vfp-neon-poky-linux-gnueabi
             export KERNEL_PATH=/home/bernie/kernel-source
             export KERNEL_VARIANT=DEFAULT
             export CROSS_COMPILE=arm-poky-linux-gnueabi-
             export ARCH=arm

     先確認 verify_kernel_config.sh 內的 CONFIG 在你的 kernel 內有沒有選取,沒有的話要記得 enable,並且 kernel 要先 build 過。

     ./sudo_build_wl18xx.sh modules

     在 build code 中,會出現一些 error,原因是 toolchain 版本問題,我的是 4.9.2,會無法識別__TIMESTAMP__問題,只要用常數取代即可。另外,得到的 wlcore_sdio.ko要載入時,會出現 time_sync error,因為它程式內寫死用 gpio66,我們並沒有gpio66,所以到 compat_wireless/drivers/net/wireless/ti/wlcore/main.c 將 time_sync 內相關的 code 註解掉即可。

am335x uart 移植

原文 http://onlybernie.blogspot.tw/2015/10/

在 dts file已經增加 uart1 和 uart2 的 pinmux 了,在系統內卻無法使用。看了 dmesg ,發現奇怪的訊息。

   WARNING: Your 'console=ttyO0' has been replaced by 'ttyS0'
[    0.000398] This ensures that you still see kernel messages. Please
[    0.000404] update your kernel commandline.


google之後發現,這是 8250 driver 在搞鬼,只要將 kernel 中的 SERIAL_8250 dirver 移除,以及選上  OMAP serial port support 的 driver,就可以使用 ttyOx了。

系統會出現

    Kernel command line: console=ttyO0,115200n8 root=/dev/mmcblk0p2 ro rootfstype=ext4 rootwait

    [    0.511510] 44e09000.serial: ttyO0 at MMIO 0x44e09000 (irq = 88, base_baud = 3000000) is a OMAP UART0
[    1.180674] 48022000.serial: ttyO1 at MMIO 0x48022000 (irq = 89, base_baud = 3000000) is a OMAP UART1
[    1.197232] 48024000.serial: ttyO2 at MMIO 0x48024000 (irq = 90, base_baud = 3000000) is a OMAP UART2

的訊息了。

移植 iptable 命令至 am335x

原文 http://onlybernie.blogspot.tw/2015/10/

下載 iptables-1.4.18.tar.gz

1先 source poky sdk 的 env setup script
2解壓後,進入資料夾內輸入

    ./configure --host=arm-poky-linux-gnueabi --prefix=/home/bernie/app/iptables --enable-static --disable-shared


最後進入 /home/bernie/app/iptables/sbin,將裡面的所有資料 tar 起來,丟至目標板,解壓放至 /usr/sbin 內。

因為我們一開始採用靜態編譯,所以執行 iptables 命令時不會去 /lib 尋找 library。

移植 iw 命令至 am335x

原文 http://onlybernie.blogspot.tw/2015/10/

TI Wlink 8 最新的 driver R8.6,不支援 Wireless Extentsion。所謂的 Wireless Extentsion,就是一組通用 API,要使用的話,也必須 wifi driver 有支援。所以我們另外使用 iw 來取代,TI 的 driver 有支援此命令。


iw-3.15
libnl-3.2.24

iw 需要 netlink library,所以我們先移植 libnl。進入 libnl 資料夾,打上

   source poky sdk env setup script
  ./configure --host=arm-poky-linux-gnueabi --prefix=/home/bernie/app/libnl-3.2.24

   make
   make install

   編譯 libnl 安裝完成
====================================================================

  接著不要 source poky sdk 環境,進入 iw 資料夾。打上

   export PKG_CONFIG_PATH=/home/bernie/app/libnl-3.2.24/lib/pkgconfig
   修改 Makefile 中的 CC 值

    CC=/opt/poky/1.8/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc --sysroot=/opt/poky/1.8/sysroots/cortexa8hf-vfp-neon-poky-linux-gnueabi

   make
======================================================================
   error:  發現少了 libnl 的 gen.h 檔案

   solution: 修改 Makefile 的 CFLAGS,讓他增加指向
                  -I/home/bernie/app/libnl-3.2.24/include/libnl3

   make
=======================================================================
   error:
 /opt/poky/1.8/sysroots/x86_64-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/4.9.2/ld: error: iw uses VFP register arguments, version.o does not
/opt/poky/1.8/sysroots/x86_64-pokysdk-linux/usr/libexec/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/4.9.2/ld: failed to merge target specific data of file version.o
collect2: error: ld returned 1 exit status

  solution: 在 Makefile 中的  CC 變數加上 poky sdk 裡的 envsetup script 中的 CC 值即可。

編譯成功後,將 iw命令丟到目標板 /usr/sbin。

 

移植 wpa_supplicant 命令至 am335x

原文 http://onlybernie.blogspot.tw/2015/10/

要有 wpa_supplicant 指令,要先有 openssl  的 library 以及 libnl 的 library,前一章已經移植過了 libnl-3.2.24 了。

選擇 openssl-1.0.1h。進入openssl-1.0.1h,打上

  source poky sdk env setup script
 ./Configure linux-generic32 --prefix=/home/bernie/app/openssl

  修改 Makefile 中的 CC 為 CC= $(CROSS_COMPILE)gcc ... 後面為 sdk 的參數設定。
   make
   make install

   編譯 openssl 安裝完成
 ========================================================================

 進入 wpa_supplicant-2.2,打上
  不用 source poky  sdk env setup script,但是要 export PATH=sdk 的 bin
  cp defconfig .config
  在 .config 內加上
 
      CC=arm-poky-linux-gnueabi-gcc  -march=armv7-a -marm  -mthumb-interwork -mfloat-
abi=hard -mfpu=neon -mtune=cortex-a8 --sysroot=/opt/poky/1.8/sysroots/cortexa8hf-vfp-neon-poky-linux-gnueabi

    CFLAGS += -I /home/bernie/app/libnl-3.2.24/include/libnl3
    CFLAGS += -I /home/bernie/app/openssl/include
    LIBS += -L /home/bernie/app/openssl/lib
    LIBS += -L /home/bernie/app/libnl-3.2.24/lib
    CONFIG_LIBNL32=y-->這個要加,不然會出現 ld找不到 -lnl 的訊息

    make

    編譯完成後,將 wpa_supplicant 和 wpa_cli 丟至開發板 /usr/sbin

=======================================================================

wpa_supplicant 用法

mkdir /var/run/wpa_supplicant

 vi  /etc/wpa_supplicant.conf

   ctrl_interface=/var/run/wpa_supplicant
   update_config=1

   network={
        psk="12345678"
        ssid="bernie"
   }

##update_config=1 /* 讓 wpa_cli 程式可以更新 wpa_supplicant */
## ctrl_interface=/var/run/wpa_supplicant /* 讓 supplicant 可以建立行程 pid */
 
 最後下指令:
wpa_supplicant -d -Dnl80211(也有可能是 wext) -c/etc/wpa_supplicant.conf -iwlan0 -B

     root@am335x-evm:/# [  684.159242] wlan0: authenticate with 18:00:2d:75:f7:80[  684.170487] wlan0: send auth to 18:00:2d:75:f7:80 (try 1/3)
[  684.199773] wlan0: authenticated
[  684.205871] wlan0: associate with 18:00:2d:75:f7:80 (try 1/3)
[  684.314794] wlan0: RX AssocResp from 18:00:2d:75:f7:80 (capab=0x431 status=0 aid=2)
[  684.335695] wlan0: associated
[  684.410374] wlcore: Association completed.

 成功會有上述字樣


 udhcpc -i wlan0

 即可拿到 IP

Poky vs Yocto vs OpenEmbedded

Package list: apps_proc/oe-core/build/tmp-glibc/deploy/images/<target>/<image>.rootfs.manifest


1. Why not just call this project Poky? What has changed between Poky and the Yocto Project?

The Yocto Project is an umbrella project. Accordingly, it includes a number of projects and resources specifically intended for facilitating development with Linux on embedded devices, and it is an appropriate place for larger organizations to collaborate on the development of build infrastructure for embedded Linux. Poky is one of the the largest components of the Yocto Project, and Poky continues as an independent, open source project developing the build system used by the Yocto Project, as well as by other open source projects.

Poky is a reference system for the Yocto Project, showing how the tools work together. It includes BitBake, openembedded-core, and several other components that anyone can use to start developing with embedded Linux. Poky as a build system is tested by the Yocto Project teams before each release. When you download and use the Yocto Project build system, you are actually downloading Poky and using it to create a distribution that by default is also named Poky. (You can, of course, name your distribution anything you like.)


2. What is the difference between OpenEmbedded and the Yocto Project?

The Yocto Project and OpenEmbedded share a core collection of metadata called openembedded-core. However, the two organizations remain separate, each with its own focus. OpenEmbedded provides a comprehensive set of metadata for a wide variety of architectures, features, and applications. The Yocto Project focuses on providing powerful, easy-to-use, interoperable, well-tested tools, metadata, and board support packages (BSPs) for a core set of architectures and specific boards.

Linux WiFi

Source: http://blog.csdn.net/liuxd3000/article/details/23761663


1. 基本概念
  • cfg80211:  用於對無線設備進行配置管理。與FullMAC, mac80211和nl80211一起工作。(Kernel態)
  • mac80211: 是一個driver開發者可用於為SoftMAC無線設備寫驅動的框架 (Kernel態)。
  • nl80211: 用於對無線設備進行配置管理,它是一個基本Netlink的使用者態協議(User態)
  • WNIC : Wireless Network Interface Controller, 它總是指望硬體執行協定(如IEEE802.11)描述的功能。
  • MLME: 即MAC(Media Access Control ) Layer Management Entity,它管理實體層MAC狀態機。
  • SoftMAC: 其MLME由軟體實現,mac80211為SoftMAC實現提供了一個driver API。 即:SoftMAC設備允許對硬體執行更好地控制,允許用軟體實現對802.11的幀管理,包括解析和產生802.11無線幀。目前大多數802.11設備為SoftMAC,而FullMAC設備較少。
  • FullMAC:  其MLME由硬體管理,當寫FullMAC無線驅動時,不需要使用mac80211。
  • wpa_supplicant: 是使用者空間一個應用程式,主要發起MLME命令,然後處理相關結果。
2. cfg80211

  • cfg80211是Linux 802.11配置API。cfg80211用於代碼wext(Wireless-Extensions),nl80211用於配置一個cfg80211設備,且用於kernel與userspace間的通信。wext現處理維護狀態,沒有新的功能被增加,只是修改bug。如果需要通過wext操作,則需要定義CONFIG_CFG80211_WEXT。
  • cfg80211 and nl80211: 基於消息機制,使用netlink介面
  • wext: 基於ioctl機制
  • struct ieee80211_hw: 表示硬體資訊和狀態
  • ieee80211_alloc_hw:每個driver調用ieee80211_alloc_hw分配ieee80211_hw,且以ieee80211_ops為參數
  • ieee80211_register_hw:每個driver調用ieee80211_register_hw創建wlan0和 wmaster0,並進行各種初始化。
  • struct ieee80211_ops:每個driver實現它的成員函數,且它的成員函數都以struct ieee80211_hw做為第一個參數。在struct ieee80211_ops中定義了24個方法,以下7個方法必須實現: tx,start,stop,add_interface,remove_interface,config和configure_filter。

3. mac80211
  • 它是一個driver開發者可用於為SoftMAC無線設備寫驅動的框架,mac80211為SoftMAC設備實現了cfg80211回呼函數,且mac80211通過cfg80211實現了向網路子系統註冊和配置。配置由cfg80211通過nl80211和wext實現。
  • mac80211在體系結構中的位置如下圖所示:


4. socket




問題:
想了解nl80211和cfg80211的工作細節。以及功能流程,nl80211是如何與網絡工具如wpa_supplicant進行交互的。
解答:
為了能夠從用戶空間控制無線驅動程序,一些IPC被用於內核和用戶態之間。


原文網址:https://read01.com/5MakMK.html
問題:
想了解nl80211和cfg80211的工作細節。以及功能流程,nl80211是如何與網絡工具如wpa_supplicant進行交互的。
解答:
為了能夠從用戶空間控制無線驅動程序,一些IPC被用於內核和用戶態之間。


原文網址:https://read01.com/5MakMK.html
問題:
想了解nl80211和cfg80211的工作細節。以及功能流程,nl80211是如何與網絡工具如wpa_supplicant進行交互的。
解答:
為了能夠從用戶空間控制無線驅動程序,一些IPC被用於內核和用戶態之間。


原文網址:https://read01.com/5MakMK.html
問題:
想了解nl80211和cfg80211的工作細節。以及功能流程,nl80211是如何與網絡工具如wpa_supplicant進行交互的。
解答:
為了能夠從用戶空間控制無線驅動程序,一些IPC被用於內核和用戶態之間。


原文網址:https://read01.com/5MakMK.html