天天看點

android系統中wifi省電模式下的四個基本概念:TIM、DTIM、Beacon-Interval、Listen-Interval

版權聲明:本文為部落客原創文章,遵循 CC 4.0 by-sa 版權協定,轉載請附上原文出處連結和本聲明。

本文連結:https://blog.csdn.net/hengkong_horse/article/details/8805860

1、TIM(traffic indication message)

    每一個Beacon的幀中都有一個TIM資訊 ,它主要用來由AP通告它管轄下的哪個STA有資訊現在緩存在AP 中,而在TIM中包含一個Bitmap control 字段,它最大是251個位元組,每一位映射一個STA,當為1時表示該位對應的STA在AP的緩存中有資訊。

2、DTIM(Delivery Traffic Indication Message )

       DTIM用于AP傳統節電模式中,多點的應用,即由AP通過設定DTIM的間隔(預設是一個beacon時間,100ms),根據這個間隔發送多點傳播流量。

    這個值不會影響單點傳播的流量傳遞,如果沒有開啟PS的使用者使用多點傳播也不會收到影響,但是會影響開啟了PS的使用者接收多點傳播資料的傳遞,如果設定的太小,起不到節電作用,太大又可能會影響多點傳播通訊的品質,這個過程是一個trial-error的調整過程,隻能一個一個測試調整,以達到最佳,即既可以達到最佳節電效果又不影響應用。

    調整方法如下:

               1.設定DTIM為1,然後記錄應用效果,作為基線

               2.然後提高間隔,使應用效果可以接受為止。

               DTIM=1表示每個beacon中都包含DTIM, DTIM=2表示每兩個beacon中包含一個DTIM,以此類推。

        設定一個合适的DTIM間隔有點麻煩。

3、Beacon-Interval(信标間隔)

    這個值變大,有助于client端省電。

    這個值變小,有助于提高client端連接配接速度。降低了基地台的buffer frame負載。

    一般預設為100mS。

    以Beacons 封包發送SSID的速率是1Mbit/S.

4、Listen-Interval, (STA即Client接收Beacon 的周期)

    AP 廣播Beacon 的周期為Beacon-Interval,STA 可以自由選擇Beacon-Interval的整數倍作為自己的Listen-Interval,比如10。

    STA 每隔Listen-Interval 接收Beacon并解碼其中的TIM,如果TIM 訓示沒有資料緩存,STA 就可以立刻轉入Doze 狀态,如果TIM 訓示其有資料緩存,STA 就要向AP 發一個競選控制包Poll,AP 在收到Poll 後就可以向該Poll 的源STA 發送一個為它緩存的資料包。

5、wifi電源子產品源碼(STATION)

        對應驅動中的pm.c檔案,可以自行分析,不是很複雜;

    設定應該是在early_suspend階段進行的,即驅動注冊的early_suspend.suspend指向的函數裡面。

    部分源碼如下:

    #ifdef CONFIG_HAS_EARLYSUSPEND

       static void ath6kl_early_suspend(struct early_suspend *handler)

       {

            struct ath6kl *ar = container_of(handler, struct ath6kl, early_suspend);

            if (ar)

                ar->screen_off = true;

       }

       static void ath6kl_late_resume(struct early_suspend *handler)

      {

            struct ath6kl *ar = container_of(handler, struct ath6kl, early_suspend);

            if (ar)

                ar->screen_off = false;

      }

    #endif

void ath6kl_setup_android_resource(struct ath6kl *ar)

{

#ifdef CONFIG_HAS_EARLYSUSPEND

 ar->screen_off = false;

 ar->early_suspend.suspend = ath6kl_early_suspend;

 ar->early_suspend.resume = ath6kl_late_resume;

 ar->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;

 register_early_suspend(&ar->early_suspend);

#endif

#ifdef CONFIG_HAS_WAKELOCK

 wake_lock_init(&ar->wake_lock, WAKE_LOCK_SUSPEND, "ath6kl_suspend_wl");

 wake_lock_init(&ar->p2p_wake_lock,

   WAKE_LOCK_SUSPEND,

   "ath6kl_p2p_suspend_wl");

#endif

}

void ath6kl_cleanup_android_resource(struct ath6kl *ar)

{

#ifdef CONFIG_HAS_EARLYSUSPEND

 unregister_early_suspend(&ar->early_suspend);

#endif

#ifdef CONFIG_HAS_WAKELOCK

 wake_lock_destroy(&ar->wake_lock);

 wake_lock_destroy(&ar->p2p_wake_lock);

#endif

}

 ———————————————— 

版權聲明:本文為CSDN部落客「hengkong_horse」的原創文章,遵循CC 4.0 by-sa版權協定,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/hengkong_horse/article/details/8805860