Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bidirectional #3

Merged
merged 10 commits into from
Sep 21, 2023
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
111 changes: 61 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> This project is a research prototype and should not be used in production.

`can2x` is a simple utility for connecting a CAN bus unidirectional with another CAN bus over the network using common web protocols, such as HTTP, MQTT, Socket.IO, and WebSockets.
`can2x` is a simple utility for connecting a CAN bus bidirectional with another CAN bus over the network using common web protocols, such as HTTP, MQTT, Socket.IO, and WebSockets.

## Overview

Expand Down Expand Up @@ -98,23 +98,27 @@ can2x bridge start [options]

The following options are supported.

| Option | Type | Default | Required | Description |
|---------------------|------------------------------------------------------------|-------------|----------|-------------|
| `--source` | `can`, `console`, `file`, `http`, `mqtt`, `socketio`, `ws` | `can` | false | |
| `--source-port` | number | `3000` | false | |
| `--source-host` | string | `localhost` | false | |
| `--source-event` | string | `can2x` | false | |
| `--source-topic` | string | `can2x` | false | |
| `--source-name` | string | `can2x` | false | |
| `--source-id` | number | none | false | |
| `--source-data` | number[] | none | false | |
| `--source-file` | string | none | false | |
| `--target` | `can`, `console`, `file`, `http`, `mqtt`, `socketio`, `ws` | `console` | false | |
| `--target-endpoint` | string | none | false | |
| `--target-event` | string | `can2x` | false | |
| `--target-topic` | string | `can2x` | false | |
| `--target-name` | string | `can2x` | false | |
| `--target-file` | string | none | false | |
| Option | Type | Default | Required | Description |
|----------------------------|------------------------------------------------------------|-------------|----------|-------------|
| `--source` | `can`, `console`, `file`, `http`, `mqtt`, `socketio`, `ws` | `can` | false | |
| `--source-port` | number | `3000` | false | |
| `--source-host` | string | `localhost` | false | |
| `--source-event` | string | `can2x` | false | |
| `--source-topic` | string | `can2x` | false | |
| `--source-name` | string | `can2x` | false | |
| `--source-id` | number | none | false | |
| `--source-data` | number[] | none | false | |
| `--source-ext` | boolean | none | false | |
| `--source-rtr` | boolean | none | false | |
| `--source-file` | string | none | false | |
| `--source-bidirectional` | boolean | `true` | false | |
| `--target` | `can`, `console`, `file`, `http`, `mqtt`, `socketio`, `ws` | `console` | false | |
| `--target-endpoint` | string | none | false | |
| `--target-event` | string | `can2x` | false | |
| `--target-topic` | string | `can2x` | false | |
| `--target-name` | string | `can2x` | false | |
| `--target-file` | string | none | false | |
| `--target-bidirectional` | boolean | `true` | false | |

### vCAN Start

Expand Down Expand Up @@ -152,6 +156,8 @@ A CAN message is internally represented as follows.
|--------|----------|-----------------------------------------|
| `id` | number | The decimal id of the CAN message. |
| `data` | number[] | The decimal payload of the CAN message. |
| `ext` | boolean | |
| `rtr` | boolean | |

## Sources

Expand All @@ -171,10 +177,11 @@ The following options are supported.
`can2x` supports a `console2x` bridge, i.e., `--source console`.
The following options are supported.

| Option | Type | Default | Required | Description |
|---------------------|------------------------------------------------------------|-------------|----------|-------------|
| `--source-id` | number | none | true | |
| `--source-data` | number[] | none | true | |
| Option | Type | Default | Required | Description |
|----------------------------|------------------------------------------------------------|-------------|----------|-------------|
| `--source-id` | number | none | true | |
| `--source-data` | number[] | none | true | |
| `--source-bidirectional` | boolean | `true` | false | |

### File

Expand All @@ -200,32 +207,35 @@ The following options are supported.
`can2x` supports a `mqtt2x` bridge, i.e., `--source mqtt`.
The following options are supported.

| Option | Type | Default | Required | Description |
|---------------------|------------------------------------------------------------|-------------|----------|-------------|
| `--source-port` | number | `3000` | false | |
| `--source-host` | string | `localhost` | false | |
| `--source-topic` | string | `can2x` | false | |
| Option | Type | Default | Required | Description |
|----------------------------|------------------------------------------------------------|-------------|----------|-------------|
| `--source-port` | number | `3000` | false | |
| `--source-host` | string | `localhost` | false | |
| `--source-topic` | string | `can2x` | false | |
| `--source-bidirectional` | boolean | `true` | false | |

### Socket.IO

`can2x` supports a `socketio2x` bridge, i.e., `--source socketio`.
The following options are supported.

| Option | Type | Default | Required | Description |
|---------------------|------------------------------------------------------------|-------------|----------|-------------|
| `--source-port` | number | `3000` | false | |
| `--source-host` | string | `localhost` | false | |
| `--source-event` | string | `can2x` | false | |
| Option | Type | Default | Required | Description |
|----------------------------|------------------------------------------------------------|-------------|----------|-------------|
| `--source-port` | number | `3000` | false | |
| `--source-host` | string | `localhost` | false | |
| `--source-event` | string | `can2x` | false | |
| `--source-bidirectional` | boolean | `true` | false | |

### WebSocket

`can2x` supports a `ws2x` bridge, i.e., `--source ws`.
The following options are supported.

| Option | Type | Default | Required | Description |
|---------------------|------------------------------------------------------------|-------------|----------|-------------|
| `--source-port` | number | `3000` | false | |
| `--source-host` | string | `localhost` | false | |
| Option | Type | Default | Required | Description |
|-----------------------------|------------------------------------------------------------|-------------|----------|-------------|
| `--source-port` | number | `3000` | false | |
| `--source-host` | string | `localhost` | false | |
| `--source-bidirectional` | boolean | `true` | false | |

## Targets

Expand Down Expand Up @@ -268,40 +278,41 @@ The following options are supported.
`can2x` supports a `x2mqtt` bridge, i.e., `--target mqtt`.
The following options are supported.

| Option | Type | Default | Required | Description |
|---------------------|------------------------------------------------------------|-------------|----------|-------------|
| `--target-endpoint` | string | none | true | |
| `--target-topic` | string | `can2x` | false | |
| Option | Type | Default | Required | Description |
|--------------------------|------------------------------------------------------------|-------------|----------|-------------|
| `--target-endpoint` | string | none | true | |
| `--target-topic` | string | `can2x` | false | |
| `--target-bidirectional` | boolean | `true` | false | |

### Socket.IO

`can2x` supports a `x2socketio` bridge, i.e., `--target socketio`.
The following options are supported.

| Option | Type | Default | Required | Description |
|---------------------|------------------------------------------------------------|-------------|----------|-------------|
| `--target-endpoint` | string | none | true | |
| `--target-event` | string | `can2x` | false | |
| Option | Type | Default | Required | Description |
|----------------------------|------------------------------------------------------------|-------------|----------|-------------|
| `--target-endpoint` | string | none | true | |
| `--target-event` | string | `can2x` | false | |
| `--target-bidirectional` | boolean | `true` | false | |

### Websocket

`can2x` supports a `x2ws` bridge, i.e., `--target ws`.
The following options are supported.

| Option | Type | Default | Required | Description |
|---------------------|------------------------------------------------------------|-------------|----------|-------------|
| `--target-endpoint` | string | none | true | |
| Option | Type | Default | Required | Description |
|----------------------------|------------------------------------------------------------|-------------|----------|-------------|
| `--target-endpoint` | string | none | true | |
| `--target-bidirectional` | boolean | `true` | false | |

## Limitations

- `can2x` currently only supports `id` and `data` of a CAN message.
- bridges are unidirectional
- security aspects, such as encryption, authentication, and authorization, are not supported
- messages are not guaranteed to be delivered

