- Research on how the Bodet Harmony PSA Protocol works
- Checksum Generator for Harmony Packets
- Tools to allow features to be used your Netsilon can't do
- Research on replacing the Bodet Software Called SIGMA and the Time Server for it (I can't even take its name serious) and eventually links to the replacement software called BE-YOUR-OWN-SIGMA (if I achieve reverse engineering it to a certain decentish degree).
If you want to help out with figuring things out this is where to look I'd say
- Platform: Freescale MQX RTOS
- MCU: Some Freescale/NXP Cortex-M4
- Networking Stack: LwIP
- Storage: MFS-style filesystem, Speakers and Sound Generating Components have an SD Card
- Web Interface: Embedded HTTP server (
Server: MQX HTTP - Freescale Embedded Web Server
)
- Ports & Protocols:
- HTTP, FTP (port 21), SNMP, IGMP multicast, UDP
- FTP Banner:
RTCS FTP Server Ready
- Project was built using Windows Jenkins (who could've guessed that), based on hardcoded paths in strings of firmware files:
d:\JenkinsJobs\workspace\Indus\Harmonys\Harmonys_trio\Metis_appli\Middlewares\Third_Party\LwIP\
- Sources show extensive use of LwIP stack and standard Freescale directory structures
Based on repeated appearances in both firmware strings :
Username |
Password |
public |
jkl1vi5erjnfh |
public |
aSe2=9Z8gOi37* |
PS: Not tested extensively
Each IP Button Bodet Sound Protocol Payload follows a consistent format:
[MEL HEADER]-[LENGTH]-[START]-[SEQUENCE]-[COMMAND]-[ZONE INFO]-[METADATA]-[CHECKSUM]
Seems to send two of the packets each time a button is pressed
- Hex:
4D 45 4C
- ASCII: "MEL" (probably short for "Melody")
- Identifies this as a Bodet Sound Protocol packet
- 2 bytes
- Indicates payload size in decimal (excluding MAC/IP/UDP headers)
- Example:
0021
= 33 bytes
- Constant:
0100
- Marks start of command block
- 2 bytes, Little Endian
- Only the first byte appears to increment; the second is just
FF
, suggesting padding or reserved space
-
Examples:
-
3001
= Melody
5001
= Alarm
5002
= Stop
- 12 bytes (6 words of 16 bits = 96 bits)
- Represents zones 1–100 using a bitfield
- Each zone bit is encoded as:
byte_index = (zone - 1) // 8
bit_index = (zone - 1) % 8
set bit (7 - bit_index) in byte[byte_index]
* You can enable multiple zones in a single packet by OR-ing the relevant bits
* Examples:
- Position: Final two bytes of packet
- Algorithm: PSA Checksum algorithm
- Implementation: See the Checksum Implementation section below
- (Looks often like this
014a
)
4d454c 0021 0100 28ff 3001 8000 0000 0000 0000 0000 0000 0001 03 00 01 09 0100 01 d5
- Zone 8 =
8000 ...
- Volume =
03
, Repeats = 00
(infinite)
- Melody =
09
- Checksum =
D5
4d454c 001a 0100 24ff 5002 ffff ffff ffff ffff ffff ffff 0f 0107
- All zones =
FF FF ...
(you actually cant choose which zone to turn of system refuses zonemaps here)
- Command = Stop (
5002
)
- Ends with
0F 01
instead of 0100
→ supports theory that 0100
indicates only the end of melody/alarm command block
- Checksum =
0107
The checksum algorithm used by Bodet PSA protocol has been successfully reverse engineered thanks to severe insanity (I didn't realize it as 2 bytes until I already wasted 5 days reverse engineering it). It works as follows btw:
def compute_psa_checksum(data: bytes) -> bytes:
var_e = 0x0000 # Starting seed value
for i in range(len(data)):
var_e ^= (data[i] + i) & 0xFFFF
return var_e.to_bytes(2, 'big') # 2-byte checksum, big-endian
PS: I extracted this info by decompiling the SIGMA Software Package by Bodet
Key characteristics:
- Uses a seed value of 0x0000
- For each byte in the data:
- Adds the byte value and its index
- XORs the result with the running checksum
- Applies a 16-bit mask (0xFFFF)
- Returns a 2-byte big-endian checksum
This algorithm allows for generating valid packets for the Bodet PSA system. It was verified against known working packets and matches the behavior observed in the system.
To use this algorithm:
1. Prepare your packet data excluding the checksum
2. Calculate the checksum using the function above or the python code in this repo.
3. Append the 2-byte checksum to your packet data
4. Send to your Bodet Harmony Multicast Address (Port 1681)
For a ready-to-use implementation, see the hex_checksum.py
script in this repository.
The executables/hexen.py
script is not recommended, I used it to make some sample data by listening if the Harmony Speaker would produce noises. It is filled with cursewords