{-# LINE 1 "src/Bindings/NFC.chs" #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# OPTIONS_GHC -fno-warn-unused-top-binds #-}
module Bindings.NFC
( NFCTarget(..)
, NFCModulation(..)
, NFCModulationType(..)
, NFCBaudRate(..)
, NFCISO14443aInfo(..)
, initialize
, open
, initiatorInit
, initiatorSelectPassiveTarget
, initiatorPollTarget
) where
import qualified Foreign.C.String as C2HSImp
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.ForeignPtr as C2HSImp
import qualified Foreign.Ptr as C2HSImp
import qualified Foreign.Storable as C2HSImp
import qualified System.IO.Unsafe as C2HSImp
import Control.Monad ((<=<))
import Data.ByteString (ByteString, packCStringLen)
import Data.Word (Word8, Word16)
import Foreign.C.String (withCStringLen)
import Foreign.C.Types (CUChar(..))
import Foreign.ForeignPtr (newForeignPtr, withForeignPtr)
import Foreign.Ptr (Ptr, castPtr, nullPtr)
import Foreign.Marshal.Alloc (alloca)
import Foreign.Marshal.Array (allocaArray, pokeArray)
import Foreign.Marshal.Utils (maybePeek, with)
import Foreign.Storable (Storable(..))
data NFCModulation =
NFCModulation { NFCModulation -> NFCModulationType
nfcModType :: NFCModulationType
, NFCModulation -> NFCBaudRate
nfcModBaudRate :: NFCBaudRate
}
data NFCISO14443aInfo =
NFCISO14443aInfo { NFCISO14443aInfo -> Word16
iso14443aAbtAtqa :: Word16
, NFCISO14443aInfo -> Word8
iso14443aBtSak :: Word8
, NFCISO14443aInfo -> ByteString
iso14443aAbtUid :: ByteString
, NFCISO14443aInfo -> ByteString
iso14443aAbtAts :: ByteString
}
data NFCTarget = NFCTargetISO14443a NFCISO14443aInfo
outNfcCtx :: Ptr (Ptr ()) -> IO NFCContextPtr
outNfcCtx :: Ptr (Ptr ()) -> IO NFCContextPtr
outNfcCtx = FinalizerPtr () -> Ptr () -> IO NFCContextPtr
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr ()
nfc_exit (Ptr () -> IO NFCContextPtr)
-> (Ptr (Ptr ()) -> IO (Ptr ()))
-> Ptr (Ptr ())
-> IO NFCContextPtr
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Ptr (Ptr ()) -> IO (Ptr ())
forall a. Storable a => Ptr a -> IO a
peek
outNfcDev :: Ptr () -> IO (Maybe NFCDevicePtr)
outNfcDev :: Ptr () -> IO (Maybe NFCContextPtr)
outNfcDev = (Ptr () -> IO NFCContextPtr) -> Ptr () -> IO (Maybe NFCContextPtr)
forall a b. (Ptr a -> IO b) -> Ptr a -> IO (Maybe b)
maybePeek ((Ptr () -> IO NFCContextPtr)
-> Ptr () -> IO (Maybe NFCContextPtr))
-> (Ptr () -> IO NFCContextPtr)
-> Ptr ()
-> IO (Maybe NFCContextPtr)
forall a b. (a -> b) -> a -> b
$ FinalizerPtr () -> Ptr () -> IO NFCContextPtr
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr ()
nfc_close
inMaybeStrLen :: Num a => Maybe String -> ((Ptr CUChar, a) -> IO b) -> IO b
inMaybeStrLen :: forall a b.
Num a =>
Maybe String -> ((Ptr CUChar, a) -> IO b) -> IO b
inMaybeStrLen Maybe String
Nothing (Ptr CUChar, a) -> IO b
f = (Ptr CUChar, a) -> IO b
f (Ptr CUChar
forall a. Ptr a
nullPtr, a
0)
inMaybeStrLen (Just String
str) (Ptr CUChar, a) -> IO b
f = String -> (CStringLen -> IO b) -> IO b
forall a. String -> (CStringLen -> IO a) -> IO a
withCStringLen String
str ((CStringLen -> IO b) -> IO b) -> (CStringLen -> IO b) -> IO b
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
ptr, Int
len) -> (Ptr CUChar, a) -> IO b
f (Ptr CChar -> Ptr CUChar
forall a b. Ptr a -> Ptr b
castPtr Ptr CChar
ptr, Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
inNfcMod :: Num a => [NFCModulation] -> ((Ptr NFCModulation, a) -> IO b) -> IO b
inNfcMod :: forall a b.
Num a =>
[NFCModulation] -> ((Ptr NFCModulation, a) -> IO b) -> IO b
inNfcMod [NFCModulation]
nfcMod (Ptr NFCModulation, a) -> IO b
f = do
let len :: Int
len = [NFCModulation] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [NFCModulation]
nfcMod
Int -> (Ptr NFCModulation -> IO b) -> IO b
forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
len ((Ptr NFCModulation -> IO b) -> IO b)
-> (Ptr NFCModulation -> IO b) -> IO b
forall a b. (a -> b) -> a -> b
$ \Ptr NFCModulation
ptr -> do
Ptr NFCModulation -> [NFCModulation] -> IO ()
forall a. Storable a => Ptr a -> [a] -> IO ()
pokeArray Ptr NFCModulation
ptr [NFCModulation]
nfcMod
(Ptr NFCModulation, a) -> IO b
f (Ptr NFCModulation
ptr, Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
data NFCModulationType = NmtIso14443a
| NmtJewel
| NmtIso14443b
| NmtIso14443bi
| NmtIso14443b2sr
| NmtIso14443b2ct
| NmtFelica
| NmtDep
deriving (NFCModulationType -> NFCModulationType -> Bool
(NFCModulationType -> NFCModulationType -> Bool)
-> (NFCModulationType -> NFCModulationType -> Bool)
-> Eq NFCModulationType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NFCModulationType -> NFCModulationType -> Bool
$c/= :: NFCModulationType -> NFCModulationType -> Bool
== :: NFCModulationType -> NFCModulationType -> Bool
$c== :: NFCModulationType -> NFCModulationType -> Bool
Eq,Int -> NFCModulationType -> ShowS
[NFCModulationType] -> ShowS
NFCModulationType -> String
(Int -> NFCModulationType -> ShowS)
-> (NFCModulationType -> String)
-> ([NFCModulationType] -> ShowS)
-> Show NFCModulationType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NFCModulationType] -> ShowS
$cshowList :: [NFCModulationType] -> ShowS
show :: NFCModulationType -> String
$cshow :: NFCModulationType -> String
showsPrec :: Int -> NFCModulationType -> ShowS
$cshowsPrec :: Int -> NFCModulationType -> ShowS
Show)
instance Enum NFCModulationType where
succ NmtIso14443a = NmtJewel
succ NmtJewel = NmtIso14443b
succ NmtIso14443b = NmtIso14443bi
succ NmtIso14443bi = NmtIso14443b2sr
succ NmtIso14443b2sr = NmtIso14443b2ct
succ NmtIso14443b2ct = NmtFelica
succ NmtFelica = NmtDep
succ NmtDep = error "NFCModulationType.succ: NmtDep has no successor"
pred NmtJewel = NmtIso14443a
pred NmtIso14443b = NmtJewel
pred NmtIso14443bi = NmtIso14443b
pred NmtIso14443b2sr = NmtIso14443bi
pred NmtIso14443b2ct = NmtIso14443b2sr
pred NmtFelica = NmtIso14443b2ct
pred NmtDep = NmtFelica
pred NmtIso14443a = error "NFCModulationType.pred: NmtIso14443a has no predecessor"
enumFromTo from to = go from
where
end = fromEnum to
go v = case compare (fromEnum v) end of
LT -> v : go (succ v)
EQ -> [v]
GT -> []
enumFrom from = enumFromTo from NmtDep
fromEnum NmtIso14443a = 1
fromEnum NmtJewel = 2
fromEnum NmtIso14443b = 3
fromEnum NmtIso14443bi = 4
fromEnum NmtIso14443b2sr = 5
fromEnum NmtIso14443b2ct = 6
fromEnum NmtFelica = 7
fromEnum NmtDep = 8
toEnum Int
1 = NmtIso14443a
toEnum Int
2 = NmtJewel
toEnum Int
3 = NmtIso14443b
toEnum 4 = NmtIso14443bi
toEnum 5 = NmtIso14443b2sr
toEnum 6 = NmtIso14443b2ct
toEnum 7 = NmtFelica
toEnum 8 = NmtDep
toEnum unmatched = error ("NFCModulationType.toEnum: Cannot match " ++ show unmatched)
{-# LINE 81 "src/Bindings/NFC.chs" #-}
data NFCBaudRate = NbrUndefined
| Nbr106
| Nbr212
| Nbr424
| Nbr847
deriving (Eq,Show)
instance Enum NFCBaudRate where
succ NbrUndefined = Nbr106
succ Nbr106 = Nbr212
succ Nbr212 = Nbr424
succ Nbr424 = Nbr847
succ Nbr847 = error "NFCBaudRate.succ: Nbr847 has no successor"
pred Nbr106 = NbrUndefined
pred Nbr212 = Nbr106
pred Nbr424 = Nbr212
pred Nbr847 = Nbr424
pred NbrUndefined = error "NFCBaudRate.pred: NbrUndefined has no predecessor"
enumFromTo from to = go from
where
end = fromEnum to
go v = case compare (fromEnum v) end of
LT -> v : go (succ v)
EQ -> [v]
GT -> []
enumFrom from = enumFromTo from Nbr847
fromEnum NbrUndefined = 0
fromEnum Nbr106 = 1
fromEnum Nbr212 = 2
fromEnum Nbr424 = 3
fromEnum Nbr847 = 4
toEnum 0 = NbrUndefined
toEnum 1 = Nbr106
toEnum 2 = Nbr212
toEnum 3 = Nbr424
toEnum 4 = Nbr847
toEnum unmatched = error ("NFCBaudRate.toEnum: Cannot match " ++ show unmatched)
{-# LINE 83 "src/Bindings/NFC.chs" #-}
type NFCContextPtr = C2HSImp.ForeignPtr (())
{-# LINE 85 "src/Bindings/NFC.chs" #-}
type NFCDevicePtr = C2HSImp.ForeignPtr (())
{-# LINE 87 "src/Bindings/NFC.chs" #-}
type NFCModulationPtr = C2HSImp.ForeignPtr (NFCModulation)
{-# LINE 89 "src/Bindings/NFC.chs" #-}
type NFCTargetPtr = C2HSImp.ForeignPtr (NFCTarget)
{-# LINE 91 "src/Bindings/NFC.chs" #-}
initialize :: IO ((NFCContextPtr))
initialize =
alloca $ \a1' ->
initialize'_ a1' >>
outNfcCtx a1'>>= \a1'' ->
return (a1'')
{-# LINE 93 "src/Bindings/NFC.chs" #-}
open :: (NFCContextPtr) -> (String) -> IO ((Maybe NFCDevicePtr))
open a1 a2 =
C2HSImp.withForeignPtr a1 $ \a1' ->
C2HSImp.withCString a2 $ \a2' ->
open'_ a1' a2' >>= \res ->
outNfcDev res >>= \res' ->
return (res')
{-# LINE 95 "src/Bindings/NFC.chs" #-}
initiatorInit :: (NFCDevicePtr) -> IO ((Int))
initiatorInit a1 =
C2HSImp.withForeignPtr a1 $ \a1' ->
initiatorInit'_ a1' >>= \res ->
let {res' = fromIntegral res} in
return (res')
{-# LINE 97 "src/Bindings/NFC.chs" #-}
initiatorSelectPassiveTarget :: NFCDevicePtr -> NFCModulation -> Maybe String -> IO (Maybe NFCTarget)
initiatorSelectPassiveTarget dev nfcMod initData =
withForeignPtr dev $ \devPtr ->
with nfcMod $ \nfcModPtr ->
inMaybeStrLen initData $ \(strPtr, strLen) ->
alloca $ \target -> do
returnValue <- __wrapped__nfc_initiator_select_passive_target
{-# LINE 105 "src/Bindings/NFC.chs" #-}
devPtr
nfcModPtr
strPtr
strLen
target
if returnValue /= 1
then return Nothing
else (return . Just <=< peek) target
initiatorPollTarget :: NFCDevicePtr -> [NFCModulation] -> Word8 -> Word8 -> IO (Maybe NFCTarget)
initiatorPollTarget dev nfcMod numPolling period = do
withForeignPtr dev $ \devPtr ->
inNfcMod nfcMod $ \(nfcModArray, nfcModLen) ->
alloca $ \target -> do
returnValue <- nfc_initiator_poll_target
{-# LINE 121 "src/Bindings/NFC.chs" #-}
devPtr
nfcModArray
nfcModLen
(fromIntegral numPolling)
(fromIntegral period)
target
if returnValue /= 1
then return Nothing
else (return . Just <=< peek) target
decodeIso14443a :: Ptr NFCTarget -> IO NFCTarget
decodeIso14443a :: Ptr NFCTarget -> IO NFCTarget
decodeIso14443a Ptr NFCTarget
p = do
Word16
abtAtqa <- (Ptr Word16 -> IO Word16
forall a. Storable a => Ptr a -> IO a
peek (Ptr Word16 -> IO Word16)
-> (Ptr CUChar -> Ptr Word16) -> Ptr CUChar -> IO Word16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr CUChar -> Ptr Word16
forall a b. Ptr a -> Ptr b
castPtr) (Ptr CUChar -> IO Word16) -> IO (Ptr CUChar) -> IO Word16
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Ptr NFCTarget -> IO (Ptr CUChar)
hs_nfc_get_nai_abtAtqa Ptr NFCTarget
p
(CUChar Word8
btSak) <- Ptr NFCTarget -> IO CUChar
hs_nfc_get_nai_btSak Ptr NFCTarget
p
Int
szUidLen <- CULong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CULong -> Int) -> IO CULong -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr NFCTarget -> IO CULong
hs_nfc_get_nai_szUidLen Ptr NFCTarget
p
Ptr CChar
abtUidPtr <- Ptr CUChar -> Ptr CChar
forall a b. Ptr a -> Ptr b
castPtr (Ptr CUChar -> Ptr CChar) -> IO (Ptr CUChar) -> IO (Ptr CChar)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr NFCTarget -> IO (Ptr CUChar)
hs_nfc_get_nai_abtUid Ptr NFCTarget
p
ByteString
abtUid <- CStringLen -> IO ByteString
packCStringLen (Ptr CChar
abtUidPtr, Int
szUidLen)
Int
szAtsLen <- CULong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CULong -> Int) -> IO CULong -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr NFCTarget -> IO CULong
hs_nfc_get_nai_szAtsLen Ptr NFCTarget
p
Ptr CChar
abtAtsPtr <- Ptr CUChar -> Ptr CChar
forall a b. Ptr a -> Ptr b
castPtr (Ptr CUChar -> Ptr CChar) -> IO (Ptr CUChar) -> IO (Ptr CChar)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr NFCTarget -> IO (Ptr CUChar)
hs_nfc_get_nai_abtAts Ptr NFCTarget
p
ByteString
abtAts <- CStringLen -> IO ByteString
packCStringLen (Ptr CChar
abtAtsPtr, Int
szAtsLen)
NFCTarget -> IO NFCTarget
forall (m :: * -> *) a. Monad m => a -> m a
return (NFCTarget -> IO NFCTarget) -> NFCTarget -> IO NFCTarget
forall a b. (a -> b) -> a -> b
$ NFCISO14443aInfo -> NFCTarget
NFCTargetISO14443a (NFCISO14443aInfo -> NFCTarget) -> NFCISO14443aInfo -> NFCTarget
forall a b. (a -> b) -> a -> b
$ Word16 -> Word8 -> ByteString -> ByteString -> NFCISO14443aInfo
NFCISO14443aInfo Word16
abtAtqa Word8
btSak ByteString
abtUid ByteString
abtAts
instance Storable NFCModulation where
alignment :: NFCModulation -> Int
alignment NFCModulation
_ = Int
4
{-# LINE 150 "src/Bindings/NFC.chs" #-}
sizeOf _ = 8
{-# LINE 151 "src/Bindings/NFC.chs" #-}
peek p = do
modType <- (toEnum . fromIntegral) <$> (\ptr -> do {C2HSImp.peekByteOff ptr 0 :: IO C2HSImp.CInt}) p
baud <- (toEnum . fromIntegral) <$> (\ptr -> do {C2HSImp.peekByteOff ptr 4 :: IO C2HSImp.CInt}) p
return $ NFCModulation modType baud
poke :: Ptr NFCModulation -> NFCModulation -> IO ()
poke Ptr NFCModulation
p (NFCModulation NFCModulationType
modType NFCBaudRate
baud) = do
(\Ptr NFCModulation
ptr CInt
val -> do {Ptr NFCModulation -> Int -> CInt -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
C2HSImp.pokeByteOff Ptr NFCModulation
ptr Int
0 (CInt
val :: C2HSImp.CInt)}) Ptr NFCModulation
p (CInt -> IO ()) -> CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CInt)
-> (NFCModulationType -> Int) -> NFCModulationType -> CInt
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NFCModulationType -> Int
forall a. Enum a => a -> Int
fromEnum) NFCModulationType
modType
(\Ptr NFCModulation
ptr CInt
val -> do {Ptr NFCModulation -> Int -> CInt -> IO ()
forall a b. Storable a => Ptr b -> Int -> a -> IO ()
C2HSImp.pokeByteOff Ptr NFCModulation
ptr Int
4 (CInt
val :: C2HSImp.CInt)}) Ptr NFCModulation
p (CInt -> IO ()) -> CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CInt) -> (NFCBaudRate -> Int) -> NFCBaudRate -> CInt
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NFCBaudRate -> Int
forall a. Enum a => a -> Int
fromEnum) NFCBaudRate
baud
instance Storable NFCTarget where
alignment :: NFCTarget -> Int
alignment NFCTarget
_ = Int
8
{-# LINE 161 "src/Bindings/NFC.chs" #-}
sizeOf _ = fromIntegral (C2HSImp.unsafePerformIO hs_nfc_target_size)
{-# LINE 162 "src/Bindings/NFC.chs" #-}
peek p = do
nfcMod <- peek =<< hs_nfc_get_nm p
case nfcModType nfcMod of
NmtIso14443a -> decodeIso14443a p
_ -> error "not implemented"
poke :: Ptr NFCTarget -> NFCTarget -> IO ()
poke = String -> Ptr NFCTarget -> NFCTarget -> IO ()
forall a. HasCallStack => String -> a
error String
"not implemented"
foreign import ccall "Bindings/NFC.chs.h &nfc_exit"
nfc_exit :: C2HSImp.FinalizerPtr ()
foreign import ccall "Bindings/NFC.chs.h &nfc_close"
nfc_close :: C2HSImp.FinalizerPtr ()
foreign import ccall safe "Bindings/NFC.chs.h nfc_init"
initialize'_ :: ((C2HSImp.Ptr (C2HSImp.Ptr (()))) -> (IO ()))
foreign import ccall safe "Bindings/NFC.chs.h nfc_open"
open'_ :: ((C2HSImp.Ptr (())) -> ((C2HSImp.Ptr C2HSImp.CChar) -> (IO (C2HSImp.Ptr (())))))
foreign import ccall safe "Bindings/NFC.chs.h nfc_initiator_init"
initiatorInit'_ :: ((C2HSImp.Ptr (())) -> (IO C2HSImp.CInt))
foreign import ccall safe "Bindings/NFC.chs.h __wrapped__nfc_initiator_select_passive_target"
__wrapped__nfc_initiator_select_passive_target :: ((C2HSImp.Ptr (())) -> ((C2HSImp.Ptr (NFCModulation)) -> ((C2HSImp.Ptr C2HSImp.CUChar) -> (C2HSImp.CULong -> ((C2HSImp.Ptr (NFCTarget)) -> (IO C2HSImp.CInt))))))
foreign import ccall safe "Bindings/NFC.chs.h nfc_initiator_poll_target"
nfc_initiator_poll_target :: ((C2HSImp.Ptr (())) -> ((C2HSImp.Ptr (NFCModulation)) -> (C2HSImp.CULong -> (C2HSImp.CUChar -> (C2HSImp.CUChar -> ((C2HSImp.Ptr (NFCTarget)) -> (IO C2HSImp.CInt)))))))
foreign import ccall safe "Bindings/NFC.chs.h hs_nfc_get_nai_abtAtqa"
hs_nfc_get_nai_abtAtqa :: ((C2HSImp.Ptr (NFCTarget)) -> (IO (C2HSImp.Ptr C2HSImp.CUChar)))
foreign import ccall safe "Bindings/NFC.chs.h hs_nfc_get_nai_btSak"
hs_nfc_get_nai_btSak :: ((C2HSImp.Ptr (NFCTarget)) -> (IO C2HSImp.CUChar))
foreign import ccall safe "Bindings/NFC.chs.h hs_nfc_get_nai_szUidLen"
hs_nfc_get_nai_szUidLen :: ((C2HSImp.Ptr (NFCTarget)) -> (IO C2HSImp.CULong))
foreign import ccall safe "Bindings/NFC.chs.h hs_nfc_get_nai_abtUid"
hs_nfc_get_nai_abtUid :: ((C2HSImp.Ptr (NFCTarget)) -> (IO (C2HSImp.Ptr C2HSImp.CUChar)))
foreign import ccall safe "Bindings/NFC.chs.h hs_nfc_get_nai_szAtsLen"
hs_nfc_get_nai_szAtsLen :: ((C2HSImp.Ptr (NFCTarget)) -> (IO C2HSImp.CULong))
foreign import ccall safe "Bindings/NFC.chs.h hs_nfc_get_nai_abtAts"
hs_nfc_get_nai_abtAts :: ((C2HSImp.Ptr (NFCTarget)) -> (IO (C2HSImp.Ptr C2HSImp.CUChar)))
foreign import ccall safe "Bindings/NFC.chs.h hs_nfc_target_size"
hs_nfc_target_size :: (IO C2HSImp.CULong)
foreign import ccall safe "Bindings/NFC.chs.h hs_nfc_get_nm"
hs_nfc_get_nm :: ((C2HSImp.Ptr (NFCTarget)) -> (IO (C2HSImp.Ptr (NFCModulation))))