## Similar Projects

It is worth to checkout the following projects.
It is worth to check out the following projects.

- [`can2udp`](https://opensource.lely.com/canopen/docs/can2udp)
- [`can2mqtt`](https://github.com/c3re/can2mqtt)
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@
"eslint-plugin-import": "^2.27.5",
"license-checker": "^25.0.1",
"mocha": "^10.2.0",
"nodemon": "^2.0.22",
"nyc": "^15.1.0",
"prettier": "^2.8.7",
"prettier-plugin-organize-imports": "^3.2.2",
Expand Down
19 changes: 18 additions & 1 deletion src/core/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ export type BridgeOptions = {
sourceName?: string
sourceId?: string
sourceData?: string[]
sourceExt?: boolean
sourceRtr?: boolean
sourceFile?: string
sourceBidirectional?: boolean
target?: string
targetEndpoint?: string
targetEvent?: string
targetTopic?: string
targetName?: string
targetFile?: string
targetBidirectional?: boolean
}

export async function startBridge(options: BridgeOptions) {
Expand Down Expand Up @@ -66,7 +70,11 @@ export async function stopVCAN(options: VCANOptions) {
}

function createSource(options: BridgeOptions) {
if (options.source === 'can') return new CANSource({name: options.sourceName ?? 'can2x'})
if (options.source === 'can')
return new CANSource({
name: options.sourceName ?? 'can2x',
bidirectional: options.sourceBidirectional ?? true,
})

if (options.source === 'console') {
assert.isDefined(options.sourceId, '--source-id undefined')
Expand All @@ -75,6 +83,8 @@ function createSource(options: BridgeOptions) {
return new ConsoleSource({
id: Number(options.sourceId),
data: options.sourceData.map(Number),
ext: options.sourceExt ?? false,
rtr: options.sourceRtr ?? false,
})
}

Expand All @@ -96,19 +106,22 @@ function createSource(options: BridgeOptions) {
port: options.sourcePort ? Number(options.sourcePort) : 3000,
host: options.sourceHost ?? 'localhost',
topic: options.sourceTopic ?? 'can2x',
bidirectional: options.sourceBidirectional ?? true,
})

if (options.source === 'socketio')
return new SocketIOSource({
port: options.sourcePort ? Number(options.sourcePort) : 3000,
host: options.sourceHost ?? 'localhost',
event: options.sourceEvent ?? 'can2x',
bidirectional: options.sourceBidirectional ?? true,
})

if (options.source === 'ws')
return new WSSource({
port: options.sourcePort ? Number(options.sourcePort) : 3000,
host: options.sourceHost ?? 'localhost',
bidirectional: options.sourceBidirectional ?? true,
})

throw new Error(`Source of type "${options.source}" unknown`)
Expand All @@ -118,6 +131,7 @@ function createTarget(options: BridgeOptions) {
if (options.target === 'can')
return new CANTarget({
name: options.targetName ?? 'can2x',
bidirectional: options.targetBidirectional ?? true,
})

if (options.target === 'console') return new ConsoleTarget()
Expand All @@ -141,6 +155,7 @@ function createTarget(options: BridgeOptions) {
return new MQTTTarget({
endpoint: options.targetEndpoint,
topic: options.targetTopic ?? 'can2x',
bidirectional: options.targetBidirectional ?? true,
})
}

Expand All @@ -149,13 +164,15 @@ function createTarget(options: BridgeOptions) {
return new SocketIOTarget({
endpoint: options.targetEndpoint,
event: options.targetEvent ?? 'can2x',
bidirectional: options.targetBidirectional ?? true,
})
}

if (options.target === 'ws') {
assert.isDefined(options.targetEndpoint, '--target-endpoint must be defined')
return new WSTarget({
endpoint: options.targetEndpoint,
bidirectional: options.targetBidirectional ?? true,
})
}

Expand Down
Loading