diff options
author | Jose A Ortega Ruiz <jao@gnu.org> | 2010-02-21 21:38:09 +0100 |
---|---|---|
committer | Jose A Ortega Ruiz <jao@gnu.org> | 2010-02-21 21:38:09 +0100 |
commit | d56e2da928343b9cadb8e034036926e089ad861e (patch) | |
tree | 9e316ea2523d97f8f208a580de9ddafc35412052 /IWlib.hsc | |
parent | 7f9eb02f5c420d8f9e425310d3982145649dbba1 (diff) | |
download | xmobar-d56e2da928343b9cadb8e034036926e089ad861e.tar.gz xmobar-d56e2da928343b9cadb8e034036926e089ad861e.tar.bz2 |
New Wireless monitor
Ignore-this: b1b66ffa9077f8d41a5c0e962ee0bff3
darcs-hash:20100221203809-748be-71bc1951a2eb8164b0043725bcb707f42e530ded.gz
Diffstat (limited to 'IWlib.hsc')
-rw-r--r-- | IWlib.hsc | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/IWlib.hsc b/IWlib.hsc new file mode 100644 index 0000000..afd6bf0 --- /dev/null +++ b/IWlib.hsc @@ -0,0 +1,75 @@ +----------------------------------------------------------------------------- +-- | +-- Module : IWlib +-- Copyright : (c) Jose A Ortega Ruiz +-- License : BSD-style (see LICENSE) +-- +-- Maintainer : Jose A Ortega Ruiz <jao@gnu.org> +-- Stability : unstable +-- Portability : unportable +-- +-- A partial binding to iwlib +-- +----------------------------------------------------------------------------- + +{-# LANGUAGE CPP, ForeignFunctionInterface, EmptyDataDecls #-} + + +module IWlib (WirelessInfo(..), getWirelessInfo) where + +import Foreign +import Foreign.C.Types +import Foreign.C.String + +data WirelessInfo = WirelessInfo { wiEssid :: String, wiQuality :: Int } + deriving Show + +#include <iwlib.h> + +data WCfg +data WStats +data WRange + +foreign import ccall "iwlib.h iw_sockets_open" + c_iw_open :: IO CInt + +foreign import ccall "unistd.h close" + c_iw_close :: CInt -> IO () + +foreign import ccall "iwlib.h iw_get_basic_config" + c_iw_basic_config :: CInt -> CString -> Ptr WCfg -> IO CInt + +foreign import ccall "iwlib.h iw_get_stats" + c_iw_stats :: CInt -> CString -> Ptr WStats -> Ptr WRange -> CInt -> IO CInt + +foreign import ccall "iwlib.h iw_get_range_info" + c_iw_range :: CInt -> CString -> Ptr WRange -> IO CInt + +getWirelessInfo :: String -> IO WirelessInfo +getWirelessInfo iface = + allocaBytes (#size struct wireless_config) $ \wc -> + allocaBytes (#size struct iw_statistics) $ \stats -> + allocaBytes (#size struct iw_range) $ \rng -> + withCString iface $ \istr -> do + i <- c_iw_open + bcr <- c_iw_basic_config i istr wc + str <- c_iw_stats i istr stats rng 1 + rgr <- c_iw_range i istr rng + c_iw_close i + if (bcr < 0) then return $WirelessInfo {wiEssid = "", wiQuality = -1} else + do hase <- (#peek struct wireless_config, has_essid) wc :: IO CInt + eon <- (#peek struct wireless_config, essid_on) wc :: IO CInt + essid <- if hase > 0 && eon > 0 then + do l <- (#peek struct wireless_config, essid_len) wc + let e = (#ptr struct wireless_config, essid) wc + peekCStringLen (e, fromIntegral (l :: CInt)) + else return "" + q <- if str >= 0 && rgr >=0 then + do let qual = (#ptr struct iw_statistics, qual) stats + qualv <- (#peek struct iw_param, value) qual :: IO CInt + let qualm = (#ptr struct iw_range, max_qual) rng + mv <- (#peek struct iw_param, value) qualm :: IO CInt + return $ fromIntegral qualv / fromIntegral (max 1 mv) + else return (-1) + let qv = round (100 * (q :: Double)) + return $ WirelessInfo { wiEssid = essid, wiQuality = qv } |