wifi direct/p2p流程分析 基于android 5.1

本文详细分析了Android 5.1平台上Wifi Direct的使用步骤,包括P2P的启用、扫描、配对和连接流程。通过分析WifiP2pSettings和WifiP2pService,阐述了P2P功能的实现机制,如数据结构、初始化、使能、扫描及连接过程。同时,探讨了P2P在WPAS中的初始化,Action帧的注册,以及P2P连接的主动建立过程。
摘要由CSDN通过智能技术生成

 Wifi Direct流程分析

      Android平台中,P2P操作比较简单,用户只需要执行如下三个步骤:

      1)进入WifiP2pSettings界面

      2)搜索周围的P2P设备。搜索到的设备将显示在WifiP2pSettings

      3)用户选择其中的某个设备发起连接或者接受某设备发起的连接

     下面将根据这些步骤来分析WifiP2pSettingsWifiP2pService的流程,主要包括:P2P的使能、P2P的扫描、P2P的配对以及P2P的连接。


Wifi Direct环境的建立

WifiP2pSettings创建

      首先从WifiP2pSettings中的onActivityCreated()函数分析,代码如下:

<pre name="code" class="html">public void onActivityCreated(Bundle savedInstanceState) {
        addPreferencesFromResource(R.xml.wifi_p2p_settings);

        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
        mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION);
        mIntentFilter.addAction(WifiP2pManager.
        WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION);
        final Activity activity = getActivity();
        mWifiP2pManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
        if (mWifiP2pManager != null) {
           mChannel = mWifiP2pManager.initialize(activity, getActivity().getMainLooper(), null);
            if (mChannel == null) {
                //Failure to set up connection
                Log.e(TAG, "Failed to set up connection with wifi p2p service");
                mWifiP2pManager = null;
            }
             ..............
        mRenameListener = new OnClickListener() {..............}
             ...............
        uper.onActivityCreated(savedInstanceState);
       }


 

      onActivityCreated()函数主要的做了三件事:

      ①将P2P特有的Action添加到过滤器中。

      ②构造和初始化WifiP2pManager对象,并建立和WifiService联系。

      ③创建UI中按钮对应的OnClickListener

      WifiP2pSettings主要通过通过监听广播方式了解系统中Wifi P2p信息以及变化情况,下面简要介绍这几个属于P2P特有的广播:

      1)WIFI_P2P_STATE_CHANGED_ACTION-用于通知P2P功能的请用情况。

      2)WIFI_P2P_PEERS_CHANGED_ACTION-系统内部保存搜索到其他P2P设备信息的变化情况

      3)WIFI_P2P_CONNECTION_CHANGED_ACTION-用于通知P2P的连接情况

      4)WIFI_P2P_THIS_DEVICE_CHANGED_ACTION-用于通知本机设备信息变化情况

      5)WIFI_P2P_DISCOVERY_CHANGED_ACTION-用于通知P2P Discovery的工作状态

      6)WIFI_P2P_PERSISTENT_GROUPS_CHANGED_ACTION-用于通知persistent group信息的变化情况。

WifiP2pService的启动

     首先WifiP2pServicenew了一个WifiP2pServiceimpl对象,下面主要来看看WifiP2pServiceimpl的构造函数:

public WifiP2pServiceImpl(Context context) {
    mContext = context;
    //STOPSHIP: get this from native side
mInterface = "p2p0";
..........
mP2pStateMachine = new P2pStateMachine(
    TAG, wifiP2pThread.getLooper(), mP2pSupported);
 mP2pStateMachine.start();
}

      WifiP2pServiceimpl构造函数主要是创建一个NetworkInfo,然后调用getPackageManager判断本机设备是否支持P2P功能。通过创建一个P2pStateMachine并启动StateMachine

     下面进入P2pStateMachine函数分析

P2pStateMachine(String name, Looper looper, boolean p2pSupported) {
    super(name, looper);
    
addState(mDefaultState);
addState(mP2pNotSupportedState, mDefaultState);
   ..............
 if (p2pSupported) {
                setInitialState(mP2pDisabledState);
            } else {
                setInitialState(mP2pNotSupportedState);
            }
            setLogRecSize(50);
            setLogOnlyTransitions(true);

      分析构造函数,看出P2pStateMachine的各个State关系如下图:

     P2pStateMachineWifiP2pService的核心,P2pStateMachine的初始状态是P2pDisableState


Wifi Direct模块的初始化

Wifi Direct的主要数据结构

     下面来分析Wifi Direct的几个主要的数据结构,首先看的是p2p_configp2p_data,它们的成员如下图5所示:

      p2p_config定义了25个回调函数,这些回调函数定义了P2P模块与外界交互的接口,均指向p2p_supplicant.c.

p2p_data指向一个p2p_config对象。

     下面来看下其他几个重要的数据结构。如下图6


        p2p_device代表一个p2p设备。其中设备名等信息存放在类型为p2p_peer_info的对象中

         p2p_group代表一个p2p group的信息,其内包含一个p2p_group_config对象和一个p2p_group_member链表。p2p_group_config代表group的配置信息,p2p_group_member链表代表的是p2p client信息。


Wifi DirectWPAS中的初始化流程

       Wifi DirectWPAS中的初始化工作主要从wpas_p2p_init()函数开始,下面看看wpas_p2p_init()代码:

int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
{
struct p2p_config p2p;
int i;
if (wpa_s->conf->p2p_disabled)
   if (wpa_s->conf->p2p_disabled)
..........
os_memset(&p2p, 0, sizeof(p2p));
p2p.cb_ctx = wpa_s;
p2p.debug_print = wpas_p2p_debug_print;
p2p.p2p_scan = wpas_p2p_scan;
p2p.send_action = wpas_send_action;
..........
os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
os_memcpy(p2p.dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN);
p2p.dev_name = wpa_s->conf->device_name;
p2p.manufacturer = wpa_s->conf->manufacturer;
p2p.model_name = wpa_s->conf->model_name;
p2p.model_number = wpa_s->conf->model_number;
p2p.serial_number = wpa_s->conf->serial_number;
if (wpa_s->wps) {
		os_memcpy(p2p.uuid, wpa_s->wps->uuid, 16);
		p2p.config_methods = wpa_s->wps->config_methods;
	}
.........

	global->p2p = p2p_init(&p2p);
	if (global->p2p == NULL)
		return -1;
	global->p2p_init_wpa_s = wpa_s;
	for (i = 0; i < MAX_WPS_VENDOR_EXT; i++) {
		if (wpa_s->conf->wps_vendor_ext[i] == NULL)
			continue;
		p2p_add_wps_vendor_extension(
			global->p2p, wpa_s->conf->wps_vendor_ext[i]);
	}
        ...........
}

wpas_p2p_init()函数主要完成两件工作:

1)构造一个p2p_config对象并对p2p_config对象对象初始化,然后根据

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值