Created
December 27, 2023 17:46
-
-
Save nrclark/186b424d1fe75f53e9c06e01ba9baedc to your computer and use it in GitHub Desktop.
Powershell script that bridges a COM port to a TCP socket.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -file | |
<# | |
.SYNOPSIS | |
PowerShell TCP/IP Client for Serial Port Communication. | |
.DESCRIPTION | |
This script establishes a TCP connection to a specified server and port and | |
relays data to and from a specified serial port (COM port). | |
.PARAMETER server | |
The IP address / hostname of the TCP server to connect to. | |
.PARAMETER port | |
The port number of the TCP server to connect to. Must be in the range 1-65535. | |
.PARAMETER comport | |
The COM port for serial communication. | |
.PARAMETER baud | |
The baud rate for serial communication. Default is 9600. | |
.PARAMETER parity | |
The parity for serial communication. Options are 'None', 'Odd', 'Even', | |
'Mark', 'Space'. Default is 'None'. | |
.PARAMETER stopbits | |
The stop bits for serial communication. Options are 'None', 'One', 'Two', | |
'OnePointFive'. Default is 'One'. | |
.PARAMETER databits | |
The data bits for serial communication. Options are 5, 6, 7, 8. Default is 8. | |
.PARAMETER help | |
Displays help information for this script. | |
.EXAMPLE | |
.\SerialBridge.ps1 -server "192.168.1.10" -port 1234 -comport "COM3" | |
Connects to a TCP server at 192.168.1.10:1234 and relays data to and from | |
COM3 with default serial settings. | |
On the other end of the link, a receiver can be set up using socat like this: | |
socat TCP-LISTEN:8080,reuseaddr pty,link=$SOME_FILE,raw,echo=0 | |
(note: the pty output can be replaced with whatever is appropriat for your | |
application) | |
.NOTES | |
Ensure that the COM port and TCP server are available and configured | |
correctly before running the script. | |
.LINK | |
Documentation_Link_If_Available | |
#> | |
param ( | |
[ValidatePattern("([0-9]{1,3}[.]){3}[0-9]{1,3}")] | |
[Parameter(Mandatory = $true)][string] $server, | |
[Parameter(Mandatory = $true)][int] $port, | |
[Parameter(Mandatory = $true)][string] $comport, | |
[int] $baud = 9600, | |
[ValidateSet("None", "Odd", "Even", "Mark", "Space")] | |
[string] $parity = "None", | |
[ValidateSet("None", "One", "Two", "OnePointFive")] | |
[string] $stopbits = "One", | |
[ValidateSet(5, 6, 7, 8)] | |
[int]$databits = 8 | |
) | |
$ErrorActionPreference = "Stop" | |
$parity = [System.IO.Ports.parity]($parity) | |
$stopbits = [System.IO.Ports.stopbits]($stopbits) | |
Write-Output "server: [$server]" | |
Write-Output "port: [$port]" | |
Write-Output "comport: [$comport]" | |
Write-Output "baud: [$baud]" | |
Write-Output "stopbits: [$stopbits]" | |
Write-Output "databits: [$databits]" | |
Write-Output "" | |
try { | |
# Connect to the TCP server | |
$client = New-Object System.Net.Sockets.TcpClient | |
$client.NoDelay = $true | |
$client.LingerState.Enabled = $true | |
$client.LingerState.LingerTime = 0 | |
Write-Output "Connecting to: ${server}:${port}..." | |
$connect_job = $client.ConnectAsync($server, $port) | |
while (-not $connect_job.IsCompleted) { | |
Start-Sleep -Milliseconds 10 | |
} | |
if ($null -ne $connect_job.Exception) { | |
Write-Error "Failed to connect to remote server." | |
throw $connect_job.Exception | |
} | |
Write-Output "Connected to the server." | |
Write-Output "Opening $comport..." | |
$serialPort = New-Object System.IO.Ports.SerialPort $comport, | |
$baud, $parity, | |
$databits, $stopbits | |
$serialPort.Open() | |
$serialPort.DiscardInBuffer() | |
$serialPort.DiscardOutBuffer() | |
Write-Output "Serial port is open." | |
$stream = $client.GetStream() | |
$bufsize = [math]::min($client.ReceiveBufferSize, $serialPort.ReadBufferSize) | |
$buffer = New-Object byte[] $bufsize | |
Write-Output "Begin forwarding serial traffic." | |
while ($true) { | |
$wait = $true | |
if ($serialPort.BytesToRead -gt 0) { | |
$wait = $false | |
$readCount = $serialPort.Read($buffer, 0, $serialPort.BytesToRead) | |
$stream.Write($buffer, 0, $readCount) | |
} | |
if ($stream.DataAvailable) { | |
$wait = $false | |
$readCount = $stream.Read($buffer, 0, $buffer.Length) | |
$serialPort.Write($buffer, 0, $readCount) | |
} | |
if ($wait) { | |
Start-Sleep -Milliseconds 1 | |
} | |
} | |
} | |
catch { | |
Write-Output "An error occurred: $_" | |
} | |
finally { | |
if ($serialPort -and $serialPort.IsOpen) { | |
$serialPort.Close() | |
} | |
if ($client -and $client.Connected) { | |
$client.Close() | |
} | |
} | |
Write-Output "Connection closed." | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment