Android Wifi小记

Android WLAN STA/AP 并发 Android 9 引入了可让设备同时在 STA 和 AP 模式下运行的功能。对于支持双频并发 (DBS) 的设备,此功能让一些新功能得以实现,例如在用户想要启用热点 (softAP) 时不会中断 STA WLAN。 阅读详情
AI摘要

本文详细剖析了Android系统的Wi-Fi架构,从Framework层到HAL层,再到Native层的实现细节,涵盖了WPA_supplicant配置、wificond进程管理、芯片模式支持及nl80211与mac80211的交互。通过代码路径和关键模块的介绍,揭示了Wi-Fi功能在Android系统中的复杂实现。

Wifi代码位置分布

代码路径作用
/framework/opt/net/wifi/service运行在system_server进程,位于Framework层。面向上层APP提供Wifi相关的服务
/framework/opt/net/wifi/wifi_hal运行在android.hardware.wifi@service-1.0 进程。 位于hal层,定义芯片接口方便不同芯片供应商实现。[1]
/external/wpa_supplicant_8wpa_supplicant & hostap 进程。位于native 层。
device/qcom/common/rootdir/etc/init.qcom.rc定义wpa_supplicant 服务的启动,以及wpa_supplicant启动时候参数配置 [2]
/system/connectivity/wificondwificond 进程。 开机的时候在zygote 起来的时候拉起,负责控制 wpa_supplicant & hostap 的启动和停止。以及scan功能[3]
/hardware/interface/wifiandroid.hardware.wifi@service-1.0 进程。 面向framework 提供服务
/vendor/qcom/opensource/interfaces/wifi运行在system_server进行,提供qcom supplicant&hostap hidl层接口
/vendor/qcom/opensource/softap运行在hostap 进程, qcom hostap 功能的实现
/vendor/qcom/opensource/wlan/qcacld-3.0qcom 芯片驱动
  • [1] wifi_hal 的实现,区别一般hal层的service通过dlopen去动态加载so库。android.hardware.wifi 直接将libwifi-hal作为动态库进行编译。那么怎么区分不同芯片供应商的实现了?这个问题可以通过wifi-hal的Android.mk(/framework/opt/net/wifi/libwifi-hal/Android.mk) 找到答案。在编译libwifi-hal的时候会根据 BORAD_WLAN_DEVICE 宏来决定链接不同芯片供应商的静态库。
LIB_WIFI_HAL := libwifi-hal-fallback
VENDOR_LOCAL_SHARED_LIBRARIES :=
ifeq ($(BOARD_WLAN_DEVICE), bcmdhd)
  LIB_WIFI_HAL := libwifi-hal-bcm
else ifeq ($(BOARD_WLAN_DEVICE), qcwcn)
  LIB_WIFI_HAL := libwifi-hal-qcom
  VENDOR_LOCAL_SHARED_LIBRARIES := libcld80211
else ifeq ($(BOARD_WLAN_DEVICE), mrvl)
  # this is commented because none of the nexus devices
  # that sport Marvell's wifi have support for HAL
  # LIB_WIFI_HAL := libwifi-hal-mrvl
else ifeq ($(BOARD_WLAN_DEVICE), MediaTek)
  # support MTK WIFI HAL
  LIB_WIFI_HAL := libwifi-hal-mt66xx
else ifeq ($(BOARD_WLAN_DEVICE), emulator)
  LIB_WIFI_HAL := libwifi-hal-emu
endif

# The WiFi HAL that you should be linking.
# ============================================================
include $(CLEAR_VARS)
LOCAL_MODULE := libwifi-hal
LOCAL_PROPRIETARY_MODULE := true
LOCAL_CFLAGS := $(wifi_hal_cflags)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_EXPORT_C_INCLUDE_DIRS := \
    $(LOCAL_PATH)/include
LOCAL_EXPORT_HEADER_LIBRARY_HEADERS := libhardware_legacy_headers
LOCAL_HEADER_LIBRARIES := libhardware_legacy_headers
LOCAL_SHARED_LIBRARIES := \
    libbase \
    libcutils \
    liblog \
    libnl \
    libutils \
    $(VENDOR_LOCAL_SHARED_LIBRARIES)
LOCAL_SRC_FILES := \
    driver_tool.cpp \
    hal_tool.cpp
LOCAL_WHOLE_STATIC_LIBRARIES := $(LIB_WIFI_HAL) libwifi-hal-common
include $(BUILD_SHARED_LIBRARY)

在hardware/interface/wifi/1.2/default/Android.mk ,android.hardware.wifi@1.0-service-lib 依赖 wifi-hal


  • [2] wpa_supplicant
    进程起来的时候可以配置参数
wpa_supplicant v2.4
Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi> and contributors

This software may be distributed under the terms of the BSD license.
See README for more details.

This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit (http://www.openssl.org/)

usage:
  wpa_supplicant [-BddhKLqqstuvW] [-P<pid file>] [-g<global ctrl>] \
        [-G<group>] \
        -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] [-p<driver_param>] \
        [-b<br_ifname>] [-e<entropy file>] [-f<debug file>] \
        [-o<override driver>] [-O<override ctrl>] \
        [-N -i<ifname> -c<conf> [-C<ctrl>] [-D<driver>] \
        [-m<P2P Device config file>] \
        [-p<driver_param>] [-b<br_ifname>] [-I<config file>] ...]

drivers:
  nl80211 = Linux nl80211/cfg80211
  wext = Linux wireless extensions (generic)
  wired = Wired Ethernet driver
  none = no driver (RADIUS server/WPS ER)
options:
  -b = optional bridge interface name
  -B = run daemon in the background
  -c = Configuration file
  -C = ctrl_interface parameter (only used if -c is not)
  -i = interface name
  -I = additional configuration file
  -d = increase debugging verbosity (-dd even more)
  -D = driver name (can be multiple drivers: nl80211,wext)
  -e = entropy file
  -f = log output to debug file instead of stdout
  -g = global ctrl_interface
  -G = global ctrl_interface group
  -K = include keys (passwords, etc.) in debug output
  -s = log output to syslog instead of stdout
  -T = record to Linux tracing in addition to logging
       (records all messages regardless of debug verbosity)
  -t = include timestamp in debug messages
  -h = show this help text
  -L = show license (BSD)
  -o = override driver parameter for new interfaces
  -O = override ctrl_interface parameter for new interfaces
  -p = driver parameters
  -P = PID file
  -q = decrease debugging verbosity (-qq even less)
  -u = enable DBus control interface
  -v = show version
  -W = wait for a control interface monitor before starting
  -m = Configuration file for the P2P Device interface
  -N = start describing new interface
example:
  wpa_supplicant -Dnl80211 -iwlan0 -c/etc/wpa_supplicant.conf

  • [3] wificond 的启动
    在/system/conectivity/wifcond 的 wificond.rc 中只定义了wificond服务器,但是并没有看到启动服务的条件。wificond是会随着zygote起来的时候顺手拉起来的。
//  /system/core/rootdir/init.zygote.64.rc
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
    group root readproc reserved_disk
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    onrestart restart wificond
    writepid /dev/cpuset/foreground/tasks
~


Wifi 芯片模式

IWifiChip.hal 定义了芯片模式的选择类型

  struct ChipIfaceCombinationLimit {
    vec<IfaceType> types; // Each IfaceType must occur at most once.
    uint32_t maxIfaces;
  };

  /**
   * Set of interfaces that can operate concurrently when in a given mode. See
   * ChipMode below.
   *
   * For example:
   *   [{STA} <= 2]
   *       At most two STA interfaces are supported
   *       [], [STA], [STA+STA]
   *
   *   [{STA} <= 1, {NAN} <= 1, {AP} <= 1]
   *       Any combination of STA, NAN, AP
   *       [], [STA], [NAN], [AP], [STA+NAN], [STA+AP], [NAN+AP], [STA+NAN+AP]
   *
   *   [{STA} <= 1, {NAN,P2P} <= 1]
   *       Optionally a STA and either NAN or P2P
   *       [], [STA], [STA+NAN], [STA+P2P], [NAN], [P2P]
   *       Not included [NAN+P2P], [STA+NAN+P2P]
   *
   *   [{STA} <= 1, {STA,NAN} <= 1]
   *       Optionally a STA and either a second STA or a NAN
   *       [], [STA], [STA+NAN], [STA+STA], [NAN]
   *       Not included [STA+STA+NAN]
   */
  struct ChipIfaceCombination {
    vec<ChipIfaceCombinationLimit> limits;
  };

首先ChipIfaceCombinationLimit 中 vec types; 表示包含的芯片支持的接口模式类型。 可能会包含多个接口。 uint32_t maxIfaces 表示最多同时能支持几种接口模式。

[ {STA} <= 2]
包含一个ChipIfaceCombinationLimit. types = { STA }; maxIfaces = 2;
组合如下:
[], //不包含STA
[STA], //支持一路STA
[STA, STA] // 支持两路STA

[{STA} <= 1, {NAN} <= 1, {AP} <= 1]
包含一个ChipIfaceCombinationLimit, types = {STA}; maxIfaces = 1;
包含一个ChipIfaceCombinationLimit, types = { NAN}; maxIfaces = 1;
包含一个ChipIfaceCombinationLimit, types = {AP}; maxIfaces = 1;
组合如下:
[], [STA], [NAN], [AP], [STA+NAN], [STA+AP], [NAN+AP], [STA+NAN+AP]

[{STA} <= 1, {NAN,P2P} <= 1]
包含一个ChipIfaceCombinationLimit, types = {STA}; maxIfaces = 1;
包含一个ChipIfaceCombinationLimit, types = { NAN, P2P}; maxIfaces = 1;
组合如下:
[], [STA], [STA+NAN], [STA+P2P], [NAN], [P2P]

不存在[NAN+P2P], [STA+NAN+P2P] 是因为 NAN,P2P在一组中,但是这组最多支持一路接口(maxIface = 1决定)。所以不存在同时NAN P2P同时支持。


根据上面的说明,我们来看一下代码走向。

/**
 * isDualInterfaceSupported 是由宏 WIFI_HIDL_FEATURE_DUAL_INTERFACE 决定。 
 * 这个宏在vendor/qcom/properity/common/msmnile_gvmq/BoardConfigVendor.mk 定义了
 */
    if (feature_flags_.lock()->isDualInterfaceSupported()) {
        // V2 Iface combinations for Mode Id = 2.
        // 最多支持一路 STA
        const IWifiChip::ChipIfaceCombinationLimit
            chip_iface_combination_limit_1 = {{IfaceType::STA}, 1};
       // 最多支持一路 AP
        const IWifiChip::ChipIfaceCombinationLimit
            chip_iface_combination_limit_2 = {{IfaceType::AP}, 1};
        IWifiChip::ChipIfaceCombinationLimit chip_iface_combination_limit_3;
        if (feature_flags_.lock()->isAwareSupported()) {
         // 最多支持 一路 NAN | P2P 但是 maxIfaces = 1 表示NAN & P2P 不能同时存在。
            chip_iface_combination_limit_3 = {{IfaceType::P2P, IfaceType::NAN},
                                              1};
        } else {
         // 最多支持一路 P2P
            chip_iface_combination_limit_3 = {{IfaceType::P2P}, 1};
        }
        //[{STA} <=1,  {AP} <= 1]
        const IWifiChip::ChipIfaceCombination chip_iface_combination_1 = {
            {chip_iface_combination_limit_1, chip_iface_combination_limit_2}};
        
        //[{STA} <= 1, {NAN, P2P} < 1] | [{STA} < 1, {P2P} < 1]
        const IWifiChip::ChipIfaceCombination chip_iface_combination_2 = {
            {chip_iface_combination_limit_1, chip_iface_combination_limit_3}};
        
        //[{STA} <= 1, {AP} <= 1, {NAN, P2P} < 1] | [{STA} < 1, {AP} <= 1, {P2P} < 1]
        const IWifiChip::ChipIfaceCombination chip_iface_combination_4 = {
            {chip_iface_combination_limit_1, chip_iface_combination_limit_2,
             chip_iface_combination_limit_3}};
       //kV2ChipModeId = 2
        if (feature_flags_.lock()->isApDisabled()) {
          const IWifiChip::ChipMode chip_mode = {
              kV2ChipModeId,
              {chip_iface_combination_2}};
          modes_ = {chip_mode};
          LOG(ERROR) << "chip mode combination 2 - STA+P2P/NAN";
        } else if (feature_flags_.lock()->isStaSapP2pEnabled()) {
          const IWifiChip::ChipMode chip_mode = {
              kV2ChipModeId,
              {chip_iface_combination_4}};
          modes_ = {chip_mode};
          LOG(ERROR) << "chip mode combination 4 - STA+SAP+P2P/NAN";
        } else {
          const IWifiChip::ChipMode chip_mode = {
            kV2ChipModeId,
            // [{STA} <=1,  {AP} <= 1, {NAN, P2P} < 1]
            {chip_iface_combination_1, chip_iface_combination_2}};
          modes_ = {chip_mode};
          LOG(ERROR) << "chip mode combination 1 or 2 - STA+AP or STA+P2P/NAN";
        }
    } else {
        // V1 Iface combinations for Mode Id = 0. (STA Mode)
        const IWifiChip::ChipIfaceCombinationLimit
            sta_chip_iface_combination_limit_1 = {{IfaceType::STA}, 1};
        IWifiChip::ChipIfaceCombinationLimit sta_chip_iface_combination_limit_2;
        if (feature_flags_.lock()->isAwareSupported()) {
            sta_chip_iface_combination_limit_2 = {
                {IfaceType::P2P, IfaceType::NAN}, 1};
        } else {
            sta_chip_iface_combination_limit_2 = {{IfaceType::P2P}, 1};
        }
        const IWifiChip::ChipIfaceCombination sta_chip_iface_combination = {
            {sta_chip_iface_combination_limit_1,
             sta_chip_iface_combination_limit_2}};
        const IWifiChip::ChipMode sta_chip_mode = {
            kV1StaChipModeId, {sta_chip_iface_combination}};
        // Iface combinations for Mode Id = 1. (AP Mode)
        const IWifiChip::ChipIfaceCombinationLimit
            ap_chip_iface_combination_limit = {{IfaceType::AP}, 1};
        const IWifiChip::ChipIfaceCombination ap_chip_iface_combination = {
            {ap_chip_iface_combination_limit}};
        const IWifiChip::ChipMode ap_chip_mode = {kV1ApChipModeId,
                                                  {ap_chip_iface_combination}};
        if (feature_flags_.lock()->isApDisabled()) {
          modes_ = {sta_chip_mode};
        } else {
          modes_ = {sta_chip_mode, ap_chip_mode};
        }
    }
}

