Chinaunix首页 | 论坛 | 博客
  • 博客访问: 89033
  • 博文数量: 47
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 315
  • 用 户 组: 普通用户
  • 注册时间: 2015-01-20 18:17
文章分类

全部博文(47)

文章存档

2018年(1)

2016年(46)

我的朋友

分类: LINUX

2018-01-10 13:38:09

原文地址:Madwifi DFS源码阅读 作者:jxq19881013

主要内容:
Radar的一些相关知识
Madwifi dfs的主要思想
主要结构体说明
主要处理流程

一.
Radar的一些相关知识 
1.常见缩略词
v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} p\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} v\:textbox {display:none;}
DFS Dynamic Frequency Selection
CACChannel Availability Check
BIT Burst Interval Time
PPB Pulses Per Burst
PRF Pulse Repetition Frequency

补充说明:每一个脉冲串(Burst)由多个Pulse(脉冲)组成,每个脉冲由多个无线电波组成;无线电波的频率,无线电波的接收信号强度,脉冲的长度和脉冲间隔的周期是区分无线电波很重要的特征。


2.固定脉冲间隔周期一次脉冲串示意图(一个脉冲)



3.固定脉冲间隔周期多次脉冲串示意图(一个脉冲串)


二.Madwifi dfs的主要思想
Madwifi主要是利用无线电波的频率、接收信号强度、脉冲长度、脉冲间隔等特征来区分噪音信号、数据信号和雷达波信号。
Madwifi首先将常见的雷达波的特征进行总结,并进行分类,主要分为固定FRI和可变FRI两种,然后又根据脉冲长度和脉冲间隔再进行细分(为此建立了两张表dfs_radarfdfs_radartable)。
根据脉冲长度可以找到脉冲类型(查找dfs_radartable,行代表脉冲的长度,列表示该长度下可能的类型),找到过滤器类型后,再根据其它特征来比对过滤器类型中的每一个过滤器。当找到一个是个的过滤器之后,将这一次无线波的特征加入到该过滤器的一个DL队列中,该队列的大小由此deltaT队列相邻前面几个元素的deltaT时间之和要恰好小于Windows(windows的值是该过滤器的每个burst中的pulse的数量和pulse width的乘积),恰好小于是指在多加一个元素就会大于windows的值。 加入到过滤器的DL队列中之后,再从中找出最可能是雷达波的元素
(查找的方法主要是通过比较pri的值,及通过比较每个元素的pri值的差值,
看是否在可接受的误差允许的范围内,直到找到该元素和其它元素的pri
差值在允许的元素个数大于预先设好的门限值rf->rf_threshold)。
找到该元素后,利用该元素再去比较dl队列中的每一个元素,条件是,当
符合条件的元素的个数大于或等于rf->rf_threshold及认为找到radar


确定DL示意图


