前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Android中WiFi的RX与TX获取流程以及配置

Android中WiFi的RX与TX获取流程以及配置

作者头像
用户7557625
发布于 2020-07-15 03:02:06
发布于 2020-07-15 03:02:06
2.4K00
代码可运行
举报
运行总次数:0
代码可运行

Android中的RX与TX,即WiFI的传输速率与接收速率,是在WifiConfigController里添加的,可以看到,只有它们的值不为0时,才会显示。

下面是代码逻辑:

/packages/apps/Settings/src/com/android/settings/wifi/WifiConfigController.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private void initWifiConfigController(AccessPoint accessPoint, int mode) {
     WifiInfo info = mAccessPoint.getInfo();
      if (info != null && info.getTxLinkSpeedMbps() != WifiInfo.LINK_SPEED_UNKNOWN) {
          addRow(group, R.string.tx_wifi_speed, String.format(
                  res.getString(R.string.tx_link_speed), info.getTxLinkSpeedMbps()));
      }

      if (info != null && info.getRxLinkSpeedMbps() != WifiInfo.LINK_SPEED_UNKNOWN) {
          addRow(group, R.string.rx_wifi_speed, String.format(
                  res.getString(R.string.rx_link_speed), info.getRxLinkSpeedMbps()));
      }
}

/frameworks/base/wifi/java/android/net/wifi/WifiInfo.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
   * Returns the current transmit link speed in Mbps.
   * @return the Tx link speed or {@link #LINK_SPEED_UNKNOWN} if link speed is unknown.
   * @see #LINK_SPEED_UNKNOWN
   */
  @IntRange(from = -1)
  public int getTxLinkSpeedMbps() {
      return mTxLinkSpeed;
  }

  /**
   * Update the last transmitted packet bit rate in Mbps.
   * @hide
   */
  public void setTxLinkSpeedMbps(int txLinkSpeed) {
      mTxLinkSpeed = txLinkSpeed;
}

/frameworks/opt/net/wifi/service/java/com/android/server/wifi/ClientModeImpl.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   private void fetchRssiLinkSpeedAndFrequencyNative() {
        WifiNative.SignalPollResult pollResult = mWifiNative.signalPoll(mInterfaceName);
        if (pollResult == null) {
            return;
        }

        int newRssi = pollResult.currentRssi;
        int newTxLinkSpeed = pollResult.txBitrate;
        int newFrequency = pollResult.associationFrequency;
        int newRxLinkSpeed = pollResult.rxBitrate;

        if (mVerboseLoggingEnabled) {
            logd("fetchRssiLinkSpeedAndFrequencyNative rssi=" + newRssi
                    + " TxLinkspeed=" + newTxLinkSpeed + " freq=" + newFrequency
                    + " RxLinkSpeed=" + newRxLinkSpeed);
        }

        /*
         * set Tx link speed only if it is valid
         */
        if (newTxLinkSpeed > 0) {
            mWifiInfo.setLinkSpeed(newTxLinkSpeed);
            mWifiInfo.setTxLinkSpeedMbps(newTxLinkSpeed);
        }
        /*
         * set Rx link speed only if it is valid
         */
        if (newRxLinkSpeed > 0) {
            mWifiInfo.setRxLinkSpeedMbps(newRxLinkSpeed);
        }
        if (newFrequency > 0) {
            mWifiInfo.setFrequency(newFrequency);
        }
        mWifiConfigManager.updateScanDetailCacheFromWifiInfo(mWifiInfo);
        /*
         * Increment various performance metrics
         */
        mWifiMetrics.handlePollResult(mWifiInfo);
    }

/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  public SignalPollResult signalPoll(@NonNull String ifaceName) {
        return mWificondControl.signalPoll(ifaceName);
    }

/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WificondControl.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  public WifiNative.SignalPollResult signalPoll(@NonNull String ifaceName) {
        IClientInterface iface = getClientInterface(ifaceName);
        if (iface == null) {
            Log.e(TAG, "No valid wificond client interface handler");
            return null;
        }

        int[] resultArray;
        try {
            resultArray = iface.signalPoll();
            if (resultArray == null || resultArray.length != 4) {
                Log.e(TAG, "Invalid signal poll result from wificond");
                return null;
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to do signal polling due to remote exception");
            return null;
        }
        WifiNative.SignalPollResult pollResult = new WifiNative.SignalPollResult();
        pollResult.currentRssi = resultArray[0];
        pollResult.txBitrate = resultArray[1];
        pollResult.associationFrequency = resultArray[2];
        pollResult.rxBitrate = resultArray[3];
        return pollResult;
    }

/system/connectivity/wificond/client_interface_binder.cpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Status ClientInterfaceBinder::signalPoll(
    vector<int32_t>* out_signal_poll_results) {
  if (impl_ == nullptr) {
    return Status::ok();
  }
  impl_->SignalPoll(out_signal_poll_results);
  return Status::ok();
}

/system/connectivity/wificond/client_interface_impl.cpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
bool ClientInterfaceImpl::SignalPoll(vector<int32_t>* out_signal_poll_results) {
  if (!IsAssociated()) {
    LOG(INFO) << "Fail RSSI polling because wifi is not associated.";
    return false;
  }

  StationInfo station_info;
  if (!netlink_utils_->GetStationInfo(interface_index_,
                                      bssid_,
                                      &station_info)) {
    return false;
  }
  out_signal_poll_results->push_back(
      static_cast<int32_t>(station_info.current_rssi));
  // Convert from 100kbit/s to Mbps.
  out_signal_poll_results->push_back(
      static_cast<int32_t>(station_info.station_tx_bitrate/10));
  // Association frequency.
  out_signal_poll_results->push_back(
      static_cast<int32_t>(associate_freq_));
  // Convert from 100kbit/s to Mbps.
  out_signal_poll_results->push_back(
      static_cast<int32_t>(station_info.station_rx_bitrate/10));

  return true;
}

/system/connectivity/wificond/net/netlink_utils.cpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
bool NetlinkUtils::GetStationInfo(uint32_t interface_index,
                                  const array<uint8_t, ETH_ALEN>& mac_address,
                                  StationInfo* out_station_info) {
  NL80211NestedAttr tx_bitrate_attr(0);
  uint32_t tx_bitrate = 0;
  if (sta_info.GetAttribute(NL80211_STA_INFO_TX_BITRATE,
                            &tx_bitrate_attr)) {
    if (!tx_bitrate_attr.GetAttributeValue(NL80211_RATE_INFO_BITRATE32,
                                         &tx_bitrate)) {
      // Return invalid tx rate to avoid breaking the get station cmd
      tx_bitrate = 0;
    }
  } else {
      LOG(ERROR) << "Failed to get NL80211_STA_INFO_TX_BITRATE";
      return false;
  }
  NL80211NestedAttr rx_bitrate_attr(0);
  uint32_t rx_bitrate = 0;
  if (sta_info.GetAttribute(NL80211_STA_INFO_RX_BITRATE,
                            &rx_bitrate_attr)) {
    if (!rx_bitrate_attr.GetAttributeValue(NL80211_RATE_INFO_BITRATE32,
                                         &rx_bitrate)) {
      // Return invalid rx rate to avoid breaking the get station cmd
      rx_bitrate = 0;
    }
  }
  *out_station_info = StationInfo(tx_good, tx_bad, tx_bitrate, current_rssi, rx_bitrate);
  return true;
}

/kernel/msm-4.9/net/wireless/nl80211.c

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static const struct genl_ops nl80211_ops[] = {
	{
		.cmd = NL80211_CMD_GET_STATION,
		.doit = nl80211_get_station,
		.dumpit = nl80211_dump_station,
		.policy = nl80211_policy,
		.internal_flags = NL80211_FLAG_NEED_NETDEV |
				  NL80211_FLAG_NEED_RTNL,
	},
	{
		.cmd = NL80211_CMD_SET_STATION,
		.doit = nl80211_set_station,
		.policy = nl80211_policy,
		.flags = GENL_UNS_ADMIN_PERM,
		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
				  NL80211_FLAG_NEED_RTNL,
	},
	{
		.cmd = NL80211_CMD_NEW_STATION,
		.doit = nl80211_new_station,
		.policy = nl80211_policy,
		.flags = GENL_UNS_ADMIN_PERM,
		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
				  NL80211_FLAG_NEED_RTNL,
	},
	{
		.cmd = NL80211_CMD_DEL_STATION,
		.doit = nl80211_del_station,
		.policy = nl80211_policy,
		.flags = GENL_UNS_ADMIN_PERM,
		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
				  NL80211_FLAG_NEED_RTNL,
	},
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static int nl80211_dump_station(struct sk_buff *skb,
				struct netlink_callback *cb)
{
	struct station_info sinfo;
	struct cfg80211_registered_device *rdev;
	struct wireless_dev *wdev;
	u8 mac_addr[ETH_ALEN];
	int sta_idx = cb->args[2];
	int err;

	rtnl_lock();
	err = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
	if (err)
		goto out_err;

	if (!wdev->netdev) {
		err = -EINVAL;
		goto out_err;
	}

	if (!rdev->ops->dump_station) {
		err = -EOPNOTSUPP;
		goto out_err;
	}

	while (1) {
		memset(&sinfo, 0, sizeof(sinfo));
		err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
					mac_addr, &sinfo);
		if (err == -ENOENT)
			break;
		if (err)
			goto out_err;

		if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
				NETLINK_CB(cb->skb).portid,
				cb->nlh->nlmsg_seq, NLM_F_MULTI,
				rdev, wdev->netdev, mac_addr,
				&sinfo) < 0)
			goto out;

		sta_idx++;
	}

 out:
	cb->args[2] = sta_idx;
	err = skb->len;
 out_err:
	rtnl_unlock();

	return err;
}

/kernel/msm-4.9/net/wireless/rdev-ops.h

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static inline int rdev_dump_station(struct cfg80211_registered_device *rdev,
				    struct net_device *dev, int idx, u8 *mac,
				    struct station_info *sinfo)
{
	int ret;
	trace_rdev_dump_station(&rdev->wiphy, dev, idx, mac);
	ret = rdev->ops->dump_station(&rdev->wiphy, dev, idx, mac, sinfo);
	trace_rdev_return_int_station_info(&rdev->wiphy, ret, sinfo);
	return ret;
}

如果NL80211_STA_INFO_TX_BITRATE没有被set,则上层得不到tx与rx数据。 /vendor/qcom/opensource/wlan/prima/CORE/HDD/src/wlan_hdd_cfg80211.c

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
	!defined(WITH_BACKPORTS)
    sinfo->filled |= STATION_INFO_TX_BITRATE;
#else
    sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/03/28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
ZeroTier实现内网穿透、异地组网
公司有几台内网服务器没有公网IP地址,只能在公司局域网内访问,多有不便。通过工具实现内网穿透后,内网服务器上的一些服务如gitlab、jira、Jenkins甚至是SSH就可以实现异地访问。目前较为流行的内网穿透工具有frp、ngrok、zerotier、花生壳等。这两天简单研究了一下zerotier,所以本篇文章主要介绍zerotier。
大刚测试开发实战
2022/11/14
15.4K2
ZeroTier实现内网穿透、异地组网
Zerotier Moon搭建教程
ps:Zerotier是一款内网互联的工具,可以使用他自己的服务器,但是使用可能会有些不稳定(我没测试过),所以为了稳妥起见,我们还是搭建一个自己的吧。
华创信息技术
2022/05/28
5.9K0
使用ZeroTier快速组建SD-WAN网络,自行搭建Moon月亮服务器
ZeroTier是一套使用UDP协议构建的SD-WAN网络软件,其主要有三部分组成:行星服务器Planet、月亮服务器Moon、客户端节点LEFA 行星服务器是ZeroTier的根节点,可以采用ZeroTier官方的服务器,也可以使用开源代码自行搭建 月亮服务器介于行星与客户端之间,官方行星都在国外,因此可以就近公网搭建月亮服务器,客户端可以优先使用延迟更低的月亮节点进行P2P打通或者网络中转 客户端节点既可以安装在客户端进行远程网络接入,也可以部署后开启路由转发功能,配置静态路由后实现两个网络组网
王忘杰
2022/09/22
5.6K0
使用ZeroTier快速组建SD-WAN网络,自行搭建Moon月亮服务器
浅尝 Zerotier
在上一篇文章中说到我已经做了frp和反向代理把内网部分端口映射到公网,也都添加了ssl证书。但是始终有一个很让人头疼的事情——我的小水管只有5M,这个限制有时候就比较头疼(应证了那句:我可以不用,但不能没有) 很早之前就了解到 Zerotier
ZGGSONG
2022/09/09
5.1K0
浅尝 Zerotier
ZeroTier 敏捷组网教程
我们在开发 Spring Cloud 微服务时候由于本机内存有限,无法同时启动多个微服务,我们如果搞? PS: 如笔记本 8G 内存本地运行 10 个微服务,基本上是是卡死状态。为了尽量达到无需配置本地环境就可以通过隧道连接云端服务器的环境进行的开发。
Lcry
2023/01/11
2.6K0
ZeroTier 敏捷组网教程
【远程办公】无需公网、无需服务端5分钟实现内网穿透
上文 《【远程办公】5分钟实现内网穿透》有个老哥私聊了我一下 好吧,正如这个老哥的需求
冷冷
2020/02/18
3.2K0
【远程办公】无需公网、无需服务端5分钟实现内网穿透
NAS新福音2,“ZeroTier”解决你的公网安全焦虑的新方案!(免费+开源+不限流量+内网穿透真神)
继文章NAS新福音,“Tailscale”解决你的公网安全焦虑的新方案!(免费+开源+不限流量+内网穿透),今天介绍更好用的内网穿透工具-----ZeroTier。
ICT系统集成阿祥
2024/12/03
1.8K0
NAS新福音2,“ZeroTier”解决你的公网安全焦虑的新方案!(免费+开源+不限流量+内网穿透真神)
内网穿透(组网)成功率更高、部署更简单
公司有服务器,或者公司的电脑配置比较自己家里的笔记本高,如果要配置外网穿透,就太麻烦,而且也不安全(公司内网被黑了,可能还要你担责)。局域网组网就相对来说既简单,又安全好多。
用户10002156
2023/10/24
2.1K0
内网穿透(组网)成功率更高、部署更简单
【教程】超详细安装和使用免费内网穿透软件Zerotier-One
3、在要互连的设备(手机、Windows、Mac、Linux)上安装zerotier-one。
小锋学长生活大爆炸
2024/02/23
16.3K0
【教程】超详细安装和使用免费内网穿透软件Zerotier-One
使用 zerotier 搭建自己的 IPv6 网络
  2019年11月27日,通过欧洲网络协调中心(RIPE NCC)的邮件确认,全球所有 43 亿个 IPv4 地址已全部分配完毕。事实上,IPv4 地址的数量是非常有限的,算起来全球 60 多亿人每个人平均不到 1 个。由于 IP 地址是由国际上的几大网络协调中心统一进行分配,必须由单位向所在区域的网络协调中心提出申请,并每年缴纳一定的费用。这笔费用对于单位来说算不了什么,对于个人来说就比较高。因此,在每个国家基本上是由国家网络中心进行国内的 IP 地址分配,分配的单位一般是政府、国家机构、高校、基础通信服务商、数据中心或企业等。我们通常家用的宽带主要是由中国移动、中国联通、中国电信三大基础通信服务商提供的。近年来也有由广播电视提供的家用宽带。在学校、国家科技机构单位,一般使用的是教育网、教育科技网,也有很多学校采用的基础通信服务商提供的商用网络。不管是学校,还是家里,基础通信服务商为了节约 IP 地址的使用,在进行基础通信网络搭建的时候,大部分采用了内部局域网共享一个公网 IP 地址代理上网的方式。现有家用使用的宽带网络基本上无法获取到公网 IPv4 地址,只能获得一个以100开头的通信专用的局域网地址。
