高通QSDK qcawifi源码日志跟踪

ieee80211_assoc_private.h 中有关于状态机的变迁说明

# disassoc 流程分析
首先是状态机
ieee80211_state_info ieee80211_assoc_sm_info[] = {

    {
        (u_int8_t) IEEE80211_ASSOC_STATE_DISASSOC,  // 状态id
        (u_int8_t) IEEE80211_HSM_STATE_NONE,		//sub 状态
        (u_int8_t) IEEE80211_HSM_STATE_NONE,        //初始化sbub状态
        false,										//如果有sub 状态 为true
        "DISASSOC",									//名字
        ieee80211_assoc_state_disassoc_entry,		//进入时候的action
        ieee80211_assoc_state_disassoc_exit,        //出来时候的action
        ieee80211_assoc_state_disassoc_event		//事件处理函数
    },

};


状态机
{
	(u_int8_t) IEEE80211_ASSOC_STATE_RUN,
	(u_int8_t) IEEE80211_HSM_STATE_NONE,
	(u_int8_t) IEEE80211_HSM_STATE_NONE,
	false,
	"RUN",
	ieee80211_assoc_state_run_entry,
	ieee80211_assoc_state_run_exit,
	ieee80211_assoc_state_run_event
},
ieee80211_assoc_state_assoc_event //收到事件后 改变状态机为 IEEE80211_ASSOC_STATE_RUN
	case IEEE80211_ASSOC_EVENT_ASSOC_SUCCESS
		ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_RUN);

上面的状态机会调用 ieee80211_assoc_state_run_entry
{
	// todo 暂时不知道干嘛
	wlan_mlme_connection_up(sm->vap_handle);
	ieee80211_update_custom_scan_chan_list(sm->vap_handle, true);	
}









------------------------------------------------------------------------



wlan_assoc_sm_stop
{
	if (flags & IEEE80211_ASSOC_SM_STOP_DISASSOC) {
		// 发送 IEEE80211_ASSOC_EVENT_DISASSOC_REQUEST 事件
		ieee80211_sm_dispatch(smhandle->hsm_handle,IEEE80211_ASSOC_EVENT_DISASSOC_REQUEST,0,NULL);
	
	}	
}
该事件 会触发 函数调用
	
	
	
	
	
下面是流程
ieee80211_assoc_state_run_event
	case IEEE80211_ASSOC_EVENT_DISASSOC_REQUEST
		// 状态变迁   RUN => DISASSOC
		ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_DISASSOC);
		
		

上面的状态机会调用
ieee80211_assoc_state_disassoc_entry
	wlan_mlme_disassoc_request_with_callback(tx_disassoc_req_completion) 
    // 注册发送完成回调--》》》等待发送完成 这个里面会发送 disassoc 帧到对端
	……………………………… 省略其他代码
	
	// 在回调函数 
	tx_disassoc_req_completion
	{	
	    // 发送事件 IEEE80211_ASSOC_EVENT_DISASSOC_SENT
		ieee80211_sm_dispatch(sm->hsm_handle, IEEE80211_ASSOC_EVENT_DISASSOC_SENT,0,NULL);
	}



上面的事件发生后会回调下面的函数
ieee80211_assoc_state_disassoc_event                                                                         
    case IEEE80211_ASSOC_EVENT_DISASSOC_SENT:                                                                
    case IEEE80211_ASSOC_EVENT_TIMEOUT:
	    // 状态变迁为 	DISASSOC => INIT
		ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_INIT); // 转态变为初始化状态

上面的状态变迁会导致下面的exit函数调用		
ieee80211_assoc_state_disassoc_exit
{
	取消定时器等操作
}



 


 










probe 帧调用流程
mlme_vdev_sta_conn_start_cb
	ieee80211_mlme_join_infra_continue
	{
			ieee80211_send_probereq(ni, vap->iv_myaddr, ni->ni_bssid,
					ni->ni_bssid, ni->ni_essid, ni->ni_esslen,
					vap->iv_opt_ie.ie, vap->iv_opt_ie.length);
	}
	
	
	
	
	
	
	
	
	
	
ieee80211_send_auth 帧的调用流程	

