{-# LINE 1 "src/Network/IWlib.hsc" #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  IWlib
-- Copyright   :  (c) 2018 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 Network.IWlib (WirelessInfo(..), getWirelessInfo) where

import Foreign
import Foreign.C.Types
import Foreign.C.String

data WirelessInfo = WirelessInfo { wiEssid :: String,  wiQuality :: Int }
                  deriving Show



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 ((184)) $ \wc ->
{-# LINE 51 "src/Network/IWlib.hsc" #-}
  allocaBytes ((32)) $ \stats ->
{-# LINE 52 "src/Network/IWlib.hsc" #-}
  allocaBytes ((588)) $ \rng ->
{-# LINE 53 "src/Network/IWlib.hsc" #-}
  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 = 0 } else
      do hase <- ((\hsc_ptr -> peekByteOff hsc_ptr 128)) wc :: IO CInt
{-# LINE 61 "src/Network/IWlib.hsc" #-}
         eon <- ((\hsc_ptr -> peekByteOff hsc_ptr 132)) wc :: IO CInt
{-# LINE 62 "src/Network/IWlib.hsc" #-}
         essid <- if hase /= 0 && eon /= 0 then
                    do let e = ((\hsc_ptr -> hsc_ptr `plusPtr` 136)) wc
{-# LINE 64 "src/Network/IWlib.hsc" #-}
                       peekCString e
                  else return ""
         q <- if str >= 0 && rgr >=0 then
                do qualv <- xqual $ ((\hsc_ptr -> hsc_ptr `plusPtr` 2)) stats
{-# LINE 68 "src/Network/IWlib.hsc" #-}
                   mv <- xqual $ ((\hsc_ptr -> hsc_ptr `plusPtr` 44)) rng
{-# LINE 69 "src/Network/IWlib.hsc" #-}
                   let mxv = if mv /= 0 then fromIntegral mv else 1
                   return $ fromIntegral qualv / mxv
              else return 0
         let qv = round (100 * (q :: Double))
         return WirelessInfo { wiEssid = essid, wiQuality = min 100 qv }
    where xqual p = let qp = ((\hsc_ptr -> hsc_ptr `plusPtr` 0)) p in
{-# LINE 75 "src/Network/IWlib.hsc" #-}
            ((\hsc_ptr -> peekByteOff hsc_ptr 0)) qp :: IO CChar
{-# LINE 76 "src/Network/IWlib.hsc" #-}