Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ jobs:
strategy:
matrix:
cabal:
- '3.12'
- '3.16'
ghc:
- '9.8.2'
- '9.8.4'
os:
- "ubuntu-latest"
name: Haskell CI
Expand Down
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
# Version [0.2.0.0](https://github.com/DistRap/network-can/compare/0.1.0.0...0.2.0.0) (2026-04-29)

* Split `slcan` and `socketcan` into public sublibraries
* Migrate to `io-classes` and switch from `MonadCAN` typeclass
to `CAN` handle (record of functions style):

```
data CAN m = CAN
{ canSend :: CANMessage -> m ()
, canRecv :: m CANMessage
}
```
* Runners renamed
* `runSocketCAN` is now `withSocketCAN`
* `runSLCAN` is now `withSLCAN`
to reflect the handle change

# Version [0.1.0.0](https://github.com/DistRap/network-can/compare/d50564...0.1.0.0) (2025-05-19)

* Initial release
Expand Down
1 change: 1 addition & 0 deletions README.lhs
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,22 @@ CAN bus networking using Linux SocketCAN or SLCAN backends.

```haskell
import qualified Control.Monad
import qualified Control.Monad.IO.Class
import qualified Network.CAN
import qualified Network.SocketCAN

main :: IO ()
main = do
Network.SocketCAN.runSocketCAN
Network.SocketCAN.withSocketCAN
(Network.SocketCAN.mkCANInterface "vcan0")
$ do
$ \can -> do
Network.CAN.send
can
$ Network.CAN.standardMessage
0x123
[0xDE, 0xAD]

Control.Monad.forever
$ Network.CAN.recv
>>= Control.Monad.IO.Class.liftIO . print
can
>>= putStrLn . Network.CAN.prettyCANMessage
```
15 changes: 7 additions & 8 deletions app/CANBridge.hs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{-# LANGUAGE LambdaCase #-}
module Main where

import Control.Monad.Trans (MonadTrans(lift))
import Data.Default.Class (Default(def))
import Control.Monad.Class.MonadAsync (race_)
import Data.Default (Default(def))
import Network.SLCAN (Transport(..))
import System.Hardware.Serialport (CommSpeed(..), SerialPortSettings(..))

Expand All @@ -11,7 +11,6 @@ import qualified Network.CAN
import qualified Network.SocketCAN
import qualified Network.SLCAN
import qualified System.Hardware.Serialport
import qualified UnliftIO.Async

-- | Bridge vcan0 to slcan over /dev/can4discouart serial port
main :: IO ()
Expand All @@ -21,12 +20,12 @@ main = do
(System.Hardware.Serialport.defaultSerialSettings
{ commSpeed = CS115200 }
)
Network.SLCAN.runSLCAN (Transport_Handle h) def $ do
Network.SocketCAN.runSocketCAN (Network.SocketCAN.mkCANInterface "vcan0") $ do
UnliftIO.Async.race_
Network.SLCAN.withSLCAN (Transport_Handle h) def $ \slcan -> do
Network.SocketCAN.withSocketCAN (Network.SocketCAN.mkCANInterface "vcan0") $ \socketcan -> do
race_
(Control.Monad.forever
$ Network.CAN.recv >>= lift . Network.CAN.send
$ Network.CAN.recv slcan >>= Network.CAN.send socketcan
)
(Control.Monad.forever
$ lift Network.CAN.recv >>= Network.CAN.send
$ Network.CAN.recv socketcan >>= Network.CAN.send slcan
)
20 changes: 7 additions & 13 deletions app/CANDump.hs
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
module Main where

import qualified Control.Monad
import qualified Control.Monad.IO.Class
import qualified Network.CAN
import qualified Network.SocketCAN

main :: IO ()
main = do
Network.SocketCAN.runSocketCAN
Network.SocketCAN.withSocketCAN
(Network.SocketCAN.mkCANInterface "vcan0")
(Control.Monad.forever
$ Network.CAN.recv
>>= Control.Monad.IO.Class.liftIO . print
)

-- needs Network.CAN.Pretty or Builder or smthing
-- that does the same ID formatting as SLCAN.Builder:78
-- a la
-- $ candump -e vcan0
-- vcan0 001237E5 [2] 4C EE
-- vcan0 7E5 [2] 4C EE
$ \can ->
(Control.Monad.forever
$ Network.CAN.recv
can
>>= putStrLn . Network.CAN.prettyCANMessage
)
21 changes: 11 additions & 10 deletions app/SLCANSerial.hs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module Main where

import Control.Monad.IO.Class
import Data.Default.Class (Default(def))
import Control.Monad.Class.MonadSay (MonadSay(say))
import Data.Default (Default(def))
import System.Hardware.Serialport (CommSpeed(..), SerialPortSettings(..))
import Network.CAN (MonadCAN)
import Network.CAN (CAN)
import Network.SLCAN (Transport(..))

import qualified Control.Monad
Expand All @@ -23,23 +23,24 @@ main = do
{ commSpeed = CS115200 }
)

Network.SLCAN.runSLCAN
Network.SLCAN.withSLCAN
(Transport_Handle h)
def
act

act
:: ( MonadCAN m
, MonadIO m
)
=> m ()
act = do
:: MonadSay m
=> CAN m
-> m ()
act can = do
Network.CAN.send
can
$ Network.CAN.standardMessage
-- vendorID SDO
0x601
[0x40, 0x18, 0x10, 0x01, 0x0, 0x0, 0x0, 0x0]

Control.Monad.forever
$ Network.CAN.recv
>>= Control.Monad.IO.Class.liftIO . print
can
>>= say . Network.CAN.prettyCANMessage
21 changes: 11 additions & 10 deletions app/SLCANUDP.hs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module Main where

import Control.Monad.IO.Class
import Data.Default.Class (Default(def))
import Network.CAN (MonadCAN)
import Control.Monad.Class.MonadSay (MonadSay(say))
import Data.Default (Default(def))
import Network.CAN (CAN)
import Network.SLCAN (Transport(..))
import Network.Socket (AddrInfo(..), SocketType(Datagram))

Expand Down Expand Up @@ -36,24 +36,25 @@ main = do
sock
(addrAddress ourAddrinfo)

Network.SLCAN.runSLCAN
Network.SLCAN.withSLCAN
(Transport_UDP sock (addrAddress targetAddrinfo))
def
act

(_, _) -> error "getAddrInfo fail"

act
:: ( MonadCAN m
, MonadIO m
)
=> m ()
act = do
:: MonadSay m
=> CAN m
-> m ()
act can = do
Network.CAN.send
can
$ Network.CAN.standardMessage
0x7E5
[0x4C]

Control.Monad.forever
$ Network.CAN.recv
>>= Control.Monad.IO.Class.liftIO . print
can
>>= say . Network.CAN.prettyCANMessage
3 changes: 3 additions & 0 deletions cabal.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
multi-repl: true

packages: .
2 changes: 1 addition & 1 deletion cabal.project.local.ci
Original file line number Diff line number Diff line change
@@ -1 +1 @@
flags: +build-apps
flags: +build-apps +build-readme
Loading
Loading