可以使用iw 命令来看信号强度,也可以解析iw 命令来做led 灯的显示
1. 先打开config
network ->rssileds
选中 iw-full
2. C语言 解析iw命令
使用如下命令:
iw mesh0 station dump
主要取出最大的signal_avg 和对应的mac addr
C语言如下:
思路为:
解析出来的最大的signal_avg 和对应的mac addr 存到 map里面
/*
* configurable RSSI LED control daemon for OpenWrt
* (c) 2012 Allnet GmbH, Daniel Golle <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* The author may be reached as [email protected], or
* ALLNET GmbH
* Maistr. 2
* D-82110 Germering
* Germany
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <syslog.h>
#include <pthread.h>
#include <net/if.h>
#include <errno.h>
#include <string.h>
#include "iwinfo.h"
#include "rbtree.h"
#include "map.h"
#define RUN_DIR "/var/run"
#define LEDS_BASEPATH "/sys/class/leds/"
#define BACKEND_RETRY_DELAY 500000
#define IWCMD "iw dev "
#define IWDUMP "station dump"
#define IWHEAD "signal avg:"
#define IWMAC "Station"
#define LEDSNAME "rb:green:led"
#define MAC_ADDR_LEN 18
#define SAFE_FREE(p) if(NULL != p) {free(p); p = NULL; }
#define SAFE_CHECK(p) if(NULL == p) { exit(1); }
#define RSSILEV_EXCELL -65
#define RSSILEV_GOOD -73
#define RSSILE_FAIR -80
#define RSSILEV_BAD -94
root_t tree = RB_ROOT;
typedef enum SIGNAL_STRENGTH
{
EXCELLENT = 0,
GOOD,
FAIR,
BAD,
}ID_SIG_STH;
char *ifname = NULL;
int sig_t1 = 0;
int sig_t2 = 0;
struct led {
char *sysfspath;
FILE *controlfd;
unsigned char state;
};
typedef struct rule rule_t;
struct rule {
struct led *led;
int minq;
int maxq;
int ontime;
int offtime;
rule_t *next;
};
typedef struct _rssi_info {
int signl_avg;
int length;
unsigned char *mac;
}rssi_info_t;
int set_led(struct led *led, unsigned char value)
{
char buf[8];
if ( ! led )
return -1;
if ( ! led->controlfd )
return -1;
if ( led->state == value )
return 0;
snprintf(buf, 8, "%d", value);
rewind(led->controlfd);
if ( ! fwrite(buf, sizeof(char), strlen(buf), led->controlfd) )
return -2;
fflush(led->controlfd);
led->state=value;
return 0;
}
int init_led(struct led **led, char *ledname)
{
struct led *newled;
struct stat statbuffer;
int status;
char *bp;
FILE *bfp;
bp = calloc(sizeof(char), strlen(ledname) + strlen(LEDS_BASEPATH) + 12);
if ( ! bp )
goto return_error;
sprintf(bp, "%s%s/brightness", LEDS_BASEPATH, ledname);
status = stat(bp, &statbuffer);
if ( status )
goto cleanup_fname;
bfp = fopen( bp, "w" );
if ( !bfp )
goto cleanup_fname;
if ( ferror(bfp) )
goto cleanup_fp;
/* sysfs path exists and, allocate LED struct */
newled = calloc(sizeof(struct led),1);
if ( !newled )
goto cleanup_fp;
newled->sysfspath = bp;
newled->controlfd = bfp;
*led = newled;
if ( set_led(newled, 0) )
goto cleanup_fp;
return 0;
cleanup_fp:
fclose(bfp);
cleanup_fname:
free(bp);
return_error:
syslog(LOG_CRIT, "can't open LED %s\n", ledname);
*led = NULL;
return -1;
}
void close_led(struct led **led)
{
fclose((*led)->controlfd);
free((*led)->sysfspath);
free((*led));
(*led)=NULL;
}
void update_leds(rule_t *rules,ID_SIG_STH rssi)
{
rule_t *rule = rules;
switch(rssi)
{
case EXCELLENT: /* set 4 leds bright */
while(rule){
set_led(rule->led, 255);
rule = rule->next;
}
// syslog(LOG_INFO,"update_leds -- EXCELLENT\n");
break;
case GOOD: /* set 3 leds bright */
while(rule){
//printf("GOOD -- rule->led->sysfspath = %s\n",rule->led->sysfspath);
if(strstr(rule->led->sysfspath, "4")){
set_led(rule->led, 0);
}else{
set_led(rule->led, 255);
}
rule = rule->next;
}
// syslog(LOG_INFO,"update_leds -- GOOD \n");
break;
case FAIR: /* set 2 leds bright */
while(rule) {
//printf(" FAIR -- rule->led->sysfspath = %s\n",rule->led->sysfspath);
if(strstr(rule->led->sysfspath, "4") || strstr(rule->led->sysfspath, "3") ) {
set_led(rule->led, 0);
}
else{
set_led(rule->led, 255);
}
rule = rule->next;
}
// syslog(LOG_INFO, "update_leds -- FAIR \n");
break;
case BAD: /* set 1 led bright */
while(rule) {
set_led(rule->led, 0);
if(strstr(rule->led->sysfspath, "1")) {
set_led(rule->led, 255);
}
rule = rule->next;
}
// syslog(LOG_INFO,"update_leds -- BAD \n");
break;
default:
printf("unknow cmd \n");
}
}
static ID_SIG_STH judge_level(int rssi)
{
/* EXCELLENT >= -65 dBm */
if(rssi >= RSSILEV_EXCELL)
return EXCELLENT;
/* GOOD < -65 >= -73 dBm */
if(rssi < RSSILEV_EXCELL && rssi >= RSSILEV_GOOD)
return GOOD;
/* FAIR < -73 >= -80 dBm */
if(rssi < RSSILEV_GOOD && rssi >= RSSILE_FAIR)
return FAIR;
/* BAD < -80 dBm */
if(rssi < RSSILE_FAIR)
return BAD;
}
static int cate_head(int count, char *org, char *tag)
{
int org_len = strlen(org);
if(org == NULL || org_len < count )
return -1;
for(int i = 0; i < org_len; i++) {
tag[i] = org[i + count];
}
return 0;
}
static int parser_cmd_buf(char *cmd, char *tag_mac, char *tag_sigvg)
{
FILE *fp = NULL;
char data[1024] = {0};
char *mac = NULL;
char tmpmac[24] = {0};
char sigavg[8] = {0};
char *tstr1 = NULL;
char *tstr2 = NULL;
int ret;
rssi_info_t *rsinf = (rssi_info_t *)malloc(sizeof(rssi_info_t));
SAFE_CHECK(rsinf);
memset(rsinf, 0, sizeof(rssi_info_t));
rsinf->mac = malloc(sizeof(char*) * 5);
SAFE_CHECK(rsinf->mac);
memset(sigavg, 0, sizeof(sigavg));
fp = popen(cmd, "r");
if(fp != NULL)
{
while(fgets(data, sizeof(data), fp) != NULL) {
if(strstr(data, IWMAC) || strstr(data, IWHEAD) ) {
tstr1 = strstr(data,"on");
if(tstr1) {
tstr1[strlen(tstr1 -1)];
int ret = cate_head(3, tstr1, &tmpmac);
if(ret)
return -2;
if(!strlen(tmpmac)){
syslog(LOG_INFO, "error get mac\n");
return -3;
}
mac = malloc(sizeof(char) * strlen(tmpmac));
SAFE_CHECK(mac);
memcpy(mac, tmpmac,sizeof(char) * MAC_ADDR_LEN);
// printf("before mac malloc strlen(mac) =%d strlen(struc mac) = %d\n",
// strlen(mac),strlen(rsinf->mac));
if(strlen(mac) == MAC_ADDR_LEN)
strcpy(rsinf->mac, mac);
else
continue;
SAFE_FREE(mac);
tstr1 = NULL;
}
tstr2 = strstr(data, "-");
if(tstr2) {
strncpy(sigavg, tstr2, 3);
sig_t1 = atoi(sigavg);
tstr2 = NULL;
} else {
continue;
}
if((strlen(rsinf->mac) == MAC_ADDR_LEN) && (sig_t1 < -1)) {
// printf("Dump List mac = %s sigavg = %d length = %d \n",
// rsinf->mac, sig_t1, strlen(rsinf->mac));
/* push to map */
put(&tree, sigavg, rsinf->mac);
}else {
continue;
}
if(rsinf->signl_avg != 0 && rsinf->signl_avg > sig_t1)
sig_t1 = rsinf->signl_avg;
else
rsinf->signl_avg = sig_t1;
/* dump map data */
map_t *node;
for (node = map_first(&tree); node; node=map_next(&(node->node))) {
printf("### %s, sigval = %s \n",node->val, node->key);
}
//printf("rsinf->signl_avg = %d \n",rsinf->signl_avg);
}
}
} else {
syslog(LOG_INFO,"parser_cmd_buf fp open failed \n");
return -4;
}
memset(tag_sigvg, 0, sizeof(tag_sigvg));
sprintf(sigavg,"%d", rsinf->signl_avg);
memcpy(tag_sigvg, sigavg, sizeof(sigavg));
memset(tag_mac, 0, sizeof(tag_mac));
/* get mesh max sigavg opposition mac addr */
map_t *data_mac = get(&tree, sigavg);
if(data_mac != NULL)
strcpy(tag_mac, data_mac->val);
rsinf->signl_avg = 0;
sig_t1 = 0;
SAFE_FREE(rsinf->mac);
SAFE_FREE(rsinf);
/* free map */
map_t *nodeFree = NULL;
for (nodeFree = map_first(&tree); nodeFree; nodeFree = map_first(&tree)) {
if (nodeFree) {
rb_erase(&nodeFree->node, &tree);
map_free(nodeFree);
}
}
pclose(fp);
return 0;
}
int main(int argc, char **argv)
{
int cret, i;
static char iwcmd[64] = {0};
char tag_mac[128] = {0};
char tag_sigvg[24] = {0};
char leds[24] = {0};
int signal_avg = 0;
rule_t *headrule = NULL, *currentrule = NULL;
if (argv[1] == NULL)
{
printf("syntax: %s (ifname) \n", argv[1]);
return 1;
}
ifname = argv[1];
sprintf(iwcmd,"%s %s %s",IWCMD, ifname, IWDUMP);
printf("iwcmd = %s\n", iwcmd);
for (i = 1; i <= 4; i++)
{
if (! currentrule)
{
printf("NULL fist \n");
currentrule = calloc(sizeof(rule_t),1);
headrule = currentrule;
}
else
{
printf("secand currentrule \n");
currentrule->next = calloc(sizeof(rule_t),1);
currentrule = currentrule->next;
}
sprintf(leds, "%s%d", LEDSNAME,i);
if (init_led(&(currentrule->led), leds))
syslog(LOG_INFO, "ERROR: init_led \n");
}
do{
cret = parser_cmd_buf(iwcmd, &tag_mac, &tag_sigvg);
signal_avg = atoi(tag_sigvg);
syslog(LOG_INFO, "parser_cmd_buf cret = %d\n", cret);
if (!cret) {
printf("################## \n signal_avg = %d mac = %s \n################## \n",
signal_avg, tag_mac);
syslog(LOG_CRIT, "signal_avg = %d tag_mac = %s\n", signal_avg, tag_mac);
if(signal_avg && strlen(tag_mac) == MAC_ADDR_LEN) {
update_leds(headrule,judge_level(signal_avg));
}
}
usleep(400000);
} while(1);
close_led(¤trule->led);
return 0;
}
完整代码下载包: