Skip to content

Commit 798287a

Browse files
feat: adding pcap file parser to cli
1 parent 3eaed1d commit 798287a

File tree

3 files changed

+55
-79
lines changed

3 files changed

+55
-79
lines changed

roborock/cli.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@
66
from typing import Any, Dict
77

88
import click
9+
from pyshark import FileCapture # type: ignore
10+
from pyshark.capture.live_capture import LiveCapture, UnknownInterfaceException # type: ignore
11+
from pyshark.packet.packet import Packet # type: ignore
912

1013
from roborock import RoborockException
1114
from roborock.api import RoborockApiClient
1215
from roborock.cloud_api import RoborockMqttClient
1316
from roborock.containers import DeviceData, LoginData
17+
from roborock.protocol import MessageParser
1418
from roborock.util import run_sync
1519

1620
_LOGGER = logging.getLogger(__name__)
@@ -135,10 +139,60 @@ async def command(ctx, cmd, device_id, params):
135139
mqtt_client.__del__()
136140

137141

142+
@click.command()
143+
@click.option("--local_key", required=True)
144+
@click.option("--device_ip", required=True)
145+
@click.option("--file", required=False)
146+
@click.pass_context
147+
@run_sync()
148+
async def parser(_, local_key, device_ip, file):
149+
file_provided = file is not None
150+
if file_provided:
151+
capture = FileCapture(file)
152+
else:
153+
_LOGGER.info("Listen for interface rvi0 since no file was provided")
154+
capture = LiveCapture(interface="rvi0")
155+
buffer = {"data": bytes()}
156+
157+
def on_package(packet: Packet):
158+
if hasattr(packet, "ip"):
159+
if packet.transport_layer == "TCP" and (packet.ip.dst == device_ip or packet.ip.src == device_ip):
160+
if hasattr(packet, "DATA"):
161+
if hasattr(packet.DATA, "data"):
162+
if packet.ip.dst == device_ip:
163+
try:
164+
f, buffer["data"] = MessageParser.parse(
165+
buffer["data"] + bytes.fromhex(packet.DATA.data),
166+
local_key,
167+
)
168+
print(f"Received request: {f}")
169+
except BaseException as e:
170+
print(e)
171+
pass
172+
elif packet.ip.src == device_ip:
173+
try:
174+
f, buffer["data"] = MessageParser.parse(
175+
buffer["data"] + bytes.fromhex(packet.DATA.data),
176+
local_key,
177+
)
178+
print(f"Received response: {f}")
179+
except BaseException as e:
180+
print(e)
181+
pass
182+
183+
try:
184+
await capture.packets_from_tshark(on_package, close_tshark=not file_provided)
185+
except UnknownInterfaceException:
186+
raise RoborockException(
187+
"You need to run 'rvictl -s XXXXXXXX-XXXXXXXXXXXXXXXX' first, with an iPhone connected to usb port"
188+
)
189+
190+
138191
cli.add_command(login)
139192
cli.add_command(discover)
140193
cli.add_command(list_devices)
141194
cli.add_command(command)
195+
cli.add_command(parser)
142196

143197

144198
def main():

roborock/package_parser.py

Lines changed: 0 additions & 78 deletions
This file was deleted.

roborock/protocol.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from asyncio import BaseTransport, Lock
1010
from typing import Callable
1111

12-
from construct import (
12+
from construct import ( # type: ignore
1313
Bytes,
1414
Checksum,
1515
ChecksumError,

0 commit comments

Comments
 (0)