-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
Copy pathblynk-ser.sh
executable file
·249 lines (215 loc) · 5.77 KB
/
blynk-ser.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#!/bin/bash
# Detect script path
pushd `dirname $0` > /dev/null
SCRIPTPATH=`pwd`
popd > /dev/null
# === Edit default options to match your need ===
FROM_TYPE="SER" # SER, TCP
TO_TYPE="SSL" # TCP, SSL
COMM_BAUD=9600
SERV_ADDR=blynk.cloud
SERV_PORT_SSL=443
SERV_PORT_TCP=80
LSTN_PORT=80
SRVR_CERT="$SCRIPTPATH/certs/server.crt"
CLNT_CERT="$SCRIPTPATH/certs/client.pem"
# === Edit the lines below only if absolutely sure what you're doing ===
usage="
This script redirects serial communication to the server.
You can specify port, baud rate, and server endpoint like this:
blynk-ser.sh -c <serial port> -b <baud rate> -s <server address> -p <server port>
The defaults are:
-c,--comm single available port (on Linux, OSX)
COM1 (on Windows)
-b,--baud 9600
-s,--server blynk.cloud
-p,--port 80
If the specified serial port is not found, it will ask to enter another one.
The script also tries to reestablish connection if it was lost.
"
avrdude_warn="Warning: avrdude is running
Avoid uploading sketches and running this script at the same time.
If you didn't run avrdude, maybe it just stuck. You can kill it using:
killall avrdude
"
function detect_conflicts {
# Detect if avrdude is running
if pgrep avrdude; then echo -n "$avrdude_warn"; fi
}
detect_conflicts
# Detect socat
if ! hash socat 2>/dev/null; then
echo "This script uses socat utility, but could not find it."
echo
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
echo " Try installing it using: sudo apt-get install socat"
elif [[ "$OSTYPE" == "darwin"* ]]; then
echo " Try installing it using: brew install socat"
fi
exit 1
fi
# Execute getopt
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
ARGS=$(getopt -o hf:c:b:l:t:s:p: -l "help,from:,comm:,baud:,listen:,to:,server:,port:,cert:" -n "blynk-gateway.sh" -- "$@");
elif [[ "$OSTYPE" == "darwin"* ]]; then
ARGS=$(getopt hf:c:b:l:t:s:p: $*);
fi
# Bad arguments
if [ $? -ne 0 ];
then
echo -n "$usage"
exit 1
fi
eval set -- "$ARGS";
while true; do
case "$1" in
-h|--help)
shift
echo -n "$usage"
exit 0
;;
####
-f|--from)
shift
if [ -n "$1" ]; then
FROM_TYPE=$1
shift
fi
;;
-c|--comm)
shift
if [ -n "$1" ]; then
COMM_PORT_USER=$1
shift
fi
;;
-b|--baud)
shift
if [ -n "$1" ]; then
COMM_BAUD=$1
shift
fi
;;
-l|--listen)
shift
if [ -n "$1" ]; then
LSTN_PORT=$1
shift
fi
;;
####
-t|--to)
shift
if [ -n "$1" ]; then
TO_TYPE=$1
shift
fi
;;
-s|--server)
shift
if [ -n "$1" ]; then
SERV_ADDR=$1
shift
fi
;;
-p|--port)
shift
if [ -n "$1" ]; then
SERV_PORT_SSL=$1
SERV_PORT_TCP=$1
shift
fi
;;
--cert)
shift
if [ -n "$1" ]; then
SRVR_CERT=$1
shift
fi
;;
####
--)
shift;
break;
;;
esac
done
# Construct command
GEN_ATTR="-d -d"
TCP_ATTR="nodelay" #,nonblock=1,rcvtimeo=1,sndtimeo=1
SER_ATTR="raw,echo=0,clocal=1,cs8,nonblock=1"
if [[ "$FROM_TYPE" == "SER" ]]; then
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
COMM_WCARD="/dev/ttyUSB* /dev/ttyACM*"
COMM_STTY="-F"
elif [[ "$OSTYPE" == "darwin"* ]]; then
COMM_WCARD="/dev/tty.usbserial* /dev/tty.usbmodem*"
COMM_STTY="-f"
else
echo "Can't detect OS type!"
exit 1
fi
COMM_FOUND=`ls $COMM_WCARD 2> /dev/null`
COMM_QTY=`printf "%s\n" $COMM_FOUND | wc -l`
if [[ ! "$COMM_PORT_USER" == "" ]]; then
COMM_PORT=$COMM_PORT_USER
elif [[ "$COMM_QTY" == "1" ]]; then
# Select single available port
COMM_PORT=$COMM_FOUND
else
# Ask for serial port interactively
echo "$COMM_QTY ports found. You can specify port manually using -c option"
echo -n "Select serial port [" $COMM_FOUND "]: "
read COMM_PORT
fi
if [ ! -e "$COMM_PORT" ]; then
echo "Can't find port: $COMM_PORT"
echo "Please specify port manually using -c option"
exit 1
fi
echo "Resetting device $COMM_PORT..."
stty $COMM_STTY $COMM_PORT hupcl
# Disable restarting
#stty $COMM_STTY $COMM_PORT -hupcl
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
FROM_ATTR="FILE:$COMM_PORT,$SER_ATTR,b$COMM_BAUD"
elif [[ "$OSTYPE" == "darwin"* ]]; then
FROM_ATTR="GOPEN:$COMM_PORT,$SER_ATTR,ixoff=0,ixon=0,ispeed=$COMM_BAUD,ospeed=$COMM_BAUD,crtscts=0"
fi
elif [[ "$FROM_TYPE" == "TCP" ]]; then
FROM_ATTR="TCP-LISTEN:$LSTN_PORT,reuseaddr,fork,$TCP_ATTR"
else
echo "$FROM_TYPE is not supported."
exit 1
fi
if [[ "$TO_TYPE" == "TCP" ]]; then
echo "Warning: Server connection may be insecure!"
TO_ATTR="TCP:$SERV_ADDR:$SERV_PORT_TCP,$TCP_ATTR"
elif [[ "$TO_TYPE" == "SSL" ]]; then
if [ -e "$SRVR_CERT" ]; then
TCP_ATTR="cafile=$SRVR_CERT,$TCP_ATTR"
else
echo "Warning: $SRVR_CERT not found. Skipping server verification (connection may be insecure)!"
TCP_ATTR="verify=0,$TCP_ATTR"
fi
if [ -e "$CLNT_CERT" ]; then
TCP_ATTR="cert=$CLNT_CERT,$TCP_ATTR"
fi
TO_ATTR="openssl-connect:$SERV_ADDR:$SERV_PORT_SSL,$TCP_ATTR"
elif [[ "$TO_TYPE" == "2WAY" ]]; then
echo "2WAY is not supported yet."
exit 1
else
echo "$TO_TYPE is not supported."
exit 1
fi
# Setup exit handler
trap "echo Exited!; exit;" SIGINT SIGTERM
echo [ Press Ctrl+C to exit ]
while [ 1 ]; do
echo Connecting: "$FROM_ATTR <-> $TO_ATTR"
socat $GEN_ATTR "$FROM_ATTR" "$TO_ATTR"
detect_conflicts
echo Reconnecting in 3s...
sleep 3
done