Skip to content

Commit c3dd1f8

Browse files
committed
Initial Commit for Scripts
Initial commit moving the scripts from microsoft/mu_feature_debugger to microsoft/uefi_debug_tools.
1 parent d46c987 commit c3dd1f8

File tree

1 file changed

+187
-0
lines changed

1 file changed

+187
-0
lines changed

Scripts/ComToTcpServer.py

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
#
2+
# Script for piping a local serial connection to a TCP port.
3+
#
4+
# Copyright (c) Microsoft Corporation.
5+
# SPDX-License-Identifier: BSD-2-Clause-Patent
6+
#
7+
8+
import time
9+
import sys
10+
import win32pipe
11+
import win32file
12+
import pywintypes
13+
import socket
14+
import threading
15+
import queue
16+
import argparse
17+
import serial
18+
19+
parser = argparse.ArgumentParser()
20+
parser.add_argument("-l", "--logfile", type=str,
21+
help="File path to log traffic")
22+
parser.add_argument("-p", "--port", type=int, default=5555,
23+
help="The TCP port to listen for connections.")
24+
parser.add_argument("-n", "--pipe", type=str,
25+
help="The named pipe to connect to connect to.")
26+
parser.add_argument("-c", "--comport", type=str,
27+
help="The number of the COM device to connect to. E.G 'COM5'")
28+
parser.add_argument("-b", "--baudrate", type=int, default=115200,
29+
help="The baudrate of the serial port.")
30+
parser.add_argument("-v", "--verbose", action="store_true",
31+
help="Enabled verbose prints.")
32+
args = parser.parse_args()
33+
34+
# Global queues used between threads.
35+
out_queue = queue.Queue()
36+
in_queue = queue.Queue()
37+
logfile = None
38+
inout_last = None
39+
40+
def socket_thread():
41+
# Set up the socket.
42+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
43+
sock.bind(('', args.port))
44+
sock.listen()
45+
46+
while True:
47+
print("Waiting for socket...")
48+
conn, addr = sock.accept()
49+
print(f"Socket Connected - {addr}")
50+
51+
# clear the out queue before starting a connection
52+
while not out_queue.empty():
53+
out_queue.get()
54+
55+
# use a short timeout to move on if no data is ready.
56+
conn.settimeout(0.01)
57+
58+
# process the queue.
59+
connected = True
60+
while connected:
61+
try:
62+
while not out_queue.empty():
63+
conn.sendall(out_queue.get())
64+
65+
data = conn.recv(4096)
66+
except socket.timeout:
67+
data = None
68+
except Exception as e:
69+
print("Socket disconnected.")
70+
connected = False
71+
continue
72+
73+
if data is not None and len(data) != 0:
74+
in_queue.put(data)
75+
76+
def write_log(inout, data):
77+
global inout_last
78+
global logfile
79+
80+
if logfile is None:
81+
return
82+
83+
if inout != inout_last:
84+
logfile.flush()
85+
if inout:
86+
logfile.write("\n\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n")
87+
else:
88+
logfile.write("\n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n")
89+
inout_last = inout
90+
91+
string = data.decode("ascii")
92+
logfile.write(string)
93+
94+
def listen_named_pipe():
95+
print("Waiting for pipe...")
96+
quit = False
97+
while not quit:
98+
try:
99+
handle = win32file.CreateFile(
100+
args.pipe,
101+
win32file.GENERIC_READ | win32file.GENERIC_WRITE,
102+
0,
103+
None,
104+
win32file.OPEN_EXISTING,
105+
0,
106+
None
107+
)
108+
109+
print("Pipe connected.")
110+
while True:
111+
if win32file.GetFileSize(handle) > 0:
112+
hr, data = win32file.ReadFile(handle, 4096)
113+
if (hr != 0):
114+
print(f"Error reading: {hr}")
115+
continue
116+
117+
write_log(False, data)
118+
if args.verbose:
119+
print(f"OUT: {data}")
120+
out_queue.put(data)
121+
122+
while not in_queue.empty():
123+
data = in_queue.get()
124+
write_log(True, data)
125+
if args.verbose:
126+
print(f"IN: {data}")
127+
win32file.WriteFile(handle, data, None)
128+
129+
except pywintypes.error as e:
130+
if e.args[0] == 2:
131+
if args.verbose:
132+
print("No pipe yet, waiting...")
133+
time.sleep(1)
134+
elif e.args[0] == 109:
135+
print("broken pipe")
136+
quit = True
137+
138+
def listen_com_port():
139+
print("Opening com port...")
140+
serial_port = serial.Serial(args.comport, args.baudrate, parity=serial.PARITY_NONE,
141+
stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS,
142+
timeout=0.1)
143+
144+
print(f"Opened {args.comport}.")
145+
while True:
146+
if serial_port.in_waiting > 0:
147+
data = serial_port.read(size=serial_port.in_waiting)
148+
write_log(False, data)
149+
if args.verbose:
150+
print(f"OUT: {data}")
151+
out_queue.put(data)
152+
153+
while not in_queue.empty():
154+
data = in_queue.get()
155+
write_log(True, data)
156+
if args.verbose:
157+
print(f"IN: {data}")
158+
serial_port.write(data)
159+
160+
def main():
161+
if args.pipe is None and args.comport is None:
162+
print("Must specify a serial connection!")
163+
return
164+
165+
global logfile
166+
if args.logfile is not None:
167+
logfile = open(args.logfile, 'w')
168+
logfile.write(f"arguments: {args} \n\n")
169+
170+
# Create the thread for the TCP port.
171+
port_thread = threading.Thread(target=socket_thread)
172+
port_thread.daemon = True
173+
port_thread.start()
174+
175+
try:
176+
if args.pipe is not None:
177+
listen_named_pipe()
178+
if args.comport is not None:
179+
listen_com_port()
180+
else:
181+
raise Exception("No serial port to connect to!")
182+
except:
183+
if logfile is not None:
184+
logfile.close()
185+
186+
187+
main()

0 commit comments

Comments
 (0)