network-can-0.1.0.0: src/Network/SocketCAN/Bindings.hsc
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Network.SocketCAN.Bindings
(
-- * Network package compatibility
SockAddrCAN(..)
, pattern CAN_RAW
-- * SocketCAN bindings
, SocketCANArbitrationField(..)
, SocketCANFrame(..)
) where
import Data.Word (Word8, Word16, Word32)
import Foreign.Storable (Storable(..))
import Foreign.Marshal.Array (peekArray, pokeArray)
import Foreign.Ptr (plusPtr)
import Network.Socket.Address (SocketAddress(..))
import Network.Socket (ProtocolNumber)
#include <linux/can.h>
#include <sys/socket.h>
-- | CAN Socket type
newtype SockAddrCAN = SockAddrCAN Word32
deriving (Eq, Ord)
-- Word16
type CSaFamily = (#type sa_family_t)
instance SocketAddress SockAddrCAN where
sizeOfSocketAddress (SockAddrCAN _) =
#const sizeof(struct sockaddr_can)
peekSocketAddress sap = do
ifidx <- (#peek struct sockaddr_can, can_ifindex) sap
return (SockAddrCAN ifidx)
pokeSocketAddress p (SockAddrCAN ifIndex) = do
(#poke struct sockaddr_can, can_family) p ((#const AF_CAN) :: CSaFamily)
(#poke struct sockaddr_can, can_ifindex) p ifIndex
-- | CAN RAW protocol family of PF_CAN
pattern CAN_RAW :: ProtocolNumber
pattern CAN_RAW = #const CAN_RAW
-- | SocketCAN Arbitration field (CAN ID including RTR, EFF, ERR bits)
newtype SocketCANArbitrationField =
SocketCANArbitrationField { unSocketCANArbitrationField :: Word32 }
deriving (Eq, Ord, Show, Storable)
data SocketCANFrame = SocketCANFrame
{ socketCANFrameArbitrationField :: SocketCANArbitrationField
, socketCANFrameLength :: Word8
, socketCANFrameData :: [Word8]
} deriving Show
instance Storable SocketCANFrame where
sizeOf ~_ = #const sizeof(struct can_frame)
alignment ~_ = #alignment struct can_frame
peek ptr = do
socketCANFrameArbitrationField
<- #{peek struct can_frame, can_id} ptr
socketCANFrameLength
<- #{peek struct can_frame, len} ptr
socketCANFrameData <-
peekArray
(fromIntegral socketCANFrameLength)
(#{ptr struct can_frame, data} ptr)
pure
$ SocketCANFrame{..}
poke ptr SocketCANFrame{..} = do
#{poke struct can_frame, can_id}
ptr
socketCANFrameArbitrationField
#{poke struct can_frame, len}
ptr
socketCANFrameLength
pokeArray
(#{ptr struct can_frame, data} ptr)
socketCANFrameData