三.主要结构体说明

  1. struct ath_dfs {
  2.     u_int32_t        dfsdomain;    /* cur. DFS domain */
  3.     STAILQ_HEAD(,dfs_event)    dfs_eventq;    /* Q of free dfs event objects */
  4.     STAILQ_HEAD(,dfs_event)    dfs_radarq;    /* Q of radar events */
  5.     STAILQ_HEAD(,dfs_event) dfs_arq;    /* Q of AR events */
  6.     struct dfs_state    dfs_radar[DFS_NUM_RADAR_STATES];     /* Per-Channel Radar detector state */
  7.     struct dfs_filtertype    *dfs_radarf[DFS_MAX_RADAR_TYPES]; /* One filter for each radar pulse type */
  8.     struct dfs_info        dfs_rinfo;    /* State variables for radar processing */
  9.     struct dfs_bin5radars    *dfs_b5radars;    /* array of bin5 radar events */
  10.     int8_t            **dfs_radartable;    /* mapping of radar durations to filter types */
  11.     struct dfs_nolelem    *dfs_nol;    /* Non occupancy list for radar */
  12.     HAL_PHYERR_PARAM    dfs_defaultparams; /* Default phy params per radar state */
  13.     struct dfs_stats ath_dfs_stats;        /* DFS related stats */
  14.             struct dfs_pulseline *pulses; /* pulse history */
  15.             struct dfs_event *events; /* Events structure */

  16. u_int8_t        sc_dfstest_ieeechan;    /* IEEE channel number to return to after a dfs mute test */
  17.         u_int32_t        sc_dfs_cac_time;    /* Time to stay off chan during dfs test */
  18.         u_int32_t        sc_dfstesttime;    /* Time to stay off chan during dfs test */
  19.         os_timer_t     sc_dfs_task_timer;/* dfs wait timer */
  20.         os_timer_t     sc_dfswaittimer;/* dfs wait timer */
  21.         os_timer_t     sc_dfstesttimer;/* dfs mute test timer */
  22.         u_int8_t dfs_bangradar;
  23.         int dur_multiplier;
  24. };
  25. 这个结构体一方面是用来和sc进行关联,从而做到和其它驱动模块进行关联,方便调用。另一方面就是用来保存本身的一些信息;
    dfsdomain:用来表示所在国家的区域;
    dfs_eventq:空的event queue,用来与dfs_radarqdfs_arq配套使用;
    dfs_radar[DFS_NUM_RADAR_STATES]:用来保存和chan相关的信息;
    *dfs_radarf[DFS_MAX_RADAR_TYPES]:用来存储filter type信息;
    dfs_radartable:用来根据pulse dur来查找可能的radar filter
    dfs_defaultparams:用来存储和硬件寄存器相关的门限值数据,用来控制网卡的敏感度;
    Pulses:用来存储pulse的历史记录,对pattern_type1的有很大作用;
     ath_dfs_stats:用来存储dfs的一些状态信息,最重要的就是检测到的雷达的数目;

  1. struct dfs_filtertype {
  2.     struct dfs_filter ft_filters[DFS_MAX_NUM_RADAR_FILTERS];    /* array of filters */
  3.     u_int32_t    ft_filterdur; /* Duration of pulse which specifies filter type */
  4.     u_int32_t    ft_numfilters; /* Num filters of this type */
  5.     u_int64_t ft_last_ts; /* Last timestamp this filtertype was used (in usecs) */
  6.     u_int32_t    ft_mindur;     /* min pulse duration to be considered
  7.                      for this filter type */
  8.     u_int32_t    ft_maxdur;     /* max pulse duration to be consdiered
  9.                          for this filter type */
  10.     u_int32_t    ft_rssithresh;     /* min rssi to be considered for this filter type */
  11.     u_int32_t    ft_numpulses;     /* Num pulses in each filter of this type */
  12.         u_int32_t ft_patterntype; /* fixed or variable pattern type */
  13.     u_int32_t     ft_minpri;     /* min pri to be considered for this type*/
  14.     u_int32_t    ft_rssimargin;     /* rssi threshold margin. In Turbo Mode HW reports rssi 3dB */
  15.                     /* lower than in non TURBO mode. This will offset that diff.*/
  16. };
这个结构体用来表示过滤器类型,ft_filters表示该过滤器类型中包含的过滤器, ft_filterdur用来区分过滤器类型, ft_numfilters表示该过滤器类型中包含的过滤器的数目(最大是10, ft_last_ts用来记录该过滤器类型的上次radar的时间, ft_mindurft_maxdur别表示该过滤器类型的脉冲的最小和最大长度, ft_rssithresh表示该过滤器允许的最小接收信号强度, ft_numpulses表示burstpulse的个数。ft_patterntype表示过滤器是属于固定PRI或者变动PRI. ft_minpri表示该过滤器允许的最小pri, ft_rssimargin表示该过滤器允许rssi误差(变化值)的最大值。


  1. struct dfs_filter {
  2.         struct dfs_delayline rf_dl; /* Delay line of pulses for this filter */
  3.         u_int32_t rf_numpulses; /* Number of pulses in the filter */
  4.         u_int32_t rf_minpri; /* min pri to be considered for this filter*/
  5.         u_int32_t rf_maxpri; /* max pri to be considered for this filter*/
  6.         u_int32_t rf_threshold; /* match filter output threshold for radar detect */
  7.         u_int32_t rf_filterlen; /* Length (in usecs) of the filter */
  8.         u_int32_t rf_patterntype; /* fixed or variable pattern type */
  9.         u_int32_t rf_mindur; /* Min duration for this radar filter */
  10.         u_int32_t rf_maxdur; /* Max duration for this radar filter */
  11.         u_int32_t rf_pulseid; /* Unique ID corresponding to the original filter ID */
  12. };
该结构体是用来表示具体的过滤器(注意和过滤器类型相区分,过滤器类型中有多个过滤器)。
rf_dl存放该过滤器满足条件的pulse,大小请参考第67页的介绍; rf_numpulses表示该过滤器的脉冲串中脉冲数目;
rf_minprirf_maxpri分别表示该过滤器最小和做大脉冲间隔周期;
rf_threshold:匹配该过滤器的radar检测数目的门限值;
rf_filterlen:过滤器的长度(等于rf_numpulses* rf_maxpri);
 rf_patterntype:固定pri(0)或者变动pri(2),值为1也属于固定但处理很特 殊,我们的6radar 没有属于1的情况。
 rf_mindurrf_maxdur分别表示该过滤器允许的最小最大脉冲长度;
 rf_pulseid:该过滤器的编号

  1. /* NB: The first element in the circular buffer is the oldest element */

  2. struct dfs_delayline {
  3.     struct dfs_delayelem dl_elems[DFS_MAX_DL_SIZE];    /* Array of pulses in delay line */
  4.     u_int64_t    dl_last_ts;        /* Last timestamp the delay line was used (in usecs) */
  5.     u_int32_t    dl_firstelem;        /* Index of the first element */
  6.     u_int32_t    dl_lastelem;        /* Index of the last element */
  7.     u_int32_t    dl_numelems;        /* Number of elements in the delay line */
  8. };
dfs_delayline用来对应dfs_filter中的rf_dl, dl_elems用来存放具体的pulse信息。其中需要注意的是dl_last_ts值,它表示该过滤器的最后一个pulse的时间,但不一定是lastelem所对应的时间(有两种情况会更新最后时间但不加入到dl中)。
struct dfs_delayelem {
u_int32_t de_time; /* Current "filter" time for start of pulse in usecs*/
u_int8_t de_dur; /* Duration of pulse in usecs*/
        u_int8_t        de_rssi;        /* rssi of pulse in dB*/
};
dfs_delayelem表示dfs_delayline中具体的元素,用来存放pulse信息;
de_time表示这个pulsedl_last_ts之间的差值;
de_dur表示脉冲的长度
de_rssi表示该脉冲的接收信号强度。


四.主要流程
初始化过程:
ath_dev_attach---àdfs_attach->dfs_init_radar_filters-àath_hal_getdfsradars
dfs_attach:主要完成dfssc的关联,eventq,radarq,arq的初始化动作,并为radar filter radar table 分配空间。
dfs_init_radar_filters:dfs domain没有被初始化或者和hal domain不同时就需要初始化radar filter tables.这个函数主要用来初始化radar filter 表同时初始化dfs_radartable,达到通过pulse dur来找到可能的filter(作用可以参考第5页)。
ath_hal_getdfsradars:这个函数会根据domain去取预先设好的几种pulse参数,并用这些数据区填充radar filter


处理过程:
ath_rx_tasklet->ath_process_phyerr(struct ath_softc *sc, struct ath_desc *ds, u_int64_t fulltsf)
当产生硬件错误中断时,调用ath_process_phyerr,在这个函数中,fulltsf用来记录硬件中断时的time stamp,
主要的信息都保存在ath_desc中,当确定是radar detect产生的错误时,从ds中算出pulserssi, chaninfo dur等信息。然后从eventq中取出一个元素并赋值,当chaninfo的信息为(CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO) event存放到arq中,但是我们的条件是不可能会出现上述情况,故不考虑。我们的情况是将event添加到radarq中,由后面的dfs_process_radarevent去处理。
OS_TIMER_FUNC(ath_radar_task)->dfs_process_radarevent
 OS_INIT_TIMER(sc->sc_osdev, &sc->sc_dfs->sc_dfs_task_timer, ath_radar_task, sc);
 ath_rx_tasklet ->OS_SET_TIMER(&sc->sc_dfs->sc_dfs_task_timer, 0);
dfs_process_radarevent:radarq中取出event,将其中的值赋给re,并立即将空间归还eventq





阅读(1508) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~