casambi-bt-revamped 0.3.6.dev1__tar.gz → 0.3.6.dev2__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.
- {casambi_bt_revamped-0.3.6.dev1/src/casambi_bt_revamped.egg-info → casambi_bt_revamped-0.3.6.dev2}/PKG-INFO +1 -1
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/setup.cfg +1 -1
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_client.py +52 -47
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2/src/casambi_bt_revamped.egg-info}/PKG-INFO +1 -1
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/LICENSE +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/README.md +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/pyproject.toml +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/__init__.py +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_cache.py +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_casambi.py +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_client_android_parser.py +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_constants.py +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_discover.py +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_encryption.py +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_keystore.py +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_network.py +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_operation.py +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_unit.py +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/errors.py +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/py.typed +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/casambi_bt_revamped.egg-info/SOURCES.txt +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/casambi_bt_revamped.egg-info/dependency_links.txt +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/casambi_bt_revamped.egg-info/requires.txt +0 -0
- {casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/casambi_bt_revamped.egg-info/top_level.txt +0 -0
|
@@ -421,23 +421,47 @@ class CasambiClient:
|
|
|
421
421
|
# TODO: Check incoming counter and direction flag
|
|
422
422
|
self._inPacketCount += 1
|
|
423
423
|
|
|
424
|
-
# Store raw encrypted packet for
|
|
425
|
-
|
|
424
|
+
# Store raw encrypted packet for Android parser analysis
|
|
425
|
+
raw_encrypted_packet = data[:]
|
|
426
|
+
|
|
427
|
+
# Try Android parser on the raw packet BEFORE decryption
|
|
428
|
+
android_switch_event = None
|
|
429
|
+
if AndroidPacketParser:
|
|
430
|
+
try:
|
|
431
|
+
# The Android parser expects unencrypted packets, but let's try anyway
|
|
432
|
+
# to see the structure
|
|
433
|
+
self._logger.debug(f"Attempting Android parser on raw packet: {b2a(raw_encrypted_packet)}")
|
|
434
|
+
android_result = AndroidPacketParser.parse_complete_packet(raw_encrypted_packet)
|
|
435
|
+
self._logger.debug(f"Android parser raw result: {android_result}")
|
|
436
|
+
except Exception as e:
|
|
437
|
+
self._logger.debug(f"Android parser on raw packet failed (expected): {e}")
|
|
426
438
|
|
|
427
439
|
try:
|
|
428
|
-
|
|
440
|
+
decrypted_data = self._encryptor.decryptAndVerify(data, data[:4] + self._nonce[4:])
|
|
429
441
|
except InvalidSignature:
|
|
430
442
|
# We only drop packets with invalid signature here instead of going into an error state
|
|
431
443
|
self._logger.error(f"Invalid signature for packet {b2a(data)}!")
|
|
432
444
|
return
|
|
445
|
+
|
|
446
|
+
# Now try Android parser on decrypted data
|
|
447
|
+
if AndroidPacketParser:
|
|
448
|
+
try:
|
|
449
|
+
self._logger.debug(f"Attempting Android parser on decrypted packet: {b2a(decrypted_data)}")
|
|
450
|
+
android_result = AndroidPacketParser.parse_complete_packet(decrypted_data)
|
|
451
|
+
if android_result.get('switch_event'):
|
|
452
|
+
android_switch_event = android_result['switch_event']
|
|
453
|
+
self._logger.info(f"Android parser found switch event: {android_switch_event['android_log']}")
|
|
454
|
+
self._logger.debug(f"Android parser decrypted result: {android_result}")
|
|
455
|
+
except Exception as e:
|
|
456
|
+
self._logger.debug(f"Android parser on decrypted packet failed: {e}")
|
|
433
457
|
|
|
434
|
-
packetType =
|
|
435
|
-
self._logger.debug(f"Incoming data of type {packetType}: {b2a(
|
|
458
|
+
packetType = decrypted_data[0]
|
|
459
|
+
self._logger.debug(f"Incoming data of type {packetType}: {b2a(decrypted_data)}")
|
|
436
460
|
|
|
437
461
|
if packetType == IncommingPacketType.UnitState:
|
|
438
|
-
self._parseUnitStates(
|
|
462
|
+
self._parseUnitStates(decrypted_data[1:])
|
|
439
463
|
elif packetType == IncommingPacketType.SwitchEvent:
|
|
440
|
-
self._parseSwitchEvent(
|
|
464
|
+
self._parseSwitchEvent(decrypted_data[1:], self._inPacketCount, raw_encrypted_packet, android_switch_event)
|
|
441
465
|
elif packetType == IncommingPacketType.NetworkConfig:
|
|
442
466
|
# We don't care about the config the network thinks it has.
|
|
443
467
|
# We assume that cloud config and local config match.
|
|
@@ -491,23 +515,13 @@ class CasambiClient:
|
|
|
491
515
|
f"Ran out of data while parsing unit state! Remaining data {b2a(data[oldPos:])} in {b2a(data)}."
|
|
492
516
|
)
|
|
493
517
|
|
|
494
|
-
def _parseSwitchEvent(self, data: bytes, packet_seq: int = None, raw_packet: bytes = None) -> None:
|
|
518
|
+
def _parseSwitchEvent(self, data: bytes, packet_seq: int = None, raw_packet: bytes = None, android_switch_event: dict = None) -> None:
|
|
495
519
|
"""Parse switch event packet which contains multiple message types"""
|
|
496
520
|
self._logger.info(f"Parsing incoming switch event packet... Data: {b2a(data)}")
|
|
497
521
|
|
|
498
|
-
#
|
|
499
|
-
if
|
|
500
|
-
|
|
501
|
-
# The raw_packet includes encryption, we need the decrypted version
|
|
502
|
-
# which starts after the type byte (data includes content after type byte)
|
|
503
|
-
# Reconstruct the full decrypted packet for Android parser
|
|
504
|
-
full_packet = bytes([IncommingPacketType.SwitchEvent]) + data
|
|
505
|
-
android_result = AndroidPacketParser.parse_complete_packet(full_packet)
|
|
506
|
-
if android_result.get('switch_event'):
|
|
507
|
-
self._logger.info(f"Android parser result: {android_result['switch_event']['android_log']}")
|
|
508
|
-
self._logger.debug(f"Android parser details: {android_result}")
|
|
509
|
-
except Exception as e:
|
|
510
|
-
self._logger.debug(f"Android parser comparison failed: {e}")
|
|
522
|
+
# Log Android parser result if available
|
|
523
|
+
if android_switch_event:
|
|
524
|
+
self._logger.info(f"Android parser comparison: {android_switch_event['android_log']}")
|
|
511
525
|
|
|
512
526
|
pos = 0
|
|
513
527
|
oldPos = 0
|
|
@@ -536,7 +550,7 @@ class CasambiClient:
|
|
|
536
550
|
|
|
537
551
|
# Process based on message type
|
|
538
552
|
if message_type == 0x08 or message_type == 0x10: # Switch/button events
|
|
539
|
-
self._processSwitchMessage(message_type, flags, parameter, payload, data, oldPos, packet_seq, raw_packet)
|
|
553
|
+
self._processSwitchMessage(message_type, flags, parameter, payload, data, oldPos, packet_seq, raw_packet, android_switch_event)
|
|
540
554
|
else:
|
|
541
555
|
# Log other message types for now
|
|
542
556
|
self._logger.debug(
|
|
@@ -552,7 +566,7 @@ class CasambiClient:
|
|
|
552
566
|
f"Remaining data {b2a(data[oldPos:])} in {b2a(data)}."
|
|
553
567
|
)
|
|
554
568
|
|
|
555
|
-
def _processSwitchMessage(self, message_type: int, flags: int, button: int, payload: bytes, full_data: bytes, start_pos: int, packet_seq: int = None, raw_packet: bytes = None) -> None:
|
|
569
|
+
def _processSwitchMessage(self, message_type: int, flags: int, button: int, payload: bytes, full_data: bytes, start_pos: int, packet_seq: int = None, raw_packet: bytes = None, android_switch_event: dict = None) -> None:
|
|
556
570
|
"""Process a switch/button message (types 0x08 or 0x10)"""
|
|
557
571
|
if not payload:
|
|
558
572
|
self._logger.error("Switch message has empty payload")
|
|
@@ -602,31 +616,22 @@ class CasambiClient:
|
|
|
602
616
|
f"action={action_display} ({event_string}), flags=0x{flags:02x}"
|
|
603
617
|
)
|
|
604
618
|
|
|
605
|
-
#
|
|
619
|
+
# Include Android parser comparison if available
|
|
606
620
|
android_comparison = None
|
|
607
|
-
if
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
self._logger.info(f"Android parser comparison: {android_evt['android_log']}")
|
|
622
|
-
|
|
623
|
-
# Log differences
|
|
624
|
-
if android_evt['unit_id'] != unit_id:
|
|
625
|
-
self._logger.warning(f"Unit ID mismatch: current={unit_id}, android={android_evt['unit_id']}")
|
|
626
|
-
if android_evt['button'] != button:
|
|
627
|
-
self._logger.warning(f"Button mismatch: current={button}, android={android_evt['button']}")
|
|
628
|
-
except Exception as e:
|
|
629
|
-
self._logger.debug(f"Android parser comparison failed: {e}")
|
|
621
|
+
if android_switch_event:
|
|
622
|
+
android_comparison = {
|
|
623
|
+
'unit_id': android_switch_event['unit_id'],
|
|
624
|
+
'button': android_switch_event['button'],
|
|
625
|
+
'state': android_switch_event['state'],
|
|
626
|
+
'param_p': android_switch_event['param_p'],
|
|
627
|
+
'param_s': android_switch_event['param_s'],
|
|
628
|
+
'android_log': android_switch_event['android_log']
|
|
629
|
+
}
|
|
630
|
+
# Log differences
|
|
631
|
+
if android_switch_event['unit_id'] != unit_id:
|
|
632
|
+
self._logger.warning(f"Unit ID mismatch: current={unit_id}, android={android_switch_event['unit_id']}")
|
|
633
|
+
if android_switch_event['button'] != button:
|
|
634
|
+
self._logger.warning(f"Button mismatch: current={button}, android={android_switch_event['button']}")
|
|
630
635
|
|
|
631
636
|
self._dataCallback(
|
|
632
637
|
IncommingPacketType.SwitchEvent,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_constants.py
RENAMED
|
File without changes
|
{casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_discover.py
RENAMED
|
File without changes
|
{casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_encryption.py
RENAMED
|
File without changes
|
{casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_keystore.py
RENAMED
|
File without changes
|
|
File without changes
|
{casambi_bt_revamped-0.3.6.dev1 → casambi_bt_revamped-0.3.6.dev2}/src/CasambiBt/_operation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|