openwrt mesh 连接 的信号强度 用led 显示出来

可以使用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(&currentrule->led);

	return 0;
}

完整代码下载包:

https://download.csdn.net/download/yang_quan_yang/12651491

猜你喜欢

转载自blog.csdn.net/yang_quan_yang/article/details/107518549