1 Star 0 Fork 0

kuangfei2019/android_external_wireless-tools

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
sample_pm.c 5.55 KB
一键复制 编辑 原始数据 按行查看 历史
/* Note : this particular snipset of code is available under
* the LGPL, MPL or BSD license (at your choice).
* Jean II
*/
/* --------------------------- INCLUDE --------------------------- */
/* Backward compatibility for Wireless Extension 9 */
#ifndef IW_POWER_MODIFIER
#define IW_POWER_MODIFIER 0x000F /* Modify a parameter */
#define IW_POWER_MIN 0x0001 /* Value is a minimum */
#define IW_POWER_MAX 0x0002 /* Value is a maximum */
#define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
#endif IW_POWER_MODIFIER
struct net_local {
int pm_on; // Power Management enabled
int pm_multi; // Receive multicasts
int pm_period; // Power Management period
int pm_period_auto; // Power Management auto mode
int pm_max_period; // Power Management max period
int pm_min_period; // Power Management min period
int pm_timeout; // Power Management timeout
};
/* --------------------------- HANDLERS --------------------------- */
static int ioctl_set_power(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *prq,
char *extra)
{
/* Disable it ? */
if(prq->disabled)
{
local->pm_on = 0;
}
else
{
/* Check mode */
switch(prq->flags & IW_POWER_MODE)
{
case IW_POWER_UNICAST_R:
local->pm_multi = 0;
local->need_commit = 1;
break;
case IW_POWER_ALL_R:
local->pm_multi = 1;
local->need_commit = 1;
break;
case IW_POWER_ON: /* None = ok */
break;
default: /* Invalid */
return(-EINVAL);
}
/* Set period */
if(prq->flags & IW_POWER_PERIOD)
{
int period = prq->value;
#if WIRELESS_EXT < 21
period /= 1000000;
#endif
/* Hum: check if within bounds... */
/* Activate PM */
local->pm_on = 1;
local->need_commit = 1;
/* Check min value */
if(prq->flags & IW_POWER_MIN)
{
local->pm_min_period = period;
local->pm_period_auto = 1;
}
else
/* Check max value */
if(prq->flags & IW_POWER_MAX)
{
local->pm_max_period = period;
local->pm_period_auto = 1;
}
else
{
/* Fixed value */
local->pm_period = period;
local->pm_period_auto = 0;
}
}
/* Set timeout */
if(prq->flags & IW_POWER_TIMEOUT)
{
/* Activate PM */
local->pm_on = 1;
local->need_commit = 1;
/* Fixed value in ms */
local->pm_timeout = prq->value/1000;
}
}
return(0);
}
static int ioctl_get_power(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *prq,
char *extra)
{
prq->disabled = !local->pm_on;
/* By default, display the period */
if(!(prq->flags & IW_POWER_TIMEOUT))
{
int inc_flags = prq->flags;
prq->flags = IW_POWER_PERIOD | IW_POWER_RELATIVE;
/* Check if auto */
if(local->pm_period_auto)
{
/* By default, the min */
if(!(inc_flags & IW_POWER_MAX))
{
prq->value = local->pm_min_period;
#if WIRELESS_EXT < 21
prq->value *= 1000000;
#endif
prq->flags |= IW_POWER_MIN;
}
else
{
prq->value = local->pm_max_period;
#if WIRELESS_EXT < 21
prq->value *= 1000000;
#endif
prq->flags |= IW_POWER_MAX;
}
}
else
{
/* Fixed value. Check the flags */
if(inc_flags & (IW_POWER_MIN | IW_POWER_MAX))
return(-EINVAL);
else
{
prq->value = local->pm_period;
#if WIRELESS_EXT < 21
prq->value *= 1000000;
#endif
}
}
}
else
{
/* Deal with the timeout - always fixed */
prq->flags = IW_POWER_TIMEOUT;
prq->value = local->pm_timeout * 1000;
}
if(local->pm_multi)
prq->flags |= IW_POWER_ALL_R;
else
prq->flags |= IW_POWER_UNICAST_R;
return(0);
}
static int ioctl_get_range(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *rrq,
char *extra)
{
struct iw_range *range = (struct iw_range *) extra;
rrq->length = sizeof(struct iw_range);
memset(range, 0, sizeof(struct iw_range));
#if WIRELESS_EXT > 10
/* Version we are compiled with */
range->we_version_compiled = WIRELESS_EXT;
/* Minimum version we recommend */
range->we_version_source = 8;
#endif /* WIRELESS_EXT > 10 */
#if WIRELESS_EXT > 9
#if WIRELESS_EXT < 21
range.min_pmp = 1000000; /* 1 units */
range.max_pmp = 12000000; /* 12 units */
#else
range.min_pmp = 1; /* 1 units */
range.max_pmp = 12; /* 12 units */
#endif
range.min_pmt = 1000; /* 1 ms */
range.max_pmt = 1000000; /* 1 s */
range.pmp_flags = IW_POWER_PERIOD | IW_POWER_RELATIVE |
IW_POWER_MIN | IW_POWER_MAX;
range.pmt_flags = IW_POWER_TIMEOUT;
range.pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_UNICAST_R;
#endif /* WIRELESS_EXT > 9 */
return(0);
}
/* --------------------------- BINDING --------------------------- */
#if WIRELESS_EXT > 12
/* Use the new driver API, save overhead */
static const iw_handler handler_table[] =
{
...
(iw_handler) ioctl_set_power, /* SIOCSIWPOWER */
(iw_handler) ioctl_get_power, /* SIOCGIWPOWER */
};
#else /* WIRELESS_EXT < 12 */
/* Use old API in the ioctl handler */
static int
do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct iwreq *wrq = (struct iwreq *) ifr;
int err = 0;
switch (cmd)
{
#if WIRELESS_EXT > 8
/* Set the desired Power Management mode */
case SIOCSIWPOWER:
err = ioctl_set_power(dev, NULL, &(wrq->u.power), NULL);
break;
/* Get the power management settings */
case SIOCGIWPOWER:
err = ioctl_get_power(dev, NULL, &(wrq->u.power), NULL);
break;
#endif /* WIRELESS_EXT > 8 */
}
return(err);
}
#endif /* WIRELESS_EXT < 12 */
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/kuangfei2019/android_external_wireless-tools.git
git@gitee.com:kuangfei2019/android_external_wireless-tools.git
kuangfei2019
android_external_wireless-tools
android_external_wireless-tools
master

搜索帮助