linux下wlan驱动代码学习-join过程

@文章中的内容不必定正确,只表明了idiotshi目前的认识水平,欢迎指正!node

首先,提出一个问题:ni是什么?vap是什么?ni与vap之间是什么关系?数据结构

ni是一个数据结构,对于STA来讲,ni存储了STA与某一个AP交互时用到的信息(这些信息对于不一样的AP是不同的,须要单独维护),表示的是对方的信息。函数

而vap存储的是STA本身的信息。ui

就从ieee80211_assoc_state_join_entry函数开始提及吧。spa

 1 /*
 2  *JOIN 
 3  */
 4 static void ieee80211_assoc_state_join_entry(void *ctx) 
 5 {
 6     wlan_assoc_sm_t sm = (wlan_assoc_sm_t) ctx;
 7     sm->is_join=1;
 8     //sm->vap_handle,指向vap的指针
 9     //sm->scan_entry,当前链接AP的scan_scentry?
10     //sm->max_tsfsync_time,join定时器超时时间,在发送probe_req的时候设置该定时器,当定时器超时以前没有收到probe_resp则出错
11     if (wlan_mlme_join_infra(sm->vap_handle, sm->scan_entry, sm->max_tsfsync_time) != 0 ) {
12         IEEE80211_DPRINTF(sm->vap_handle,IEEE80211_MSG_STATE,"%s: join_infra failed \n",__func__);
13         ieee80211_sm_dispatch(sm->hsm_handle,IEEE80211_ASSOC_EVENT_JOIN_FAIL,0,NULL);
14         return;
15     }
16 }

wlan_mlme_join_infra函数中调用ieee80211_sta_join函数,该函数主要做用是对ni进行操做:释放旧node,创建新的node并对新的node赋值。并借着调用ieee80211_sta_join_bss(ni);函数中将vap->iv_bss替换成新创建的ni,而且若是原来的vap->iv_bss != NULL ,须要作一次释放。线程

1     ...
2     error = ieee80211_sta_join(vap, scan_entry);
3     if (error) {
4         IEEE80211_DPRINTF(vap, IEEE80211_MSG_MLME, "%s: Error %d (0x%08X) in ieee80211_sta_join\n", 
5             __func__, error, error);
6         goto err;
7     }
8     ...

当ieee80211_sta_join函数返回之后,wlan_mlme_join_infra就得到了ni信息,下面继续调用ieee80211_mlme_join_infra_continue函数,在该函数中调用ieee80211_send_probereq发送probe request,而且启动一个定时器等待probe resp。函数执行完毕后,一步步返回退出,直到ieee80211_assoc_state_join_entry返回。debug

那ieee80211_assoc_state_join_entry是如何被调用的?指针

对于join过程而言,该函数经过assoc状态机来维护,assoc状态机在INIT状态下收到IEEE80211_ASSOC_EVENT_REASSOC_REQUEST事件或者IEEE80211_ASSOC_EVENT_CONNECT_REQUEST事件时会调用ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_JOIN);rest

 

2.状态机是神马?code

我的理解,状态机是一个由定时器维护的数据结构的”组合“。猜想应该能够用线程来替代。

驱动程序在建立VAP的时候(osif_vap_setup)建立了两个状态机:connection状态机和assoc状态机。connection状态机的数据结构以下:

 1 struct _wlan_connection_sm {
 2 
 3     osdev_t                     os_handle;
 4     wlan_if_t                   vap_handle;
 5     ieee80211_hsm_t             hsm_handle; 
 6     wlan_assoc_sm_t             assoc_sm_handle; 
 7     wlan_scan_entry_t           cur_scan_entry; /* current bss scan entry */
 8     u_int8_t                    cur_bssid[IEEE80211_ADDR_LEN];
 9     wlan_connection_sm_event_handler sm_evhandler;
10     u_int8_t                    bgscan_rssi_thresh;
11     u_int8_t                    bgscan_rssi_change;
12     u_int8_t                    bgscan_rssi_thresh_forced_scan;  /* rssi below which it scan is a forces scan */
13     u_int8_t                    roam_threshold;
14     u_int32_t                   bgscan_period; /* in seconds */
15     u_int32_t                   scan_cache_valid_time; /* in msec */
16     u_int32_t                   roam_check_period; /* in msec */
17     u_int32_t                   connect_timeout;   /* connection attempt timeout in msec */
18     u_int32_t                   reconnect_timeout; /* after losing connection max re connection attempt timeout */
19     u_int32_t                   connection_lost_timeout; /* after losing connection time to wait before sending notification up */
20     u_int32_t                   bad_ap_timeout; /* time out before trying out the AP after connection failure */
21     u_int32_t                   bgscan_min_dwell_time; /* minimum dwell time for bg scan */
22     u_int32_t                   bgscan_max_dwell_time; /* maximum dwell time for bg scan */
23     u_int32_t                   bgscan_min_rest_time;  /* minimum rest time for bg scan */
24     u_int32_t                   bgscan_max_rest_time;  /* maximum rest time for bg scan */
25     wlan_connection_sm_bgscan_policy bgscan_policy;
26     os_if_t                     osif;
27     os_timer_t                  sm_timer;      /* generic event timer */
28     os_timer_t                  sm_roam_check_timer; /* roam check timer */
29     u_int8_t                    timeout_event;      /* event to dispacth when timer expires */
30     u_int32_t                   is_running:1,       /* SM is running */
31                                 is_stop_requested:1,      /* SM is being stopped */
32                                 sync_stop_requested:1,    /* SM is being stopped synchronously */
33                                 is_aplist_built:1,  /* ap list has been built */
34                                 is_reconnecting:1, /* connection lost(bmiss, deauth), reconnecting. also called hard roam */
35                                 lost_notification_sent:1,
36                                 is_connected:1;  /* lost connection with an ap reconnecting */
37     IEEE80211_SCAN_REQUESTOR    scan_requestor;  /* requestor id assigned by scan module */
38     IEEE80211_SCAN_ID           scan_id;         /* id assigned by scan scheduler */
39     u_int32_t                   candidate_aplist_count;
40     u_int32_t                   candidate_aplist_index;
41     u_int32_t                   connection_req_time;  /* os time stamp at which connection request is made  */
42     u_int32_t                   connection_lost_time; /* os time stamp at which connection is lost  */
43     u_int32_t                   last_scan_time;       /* os time stamp when last scan was complete*/
44     u_int32_t                   scan_channels[IEEE80211_CHAN_MAX];
45     u_int16_t                   num_channels;
46     u_int8_t                    last_scan_rssi;       /* last bss rssi at which scan is done  */
47     u_int8_t          scan_fail_count;      /* how mainy times scan start has failed  */
48     wlan_assoc_sm_event         assoc_event; /* last assoc event */
49     wlan_connection_sm_event_disconnect_reason disconnect_reason; /* reason for connection down */
50 }