zhonger
2022/10/28
16.3K2
使用 zerotier 搭建自己的 IPv6 网络
利用三丰云主机搭建zerotier moon节点服务器
利用三丰云主机搭建zerotier moon节点服务器,这个教程比较多了,网上有写的都是针对centos的,我尝试使用的版本是7.6,但是没成功,只好去使用ubuntu 16.04,终于成功,把过程分享给大家。
用户10803945
2023/10/23
7580
关于WireGuard和zerotier 隧道实现异地组网实现的一些记录
分发有一个集成第三方的组件'Netmaker',分发的实现,但是客户端也要依靠Netcile实现,而且暂未做到ios端 但是有通过DNS组件实现的案例,个人能力有限并未实现。
怪兽
2022/10/04
5.6K0
关于WireGuard和zerotier 隧道实现异地组网实现的一些记录
有关nas中使用zerotier实现内网穿透的配置说明
中间踩了不少坑,趟雷的过程很有共性,供大家参考,本文重点说zerotier实现内网穿透。
黯然销魂掌
2022/07/12
7K0
群晖NAS配置之ZeroTier实现内网穿透
内网穿透是指通过一种技术让外部网络可以访问到内网的NAS设备,这样即使在不同网络环境下,也能够远程访问和管理NAS设备。以下是一些常见的内网穿透方案:
星哥玩云
2023/11/25
4.3K0
群晖NAS配置之ZeroTier实现内网穿透
内网穿透
一般的校园网/企业网往往都设置有防火墙,在内网可以访问外网,但在外网却无法访问内网。比如校园的服务器,当我们在校外时,只能通过学校的 VPN 访问校园网。然而,这个 VPN 一来可能不稳定,二来往往只有 Windows 平台有(气抖冷),对于 Linux 用户极其不友好。在朋友的推荐下,我使用了 ZeroTier 这款跨平台的虚拟局域网构建工具,使用它能够进行内网穿透,使得外网也能访问内网~~,妈妈再也不用担心我连不上校网服务器了~~。
hotarugali
2022/03/18
2.1K0
内网穿透工具之星空组网(无需公网IP进行异地组网)
注册地址:https://ip4.ink/register.html?referralCode=lhrxxt
AiDBA宝典
2024/03/21
3.8K0
内网穿透工具之星空组网(无需公网IP进行异地组网)
利用frp工具实现内网穿透、随时随地访问内网服务
之前分享过一次《ZeroTier实现内网穿透、异地组网》,其基本工作原理是组建一个虚拟局域网,各个设备(NAS、Linux、Windows、Mac、iOS、Android)安装了客户端、加入到这个虚拟局域网后,就会自动分配一个IP,从而实现局域网内各个设备及服务的相互访问。
大刚测试开发实战
2023/01/18
2.9K0
Linux系统实战——批量无人值守安装操作系统
实际生产环境中肯定会有一次性安装多台服务器操作系统的工作,因此,光靠传统的一台台安装,很费时费力,数量不多的情况,还是比较好应付,如果一次是几十、几百台,就比较麻烦了,因此,实际生产环境中都用采用批量无人值守的安装方式来安装操作系统,所以今天来详细介绍下,通过利用kickstart+PXE+dhcp+nfs组合的方式批量安装操作系统。
民工哥
2020/09/16
2.5K0
Linux系统实战——批量无人值守安装操作系统
树莓派Pi4B+激光雷达SLAM建图环境搭建(Ubuntu20.04.3 + ROS Noetic)
原文:树莓派Pi4B+激光雷达SLAM建图环境搭建(Ubuntu20.04.3 + ROS Noetic)
一点人工一点智能
2023/03/04
4.3K0
树莓派Pi4B+激光雷达SLAM建图环境搭建(Ubuntu20.04.3 + ROS Noetic)
如何安装 btsync 优点windows 安装Centos 6 安装国内如何下载搭建预定义主机ZeroTier
本文告诉大家如何在 windows 和 Linux 安装使用 Btsync ,而且分享一些小东西给大家
林德熙
2018/09/18
2.6K0
如何安装 btsync
            优点windows 安装Centos 6 安装国内如何下载搭建预定义主机ZeroTier
推荐阅读
相关推荐
ZeroTier实现内网穿透、异地组网
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档