aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: 0b851547c9a414c6a063872050251995c2b887f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

   

Bodeting, Understanding Bodets Harmony PSA Protocol

What will you find here?

  • 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).

Research folder contains active stuff im working on right now.

If you want to help out with figuring things out this is where to look I'd say

General info

Common Hardware Details (Seemingly for all but Master Clock)

  • 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

Build Pipeline

  • 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

Possible Default Credentials

Based on repeated appearances in both firmware strings :

Username Password
public jkl1vi5erjnfh
public aSe2=9Z8gOi37*

PS: Not tested extensively

IP Button Packet Anatomy

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

MEL Header

  • Hex: 4D 45 4C
  • ASCII: "MEL" (probably short for "Melody")
  • Identifies this as a Bodet Sound Protocol packet

Length

  • 2 bytes
  • Indicates payload size in decimal (excluding MAC/IP/UDP headers)
  • Example: 0021 = 33 bytes

Start Marker

  • Constant: 0100
  • Marks start of command block

Sequence Number

  • 2 bytes, Little Endian
  • Only the first byte appears to increment; the second is just FF, suggesting padding or reserved space

Command Code

  • Examples:

  • 3001 = Melody

  • 5001 = Alarm
  • 5002 = Stop

Zone Info

  • 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:

  • 8000 0000 0000 0000 0000 0000 = Zone 8 only
  • 0000 8000 0000 0000 0000 0000 = Zone 16 only
  • 0000 0000 0000 0000 0020 0000 = Zone 86

  • Note : this is just an assumption not enough testing has been done

Metadata Fields

  • After Zone Info:

  • 0001 - Probably Fixed field (sometimes 0002 with certain multizone commands)

  • 03 - Volume (1-8)
  • 02 - Repeat count (or 00 for infinite)
  • `01 - Probably Fixed field or field to actually tell the device yes play something lol
  • 09 - Melody ID (9 in this case)
  • 0100 - end-of-command marker, appears to terminate command blocks (expept for stop commands)

Checksum (2 bytes)

  • Position: Final two bytes of packet
  • Algorithm: PSA Checksum algorithm
  • Implementation: See the Checksum Implementation section below
  • (Looks often like this 014a)

Examples (Annotated)

Melody to Zone 8, Melody 9, Infinite Repeats

4d454c 0021 0100 28ff 3001 8000 0000 0000 0000 0000 0000 0001 03 00 01 09 0100 01d5
  • Zone 8 = 8000 ...
  • Volume = 03, Repeats = 00 (infinite)
  • Melody = 09
  • Checksum = 01D5

Stop All Zones

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

Checksum Implementation

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.


Reminence of the Journey here.

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