assoc状态机的数据结构以下:

 1 typedef struct _ieee80211_hsm {
 2     u_int8_t                      name[IEEE80211_HSM_MAX_NAME];  /* name of the state machine */
 3     u_int8_t                      cur_state;
 4     u_int8_t                      next_state; /* is different from cur_state in the middle of ieee80211_transition_to */
 5     u_int8_t                      event_state; /* holds the current state to which  the event is delivered to */
 6     u_int8_t                      num_states;
 7     u_int8_t                      last_event;  /* last event */
 8     osdev_t                       oshandle;
 9     const ieee80211_state_info    *state_info;
10     void                          *ctx;                    /* context specific to the caller */
11     u_int32_t                     in_state_transition : 1; /* in state transition */
12     os_mesg_queue_t               mesg_q;
13     const char                    **event_names;   /* for debug printing */
14     u_int32_t                     num_event_names; /* for debug printing */
15 #if ENABLE_HSM_HISTORY
16     hsm_history_t                 history;
17 #endif    /* ENABLE_HISTORY */
18 
19     void (*ieee80211_hsm_debug_print) (void *ctx, const char *fmt,...);     
20 } ieee80211_hsm; 

而真正维护状态机状态信息的数据结构以下:

 1 typedef struct _ieee80211_hsm {
 2     u_int8_t                      name[IEEE80211_HSM_MAX_NAME];  /* name of the state machine */
 3     u_int8_t                      cur_state;
 4     u_int8_t                      next_state; /* is different from cur_state in the middle of ieee80211_transition_to */
 5     u_int8_t                      event_state; /* holds the current state to which  the event is delivered to */
 6     u_int8_t                      num_states;
 7     u_int8_t                      last_event;  /* last event */
 8     osdev_t                       oshandle;
 9     const ieee80211_state_info    *state_info;
10     void                          *ctx;                    /* context specific to the caller */
11     u_int32_t                     in_state_transition : 1; /* in state transition */
12     os_mesg_queue_t               mesg_q;
13     const char                    **event_names;   /* for debug printing */
14     u_int32_t                     num_event_names; /* for debug printing */
15 #if ENABLE_HSM_HISTORY
16     hsm_history_t                 history;
17 #endif    /* ENABLE_HISTORY */
18 
19     void (*ieee80211_hsm_debug_print) (void *ctx, const char *fmt,...);     
20 } ieee80211_hsm; 

上述数据结构中各字段的意义后面再分析,首先继续来看流程。 sm是wlan_connection_sm_create函数的局部变量(指针),在该函数中得到了分配的内核空间空间后调用    

1 OS_INIT_TIMER(oshandle, &(sm->sm_timer),connection_sm_timer_handler, (void *)sm);
2 
3 OS_INIT_TIMER(oshandle, &(sm->sm_roam_check_timer),connection_sm_roam_check_timer_handler, (void *)sm); 

注册了两个定时器。sm->sm_timer是assoc的各状态超时时间,sm->sm_roam_check_timer是为了切换设置的,定时器超时后驱动程序回去从新计算当前扫描到的AP排名, 以决定是否须要扫描(可是此时定时器并无开启)。

调用  

1 rc = wlan_scan_register_event_handler(sm->vap_handle,ieee80211_connection_sm_scan_evhandler, sm); 

将ieee80211_connection_sm_scan_evhandler函数赋给ss->ss_event_handlers//(ss = vaphandle->iv_ic->ic_scanner)。 函数ieee80211_connection_sm_scan_evhandler的功能是开始/结束SCAN。

目前只猜想osif_ioctl_create_vap函数接收应用层ioctl命令后调用osif_vap_setup函数完成了上述状态机的创建。可是创建起这一套状态机之后,是谁在什么地方出发了该这些状态机的运转呢??

相关文章
相关标签/搜索