File: sample_pm_cs.c

package info (click to toggle)
wireless-tools 23-2
  • links: PTS
  • area: main
  • in suites: woody
  • size: 356 kB
  • ctags: 924
  • sloc: ansic: 4,391; makefile: 82; sh: 69
file content (146 lines) | stat: -rw-r--r-- 3,967 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* Note : this particular snipset of code is available under
 * the LGPL, MPL or BSD license (at your choice).
 * Jean II
 */

/* 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
};

      /* Set the desired Power Management mode */
    case SIOCSIWPOWER:
      /* Disable it ? */
      if(wrq->u.power.disabled)
	{
	  local->pm_on = 0;
	  local->need_commit = 1;
	}
      else
	{
	  /* Check mode */
	  switch(wrq->u.power.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 */
	      rc = -EINVAL;
	    }
	  /* Set period */
	  if(wrq->u.power.flags & IW_POWER_PERIOD)
	    {
	      int	period = wrq->u.power.value/1000000;
	      /* Hum: check if within bounds... */

	      /* Activate PM */
	      local->pm_on = 1;
	      local->need_commit = 1;

	      /* Check min value */
	      if(wrq->u.power.flags & IW_POWER_MIN)
		{
		  local->pm_min_period = period;
		  local->pm_period_auto = 1;
		}
	      else
		/* Check max value */
		if(wrq->u.power.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(wrq->u.power.flags & IW_POWER_TIMEOUT)
	    {
	      /* Activate PM */
	      local->pm_on = 1;
	      local->need_commit = 1;
	      /* Fixed value in ms */
	      local->pm_timeout = wrq->u.power.value/1000;
	    }
	}
      break;

      /* Get the power management settings */
    case SIOCGIWPOWER:
      wrq->u.power.disabled = !local->pm_on;
      /* By default, display the period */
      if(!(wrq->u.power.flags & IW_POWER_TIMEOUT))
	{
	  int	inc_flags = wrq->u.power.flags;
	  wrq->u.power.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))
		{
		  wrq->u.power.value = local->pm_min_period * 1000000;
		  wrq->u.power.flags |= IW_POWER_MIN;
		}
	      else
		{
		  wrq->u.power.value = local->pm_max_period * 1000000;
		  wrq->u.power.flags |= IW_POWER_MAX;
		}
	    }
	  else
	    {
	      /* Fixed value. Check the flags */
	      if(inc_flags & (IW_POWER_MIN | IW_POWER_MAX))
		rc = -EINVAL;
	      else
		wrq->u.power.value = local->pm_period * 1000000;
	    }
	}
      else
	{
	  /* Deal with the timeout - always fixed */
	  wrq->u.power.flags = IW_POWER_TIMEOUT;
	  wrq->u.power.value = local->pm_timeout * 1000;
	}
      if(local->pm_multi)
	wrq->u.power.flags |= IW_POWER_ALL_R;
      else
	wrq->u.power.flags |= IW_POWER_UNICAST_R;
      break;
#endif	/* WIRELESS_EXT > 8 */

#if WIRELESS_EXT > 9
      range.min_pmp = 1000000;	/* 1 units */
      range.max_pmp = 12000000;	/* 12 units */
      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 */