2 * configurable RSSI LED control daemon for OpenWrt
3 * (c) 2012 Allnet GmbH, Daniel Golle <dgolle@allnet.de>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * The author may be reached as dgolle@allnet.de, or
37 #define RUN_DIR "/var/run"
38 #define LEDS_BASEPATH "/sys/class/leds/"
39 #define BACKEND_RETRY_DELAY 500000
50 typedef struct rule rule_t
;
60 void log_rules(rule_t
*rules
)
65 syslog(LOG_INFO
, " %s r: %d..%d, o: %d, f: %d\n",
67 rule
->minq
, rule
->maxq
,
68 rule
->boffset
, rule
->bfactor
);
73 int set_led(struct led
*led
, unsigned char value
)
80 if ( ! led
->controlfd
)
83 if ( led
->state
== value
)
86 snprintf(buf
, 8, "%d", value
);
88 rewind(led
->controlfd
);
90 if ( ! fwrite(buf
, sizeof(char), strlen(buf
), led
->controlfd
) )
93 fflush(led
->controlfd
);
99 int init_led(struct led
**led
, char *ledname
)
102 struct stat statbuffer
;
107 bp
= calloc(sizeof(char), strlen(ledname
) + strlen(LEDS_BASEPATH
) + 12);
111 sprintf(bp
, "%s%s/brightness", LEDS_BASEPATH
, ledname
);
113 status
= stat(bp
, &statbuffer
);
117 bfp
= fopen( bp
, "w" );
124 /* sysfs path exists and, allocate LED struct */
125 newled
= calloc(sizeof(struct led
),1);
129 newled
->sysfspath
= bp
;
130 newled
->controlfd
= bfp
;
134 if ( set_led(newled
, 255) )
137 if ( set_led(newled
, 0) )
147 syslog(LOG_CRIT
, "can't open LED %s\n", ledname
);
152 void close_led(struct led
**led
)
154 fclose((*led
)->controlfd
);
155 free((*led
)->sysfspath
);
161 int quality(const struct iwinfo_ops
*iw
, const char *ifname
)
165 if ( ! iw
) return -1;
168 if (iw
->quality_max(ifname
, &qual_max
))
171 if (iw
->quality(ifname
, &qual
))
174 return ( qual
* 100 ) / qual_max
;
177 int open_backend(const struct iwinfo_ops
**iw
, const char *ifname
)
179 *iw
= iwinfo_backend(ifname
);
187 void update_leds(rule_t
*rules
, int q
)
189 rule_t
*rule
= rules
;
193 /* offset and factore correction according to rule */
194 b
= ( q
+ rule
->boffset
) * rule
->bfactor
;
200 if ( q
>= rule
->minq
&& q
<= rule
->maxq
)
201 set_led(rule
->led
, (unsigned char)b
);
203 set_led(rule
->led
, 0);
209 int main(int argc
, char **argv
)
212 const struct iwinfo_ops
*iw
= NULL
;
213 rule_t
*headrule
= NULL
, *currentrule
= NULL
;
215 if (argc
< 9 || ( (argc
-4) % 5 != 0 ) )
217 printf("syntax: %s (ifname) (refresh) (threshold) (rule) [rule] ...\n", argv
[0]);
218 printf(" rule: (sysfs-name) (minq) (maxq) (offset) (factore)\n");
224 /* refresh interval */
225 if ( sscanf(argv
[2], "%d", &r
) != 1 )
228 /* sustain threshold */
229 if ( sscanf(argv
[3], "%d", &s
) != 1 )
232 openlog("rssileds", LOG_PID
, LOG_DAEMON
);
233 syslog(LOG_INFO
, "monitoring %s, refresh rate %d, threshold %d\n", ifname
, r
, s
);
235 currentrule
= headrule
;
236 for (i
=4; i
<argc
; i
=i
+5) {
239 /* first element in the list */
240 currentrule
= calloc(sizeof(rule_t
),1);
241 headrule
= currentrule
;
245 /* follow-up element */
246 currentrule
->next
= calloc(sizeof(rule_t
),1);
247 currentrule
= currentrule
->next
;
250 if ( init_led(&(currentrule
->led
), argv
[i
]) )
253 if ( sscanf(argv
[i
+1], "%d", &(currentrule
->minq
)) != 1 )
256 if ( sscanf(argv
[i
+2], "%d", &(currentrule
->maxq
)) != 1 )
259 if ( sscanf(argv
[i
+3], "%d", &(currentrule
->boffset
)) != 1 )
262 if ( sscanf(argv
[i
+4], "%d", &(currentrule
->bfactor
)) != 1 )
269 q
= quality(iw
, ifname
);
270 if ( q
< q0
- s
|| q
> q0
+ s
) {
271 update_leds(headrule
, q
);
274 // re-open backend...
275 if ( q
== -1 && q0
== -1 ) {
279 usleep(BACKEND_RETRY_DELAY
);
281 while (open_backend(&iw
, ifname
))
282 usleep(BACKEND_RETRY_DELAY
);