版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
linuxwifi分析源碼,madwifi?線?卡源代碼閱讀在我的Doctor課題研究中,基于ARF協(xié)議設(shè)計(jì)了?個(gè)改進(jìn)型的AMARF協(xié)議,該?發(fā)表在milcom06和電?科學(xué)學(xué)刊英?版上。最近,我們將PC機(jī)上,使?linux操作系統(tǒng),基于madwifi開源代碼實(shí)現(xiàn)了AMARF協(xié)議,已經(jīng)在室內(nèi)固定以及移動(dòng)環(huán)境測(cè)試表明,AMARF協(xié)議明顯優(yōu)越于現(xiàn)有的協(xié)議。2008-9-20現(xiàn)在使?了madwifi程序?qū)崿F(xiàn)AMARF協(xié)議,下?分析其代碼。使?iwconfig命令可以設(shè)置速率:1、iwconfig源代碼閱讀?先下載iwconfig.c代碼,源代碼包為\wireless_tools.29?錄先看執(zhí)?iwconfigeth0的命令的執(zhí)?過(guò)程:調(diào)?main函數(shù),因?yàn)槭莾蓚€(gè)參數(shù):if(argc==2)print_info(skfd,argv[1],NULL,0);print_info調(diào)?get_info(intskfd,char*ifname,structwireless_info*info)將?卡的各種信息打印出來(lái)。下?與打印發(fā)送速率為例,說(shuō)明調(diào)?過(guò)程,get_info函數(shù)??:/*Getbitrate*/if(iw_get_ext(skfd,ifname,SIOCGIWRATE,&wrq)>=0){info->has_bitrate=1;memcpy(&(info->bitrate),&(wrq.u.bitrate),sizeof(iwparam));}對(duì)信息的獲取都是通過(guò)iw_get_ext函數(shù)來(lái)實(shí)現(xiàn)的,通過(guò)參數(shù)SIOCGIWRATE來(lái)識(shí)別不同的內(nèi)容iwlib.h?件定義了iw_get_ext:iw_get_ext(intskfd,/*Sockettothekernel*/constchar*ifname,/*Devicename*/intrequest,/*WEID*/structiwreq*pwrq)/*Fixedpartoftherequest*/{
/*Setdevicename*/strncpy(pwrq->ifr_name,ifname,IFNAMSIZ);/*Dotherequest*/return(ioctl(skfd,request,pwrq));}因此,真正對(duì)?卡其他參數(shù)的實(shí)現(xiàn)是通過(guò)ioctl函數(shù)實(shí)現(xiàn)的,ioctl是驅(qū)動(dòng)程序的基本功能,因此,如果??想編寫?個(gè)對(duì)?卡參數(shù)設(shè)置的程序,也應(yīng)該使?ioctl函數(shù)。下?在看使?iwconfigeth0rateauto命令執(zhí)?情況main函數(shù),當(dāng)輸?參數(shù)?于2的時(shí)候,調(diào)?:goterr=set_info(skfd,argv+2,argc-2,argv[1]);set_info函數(shù)調(diào)?iwcmd=find_command(args[0]);?來(lái)查找命令,所有的命令都存放在?個(gè)表中,只要查找這個(gè)表即可:staticconststructiwconfig_entryiwconfig_cmds[]={……….{"bit",set_bitrate_info,1,SIOCSIWRATE,"SetBitRate","{N[k|M|G]|auto|fixed}"},{"rate",set_bitrate_info,1,SIOCSIWRATE,"SetBitRate","{N[k|M|G]|auto|fixed}"},當(dāng)?shù)谌齻€(gè)參數(shù)為rate的時(shí)候,就會(huì)?動(dòng)調(diào)?set_bitrate_info函數(shù),該函數(shù)的定義為:set_bitrate_infoif(!strcasecmp(args[0],"auto")){wrq.u.bitrate.value=-1;wrq.u.bitrate.fixed=0;//如果輸?是auto,那么設(shè)置為bitrate.value=-1;}else{if(!strcasecmp(args[0],"fixed")){/*Getoldbitrate*/if(iw_get_ext(skfd,ifname,SIOCGIWRATE,&wrq)<0)return(IWERR_GET_EXT);
wrq.u.bitrate.fixed=1;}……………if(iw_set_ext(skfd,ifname,SIOCSIWRATE,&wrq)<0)return(IWERR_SET_EXT);也就是說(shuō),如果選擇auto,那么設(shè)置變量bitrate.fixed=0,最后調(diào)?iw_set_ext(skfd,ifname,SIOCSIWRATE,&wrq)函數(shù),這個(gè)函數(shù)也是直接與?卡相關(guān)的。與iw_get_ext函數(shù)?樣,iw_set_ext也是通過(guò)SIOCGIWRATE來(lái)識(shí)別的:staticinlineintiw_set_ext(intskfd,/*Sockettothekernel*/constchar*ifname,/*Devicename*/intrequest,/*WEID*/structiwreq*pwrq)/*Fixedpartoftherequest*/{/*Setdevicename*/strncpy(pwrq->ifr_name,ifname,IFNAMSIZ);/*Dotherequest*/return(ioctl(skfd,request,pwrq));}2、madiwifi驅(qū)動(dòng)和硬件說(shuō)明該說(shuō)明來(lái)源于“IEEE802.11RateAdaptation:APracticalApproach”該?主要提出了AMRR算法。本??先談到是否能夠基于包級(jí)的速率控制需要看硬件是否?持,有些芯?在硬件??包含了CPU,TexasInstrumentsaroundanARMcore,WaveLAN802.11b,因此具有低的延時(shí)。然?,Atheros802.11chipsets芯?不包含CPU,需要主機(jī)CPU來(lái)完成很多的MAC功能,?主機(jī)CPU很難實(shí)現(xiàn)實(shí)時(shí)的控制,基于包的速率控制是不可?的,認(rèn)為是?延時(shí)的?類。ARF算法和AARF算法、以及AMARF都是基于低延時(shí)的控制算法,Atheros的linux驅(qū)動(dòng),稱為MultibandAtherosDriverforWiFi(MadWiFi),可以在SourceForge上找到源代碼,使?了HAL(硬件抽象層的概念),與硬件有關(guān)的部分是進(jìn)制的代碼,不提供源代碼。Atheros硬件允許?戶創(chuàng)建9個(gè)發(fā)送FIFIO描述符,對(duì)發(fā)送進(jìn)?調(diào)度;每個(gè)發(fā)送描述符包含了發(fā)送狀況,數(shù)據(jù)的指針和長(zhǎng)度,并且包含了?個(gè)4對(duì)的“速率/重傳次數(shù)”對(duì)(r0/c0,r1/c1,r2/c2,r3/c3)。當(dāng)?線信道可以發(fā)送的時(shí)候,硬件將引發(fā)處于FIFO頭的數(shù)據(jù)的發(fā)送,?先以速率r0發(fā)送,如果發(fā)送失敗,繼續(xù)以速率r0發(fā)送c0-1次,然?再次以速率r1發(fā)送,如果發(fā)送失敗,繼續(xù)以速率r1發(fā)送c1-1次……如果發(fā)送失敗了c0+c1+c2+c3次,那么放棄這次發(fā)送。當(dāng)發(fā)送完畢,或者發(fā)送放棄,硬件會(huì)在發(fā)送描述符中報(bào)告本次發(fā)送丟失的ACK的數(shù)?,因此,通過(guò)獲知丟失的ACK的數(shù)?可以間接的得到本次的發(fā)送速率。MadWiFi的這個(gè)機(jī)制稱為MultiRateRetrymechanism。
3、onoe?適應(yīng)速率說(shuō)明該說(shuō)明來(lái)源于“Bit-rateSelectioninWirelessNetworks“,JohnC.Bicket,MIT碩?論?P29該?主要提出了SampleRate算法,也對(duì)其他的算法進(jìn)?了說(shuō)明。onoe對(duì)每個(gè)包的失敗與否并不敏感,試圖找到丟幀率?于50%的最?速率;對(duì)于每個(gè)?的連接,onoe保存了?個(gè)當(dāng)前鏈路的?特速率、以及該?特率的信?度;算法跟蹤每個(gè)鏈路當(dāng)前?特速率的信?度,如果丟包率較?,那么增加該信?度;如果該信?度達(dá)到?定的閾值,那么嘗試增加信?度;如果發(fā)?了?些錯(cuò)誤,那么該信?度復(fù)位,速率下降。當(dāng)?shù)?次發(fā)送到?的地址的時(shí)候,將初始的速率設(shè)置為24M(802.11a/g),11M(802.11b);onoe周期性的執(zhí)?算法(缺省值為1秒)1)如果沒(méi)有數(shù)據(jù)發(fā)送成功,降低到下?個(gè)速率;2)如果發(fā)送了10個(gè)以上的包,并且每個(gè)包的平均重傳次數(shù)?于1,降低到下?個(gè)速率;3)如果超過(guò)10%的包需要重傳,將信?值減?(保持?于0),4)如果少于10%的包需要重傳,增加信?值;次數(shù)5)如果信?值?于10,增加速率;相關(guān)代碼為://每次發(fā)送完數(shù)據(jù)后,都會(huì)調(diào)?該函數(shù),來(lái)判斷發(fā)送的結(jié)果,成功還是失敗,以及重傳的次數(shù)voidath_rate_tx_complete(structath_softc*sc,structath_node*an,conststructath_desc*ds){structonoe_node*on=ATH_NODE_ONOE(an);if(ds->ds_txstat.ts_status==0)//如果ts_status為0,表明發(fā)送成功on->on_tx_ok++;//統(tǒng)計(jì)發(fā)送成功和發(fā)送失敗的次數(shù),elseon->on_tx_err++;on->on_tx_retr+=ds->ds_txstat.ts_shortretry//統(tǒng)計(jì)重傳的次數(shù),長(zhǎng)重傳加上短重傳,適?于不同的長(zhǎng)度,?般來(lái)說(shuō)應(yīng)該是?個(gè)為0,?另外?個(gè)不為0,+ds->ds_txstat.ts_longretry;if(jiffies>=on->on_nextcheck){//判斷現(xiàn)在的時(shí)間,每?約1秒鐘執(zhí)??次速率控制ath_rate_ctl(sc,&an->an_node);/*XXXhalverateforstationmode*/on->on_nextcheck=jiffies+(ath_rateinterval*HZ)/1000;//ath_rateinterval定義為1000,}}//這個(gè)是速率控制函數(shù)staticvoidath_rate_ctl(void*arg,structieee80211_node*ni)
{structath_softc*sc=arg;structonoe_node*on=ATH_NODE_ONOE(ATH_NODE(ni));structieee80211_rateset*rs=&ni->ni_rates;intdir=0,nrate,enough;sc->sc_stats.ast_rate_calls++;/**Ratecontrol*XXX:veryprimitiveversion.*/enough=(on->on_tx_ok+on->on_tx_err>=10);//這兩參數(shù)是從ath_rate_tx_complete中獲得的,onoe算法要統(tǒng)計(jì)10次以上的發(fā)送結(jié)果才?有動(dòng)作/*nopacketreached->down*/if(on->on_tx_err>0&&on->on_tx_ok==0)//如果壓根就沒(méi)有任何?次發(fā)送成功,速率控制的?向是遞減,也就是算法中的第?中情況dir=-1;/*allpacketsneedsretryinaverage->down*/if(enough&&on->on_tx_ok<on->on_tx_retr)//就是算法中的第?種情況,基本上所有的包都需要重傳,降低速率dir=-1;//ath_rate_raise初始值定義為10,判斷?于10%的?個(gè)變量//如果沒(méi)有發(fā)?傳輸失敗,并且少于10%的包需要重傳,增加速率,也就是第四鐘情況/*noerrorandlessthanrate_raise%ofpacketsneedretry->up*/if(enough&&on->on_tx_err==0&&on->on_tx_retr<(on->on_tx_ok*ath_rate_raise)/100)dir=1;DPRINTF(sc,"%s:ok%derr%dretr%dupper%ddir%d\n",ether_sprintf(ni->ni_macaddr),on->on_tx_ok,on->on_tx_err,on->on_tx_retr,on->on_tx_upper,dir);nrate=ni->ni_txrate;//?前使?的速率,實(shí)際上是?個(gè)?于等于0的編號(hào)switch(dir){case0://不增加也不減少if(enough&&on->on_tx_upper>0)on->on_tx_upper--;//on_tx_upper定義為信?值
//如果發(fā)送超過(guò)了10次,并且超過(guò)10%的包需要重傳,信?值on_tx_upper減?break;case-1://減少速率,if(nrate>0){nrate--;//如果?于0,減?速率sc->sc_stats.ast_rate_drop++;}on->on_tx_upper=0;//將信?值復(fù)位置0break;case1:/*raiserateifwehitrate_raise_threshold*/if(++on->on_tx_upper<ath_rate_raise_threshold)break;//信?值加1,如果信?值沒(méi)有達(dá)到閾值,那么直接退出,on->on_tx_upper=0;//否則,增加速率,將信?值復(fù)位置0if(nrate+1<rs->rs_nrates){nrate++;sc->sc_stats.ast_rate_raise++;}break;}if(nrate!=ni->ni_txrate){//如果速率發(fā)?了改變,更新速率DPRINTF(sc,"%s:%dM->%dM(%dok,%derr,%dretr)\n",__func__,(rs->rs_rates[ni->ni_txrate]&IEEE80211_RATE_VAL)/2,(rs->rs_rates[nrate]&IEEE80211_RATE_VAL)/2,on->on_tx_ok,on->on_tx_err,on->on_tx_retr);ath_rate_update(sc,ni,nrate);}elseif(enough)//如果速率沒(méi)有發(fā)?改變,發(fā)送次數(shù)已經(jīng)?約10次了,重新復(fù)位on->on_tx_ok=on->on_tx_err=on->on_tx_retr=0;//復(fù)位}//速率更新的代碼staticvoidath_rate_update(structath_softc*sc,structieee80211_node*ni,intrate){
//ath_rate_ctl函數(shù)僅僅是確定了合適使?的速率,然?,atheor?卡需要在發(fā)送描述符中寫?r0/c0,r1/c1,r2/c2,r3/c3四個(gè)速率和retry對(duì),如果填充這四個(gè)發(fā)送對(duì)呢?r0速率,就是判斷的最佳發(fā)送速率,r1就是最佳速率的下?個(gè)速率(如果r0已經(jīng)是最低速率,那么r1為0);r2是r1的下?個(gè)速率,r3是r2的下?個(gè)速率,對(duì)于retry次數(shù),分別設(shè)置為4,2,2,2on->on_tx_rix0=sc->sc_rixmap[ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL];on->on_tx_rate0=rt->info[on->on_tx_rix0].rateCode;on->on_tx_try0=1+3;/*4triesatrate0*///速率r0的設(shè)置,就是最佳速率rateif(--rate>=0){//速率r1的設(shè)置,就是最佳速率rate的下?個(gè)速率rix=sc->sc_rixmap[ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL];on->on_tx_rate1=rt->info[rix].rateCode;on->on_tx_rate1sp=on->on_tx_rate1|rt->info[rix].shortPreamble;}elseon->on_tx_rate1=on->on_tx_rate1sp=0;……….速率r1/c1,r2/c2,r3/c3是通過(guò)ath_rate_setupxtxdesc函數(shù)寫?硬件的,這是與硬件相關(guān)的函數(shù),ath_rate_setupxtxdesc(structath_softc*sc,structath_node*an,structath_desc*ds,intshortPreamble,size_tframe_size,u_int8_trix){structonoe_node*on=ATH_NODE_ONOE(an);ath_hal_setupxtxdesc(sc->sc_ah,ds,on->on_tx_rate1sp,2/*series1*/,on->on_tx_rate2sp,2/*series2*/,on->on_tx_rate3sp,2/*series3*/);}速率r0/c0是通過(guò)ath_hal_setuptxdesc函數(shù)寫?硬件的,ath_hal_setuptxdesc(ah,ds,pktlen/*packetlength*/,hdrlen/*headerlength*/,atype/*Atherospackettype*/,MIN(ni->ni_txpower,60)/*txpower*/,txrate,try0/*series0rate/tries*/,keyix/*keycacheindex*/
先看ath_rate_tx_complete函數(shù),每次發(fā)送后是如何處理的,該函數(shù)在if_ath.c中每次ath_tx_start函數(shù)進(jìn)?發(fā)送的時(shí)候調(diào)?通過(guò)上?的分析,我們認(rèn)為實(shí)際上使?的發(fā)送速率就是r0,那么如何獲取呢?速率控制的驅(qū)動(dòng)中有?個(gè)函數(shù):voidath_rate_findrate(structath_softc*sc,structath_node*an,intshortPreamble,size_tframeLen,u_int8_t*rix,int*try0,u_int8_t*txrate){structonoe_node*on=ATH_NODE_ONOE(an);*rix=on->on_tx_rix0;*try0=on->on_tx_try0;if(shortPreamble)*txrate=on->on_tx_rate0sp;else*txrate=on->on_tx_rate0;}返回的txrate就是實(shí)際上使?的on->on_tx_rate0,r0該函數(shù)也在if_ath.c中每次ath_tx_start函數(shù)進(jìn)?發(fā)送的時(shí)候調(diào)?,這個(gè)函數(shù)雖然參數(shù)很多,但是查看代碼,只有structath_node*an的輸?代碼是有效的,shortPreamble是否為短符號(hào),可以不考慮,設(shè)置為0.因此,需要修改ioctl部分的函數(shù),將auto部分返回-1的代碼,修改為調(diào)?ath_rate_findrat函數(shù),調(diào)?該函數(shù)的關(guān)鍵就是如何獲取structath_node*an參數(shù)。4、AMRR代碼閱讀AMRR是onoe的改進(jìn),使?了?進(jìn)制避退(BEB)的概念,來(lái)適應(yīng)改變r(jià)n/cn的周期,為了適應(yīng)快速變化的?線信道,設(shè)置c0=c1=c2=c3=1,速率r3設(shè)置為最?可?速率(6Mbps802.11a),?r1和r2由r0決定,也就是r1為r0的下?個(gè)低速率,r2為r1的下?個(gè)低速率;因此,核?是改變r(jià)0。AMRR使?了?個(gè)定時(shí)器來(lái)周期性的進(jìn)?速率控制,時(shí)間設(shè)置為1秒。staticvoidath_ratectl(unsignedlongdata){……..asc->timer.expires=jiffies+((HZ*interval)/1000);add_timer(&asc->timer);}void
ath_rate_tx_complete(structath_softc*sc,structath_node*an,conststructath_desc*ds){structamrr_node*amn=ATH_NODE_AMRR(an);intsr=ds->ds_txstat.ts_shortretry;intlr=ds->ds_txstat.ts_longretry;intretry_count=sr+lr;//這個(gè)變量表明重傳的次數(shù),需要注意c0=c1=c2=c3=1,因此,重傳次數(shù)最多為4次,amn->amn_tx_try0_cnt++;//amn->amn_tx_try0_cnt變量為使?速率r0發(fā)送的次數(shù),因?yàn)閏0=1,每次發(fā)送,都會(huì)并且只會(huì)使//?r0發(fā)送?次,因此,這個(gè)變量還可以同時(shí)表?發(fā)送的包的個(gè)數(shù)(包括成功和失敗的)if(retry_count==1){//如果重傳次數(shù)是?次,由于c0=c1=c2=c3=1,必然可以得出使?速率r0發(fā)送了?次,失敗之后,?使?速率r1發(fā)送了?次amn->amn_tx_try1_cnt++;}elseif(retry_count==2){//同理可以得出如果重傳次數(shù)是2次,由于c0=c1=c2=c3=1,必然可以得出使?速率r0發(fā)送了?次,失敗之后,?使?速率r1發(fā)送了?次,再使?r2發(fā)送了?次amn->amn_tx_try1_cnt++;amn->amn_tx_try2_cnt++;}elseif(retry_count==3){amn->amn_tx_try1_cnt++;amn->amn_tx_try2_cnt++;amn->amn_tx_try3_cnt++;}elseif(retry_count>3){//如果次數(shù)為4次,說(shuō)明各個(gè)速率都嘗試過(guò),并且最后都發(fā)送都失敗了。amn->amn_tx_try1_cnt++;amn->amn_tx_try2_cnt++;amn->amn_tx_try3_cnt++;amn->amn_tx_failure_cnt++;}}staticvoidath_rate_ctl(void*arg,structieee80211_node*ni){structath_softc*sc=arg;
structamrr_node*amn=ATH_NODE_AMRR(ATH_NODE(ni));intold_rate;#defineis_success(amn)(amn->amn_tx_try1_cnt<(amn->amn_tx_try0_cnt/10))如果發(fā)送包的中?于10%的包出現(xiàn)了重傳,那么認(rèn)為上次速率設(shè)置發(fā)送是成功的,#defineis_enough(amn)(amn->amn_tx_try0_cnt>10)如果發(fā)送包的個(gè)數(shù)?于10,認(rèn)為是?夠進(jìn)?判斷了#defineis_failure(amn)(amn->amn_tx_try1_cnt>(amn->amn_tx_try0_cnt/3))如果發(fā)送包中出現(xiàn)?約33%的包需要重傳,那么認(rèn)為上次速率設(shè)置是失敗的#defineis_max_rate(ni)((ni->ni_txrate+1)>=ni->ni_rates.rs_nrates)#defineis_min_rate(ni)(ni->ni_txrate==0)old_rate=ni->ni_txrate;if(is_success(amn)&&is_enough(amn)){//如果發(fā)送成功,將成功的計(jì)數(shù)器加1amn->amn_success++;if(amn->amn_success==amn->amn_success_threshold&&!is_max_rate(ni)){如果計(jì)數(shù)器達(dá)到閾值,那么將速率增加,并且設(shè)置?個(gè)變量,amn_recovery=1,表明處于嘗試速率增加階段amn->amn_recovery=1;amn->amn_success=0;ni->ni_txrate++;DPRINTF(sc,"increaserateto%d\n",ni->ni_txrate);}elseamn->amn_recovery=0;}elseif(is_failure(amn)){如果發(fā)送失敗,成功的計(jì)數(shù)器清零。amn->amn_success=0;if(!is_min_rate(ni)){if(amn->amn_recovery){/*recoveryfailure.*/如果處于是處于嘗試速率增加階段,那么將閾值翻倍,amn->amn_success_threshold*=2;amn->amn_success_threshold=min(amn->amn_success_threshold,(u_int)ath_rate_max_success_threshold);DPRINTF(sc,"decreaseraterecoverythr:%d\n",
amn->amn_success_threshold);}else{/*simplefailure.*/否則,如果處于正常情況下的失敗,將閾值設(shè)置為最?amn->amn_success_threshold=ath_rate_min_success_threshold;DPRINTF(sc,"decreaseratenormalthr:%d\n",amn->amn_success_threshold);}amn->amn_recovery=0;ni->ni_txrate--;}elseamn->amn_recovery=0;}}可以看出來(lái),AMRR協(xié)議類似于AARF,每次嘗試速率增加的時(shí)候,如果嘗試失敗,將閾值翻倍。5、SampleRate?適應(yīng)速率說(shuō)明該說(shuō)明來(lái)源于“Bit-rateSelectioninWirelessNetworks“,JohnC.Bicket,MIT碩?論?P29該?主要提出了SampleRate算法,也對(duì)其他的算法進(jìn)?了說(shuō)明。該算法周期性的發(fā)送其他速率的包進(jìn)?探詢,看其他速率發(fā)送是否合適。本?認(rèn)為速率選擇算法需要考慮?下?個(gè)??:1)不能認(rèn)為因?yàn)槿绻车退俾市阅苄阅懿睿敲?它??級(jí)的速率會(huì)性能更差(3.5章節(jié)的說(shuō)明)2)最?吞吐量的算法可能丟包率也多,丟包率?的速率可能吞吐量未必最?(3.2節(jié))3)鏈路狀態(tài)是會(huì)發(fā)?變化的,不能對(duì)鏈路狀態(tài)進(jìn)?反映,會(huì)導(dǎo)致低的吞吐量;4)速率選擇算法必須要?效,不能嘗試所有的速率;6、AMARF協(xié)議的實(shí)現(xiàn)AMARF協(xié)議是ARF協(xié)議的改進(jìn),核?是給每個(gè)速率設(shè)置?個(gè)不同的閾值,閾值的??可以?適應(yīng)的變化,因此,AMARF適?于信道快速變化的場(chǎng)合。使?madwifi可能存在的問(wèn)題:1)madwifi屬于?延時(shí)的系統(tǒng),是否能夠進(jìn)?每個(gè)包的控制,另外如何控制FIFIO?2)madwifi驅(qū)動(dòng)本?提供了多速率多重傳的機(jī)制,如何利??因此,我們提出兩種?法:純粹的P-AMARF,結(jié)合madwifi的M-AMARF?先分析P-AMARF:還是從ath_rate_tx_complete函數(shù)看其,每次發(fā)送后是如何處理的。
上?的?個(gè)算法都是周期性的對(duì)速率進(jìn)?控制,引?了定時(shí)器,每次發(fā)送之后僅僅是對(duì)速率進(jìn)?統(tǒng)計(jì),我們的算法需要進(jìn)?快速的調(diào)整速率,每次發(fā)送完之后都進(jìn)?控制??!voidath_rate_tx_complete(structath_softc*sc,structath_node*an,conststructath_desc*ds){structamarf_node*arn=ATH_NODE_AMARF(an);arn->amarf_txok=!(ds->ds_txstat.ts_status);//判斷是否發(fā)送成功//printk("txokis%d\n",arn->amarf_txok);ath_rate_ctl(sc,&an->an_node);}staticvoidath_rate_ctl(void*arg,structieee80211_node*ni){structath_softc*sc=arg;structamarf_node*arn=ATH_NODE_AMARF(ATH_NODE(ni));intold_rate;sc->sc_stats.ast_rate_calls++;#defineis_max_rate(ni)((ni->ni_txrate+1)>=ni->ni_rates.rs_nrates)#defineis_min_rate(ni)(ni->ni_txrate==0)/*ni_txrate:indextoni_rates[]*/old_rate=ni->ni_txrate;if(arn->amarf_txok){if(arn->amarf_counter_success>=amarf_th[ni->ni_txrate]){arn->amarf_counter_success=0;amarf_th[ni->ni_txrate]+=amarf_c;DEBUG2("amarf_cis%f\n",amarf_c);if(!is_max_rate(ni)){ni->ni_txrate++;DEBUG2("increaseto%d\n",ni->ni_txrate);arn->amarf_isprobe=1;}}elsearn->amarf_counter_success++;arn->amarf_isprobe=0;//DEBUG2("consecutivecounter_successis%d\n",arn->amarf_counter_success);
}else{arn->amarf_counter_success=0;if(arn->amarf_isprobe==1)amarf_th[ni->ni_txrate]-=amarf_a;DEBUG2("amarf_ais%f\n",amarf_a);elseamarf_th[ni->ni_txrate]-=amarf_b;DEBUG2("amarf_bis%f\n",amarf_b);if(!is_min_rate(ni)){ni->ni_txrate--;DEBUG2("decreaseto%d\n",ni->ni_txrate);}arn->amarf_isprobe=0;}if(ni->ni_txrate!=old_rate)ath_rate_update(sc,ni,ni->ni_txrate);}7、madwifi驅(qū)動(dòng)閱讀該程序有好?個(gè)?錄ath:物理?卡的控制函數(shù),例如發(fā)送等ath_rate:速率控制的相關(guān)代碼hal:硬件抽象層的相關(guān)庫(kù),不公開源代碼net80211:802.11相關(guān)的代碼,與物理層獨(dú)?,完成諸如scan、wap、VAP等功能。Ieee80211_wireless.cstaticconstiw_handlerieee80211_handlers[]={(iw_handler)ieee80211_ioctl_siwrate,/*SIOCSIWRATE*/(iw_handler)ieee80211_ioctl_giwrate,/*SIOCGIWRATE*/模塊的??函數(shù):if_ath_pci.c/module_init(init_ath_pci);staticint__initinit_ath_pci(void){
printk(KERN_INFO"%s:%s\n",dev_info,version);if(pci_register_driver(&ath_pci_drv_id)<0){printk("ath_pci:Nodevicesfound,drivernotinstalled.\n");return(-ENODEV);}#ifdefCONFIG_SYSCTLath_sysctl_register();#endifreturn(0);}module_init(init_ath_pci);初始化會(huì)調(diào)?ath_pci_probe(structpci_dev*pdev,conststructpci_device_id*id)函數(shù),進(jìn)?步加載ath?線?卡:if(ath_attach(vdevice,dev)!=0)gotobad4;If_ath.c(ath)?件實(shí)現(xiàn)ath_attach函數(shù),該函數(shù)的實(shí)現(xiàn)?常復(fù)雜,關(guān)鍵的代碼如下:ath_attach(u_int16_tdevid,structnet_device*dev){……………ah=_ath_hal_attach(devid,sc,NULL,(void*)dev->mem_start,&status);可能是探測(cè)與硬件相關(guān)的東西,不能顯?更進(jìn)?步的代碼:………………..dev->hard_start_xmit=ath_hardstart;dev->do_ioctl=ath_ioctl;ieee80211_ifattach(ic);該函數(shù)在Ieee80211.c?件中實(shí)現(xiàn)ic->ic_vap_create=ath_vap_create;ic->ic_vap_delete=ath_vap_delete;重點(diǎn)需要掌握ath與80211?錄的關(guān)聯(lián),ath_vap_create是做什么的。staticstructieee80211vap*ath_vap_create(structieee80211com*ic,constchar*name,intunit,intopmode,intflags,structnet_device*mdev){……ieee80211_vap_setup(ic,dev,name,unit,opmode,flags);………….
(void)ieee80211_vap_attach(vap,ieee80211_media_change,ieee80211_media_status);Ieee80211_wireless.cieee80211_vap_setup(structieee80211com*ic,structnet_device*dev,constchar*name,intunit,intopmode,intflags)->調(diào)?下?的函數(shù),實(shí)現(xiàn)ioctl函數(shù),ieee80211_ioctl_vattach(structieee80211vap*vap){structnet_device*dev=vap->iv_dev;dev->do_ioctl=ieee80211_ioctl;這?就存在兩次對(duì)dev->do_ioctl賦值的情況,?次是在ath_attach函數(shù)中,?次在ieee80211_ioctl_vattach函數(shù)中,懷疑第?次是不是就將第?次的覆蓋了。ieee80211_ioctl函數(shù)就有很多的?函數(shù)?以實(shí)現(xiàn)不同的功能,以設(shè)置和獲取速率為例:ieee80211_ioctl_siwrate(structnet_device*dev,structiw_request_info*info,structiw_param*rrq,char*extra)獲取速率的ioctl函數(shù)的實(shí)現(xiàn)ieee80211_ioctl_giwrate(structnet_device*dev,structiw_request_info*info,structiw_param*rrq,char*extra){structieee80211vap*vap=dev->priv;structifmediareqimr;intrate;memset(&imr,0,sizeof(imr));vap->iv_media.ifm_status(vap->iv_dev,&imr);rrq->fixed=IFM_SUBTYPE(vap->iv_media.ifm_media)!=IFM_AUTO;/*mediastatuswillhavethecurrentxmitrateifavailable*/rate=ieee80211_media2rate(imr.ifm_active);//這個(gè)函數(shù)的意思是將速率編號(hào)轉(zhuǎn)換為實(shí)際的速率if(rate==-1)/*IFM_AUTO*/rate=0;//如果是auto,那么就返回0rrq->value=1000000*(rate/2);return0;}有關(guān)于速率的東西都在ifm_active變量中,這個(gè)變量包含了很多的屬性,包括速率、模式等等,在if_media.h?件中#defineIFM_IEEE80211_DS15/*DirectSequence1Mbps*/
#defineIFM_IEEE80211_DS26/*DirectSequence2Mbps*/#defineIFM_IEEE80211_DS57/*DirectSequence5.5Mbps*/#defineIFM_IEEE80211_DS118/*DirectSequence11Mbps*/函數(shù)ieee80211com_media_status實(shí)現(xiàn)獲得ifm_active變量ieee80211com_media_status(structnet_device*dev,structifmediareq*imr){structieee80211com*ic=dev->priv;/*XXX*/imr->ifm_status=IFM_AVALID;if(!TAILQ_EMPTY(&ic->ic_vaps))imr->ifm_status|=IFM_ACTIVE;imr->ifm_active=media_status(ic->ic_opmode,ic->ic_curchan);}通過(guò)上述分析,發(fā)現(xiàn)ifm_active變量的獲得實(shí)際上是ieee80211com*ic結(jié)構(gòu)體獲得的。數(shù)據(jù)發(fā)送過(guò)程分析:staticintath_hardstart(structsk_buff*skb,structnet_device*dev)->ath_tx_start(structnet_device*dev,structieee80211_node*ni,structath_buf*bf,structsk_buff*skb,intnextfraglen){……….ath_rate_findrate(sc,an,shortPreamble,skb->len,&rix,&try0,&txrate);//有關(guān)速率控制的東西………ath_hal_setuptxdesc(ah,ds,pktlen/*packetlength*/,hdrlen/*headerlength*/,atype/*Atherospackettype*/,MIN(ni->ni_txpower,60)/*txpower*/,txrate,try0/*series0rate/tries*/,keyix/*keycacheindex*/,antenna/*antennamode*/,flags/*flags*/,ctsrate/*rts/ctsrate*/,ctsduration/*rts/ctsduration*/,icvlen/*compicvlen*/
,ivlen/*compivlen*/,comp/*compscheme*/);//與硬件相關(guān)的函數(shù)if(try0!=ATH_TXMAXTRY)ath_rate_setupxtxdesc(sc,an,ds,shortPreamble,skb->len,rix);//速率控制的描述符}8、有關(guān)速率獲取的問(wèn)題通過(guò)上?的代碼分析,我們認(rèn)為在madwifi情況下,r0就是實(shí)際的速率,因此,需要在應(yīng)?層能夠獲得r0的指,經(jīng)過(guò)跟蹤,發(fā)現(xiàn)當(dāng)調(diào)?iwconfig命令,來(lái)獲取速率的值的時(shí)候,會(huì)調(diào)?ieee80211_ioctl_giwrate(structnet_device*dev,structiw_request_info*info,structiw_param*rrq,char*extra){structieee80211vap*vap=dev->priv;現(xiàn)在當(dāng)使?auto的?適應(yīng)速率時(shí)候,?動(dòng)返回-1,因此,獲得速率值為0.因此,需要修改這個(gè)函數(shù),調(diào)?ARMARF?適應(yīng)速率的ath_rate_findrate函數(shù)通過(guò)上?的分析,我們認(rèn)為實(shí)際上使?的發(fā)送速率就是r0,那么如何獲取呢?速率控制的驅(qū)動(dòng)中有?個(gè)函數(shù):voidath_rate_findrate(structath_softc*sc,structath_node*an,intshortPreamble,size_tframeLen,u_int8_t*rix,int*try0,u_int8_t*txrate){structonoe_node*on=ATH_NODE_ONOE(an);*rix=on->on_tx_rix0;*try0=on->on_tx_try0;if(shortPreamble)*txrate=on->on_tx_rate0sp;else*txrate=on->on_tx_rate0;}返回的txrate就是實(shí)際上使?的on->on_tx_rate0,r0該函數(shù)為實(shí)際上只有structath_node*an參數(shù)是需要傳遞的,ieee80211_ioctl_giwrate輸?的參數(shù)為net_device*dev,因此,需要將該輸?參數(shù)轉(zhuǎn)換得到structath_node*an參數(shù):因此,我們需要關(guān)注三個(gè)結(jié)構(gòu)體:
structnet_device*dev結(jié)構(gòu)體包含了ieee80211vap*vap結(jié)構(gòu)體:ieee80211vap*vap=dev->priv;an=ATH_NODE(ni);structath_softc{structieee80211comsc_ic;/*NB:mustbefirst*/structnet_device*sc_dev;structsemaphoresc_lock;/*dev-levellock*/structath_node{structieee80211_nodean_node;/*baseclass*/u_int16_tan_decomp_index;/*decompressionmaskindex*/u_int32_tan_avgrssi;/*averagerssioverallrxframes*/u_int8_tan_prevdatarix;/*rateixoflastdataframe*/u_int16_tan_minffrate;/*mimumrateinkbpsforfftoaggragate*/HAL_NODE_STATSan_halstats;/*rssistatisticsusedbyhal*/structath_buf*an_tx_ffbuf[WME_NUM_AC];/*ffstagingarea*/ath_bufheadan_uapsd_q;/*U-APSDdeliveryqueue*/intan_uapsd_qdepth;/*U-APSDdeliveryqueuedepth*/ath_bufheadan_uapsd_overflowq;/*U-APSDoverflowqueue(for>MaxSpframes)*/intan_uapsd_overflowqdepth;/*U-APSDoverflowqueuedepth*/spinlock_tan_uapsd_lock;/*U-APSDdeleiveryqueuelock*//*variable-lengthratecontrolstatefollows*/};structieee80211_node{structieee80211vap*ni_vap;structieee80211com*ni_ic;structieee80211_node_table*ni_table;…………..structieee80211vap{structnet_device*iv_dev;/*associateddevice*/structnet_device_statsiv_devstats;/*interfacestatistics*/structifmediaiv_media;/*interfacemediaconfig*/#ifdefCONFIG_NET_WIRELESSstructiw_statisticsiv_iwstats;/*wirelessstatisticsblock*/#endif
…………structieee80211com*iv_ic;/*backptrtocommonstate*/……………下?三個(gè)結(jié)構(gòu)體的包含關(guān)系為:ath_node->ieee80211_node->ieee80211vap并且由于?地址是?樣的,因此,只要獲得任意?個(gè)結(jié)構(gòu)體,可以使?指針強(qiáng)制轉(zhuǎn)換為另外兩個(gè)結(jié)構(gòu)體,例如已知ieee80211_node結(jié)構(gòu)體,可以獲得ath_node,在if_ath.c的ath_tx_start函數(shù)中,使?an=ATH_NODE(ni)命令獲得,#defineATH_NODE(_n)((structath_node*)(_n))structath_softc*sc=dev->priv;structieee80211com*an=dev->priv;ath_rate_findrate(sc,an,shortPreamble,skb->len,&rix,&try0,&txrate);調(diào)試中發(fā)現(xiàn),始終不能正確的傳遞參數(shù),經(jīng)過(guò)調(diào)試,發(fā)現(xiàn)ieee80211.c和if_ath.c代碼的structnet_device變量是不?樣的,兩者的參數(shù)名字分別為ath0和wifi0,也就是兩個(gè)?絡(luò)設(shè)備的名字,因此,沒(méi)有辦法傳遞參數(shù)。下?還是分析iwconfig中的參數(shù)是如何傳遞的,以ieee80211_ioctl_siwpower函數(shù)為例,設(shè)置發(fā)送功率。ieee80211_ioctl_siwpower(structnet_device*dev,structiw_request_info*info,structiw_param*wrq,char*extra){structieee80211vap*vap=dev->priv;structieee80211com*ic=vap->iv_ic;……………..returnIS_UP(ic->ic_dev)?ic->ic_reset(ic->ic_dev):0;如果設(shè)備已經(jīng)UP,那么以新的參數(shù)對(duì)設(shè)備設(shè)置。這??調(diào)?了?個(gè)函數(shù)指針,ic->ic_reset,經(jīng)過(guò)檢查,只有if_ath.c?件調(diào)?了,if_ath.c(692):ic->ic_reset=ath_reset;ath_attach(u_int16_tdevid,structnet_device*dev){structath_softc*sc=dev->priv;structieee80211com*ic=&sc->sc_ic;structath_hal*ah;………….ic->ic_reset=ath_reset;ath_reset(structnet_device*dev){structath_softc*sc=dev->priv;structieee80211com*ic=&sc->sc_ic;
structath_hal*ah=sc->sc_ah;structieee80211_channel*c;HAL_STATUSstatus;iwconfig命令會(huì)最終調(diào)?ieee80211_wireless.c中的各種參數(shù)設(shè)置和控制命令,查看代碼,發(fā)現(xiàn)ieee80211_wireless中本?定義了很多的參數(shù)變量,如果需要設(shè)置,再調(diào)?底層的函數(shù)將參數(shù)寫??卡芯?,如果讀參數(shù),就直接讀??已經(jīng)保存好的參數(shù),?并不是讀真正的物理層的參數(shù)!ieee80211_ioctl_siwpower代碼最終會(huì)調(diào)?ath_reset,這兩個(gè)函數(shù)的輸?參數(shù)都是structnet_device*dev,他是如何進(jìn)?參數(shù)轉(zhuǎn)換的呢?將ath0變?yōu)閣ifi0?Iwconfig中,?先由輸?參數(shù)ath0(structnet_device*dev)獲得vapstructieee80211vap*vap=dev->priv;該結(jié)構(gòu)體定義為:structieee80211vap{structnet_device*iv_dev;/*associateddevice*/structieee80211com*iv_ic;/*backptrtocommonstate*/……………然后由vap獲得ic,structieee80211com*ic=vap->iv_ic;?該結(jié)構(gòu)體定義為:structieee80211com{structnet_device*ic_dev;/*associateddevice*/?關(guān)聯(lián)了?個(gè)net_device設(shè)備,這個(gè)設(shè)備正是wifi0,因此,調(diào)?ic_reset的時(shí)候,并不是直接將ieee80211_ioctl_siwpower的輸出參數(shù)dev放進(jìn)去,?是轉(zhuǎn)了兩個(gè)彎,ic->ic_reset(ic->ic_dev)。再次回到獲取速率的函數(shù),調(diào)?下?的函數(shù)獲得速率,ath_rate_findrate(sc,an,shortPreamble,skb->len,&rix,&try0,&txrate);這?,sc以前直接定義為:ieee80211_ioctl_siwpower輸?參數(shù)的dev,structath_softc*sc=dev->priv;需要將其定義為wifi0,因此,需要定義為:structieee80211vap*vap=dev->priv;由ath0device獲得vapstructieee80211com*ic=vap->iv_ic;structnet_device*wifi=ic->ic_dev;再次獲得wifidevicestructath_softc*sc=wifi->priv;獲得sc如果調(diào)?findrate函數(shù),第?個(gè)參數(shù)ath_node需要傳遞過(guò)來(lái),發(fā)現(xiàn)這較困難,因此,暫時(shí)不使?這個(gè)?法,?是??在ieee80211com結(jié)構(gòu)體中定義?個(gè)變量,利?該變量傳遞參數(shù)。ath_rate_findrate(structath_softc*sc,structath_node*an,
intshortPreamble,size_tframeLen,u
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 體檢中心前臺(tái)服務(wù)工作總結(jié)
- 租賃商業(yè)用房合同三篇
- 化工行業(yè)員工安全培訓(xùn)方案實(shí)施
- 制造行業(yè)安全管理工作總結(jié)
- 2023年高考語(yǔ)文試卷(天津)(空白卷)
- 2024年美術(shù)教案集錦7篇
- 2024年電力通信設(shè)備運(yùn)檢員理論備考試題庫(kù)及答案
- 創(chuàng)意設(shè)計(jì)人才中介合同(2篇)
- 黃金卷8-【贏在中考·黃金八卷】(解析版)
- 2025新生入學(xué)貸款還款協(xié)議合同
- 火力發(fā)電廠有關(guān)職業(yè)病的危害及防護(hù)
- 民主測(cè)評(píng)票(三種樣式)
- 班車安全檢查表(2015-7-14)V3 0 (2)
- 城投集團(tuán)年度安全管理工作計(jì)劃
- 一、 行業(yè)協(xié)會(huì)申請(qǐng)?jiān)O(shè)立分支機(jī)構(gòu)、代表機(jī)構(gòu)應(yīng)提交的文件:
- 幼兒園幼兒園理事會(huì)成員一覽表
- 學(xué)生對(duì)課堂教學(xué)滿意度調(diào)查
- 住房公積金中心窗口人員個(gè)人工作總結(jié)
- 集成電路單粒子效應(yīng)評(píng)估技術(shù)研究PPT課件
- 幼兒園小班生成活動(dòng)教案20篇
- 講師與平臺(tái)的合作協(xié)議
評(píng)論
0/150
提交評(píng)論