/* $Id: plugin_wireless.c,v 1.7 2004/06/26 12:05:00 reinelt Exp $ * * Wireless Extension plugin * * Copyright 2004 Xavier Vello * Copyright 2004 Martin Hejl * Copyright 2004 The LCD4Linux Team * * Losts of code borrowed from Wireless Tools, which is * Copyright (c) 1997-2002 Jean Tourrilhes * (avaible at http://web.hpl.hp.com/personal/Jean_Tourrilhes/Linux/) * * This file is part of LCD4Linux. * * LCD4Linux 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, or (at your option) * any later version. * * LCD4Linux 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., 675 Mass Ave, Cambridge, MA 02139, USA. * * * $Log: plugin_wireless.c,v $ * Revision 1.7 2004/06/26 12:05:00 reinelt * * uh-oh... the last CVS log message messed up things a lot... * * Revision 1.6 2004/06/26 09:27:21 reinelt * * added '-W' to CFLAGS * changed all C++ comments to C ones * cleaned up a lot of signed/unsigned mistakes * * Revision 1.5 2004/06/20 10:09:56 reinelt * * 'const'ified the whole source * * Revision 1.4 2004/06/17 06:23:43 reinelt * * hash handling rewritten to solve performance issues * * Revision 1.3 2004/05/27 03:39:47 reinelt * * changed function naming scheme to plugin::function * * Revision 1.2 2004/04/17 13:05:58 nicowallmeier * minor bugfix * * Revision 1.1 2004/04/07 08:29:05 hejl * New plugin for wireless info * */ /* * Exported functions: wifi_level wifi_noise wifi_quality wifi_protocol wifi_frequency wifi_bitrate wifi_essid wifi_op_mode wifi_sensitivity wifi_sec_mode All Functions take one parameter (the name of the device, like "wlan0", "ath0" and so on) */ #include "config.h" #include #include #include #include #include #include #include #include #include "debug.h" #include "plugin.h" #include "cfg.h" #include "hash.h" #include "qprintf.h" #ifdef WITH_DMALLOC #include #endif #define HASH_TTL 100 /*#define KILO 1e3 */ /*#define MEGA 1e6 */ /*#define GIGA 1e9 */ #define KEY_LEVEL "level" #define KEY_QUALITY "quality" #define KEY_NOISE "noise" #define KEY_PROTO "proto" #define KEY_FREQUENCY "frequency" #define KEY_BIT_RATE "bit_rate" #define KEY_ESSID "essid" #define KEY_OP_MODE "op_mode" #define KEY_SENS "sens" #define KEY_SEC_MODE "sec_mode" #define FREQ2FLOAT(m,e) (((double) m) * pow(10,e)) #define MWATT2DBM(in) ((int) (ceil(10.0 * log10((double) in)))) static HASH wireless; static int sock=-2
# Sweden - Emmaboda/B�lshult
# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy
T 554000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
T 530000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
T 474000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE
if (age>0 && age<=HASH_TTL) { return(0); } if (get_ifname(&req,dev)!=0) { return(-1); } if(do_ioctl(sock, dev, SIOCGIWSENS, &req) >= 0) { has_sens = 1; } if(get_range_info(sock, dev, &range) < 0) { memset(&range, 0, sizeof(range)); } else { has_range=1; } if(has_range) { if(req.u.sens.value < 0) { qprintf(buffer, sizeof(buffer), "%d dBm", req.u.sens.value); } else { qprintf(buffer, sizeof(buffer), "%d/%d", req.u.sens.value, range.sensitivity); } } else { qprintf(buffer, sizeof(buffer), "%d", req.u.sens.value); } hash_put(&wireless,key_buffer, buffer); return(0); } static int get_sec_mode(const char* dev, const char* key) { /* Get encryption information */ struct iwreq req; char key_buffer[32]; char encrypt_key[IW_ENCODING_TOKEN_MAX+1]; int age; int has_key=0; int key_flags=0; int key_size=0; qprintf(key_buffer,sizeof(key_buffer), "%s.%s", dev,key); age=hash_age(&wireless, key); /* reread every HASH_TTL msec only */ if (age>0 && age<=HASH_TTL) { return(0); } if (get_ifname(&req,dev)!=0) { return(-1); } req.u.data.pointer = (caddr_t) &encrypt_key; req.u.data.length = IW_ENCODING_TOKEN_MAX; req.u.data.flags = 0; if(do_ioctl(sock, dev, SIOCGIWENCODE, &req) >= 0) { has_key = 1; key_flags = req.u.data.flags; key_size = req.u.data.length; } else { return(-1); } /* Display encryption information */ /*if(has_key && (key_flags & IW_ENCODE_INDEX) > 1) */ /* printf(" [%d]", info->key_flags & IW_ENCODE_INDEX); */ if(has_key && (key_flags & IW_ENCODE_RESTRICTED)) hash_put(&wireless,key_buffer, "restricted"); else if(has_key && (key_flags & IW_ENCODE_OPEN)) hash_put(&wireless,key_buffer, "open"); return(0); } static int get_stats(const char *dev, const char *key) { struct iw_statistics stats; struct iwreq req; char qprintf_buffer[1024]; char key_buffer[32]; int age; struct iw_range range; qprintf(key_buffer,sizeof(key_buffer), "%s.%s", dev,key); age=hash_age(&wireless, key); /* reread every HASH_TTL msec only */ if (age>0 && age<=HASH_TTL) { return(0); } if (get_ifname(&req,dev)!=0) { return(-1); } req.u.data.pointer = (caddr_t) &stats; req.u.data.length = 0; req.u.data.flags = 1; /* Clear updated flag */ if(do_ioctl(sock, dev,SIOCGIWSTATS, &req) < 0) { ioctl_error(__LINE__); return -1; } if(get_range_info(sock, dev, &range) < 0) memset(&range, 0, sizeof(range)); if(stats.qual.level > range.max_qual.level) { qprintf(qprintf_buffer, sizeof(qprintf_buffer), "%d", stats.qual.level-0x100); qprintf(key_buffer,sizeof(key_buffer), "%s.%s", dev, KEY_LEVEL); hash_put(&wireless,key_buffer, qprintf_buffer); qprintf(qprintf_buffer, sizeof(qprintf_buffer), "%d", stats.qual.noise-0x100); qprintf(key_buffer,sizeof(key_buffer), "%s.%s", dev, KEY_NOISE); hash_put(&wireless,key_buffer, qprintf_buffer); qprintf(qprintf_buffer, sizeof(qprintf_buffer), "%d/%d", stats.qual.qual,range.max_qual.qual); qprintf(key_buffer,sizeof(key_buffer), "%s.%s", dev, KEY_QUALITY); hash_put(&wireless,key_buffer, qprintf_buffer); } else { qprintf(qprintf_buffer, sizeof(qprintf_buffer), "%d/%d", stats.qual.level, range.max_qual.level); qprintf(key_buffer,sizeof(key_buffer), "%s.%s", dev, KEY_LEVEL);; hash_put(&wireless,key_buffer, qprintf_buffer); qprintf(qprintf_buffer, sizeof(qprintf_buffer), "%d/%d", stats.qual.noise,range.max_qual.noise); qprintf(key_buffer,sizeof(key_buffer), "%s.%s", dev, KEY_NOISE); hash_put(&wireless,key_buffer, qprintf_buffer); qprintf(qprintf_buffer, sizeof(qprintf_buffer), "%d/%d", stats.qual.qual, range.max_qual.qual); qprintf(key_buffer,sizeof(key_buffer), "%s.%s", dev, KEY_QUALITY); hash_put(&wireless,key_buffer, qprintf_buffer); } return 0; } static int check_socket() { /* already handled in a previous run */ if (sock==-3) return(-1); /* socket not initialized */ if (sock==-2) sock = socket(AF_INET, SOCK_DGRAM, 0); /* error initilalizing socket */ if (sock<=0) { error("Error opening socket for reading wireless stats"); sock=-3; return(-1); } return(0); } static void save_result(RESULT *result, const char* dev, const char* key, const int res) { char key_buffer[64]; char* val=NULL; qprintf(key_buffer, sizeof(key_buffer), "%s.%s", dev,key); if (res<0) { SetResult(&result, R_STRING, ""); return; } val=hash_get(&wireless,key_buffer, NULL); if (val) { SetResult(&result, R_STRING, val); } else { SetResult(&result, R_STRING, ""); } } /* *functions exported to the evaluator */ static void wireless_quality(RESULT *result, RESULT *arg1) { char *dev=R2S(arg1); if (check_socket() != 0) return; save_result(result,dev,KEY_QUALITY,get_stats(dev, KEY_QUALITY)); } static void wireless_level(RESULT *result, RESULT *arg1) { char *dev=R2S(arg1); if (check_socket() != 0) return; save_result(result,dev,KEY_LEVEL,get_stats(dev, KEY_LEVEL)); } static void wireless_noise(RESULT *result, RESULT *arg1) { char *dev=R2S(arg1); if (check_socket() != 0) return; save_result(result,dev,KEY_NOISE,get_stats(dev, KEY_NOISE)); } static void wireless_protocol(RESULT *result, RESULT *arg1) { char *dev=R2S(arg1); if (check_socket() != 0) return; save_result(result,dev,KEY_PROTO,get_ifname(NULL, dev)); } static void wireless_frequency(RESULT *result, RESULT *arg1) { char *dev=R2S(arg1); if (check_socket() != 0) return; save_result(result,dev,KEY_FREQUENCY,get_frequency(dev, KEY_FREQUENCY)); } static void wireless_bitrate(RESULT *result, RESULT *arg1) { char *dev=R2S(arg1); if (check_socket() != 0) return; save_result(result,dev,KEY_BIT_RATE,get_bitrate(dev, KEY_BIT_RATE)); } static void wireless_essid(RESULT *result, RESULT *arg1) { char *dev=R2S(arg1); if (check_socket() != 0) return; save_result(result,dev,KEY_ESSID,get_essid(dev, KEY_ESSID)); } static void wireless_op_mode(RESULT *result, RESULT *arg1) { char *dev=R2S(arg1); if (check_socket() != 0) return; save_result(result,dev,KEY_OP_MODE,get_op_mode(dev, KEY_OP_MODE)); } static void wireless_sensitivity(RESULT *result, RESULT *arg1) { char *dev=R2S(arg1); if (check_socket() != 0) return; save_result(result,dev,KEY_SENS,get_sens(dev, KEY_SENS)); } static void wireless_sec_mode(RESULT *result, RESULT *arg1) { char *dev=R2S(arg1); if (check_socket() != 0) return; save_result(result,dev,KEY_SEC_MODE,get_sec_mode(dev, KEY_SEC_MODE)); } /* init and cleanup */ int plugin_init_wireless(void) { hash_create(&wireless); AddFunction ("wifi::level", 1, wireless_level); AddFunction ("wifi::noise", 1, wireless_noise); AddFunction ("wifi::quality", 1, wireless_quality); AddFunction ("wifi::protocol", 1, wireless_protocol); AddFunction ("wifi::frequency", 1, wireless_frequency); AddFunction ("wifi::bitrate", 1, wireless_bitrate); AddFunction ("wifi::essid", 1, wireless_essid); AddFunction ("wifi::op_mode", 1, wireless_op_mode); AddFunction ("wifi::sensitivity", 1, wireless_sensitivity); AddFunction ("wifi::sec_mode", 1, wireless_sec_mode); return 0; } void plugin_exit_wireless(void) { if (sock>0) close(sock); hash_destroy(&wireless); }