meshcore 2.2.20__tar.gz → 2.2.22__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {meshcore-2.2.20 → meshcore-2.2.22}/PKG-INFO +1 -1
- {meshcore-2.2.20 → meshcore-2.2.22}/pyproject.toml +1 -1
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/reader.py +21 -10
- {meshcore-2.2.20 → meshcore-2.2.22}/.github/python-test.yml +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/.gitignore +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/LICENSE +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/README.md +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/.pubsub_example.py.swp +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/ble_chat.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/ble_pin_pairing_example.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/ble_private_key_export.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/ble_sign_example.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/ble_stats.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/ble_t1000_chan_msg.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/ble_t1000_custom_vars.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/ble_t1000_infos.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/ble_t1000_msg.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/ble_t1000_msg_retries.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/ble_t1000_set_cv.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/chan_recv_with_path.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/connection_events_example.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/mepo_mc_gps.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/pubsub_example.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/rf_packet_monitor.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/serial_battery_monitor.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/serial_channel_manager.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/serial_chat.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/serial_contacts.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/serial_infos.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/serial_meshcore_ollama.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/serial_msg.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/serial_pingbot.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/serial_repeater_status.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/serial_repeater_telemetry.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/serial_rss_bot.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/serial_trace.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/tcp_chat.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/tcp_login_status.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/tcp_mchome_contacts.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/tcp_mchome_infos.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/tcp_mchome_msg.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/examples/tcp_mchome_readmsgs.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/pytest.ini +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/__init__.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/ble_cx.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/commands/__init__.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/commands/base.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/commands/binary.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/commands/contact.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/commands/control_data.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/commands/device.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/commands/messaging.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/connection_manager.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/events.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/lpp_json_encoder.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/meshcore.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/packets.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/parsing.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/serial_cx.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/src/meshcore/tcp_cx.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/tests/README.md +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/tests/test_ble_connection.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/tests/test_ble_pin_pairing.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/tests/test_meshcore_ble_pin.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/tests/unit/test_commands.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/tests/unit/test_events.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/tests/unit/test_private_key_export.py +0 -0
- {meshcore-2.2.20 → meshcore-2.2.22}/tests/unit/test_reader.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meshcore
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.22
|
|
4
4
|
Summary: Base classes for communicating with meshcore companion radios
|
|
5
5
|
Project-URL: Homepage, https://github.com/fdlamotte/meshcore_py
|
|
6
6
|
Project-URL: Issues, https://github.com/fdlamotte/meshcore_py/issues
|
|
@@ -29,7 +29,7 @@ class MessageReader:
|
|
|
29
29
|
# Track pending binary requests by tag for proper response parsing
|
|
30
30
|
self.pending_binary_requests: Dict[str, Dict[str, Any]] = {} # tag -> {request_type, expires_at}
|
|
31
31
|
|
|
32
|
-
self.channels = [{} for _ in range(
|
|
32
|
+
self.channels = [{} for _ in range(40)] # keep our own copy of channels, 40 elements by default
|
|
33
33
|
self.decrypt_channels = True
|
|
34
34
|
self.channels_log = [] # stores the channel msg events
|
|
35
35
|
|
|
@@ -219,12 +219,12 @@ class MessageReader:
|
|
|
219
219
|
res["channel_idx"] = dbuf.read(1)[0]
|
|
220
220
|
res["path_len"] = dbuf.read(1)[0]
|
|
221
221
|
res["txt_type"] = dbuf.read(1)[0]
|
|
222
|
-
res["sender_timestamp"] = int.from_bytes(dbuf.read(4), byteorder="little")
|
|
222
|
+
res["sender_timestamp"] = int.from_bytes(dbuf.read(4), byteorder="little", signed=False)
|
|
223
223
|
text = dbuf.read().strip(b"\0")
|
|
224
224
|
res["text"] = text.decode("utf-8", "ignore")
|
|
225
225
|
|
|
226
226
|
# search for text in log_channels
|
|
227
|
-
txt_hash = int.from_bytes(SHA256.new(text).digest()[0:4], "little", signed=False)
|
|
227
|
+
txt_hash = int.from_bytes(SHA256.new(res["sender_timestamp"].to_bytes(4, "little", signed=False)+text).digest()[0:4], "little", signed=False)
|
|
228
228
|
if self.decrypt_channels:
|
|
229
229
|
logged = next((l for l in reversed(self.channels_log) if 'msg_hash' in l and l['msg_hash'] == txt_hash), None)
|
|
230
230
|
if not logged is None:
|
|
@@ -232,6 +232,7 @@ class MessageReader:
|
|
|
232
232
|
res["RSSI"] = logged["rssi"]
|
|
233
233
|
res["SNR"] = logged["snr"]
|
|
234
234
|
res["recv_time"] = logged["recv_time"]
|
|
235
|
+
res["attempt"] = logged["attempt"]
|
|
235
236
|
|
|
236
237
|
attributes = {
|
|
237
238
|
"channel_idx": res["channel_idx"],
|
|
@@ -250,12 +251,12 @@ class MessageReader:
|
|
|
250
251
|
res["channel_idx"] = dbuf.read(1)[0]
|
|
251
252
|
res["path_len"] = dbuf.read(1)[0]
|
|
252
253
|
res["txt_type"] = dbuf.read(1)[0]
|
|
253
|
-
res["sender_timestamp"] = int.from_bytes(dbuf.read(4), byteorder="little")
|
|
254
|
+
res["sender_timestamp"] = int.from_bytes(dbuf.read(4), byteorder="little", signed=False)
|
|
254
255
|
text = dbuf.read()
|
|
255
256
|
res["text"] = text.decode("utf-8", "ignore")
|
|
256
257
|
|
|
257
258
|
# search for text in log_channels
|
|
258
|
-
txt_hash = int.from_bytes(SHA256.new(text).digest()[0:4], "little", signed=False)
|
|
259
|
+
txt_hash = int.from_bytes(SHA256.new(res["sender_timestamp"].to_bytes(4, "little", signed=False)+text).digest()[0:4], "little", signed=False)
|
|
259
260
|
res["txt_hash"] = txt_hash
|
|
260
261
|
logged = next((l for l in reversed(self.channels_log) if 'msg_hash' in l and l['msg_hash'] == txt_hash), None)
|
|
261
262
|
|
|
@@ -264,6 +265,7 @@ class MessageReader:
|
|
|
264
265
|
res["path"] = logged["path"]
|
|
265
266
|
res["RSSI"] = logged["rssi"]
|
|
266
267
|
res["recv_time"] = logged["recv_time"]
|
|
268
|
+
res["attempt"] = logged["attempt"]
|
|
267
269
|
|
|
268
270
|
attributes = {
|
|
269
271
|
"channel_idx": res["channel_idx"],
|
|
@@ -428,9 +430,8 @@ class MessageReader:
|
|
|
428
430
|
idx = dbuf.read(1)[0]
|
|
429
431
|
res["channel_idx"] = idx
|
|
430
432
|
|
|
431
|
-
if
|
|
432
|
-
self.channels
|
|
433
|
-
[{} for _ in range(idx - len(self.channels) + 1)])
|
|
433
|
+
if len(self.channels) <= idx:
|
|
434
|
+
self.channels.extend([{} for _ in range(1 + idx - len(self.channels))])
|
|
434
435
|
|
|
435
436
|
# Channel name is null-terminated, so find the first null byte
|
|
436
437
|
name_bytes = dbuf.read(32)
|
|
@@ -653,14 +654,24 @@ class MessageReader:
|
|
|
653
654
|
# not found: decrypt the text and hash it
|
|
654
655
|
aes_key = channel["channel_secret"]
|
|
655
656
|
cipher = AES.new(aes_key, AES.MODE_ECB)
|
|
656
|
-
|
|
657
|
-
|
|
657
|
+
uncrypted = cipher.decrypt(msg)
|
|
658
|
+
timestamp = int.from_bytes(uncrypted[0:4], "little", signed=False)
|
|
659
|
+
attempt = uncrypted[4] & 3
|
|
660
|
+
txt_type = int.from_bytes(uncrypted[4:4], "little", signed=False) >> 2
|
|
661
|
+
message = uncrypted[5:].strip(b"\0")
|
|
662
|
+
msg_hash = int.from_bytes(SHA256.new(timestamp.to_bytes(4, "little", signed=False) + message).digest()[0:4], "little", signed=False)
|
|
658
663
|
log_data["message"] = message.decode("utf-8", "ignore")
|
|
659
664
|
log_data["msg_hash"] = msg_hash
|
|
665
|
+
log_data["sender_timestamp"] = timestamp
|
|
666
|
+
log_data["attempt"] = attempt
|
|
667
|
+
log_data["txt_type"] = txt_type
|
|
660
668
|
else:
|
|
661
669
|
# found: copy
|
|
662
670
|
log_data["message"] = logged["message"]
|
|
663
671
|
log_data["msg_hash"] = logged["msg_hash"]
|
|
672
|
+
log_data["sender_timestamp"] = logged["sender_timestamp"]
|
|
673
|
+
log_data["attempt"] = logged["attempt"]
|
|
674
|
+
log_data["txt_type"] = logged["txt_type"]
|
|
664
675
|
|
|
665
676
|
self.channels_log.append(log_data)
|
|
666
677
|
if len(self.channels_log) > 100:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|