ieee80211_assoc_state_join_event
	case IEEE80211_ASSOC_EVENT_JOIN_SUCCESS:
		ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_AUTH);
		
ieee80211_assoc_state_auth_event
	case IEEE80211_ASSOC_EVENT_AUTH_FAIL
	case IEEE80211_ASSOC_EVENT_TIMEOUT
		ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_AUTH)

	case IEEE80211_ASSOC_EVENT_DEAUTH:
		ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_AUTH)
	

ieee80211_assoc_state_assoc_event
	case IEEE80211_ASSOC_EVENT_DEAUTH
		ieee80211_sm_transition_to(sm->hsm_handle,IEEE80211_ASSOC_STATE_AUTH);

上面的函数收到事件后,触发状态机调用ieee80211_assoc_state_auth_entry

static void ieee80211_assoc_state_auth_entry(void *ctx)
	wlan_mlme_auth_request
		ieee80211_send_auth(ni, IEEE80211_AUTH_SHARED_REQUEST, 0, NULL, 0, NULL);
struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
{
	#ifndef CONFIG_NO_WPA_MSG
	wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);--------------解释1
	#endif /* CONFIG_NO_WPA_MSG */

	ret = eap_register_methods();// 注册eap方法 比如MD5 TLS TTLS 
	eloop_init()
	global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global); // 建立ctrl sockt -g 注册eloop read socket 注册 wpa msg callback 函数
	wpas_notify_supplicant_initialized(global)// dbus初始化 hidl初始化 注册hidl read sockt 注册 hidl service vendor HIDL service
	wifi_display_init(global)
	eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,wpas_periodic, global, NULL)

}

解释1
{
wpa_supplicant_init函数的主要功能是初始化wpa_global以及一些与整个程序相关的资源,包括随机数资源、eloop事件循环机制以及设置消息全局回调函数。

此处先简单介绍消息全局回调函数,一共有两个。

wpa_msg_get_ifname_func:有些输出信息中需要打印出网卡接口名。该回调函数用于获取网卡接口名。
wpa_msg_cb_func:除了打印输出信息外,还可通过该回调函数进行一些特殊处理,如把输出信息发送给客户端进行处理。
上述两个回调函数相关的代码如下所示。
wpa_debug.c


// wpa_msg_ifname_cb用于获取无线网卡接口名
// WPAS为其设置的实现函数为wpa_supplicant_msg_ifname_cb
// 读者可自行阅读此函数
static wpa_msg_get_ifname_func wpa_msg_ifname_cb = NULL;
void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func){
	wpa_msg_ifname_cb = func;
} 
// WPAS中,wpa_msg_cb的实现函数是wpa_supplicant_ctrl_iface_msg_cb,它将输出信息发送给客户端
// 图4-2最后两行的信息就是由此函数发送给客户端的。而且前面的"<3>"也是由它添加的
static wpa_msg_cb_func wpa_msg_cb = NULL;
void wpa_msg_register_cb(wpa_msg_cb_func func){
	wpa_msg_cb = func;
}

}




wpa_supplicant_ctrl_iface_process{
	if (os_strncmp(buf, "SELECT_NETWORK ", 15) == 0) {
		wpa_supplicant_ctrl_iface_select_network(wpa_s, buf + 15)
		{
			wpa_supplicant_select_network(wpa_s, ssid);----------------------------------
			{                                                                             127us
				wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING)---------删除掉接入认证
				{                                                                         69us
					wpa_supplicant_clear_connection()
					{
						
					}----------------------------------------------------------------------
				}
				
				
				
				if (wpa_s->connect_without_scan ||
					wpa_supplicant_fast_associate(wpa_s) != 1) {快速链路认证
					wpa_s->scan_req = NORMAL_SCAN_REQ;
					wpas_scan_reset_sched_scan(wpa_s);
					wpa_supplicant_req_scan(wpa_s, 0, disconnected ? 100000 : 0);
					log_w("step7\n");
				}
			}
			
			
			
			
			
			
			
		}---------------------------------------------------------------------------------------------------------274us
}





