summaryrefslogtreecommitdiffhomepage
path: root/IWlib.hsc
diff options
context:
space:
mode:
authorJose A Ortega Ruiz <jao@gnu.org>2010-02-21 21:38:09 +0100
committerJose A Ortega Ruiz <jao@gnu.org>2010-02-21 21:38:09 +0100
commitd56e2da928343b9cadb8e034036926e089ad861e (patch)
tree9e316ea2523d97f8f208a580de9ddafc35412052 /IWlib.hsc
parent7f9eb02f5c420d8f9e425310d3982145649dbba1 (diff)
downloadxmobar-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.hsc75
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 }