Framework aidl 和 wificond 通讯

aidl 生成 java 和 c++ 的代码。

connectivity/wificond/aidl/android/net/wifi/IWificond.aidl

interface IWificond {
    // Create a network interface suitable for use as a WiFi client.
    @nullable IClientInterface createClientInterface(@utf8InCpp String iface_name);
    ...
    }

生成位置
Java代码生成位置:
out/target/common/obj/JAVA_LIBRARIES/wifi-service_intermediates/aidl/dotdot/dotdot/dotdot/dotdot/dotdo/
在这里插入图片描述
从Java层往下调用,Java层获取的是Bp,wificond是Bn。从下面的代码中可以看出,client直接transact()。
生成代码:

@Override public android.net.wifi.IClientInterface createClientInterface(java.lang.String iface_name) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
android.net.wifi.IClientInterface _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeString(iface_name);
mRemote.transact(Stub.TRANSACTION_createClientInterface, _data, _reply, 0);
_reply.readException();
_result = android.net.wifi.IClientInterface.Stub.asInterface(_reply.readStrongBinder());
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}

C++ 侧生成的代码位置:
out/target/product/msmnile_gvmq/obj/STATIC_LIBRARIES/libwificond_ipc_intermediates/aidl-generated

在这里插入图片描述
wificond进程, server.h 实现BnWifiCond。然后Java层通过transact()直接调到BnWificond的onTransact方法中。最后调到server方法中。

::android::status_t BnWificond::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
::android::status_t _aidl_ret_status = ::android::OK;
switch (_aidl_code) {
...
case Call::CREATECLIENTINTERFACE:
{
::std::string in_iface_name;
::android::sp<::android::net::wifi::IClientInterface> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
_aidl_ret_status = _aidl_data.readUtf8FromUtf16(&in_iface_name);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
//此处调用server.h中的实现。
::android::binder::Status _aidl_status(createClientInterface(in_iface_name, &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeStrongBinder(::android::net::wifi::IClientInterface::asBinder(_aidl_return));
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
...
}


nl80211 & netlink

+-------------+
|             |
|  Userspace  |
|             |
+-------------+
      ^
- - - | - - - - 
      | nl80211 (netlink)
      v
+-------------+
|             |
|  cfg80211   |
|             |
+-------------+
+-------------+
|             |
|  mac80211   |
|   driver    |
|             |
+-------------+
mac80211 driver

mac80211是一个框架,驱动程序开发人员可以使用它来编写SoftMAC无线设备的驱动程序。

SoftMAC设备允许对硬件进行更精细的控制,允许在软件中实现802.11帧管理,包括解析和生成802.11无线帧。今天大多数的802.11设备往往是这种类型的,FullMAC设备已经变得稀少。

mac80211为SoftMAC设备实现cfg80211回调,mac80211依靠cfg80211来注册到网络子系统和配置。 配置是通过cfg80211处理,可以通过nl80211和wireless extensions。
在mac80211中MLME在station 模式(STA )下是在内核中实现的,AP模式( hostapd )下是在用户空间实现的。

如果你有支持nl80211的新的用户空间的应用程序,那你不需要wireless-extensions来支持mac80211设备。

(先挖坑,后面再补)
参考:
About nl80211
man 7 netlink
libnl


ifconfig

通过ioctl 操作interface
man 7 netdevice


SYNOPSIS
       #include <sys/ioctl.h>
       #include <net/if.h>

DESCRIPTION
       This man page describes the sockets interface which is used to configure network devices.

       Linux supports some standard ioctls to configure network devices.  They can be used on any socket's file descriptor regardless of the family or type.  Most of them pass an ifreq struc-
       ture:

           struct ifreq {
               char ifr_name[IFNAMSIZ]; /* Interface name */
               union {
                   struct sockaddr ifr_addr;
                   struct sockaddr ifr_dstaddr;
                   struct sockaddr ifr_broadaddr;
                   struct sockaddr ifr_netmask;
                   struct sockaddr ifr_hwaddr;
                   short           ifr_flags;
                   int             ifr_ifindex;
                   int             ifr_metric;
                   int             ifr_mtu;
                   struct ifmap    ifr_map;
                   char            ifr_slave[IFNAMSIZ];
                   char            ifr_newname[IFNAMSIZ];
                   char           *ifr_data;
               };
           };
bool InterfaceTool::GetUpState(const char* if_name) {
  base::unique_fd sock(socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
  if (sock.get() < 0) {
    LOG(ERROR) << "Failed to open socket to set up/down state ("
               << strerror(errno) << ")";
    return false;
  }

  struct ifreq ifr;
  if (!GetIfState(if_name, sock.get(), &ifr)) {
    return false;  // logging done internally
  }

  return ifr.ifr_flags & IFF_UP;
}

bool InterfaceTool::SetUpState(const char* if_name, bool request_up) {
  base::unique_fd sock(socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
  if (sock.get() < 0) {
    LOG(ERROR) << "Failed to open socket to set up/down state ("
               << strerror(errno) << ")";
    return false;
  }

  struct ifreq ifr;
  if (!GetIfState(if_name, sock.get(), &ifr)) {
    return false;  // logging done internally
  }

  const bool currently_up = ifr.ifr_flags & IFF_UP;
  if (currently_up == request_up) {
    return true;
  }

  if (request_up) {
    ifr.ifr_flags |= IFF_UP;
  } else {
    ifr.ifr_flags &= ~IFF_UP;
  }

  if (TEMP_FAILURE_RETRY(ioctl(sock.get(), SIOCSIFFLAGS, &ifr)) != 0) {
    LOG(ERROR) << "Could not set interface flags for " << if_name
               << " (" << strerror(errno) << ")";
    return false;
  }

  return true;
}

qcom 平台WLAN相关编译文件

在qcom平台,就wlan相关的编译分布的比较散,一时间难以追踪。先记一笔方便后续的工作查看。
跟qcom相关的编译主要分布 /device 和 /vendor下面。
在进行编译的时候我们都是需要lunch,这个过程就是选择需要编译的工程版本。

//加载编译Android相关的环境变量
source build/env   
//选择工程版本,后续进行编译的时候,就是从 /device/qcom/msmnile_gvmq/msmnile_gvmq.mk 下的编译脚本开始加载编译。
lunch msmnile_gvmq  

从msmnile_gvmq.mk开始。

  • 1
    加载 /device/qcom/common/common.mk 进行编译
// file path: /device/qcom/msmnile_gvmq/msmnile_gvmq.mk
$(call inherit-product, device/qcom/common/common64.mk)
  • 2
    加载同目录下base.mk 进行编译
    加载 /vendor/qcom/proprietary/common/config/device-vendor.mk 进行编译
//file path: /device/qcom/common/commom.mk
$(call inherit-product, device/qcom/common/base.mk)

# For PRODUCT_COPY_FILES, the first instance takes precedence.
# Since we want use QC specific files, we should inherit
# device-vendor.mk first to make sure QC specific files gets installed.
$(call inherit-product-if-exists, $(QCPATH)/common/config/device-vendor.mk)
$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
  • 2-1
    这个文件里配置了需要很高通相关的module,值得去研究一下。
//file path:  /device/qcom/msmnile_gvmq/AndroidBoard.mk
#----------------------------------------------------------------------
# wlan specific
#----------------------------------------------------------------------
ifeq ($(strip $(BOARD_HAS_QCOM_WLAN)),true)
include device/qcom/wlan/msmnile_au/AndroidBoardWlan.mk
endif

//file path:  /device/qcom/wlan/msmnile_au/AndroidBoardWlan.mk
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE       := hostapd_default.conf
LOCAL_MODULE_TAGS  := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH  := $(TARGET_OUT_ETC)/hostapd
LOCAL_SRC_FILES    := hostapd.conf
include $(BUILD_PREBUILT)

include $(CLEAR_VARS)
LOCAL_MODULE       := hostapd.accept
LOCAL_MODULE_TAGS  := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH  := $(TARGET_OUT_ETC)/hostapd
LOCAL_SRC_FILES    := hostapd.accept
include $(BUILD_PREBUILT)

include $(CLEAR_VARS)
LOCAL_MODULE       := hostapd.deny
LOCAL_MODULE_TAGS  := optional
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH  := $(TARGET_OUT_ETC)/hostapd
LOCAL_SRC_FILES    := hostapd.deny
include $(BUILD_PREBUILT)

//file path: /device/qcom/common/base.mk
#HOSTAPD
HOSTAPD := hostapd
HOSTAPD += hostapd_cli
HOSTAPD += nt_password_hash
HOSTAPD += hlr_auc_gw
HOSTAPD += test-milenage
HOSTAPD += hostapd.conf
HOSTAPD += hostapd_default.conf
HOSTAPD += hostapd.deny
HOSTAPD += hostapd.accept

#INIT
INIT += init.qcom.rc

//file path: /device/qcom/common/rootdir/Android.mk
include $(CLEAR_VARS)
LOCAL_MODULE       := init.qcom.rc
LOCAL_MODULE_TAGS  := optional eng
LOCAL_MODULE_CLASS := ETC
LOCAL_SRC_FILES    := etc/init.qcom.rc
LOCAL_MODULE_PATH  := $(TARGET_OUT_VENDOR_ETC)/init/hw
include $(BUILD_PREBUILT)

//file path: device/qcom/common/rootdir/etc/init.qcom.rc
service wpa_supplicant /vendor/bin/hw/wpa_supplicant \
    -iwlan0 -Dnl80211 -c/vendor/etc/wifi/wpa_supplicant.conf
#    -O/data/vendor/wifi/wpa/sockets -puse_p2p_group_interface=1 -dd \
#    -g@android:vendor_wpa_wlan0
#   we will start as root and wpa_supplicant will switch to user wifi
#   after setting up the capabilities required for WEXT
#   user wifi
#   group wifi inet keystore
#    interface android.hardware.wifi.supplicant@1.0::ISupplicant default
#    interface android.hardware.wifi.supplicant@1.1::ISupplicant default
    class main
    socket vendor_wpa_wlan0 dgram 660 wifi wifi
    disabled
    oneshot
  • 3
    加载 /vendor/qcom/proprietary/common/msmnile_gvmq/BoradConfigVendor.mk 进行编译
    加载 /device/qcom/wlan/msmnile_au/BoardConfigWlan.mk 进行编译
//file path:/device/qcom/msmnile_gvmq/BoardConfig.mk
-include $(QCPATH)/common/msmnile_gvmq/BoardConfigVendor.mk

ifeq ($(strip $(BOARD_HAS_QCOM_WLAN)),true)
include device/qcom/wlan/msmnile_au/BoardConfigWlan.mk
endif
  • 4
    加载 device/qcom/wlan/msmnile_au/wlan.mk 进行编译
include device/qcom/wlan/msmnile_au/wlan.mk

hostapd.conf 解析

摘抄自:hostapd配置解析

interface=wlp2s0
#bridge=br0
driver=nl80211
logger_syslog=-1
logger_syslog_level=2
logger_stdout=-1
logger_stdout_level=2
#ctrl_interface=/var/run/hostapd
#ctrl_interface_group=wheel
#ctrl_interface_group=0
##### IEEE 802.11 related configuration #######################################
ssid=test
#ssid2=mytest
#ssid2=P"hello\nthere"
utf8_ssid=1
# ISO/IEC 3166-1 标准的国家代码,用于设置监管域。根据需要设置,按照哪个国家来操作设备。
# 这可以限制可用的频道和发射功率。
#country_code=CN
# 是否启用 IEEE 802.11d,0 禁用(默认),1 启用。
# 需要正确设置 country_code 才能使 IEEE 802.11d 正常工作。
#ieee80211d=1
# 是否启用 IEEE 802.11h,0 禁用(默认),1 启用。
# 这将启用雷达探测和 DFS 支持,如果可用话。
#ieee80211h=1
# 添加 Power Constraint element 到 Beacon 和 Probe Response frames 中去。
#local_pwr_constraint=5
# 该选项仅在 ieee80211h=1 选项并且已经配置 local_pwr_constraint 选项时可用。
#spectrum_mgmt_required=1
# 设置无线模式需要硬件支持,a = IEEE 802.11a, b = IEEE 802.11b, g = IEEE 802.11g, ad = IEEE 802.11ad (60 GHz)
# hw_mode=a 或 hw_mode=g 选项也与 IEEE 802.11n 一起使用来设置波段。
# 当使用 ACS 时(看下文 channel parameter ),可以使用特殊的选项值 hw_mode=any ,说明可以使用任何可用的波段,该值当前仅在驱动使用了 offloaded ACS 的情况下有效。
# 默认: hw_mode=b
hw_mode=g
# 注意有些设备不使用这个选项,而是需要在 iwconfig 中另外配置。
# 如果编译的时候启用了 CONFIG_ACS 选项。通过设置 channel=acs_survey 或 channel=0,这样 hostapd 可以在运行时基于 ACS survey 算法自动选择合适的信道。
# 有些设备仅支持最大为11频道,有些支持最大为13频道,可以通过iw list 查看。
# 另外启用 ht_capab 将影响可用的频道数
channel=6
# ACS tuning - 信道自动选择
# 参考:http://wireless.kernel.org/en/users/Documentation/acs
# 信道自动选择,有助于选择更好的信道,但是会增加启动时间,一般不需要修改。
# 可以通过设置下面选项自定义 ACS survey 算法。
# 默认:acs_num_scans=5  acs_chan_bias=1:0.8 6:0.8 11:0.8
#acs_num_scans=40
#acs_chan_bias=1:0.8 6:0.8 11:0.8
# 默认允许所有信道
#chanlist=100 104 108 112 116
#chanlist=1 6 11-13
# beacon 间隔  (默认: 100; 范围 15到65535)
#beacon_int=100
#dtim_period=1
# 默认且最大值为2007个列表
#max_num_sta=255
#rts_threshold=2347
#fragm_threshold=2346
#supported_rates=10 20 55 110 60 90 120 180 240 360 480 540
#basic_rates=10 20
#basic_rates=10 20 55 110
#basic_rates=60 120 240
# 用命令:iw list 查看无线网卡是否有“short preamble supported”。
# 0 禁用,1 启用,无线网卡支持的话可以启用以改善网络性能。
#preamble=1
# 无线MAC地址过滤
# 此选项要求 driver=hostap 或 driver=nl80211
# 0 = 接受所有连接,仅拒绝 deny 列表中的连接
# 1 = 拒绝所有连接,仅接受 accept 列表中的连接
# 2 = 使用外部 RADIUS 服务器 (还是会优先查找 accept/deny 列表)
# 简单一点的话,可以将两个列表设置为同一个文件,仅由 macaddr_acl 来控制允许或拒绝
macaddr_acl=0
accept_mac_file=/etc/hostapd/hostapd.accept
deny_mac_file=/etc/hostapd/hostapd.deny
# 身份验证算法,1 开放系统认证,2 共享密钥认证(需要 WEP),3 两者
auth_algs=3
# 是否广播,0 广播SSID,1 不广播SSID(发送空SSID,即长度为0的SSID),
# 2 忽略广播 SSID 的探测请求,跟1类似,但是兼容某些不支持空SSID的设备
#ignore_broadcast_ssid=0
#vendor_elements=dd0411223301
# 启用WMM
wmm_enabled=1
#
# WMM-PS Unscheduled Automatic Power Save Delivery [U-APSD]
# Enable this flag if U-APSD supported outside hostapd (eg., Firmware/driver)
#uapsd_advertisement_enabled=1
#
# Low priority / AC_BK = background
#wmm_ac_bk_cwmin=4
#wmm_ac_bk_cwmax=10
#wmm_ac_bk_aifs=7
#wmm_ac_bk_txop_limit=0
#wmm_ac_bk_acm=0
# Note: for IEEE 802.11b mode: cWmin=5 cWmax=10
#
# Normal priority / AC_BE = best effort
#wmm_ac_be_aifs=3
#wmm_ac_be_cwmin=4
#wmm_ac_be_cwmax=10
#wmm_ac_be_txop_limit=0
#wmm_ac_be_acm=0
# Note: for IEEE 802.11b mode: cWmin=5 cWmax=7
#
# High priority / AC_VI = video
#wmm_ac_vi_aifs=2
#wmm_ac_vi_cwmin=3
#wmm_ac_vi_cwmax=4
#wmm_ac_vi_txop_limit=94
#wmm_ac_vi_acm=0
# Note: for IEEE 802.11b mode: cWmin=4 cWmax=5 txop_limit=188
#
# Highest priority / AC_VO = voice
#wmm_ac_vo_aifs=2
#wmm_ac_vo_cwmin=2
#wmm_ac_vo_cwmax=3
#wmm_ac_vo_txop_limit=47
#wmm_ac_vo_acm=0
# Note: for IEEE 802.11b mode: cWmin=3 cWmax=4 burst=102
# 检测客户端不活动超时,是否在线间隔时间,默认每5分钟检测客户端是否在线
# 站点不活动限制,默认5分钟
#ap_max_inactivity=300
# 默认禁用,设置为1,说明只要客户在5分钟内没有活动就断线,即使客户端仍然在AP信号的范围内,如果客户端过多可以启用来提高带机量。
#skip_inactivity_poll=0
# 对于过度的传输失败或其他连接丢失的情况下,断开连接,这并不适合所有设备
#disassoc_low_ack=1
# 最大允许侦听间隔,默认65535,即不限制 (how many Beacon periods STAs are allowed to remain asleep)
#max_listen_interval=100
# WDS(4-address frame)模式,仅在 driver=nl80211 的情况下支持
#wds_sta=1
# 仅在设置了bridge= 时有效,默认情况下,例如当设置了bridge=br0,那么wds_bridge=br0。
# 当然也可以手动指定为wds_bridge=XXXXX。
#wds_bridge=wds-br0
# Start the AP with beaconing disabled by default.没明白是什么意思。
#start_disabled=0
# AP隔离,1启用,0禁用。默认不隔离。
#ap_isolate=1
#bss_load_update_period=50
# 用于测试的
#bss_load_test=12:80:20000
##### IEEE 802.11n related configuration ######################################
# 启用80211n,你也将需要启用WMM来使用全部HT功能。
ieee80211n=1
# [HT40-]或[HT40+]没有设置的话将只工作在20MHz,
# [HT40-]对应可使用的频道为5-13
# [HT40+]对应可使用的频道为1-7(欧洲标准为1-9)
# 当多径效应不是很严重时,用户可以将该间隔配置为[SHORT-GI-20][SHORT-GI-40]
# 个人理解,如果不上天馈系统的话可以启用[SHORT-GI-20][SHORT-GI-40],前提是硬件支持。
#ht_capab=[LDPC][HT40-][HT40+][SHORT-GI-20][SHORT-GI-40][SMPS-DYNAMIC][GF][TX-STBC][RX-STBC123][DELAYED-BA][MAX-AMSDU-7935][DSSS_CCK-40][40-INTOLERANT][LSIG-TXOP-PROT]
# intel Wireless-N 105 (rev c4) 网卡支持的选项
ht_capab=[HT40-][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40][40-INTOLERANT][GF]
# Atheros AR9271 网卡支持的选项
#ht_capab=[HT40-][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40][40-INTOLERANT][RX-STBC1]
#ht_capab=[HT40-][SHORT-GI-20][SHORT-GI-40][DSSS_CCK-40]
#ht_capab=[HT40-][SHORT-GI-20][SHORT-GI-40]
#ht_capab=[HT40+][DSSS_CCK-40][40-INTOLERANT]
# 强制要求客户端使用HT PHY,不使用就拒绝。
#require_ht=0
# 间隔时间(秒)
#obss_interval=5
##### WPA/IEEE 802.11i configuration ##########################################
# 1 wpa,2 wpa2, 3 两者。 新的设备可以设置为2,仅使用wpa2版本。
wpa=2
# 指定密码,ASCII码或密码字符。
#wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
#wpa_passphrase=12345678
# 使用密码文件,可以跟客户端MAC地址绑定设置不同的密码,比较实用。
wpa_psk_file=/etc/hostapd/hostapd.wpa_psk
# 是否使用验证服务器,0 禁用(默认),1 可用,2 强制使用(其他方式将拒绝)
#wpa_psk_radius=0
# 设置密钥管理算法WPA-PSK WPA-EAP或两者
wpa_key_mgmt=WPA-PSK
# 设置加密算法,CCMP就是AES,不推荐使用TKIP,除非设备不支持。
wpa_pairwise=CCMP
# 默认情况下rsn_pairwise自动设置为wpa_pairwise的值,当然也可以手动指定。
#rsn_pairwise=CCMP
#wpa_group_rekey=600
#wpa_strict_rekey=1
#wpa_gmk_rekey=86400
#wpa_ptk_rekey=600
# 预认证
#rsn_preauth=1
#rsn_preauth_interfaces=wlp2s0 br0 enp3s0
#peerkey=1
# 80211w支持,0 禁用(默认),1 可选,2 强制使用(其他方式将拒绝) 有些网卡不支持
#ieee80211w=1
# AES-128-CMAC(默认) BIP-GMAC-128 BIP-GMAC-256 BIP-CMAC-256 四种
# 一般通用设备都支持AES-128-CMAC,其他的不一定
#group_mgmt_cipher=AES-128-CMAC
#assoc_sa_query_max_timeout=1000
#assoc_sa_query_retry_timeout=201
#disable_pmksa_caching=0
#okc=1
#sae_anti_clogging_threshold=5
#sae_groups=19 20 21 25 26
##### IEEE 802.11r configuration ##############################################
# Wi-Fi无线漫游标准
#mobility_domain=a1b2
#r0_key_lifetime=10000
#r1_key_holder=000102030405
#reassociation_deadline=1000
#pmk_r1_push=1
##### Neighbor table ##########################################################
#ap_table_max_size=255
#ap_table_expiration_time=3600
##### IEEE 802.11v-2011 #######################################################
# Wi-Fi节能版 
#time_advertisement=2
#time_zone=CST8
# 下面三项有些网卡不支持
#wnm_sleep_mode=1
#bss_transition=1
#proxy_arp=1

#bss=wifi0
#bssid=00:13:10:95:fe:0d
#interface=wifi0
#ssid=test2
#bridge=br0
#driver=nl80211
#auth_algs=1
#ignore_broadcast_ssid=0
#wpa=2
#wpa_passphrase=12345678
SDIO_WiFi驱动学习之安卓WLAN架构介绍及调用流程分析 一、引言 上一篇博客大概介绍了MMC子系统和SDIO相关知识及架构,这一篇博客则大致分析安卓的WLAN架构及上层如何调用WLAN驱动的流程。 虽然我工作的开发环境是安卓系统,但由于我不是专业的安卓应用/框架开发工程师,所以对安卓层的一些代码并不是特别熟悉,只能大致梳理流程,不专业的地方请谅解。 本文部分内容摘抄自网络,若有侵权,请联系删除。 二、安卓WLAN架构 1、应用框架(Application framework) 在应用程序框架级别是应用程序代码,它使用各种android.net.. 阅读详情

相关推荐

Android.bp/mk的常见语法对比

Android.mk和Android.bp文件中的一些常见属性的对应关系可以参考:build/soong/androidmk/androidmk/android.go文件。vendor: true或者。

今天也是星期五的博客 1226

Android10 wifi AP功能

wifi AP功能1.概述2.wifi Ap功能在应用层开发3.配置信息系统时序图4.startTethering时序图 1.概述 随着网络的广泛应用,广大用户对网络使用的便利性有了更高的要求。为了方便网络的使用,在一些有固定网络信号的设备上,有共享网络的需求。因此,Android实现了三种方式的网络共享(tether): usb 通过usb连接,可以把有网络的设备网络信息通过usb连接线传输给连接的设备 蓝牙 网络信息通过wifi天线发送,实现类似wifi的无线网络 wifi 本篇文章重点说明wifi

卓越之路 4243

使用IDAE,开发android,真机调试,自用小记

使用IDAE,开发android小记 安装IDEA 参考地址 https://blog.youkuaiyun.com/qq_34668897/article/details/88251913 安装android SDK 修改项目的gradle配置 buildscript { repositories { // google() // jcenter() ...

weixin_45775077的博客 385

[Android][踩坑]libwifi-hal是如何兼容平台差异的

背景 事情起因是我在学习WIFI Hal部分时,发现一个比较困惑的地方: 代码路径:hardware/interfaces/wifi/1.2/default/wifi_legacy_hal.cpp: wifi_error WifiLegacyHal::QcAddInterface(const std::string& iface_name, const std::string& new_ifname,

Ryan ZHENG的专栏 9229

Android电量测试工具battery-historian学习小记

1. 环境配置: 1.1. 下载Go安装文件pkg,并进行安装, 输入命令go version检测是否安装成功: 1.2 配置Go的环境变量: 终端执行命令sudo vim .zshrc,打开环境变量配置文件,并写入如下内容: export GOPATH=$HOME/work export GOBIN=$GOPATH/bin export PATH=$PATH:$GOBIN

安静的偏执的专栏 1万+

MATLAB不能识别已安装的visual studio 2015解决方法

首先,对于MATLAB识别已经安装的vs版本通过命令: mex -setup 下图为本电脑下同时安装的两个visual studio 如果搞清楚MATLAB识别电脑上安装vs的过程,可通过命令: mex -setup -v MATLAB输出识别编译器的整个过程。其中HKLM和HKCU分别是注册表中的HKEY_CURRENT_USER,HKEY_LOCAL_MA…的缩写,MATLAB没有找到对应编译器是由于注册表里没有对应信息(主要是文件路径,C++编译器的路径),或者在注册表里存在该信息,但是找不到

qq_36320710的博客 4895

Android Wifi小记 (2)

Hostapd ACS 开关控制 public HostapdHal(Context context) { mEnableAcs = context.getResources().getBoolean(R.bool.config_wifi_softap_acs_supported); mEnableIeee80211AC = context.getResources().getBoolean(R.bool.config_wifi_sof

github_33381613的博客 2485

从零开始的BW(五) 外部系统供数之OData测试

5、激活添加的服务,如提示下图中的激活失败,根据生成URI在事务代码SICF目录中找到对应的服务,设置超时时间,设置完之后重新激活即可,详情可参考SAP note 1986626。如果刚才设置BY Odata的query在这没有显示,SE38执行程序EQ_RS_AUTOSETUP,选中需要生成服务的query,生成服务后再去添加服务。测试get方法,URI中默认的参数是?4、事务代码/IWFND/MAINT_SERVICE中添加服务,如果提示用户不再登陆,在事务代码前加上/O或者/N即可。

m0_61386064的博客 1107

安卓如何获得WiFi SSID,BSSID,及其区别。

今天踩了个坑,可能也是自己看文档不够认真,产生了一点点SSID,BSSID的认知误差,当时百度查看了一篇文档,在文档中提取了统称SSID之类的字眼,在脑海中生成了错误的信息既SSID内包含了BSSID,小记一下。 SSID:WIFI名称 BSSID:MAC物理地址 安卓如何得到这些。如下,其WiFi信息大致都在,WiFiinfo这个对象中。 /** * 获取当前连接WIFI的S...

三月的船长 1万+

STM32 SYSTICK定时器及延时函数详解

STM32 SYSTICK及延时函数详解 SysTick定时器 SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。例如,为多个任务许以不同数目的时间片,确保没有一个任务能霸占系统;或者把每个定时器周期的某个时间范围赐予特定的任务等,还有操作系统提供的各种定时功能,都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心

w1050321758的博客 2365

stm32F103定时器使用方法

文章目录1、STM32的Timer简介2、普通定时器TIM2-TIM52.1 时钟来源2.2 计数器模式2.3 编程步骤3、程序源代码4、总结 1、STM32的Timer简介 STM32中一共有11个定时器,其中2个高级控制定时器,4个普通定时器和2个基本定时器,以及2个看门狗定时器和1个系统嘀嗒定时器。其中系统嘀嗒定时器是前文中所描述的SysTick,看门狗定时器以后再详细研究。今天主要是研究剩下的8个定时器。 其中TIM1和TIM8是能够产生3对PWM互补输出的高级登时其,常用于三相电机的驱动,时钟

weixin_43582209的博客 4515

android wifi bssid是什么意思,安卓如何得到WiFi SSID,BSSID,及其区别。

今天踩了个坑,可能也是本身看文档不够认真,产生了一点点SSID,BSSID的认知偏差,当时百度查看了一篇文档,在文档中提取了统称SSID之类的字眼,在脑海中生成了错误的信息既SSID内包含了BSSID,小记一下。codeSSID:WIFI名称对象BSSID:MAC物理地址文档安卓如何获得这些。以下,其WiFi信息大体都在,WiFiinfo这个对象中。get/*** 获取当前链接WIFI的SSID*...

weixin_36269733的博客 2971

手把手教你用ESP32驱动MAX30102心率血氧传感器(含完整代码)

本文详细介绍了如何使用ESP32微控制器驱动MAX30102心率血氧传感器,构建智能健康监测系统。内容涵盖PPG原理、硬件连接、驱动配置、信号处理算法以及Web服务器数据可视化,提供完整代码实现,帮助开发者快速上手物联网健康设备开发。

weixin_29208077的博客 586

如何获取bssid_安卓如何获得WiFi SSID,BSSID,及其区别。

今天踩了个坑,可能也是自己看文档不够认真,产生了一点点SSID,BSSID的认知误差,当时百度查看了一篇文档,在文档中提取了统称SSID之类的字眼,在脑海中生成了错误的信息既SSID内包含了BSSID,小记一下。SSID:WIFI名称BSSID:MAC物理地址安卓如何得到这些。如下,其WiFi信息大致都在,WiFiinfo这个对象中。/*** 获取当前连接WIFI的SSID*/public sta...

weixin_33895396的博客 3914

QT编程系列1--QT学习前需知

本周学习了一些QT编程方面的知识,学写了几个程序,这里把记录下来。一方面对前面学习的知识做一个总结,便于以后复习、再学习和应用;另一方面也和大家做个交流,有不足的地方请各位看官多指点。   首先是做一些学习之前的交代:一,学习QT需要哪些基础;二,学习QT有哪些用途,QT较其他的开发工具有哪些特点;三,学习QT的思路。

霜月孤鸟&RTEMS&TinyOS 1115

互联网的发展简史—web

互联网是我现在生活所离不开的一个东西,但是你知道互联网的前世今生吗?本文将讲解互联网的发展史,以及很火的元宇宙概念。

yj11290301的博客 3561

Windows 11 Android subsystem无需美区ID和测试通道直接安装——Win11 安卓子系统安装小记

Windows 11 Android subsystem——Win11 安卓子系统安装小记 文章目录Windows 11 Android subsystem——Win11 安卓子系统安装小记前言一、运行环境二、使用步骤1.下载appx安装程序2.打开hyper-v功能3.用管理员权限打开windows terminal4.使用5.安装软件6.使用软件总结 前言 微软发布win11之时有一个我很期待的功能就是可以运行安卓app,现在它终于来了 一、运行环境 官方要求系统更新beta通道并且要在北美

OooLeeeeee的博客 8107

EndNote导入文献出现带有大括号{}乱码的解决办法

进入word中的Endnote工具栏——Bibliography Preferences(位于Bibliography区块的右下角),就是那个输入杂志名的小三角形,在Temporary citation delimiters处修改变量的默认符号。将默认的大括号{}修改为文章中不回使用到的符号。原因:因为Endnote插入的参考文献在Word中的代码就是以大括号隔开的,当文章中出现了该符号,endnote就会自动比对Library中的书目,而此时endnote出现错误。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 4万+

Android开发中常用的工具命令小记

闲来无事,把开发过程中用到的一些工具及其命令做个小记(主要是记性太差!),这个博客会持续更新。 一、adb 篇 adb 工具是Android开发不可或缺的一个调试工具,利用该工具可以执行应用安装,文件导入导出,log调试,模拟硬件发出信号等等。 1. 安装/卸载 安装一个APK,安装时可以带上一些参数,也可以不带。 adb install [-lrtsdg] APK -l: forwar...

勤奋的果子的博客 648

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

android小记

1.去除android状态栏(含运营商,wifi的一栏) android:theme="@android:style/Theme.NoTitleBar.Fullscreen" View Code 2.去除标题栏:不加Fullscreen 3.spinner下拉框挡住spinner(解决方法): <Spinner android:id="...

weixin_30649641的博客 143

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

dSploit—Android网络渗透套件测试小记(含视频)

dSploit—Android网络渗透套件测试小记(含视频) dSploit是什么? dSploit是Android系统下的网络分析和渗透套件,其目的是面向IT安全专家和爱好者提供最完整、最先进的专业工具包 ,以便在移动设备上进行网络安全评估。 一旦dSploit运行,你将能够轻易地映射你的网络,发现活动主机和运行的服务,搜索已知漏洞,多种TCP协议登录破解,中间人攻击

jacky choise 1836

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

MOSEC-2020参会小记

昨天有幸参加了mosec2020的安全会议,这也是我第一次参加mosec,议题质量出于意料地高,因此在这记录一下其中几个有意思的议题。受限于个人知识水平,恕笔者挂一漏万。 IO80211Family 第一个议题是王宇师傅(@keenjoy95)关于苹果WiFi子系统的安全研究分享,其实王宇在前一段时间就提了一大波苹果蓝牙子系统的漏洞,看来手里的料还是挺多的。之所以去撸WiFi子系统,也是因为“之前的一个0day在升级系统后不work了”,……说回思路方面,研究入口的寻找个人认为比较有启发性,利用Kemon的

有价值炮灰 1119

android以太网服务,android Ethernet移植小记

在 ConnectivityManager.java 中定义的有如下类型:public static final int TYPE_MOBILE = 0;public static final int TYPE_WIFI = 1;public static final int TYPE_MOBILE_MMS = 2;public static final int TYPE...

weixin_30390951的博客 670

个人笔记小记,about network of android

拷贝自其它网站 http://www.jb51.net/article/32920.htm 获取网络信息需要在AndroidManifest.xml文件中加入相应的权限。    1)判断是否有网络连接  复制代码代码如下: public boolean isNetworkConnected(Context context) {  if (context

达达拉 486

Android小记:之 Android permission 大全

转载自:http://www.cnblogs.com/classic/archive/2011/06/20/2085055.html google提供的权限:http://developer.android.com/reference/android/Manifest.permission.html 访问登记属性 android.permission.ACCESS_CHECKIN_PR

HolyKnight的专栏 2056

1.17android小记

ConnectivityManager mService = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); EthernetManager mEthManager = (EthernetManager) getSystemService(Context.ETHERNET_SERVICE); if(

touch_ping的专栏 1240
上一篇: 使用Ellisys抓取蓝牙空中包
下一篇: 启动AP导致system_server挂掉
leoStack
博客等级 码龄11年 16粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值