wpa_supplicant_ctrl_iface_roam
{

	wpa_supplicant_connect
	{
		wpa_supplicant_req_new_scan
		{
		
			return 0
		}
		
		wpa_supplicant_associate
		{
			wpas_start_assoc_cb
			{
				wpas_populate_assoc_ies
				
				
				wpa_drv_associate
				{

					wpa_driver_nl80211_associate
					{
						wpa_driver_nl80211_connect
						{
							wpa_driver_nl80211_try_connect
							{
								// 
								wpa_printf(MSG_DEBUG, "nl80211: Connect (ifindex=%d)", drv->ifindex);
								……
								ret = send_and_recv_msgs_owner(drv, msg, nl_connect, 1, NULL,(void *) -1, NULL, NULL); // 10ms 左右
								……
								wpa_printf(MSG_DEBUG,
										   "nl80211: Connect request send successfully");
							}
						}
					}
				}

			}
		}
	}
}


void IEEE80211_DPRINTF(struct ieee80211vap *vap, unsigned category, const char *fmt, ...)
{
	#if DBG_LVL_MAC_FILTERING
        if (!vap->iv_print.dbgLVLmac_on) {
	#endif
             va_start(ap, fmt);
             vsnprintf (tmp,(OS_TEMP_BUF_SIZE - (tmp - tmp_buf)), fmt, ap);
             va_end(ap);
			 void print_vap_msg(struct ieee80211vap *vap, unsigned category, const char *fmt, ...)
			 {
				
				 va_list ap;
				 va_start(ap, fmt);
				 if (vap) {
					asf_vprint_category(&vap->iv_print, category, fmt, ap);
					{
						
						
					}
				 } else {
					qdf_vprint(fmt, ap);
					{
						QDF_VTRACE_INFO(QDF_MODULE_ID_ANY, fmt, args);
						{
							#ifdef WLAN_LOG_INFO
							QDF_VTRACE(module_id, QDF_TRACE_LEVEL_INFO, fmt, args)
							{
								qdf_vtrace_msg
								{
									qdf_trace_msg_cmn(qdf_pidx, module, level, str_format, val);
									{
										void pr_info(const char *fmt, ...) ATTRIBUTE_FORMAT_PRINTF(1, 2);
									}
									
								}
								
							}
							
						}						
						
					}
				 }
				 va_end(ap);
					
					
				
				 
				 
				 
			 }
             ic->ic_log_text(ic,tmp_buf);
             OS_LOG_DBGPRINT("%s\n", tmp_buf);
	#if DBG_LVL_MAC_FILTERING
			}
	#endif
	
	
}



#ifdef QDF_TRACE_PRINT_ENABLE
#define qdf_print(args...) QDF_TRACE_INFO(QDF_MODULE_ID_ANY, ## args)
#define qdf_alert(args...) QDF_TRACE_FATAL(QDF_MODULE_ID_ANY, ## args)
#define qdf_err(args...)   QDF_TRACE_ERROR(QDF_MODULE_ID_ANY, ## args)
#define qdf_warn(args...)  QDF_TRACE_WARN(QDF_MODULE_ID_ANY, ## args)
#define qdf_info(args...)  QDF_TRACE_INFO(QDF_MODULE_ID_ANY, ## args)
#define qdf_debug(args...) QDF_TRACE_DEBUG(QDF_MODULE_ID_ANY, ## args)


 #ifdef WLAN_LOG_INFO
#define QDF_TRACE_INFO(params...) \
	__QDF_TRACE_FL(QDF_TRACE_LEVEL_INFO, ## params)


#define __QDF_TRACE_FL(log_level, module_id, format, args...) \
	QDF_TRACE(module_id, log_level, FL(format), ## args)

#if defined(WLAN_DEBUG) || defined(DEBUG) || defined(QDF_TRACE_PRINT_ENABLE)
	#define QDF_TRACE qdf_trace_msg
					  void qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,const char *str_format, ...)
					  {
							va_list val;

							va_start(val, str_format);
							qdf_trace_msg_cmn(qdf_pidx, module, level, str_format, val);
							va_end(val);
					  }




    qdf_print("[xym debug]qdf_print ieee80211_recv_mgmt\n");
    pr_info("[xym debug]pr_info ieee80211_recv_mgmt\n");
    printk("[xym debug]printk ieee80211_recv_mgmt\n");