{-# LANGUAGE TypeApplications #-}
module Network.SocketCAN.LowLevel
( socket
, bind
, send
, recv
, module Network.Socket
) where
import Control.Monad (void)
import Foreign.Ptr (Ptr)
import Network.Socket (Family(AF_CAN), Socket, close)
import Network.SocketCAN.Bindings (SockAddrCAN(..), SocketCANFrame)
import qualified Foreign.Ptr
import qualified Foreign.Marshal.Alloc
import qualified Foreign.Storable
import qualified Network.Socket
import qualified Network.Socket.Address
import qualified Network.SocketCAN.Bindings
socket
:: IO Socket
socket :: IO Socket
socket =
Family -> SocketType -> ProtocolNumber -> IO Socket
Network.Socket.socket
Family
AF_CAN
SocketType
Network.Socket.Raw
ProtocolNumber
Network.SocketCAN.Bindings.CAN_RAW
bind
:: Socket
-> SockAddrCAN
-> IO ()
bind :: Socket -> SockAddrCAN -> IO ()
bind = Socket -> SockAddrCAN -> IO ()
forall sa. SocketAddress sa => Socket -> sa -> IO ()
Network.Socket.Address.bind
send
:: Socket
-> SocketCANFrame
-> IO ()
send :: Socket -> SocketCANFrame -> IO ()
send Socket
canSock SocketCANFrame
cf =
(Ptr SocketCANFrame -> IO ()) -> IO ()
forall a b. Storable a => (Ptr a -> IO b) -> IO b
Foreign.Marshal.Alloc.alloca ((Ptr SocketCANFrame -> IO ()) -> IO ())
-> (Ptr SocketCANFrame -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr SocketCANFrame
ptr -> do
Ptr SocketCANFrame -> SocketCANFrame -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
Foreign.Storable.poke Ptr SocketCANFrame
ptr SocketCANFrame
cf
IO Int -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void
(IO Int -> IO ()) -> IO Int -> IO ()
forall a b. (a -> b) -> a -> b
$ Socket -> Ptr Word8 -> Int -> IO Int
Network.Socket.sendBuf
Socket
canSock
(Ptr SocketCANFrame -> Ptr Word8
forall a b. Ptr a -> Ptr b
Foreign.Ptr.castPtr Ptr SocketCANFrame
ptr)
(SocketCANFrame -> Int
forall a. Storable a => a -> Int
Foreign.Storable.sizeOf SocketCANFrame
cf)
recv
:: Socket
-> IO SocketCANFrame
recv :: Socket -> IO SocketCANFrame
recv Socket
canSock =
(Ptr SocketCANFrame -> IO SocketCANFrame) -> IO SocketCANFrame
forall a b. Storable a => (Ptr a -> IO b) -> IO b
Foreign.Marshal.Alloc.alloca ((Ptr SocketCANFrame -> IO SocketCANFrame) -> IO SocketCANFrame)
-> (Ptr SocketCANFrame -> IO SocketCANFrame) -> IO SocketCANFrame
forall a b. (a -> b) -> a -> b
$ \Ptr SocketCANFrame
ptr -> do
(Int
_nBytes, SockAddrCAN
_sockAddr) <-
forall sa a.
SocketAddress sa =>
Socket -> Ptr a -> Int -> IO (Int, sa)
Network.Socket.Address.recvBufFrom
@SockAddrCAN
Socket
canSock
(Ptr SocketCANFrame
ptr :: Ptr SocketCANFrame)
(SocketCANFrame -> Int
forall a. Storable a => a -> Int
Foreign.Storable.sizeOf (SocketCANFrame
forall a. HasCallStack => a
undefined :: SocketCANFrame))
Ptr SocketCANFrame -> IO SocketCANFrame
forall a. Storable a => Ptr a -> IO a
Foreign.Storable.peek Ptr SocketCANFrame
ptr IO SocketCANFrame
-> (SocketCANFrame -> IO SocketCANFrame) -> IO SocketCANFrame
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= SocketCANFrame -> IO SocketCANFrame
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure