# Bodeting, Understanding Bodets Harmony PSA Protocol

## What will you find here?
- Research on how the Bodet Harmony PSA Protocol works
- 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).

**Important Disclaimer:** While the structural fields of the packets are mostly well understood, the checksum calculation remains quiet mysterious. Without correctly reproducing the checksum, generating functional packets yourself remains unreliable unless you copy known working ones, therefore this can only be used for repetitive actions with already learnt and working commands.

## Sample Data Folder :
Contains valid payloads that get accepted by the system if sent to multicast address 239.192.55.2
stop-payloads.txt

## 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


Please IF YOU KNOW HOW TO MAKE THE CHECKSUMS WORK PROPERLY OR KNOW MORE THAN ME PLEASE HELP ME!!!

## General info


### Hardware Details

- **Platform**: Freescale MQX RTOS
- **MCU**: Most likely a Freescale/NXP Cortex-M4 (based on MQX + strings + 2017 build date)
- **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*`     |

### Checksum Observations

- Found log strings that explicitly reference checksum calculation and failures:
`CHK = %04x (%d)`
`CHK BAD !!! %d`
- Could however also be just for firmware integrity maybe? Rather unlikely though.

Also of note : 
```
F_traitement_trame_PROTOCOLE
F_traitement_trame_vie_repeteur
REP STREAM !!! ERREUR !!!
RX %d/%d (%d/%d)
```
- These functions appear responsible for:
- Receiving and validating packets
- Detecting checksum mismatches
- Possibly retrying on failures?


## 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]
```

### 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 often `FF`, suggesting padding or reserved space
* Likely acts as a replay or event counter

### 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` - **Possible end-of-command marker**, appears to terminate command blocks (expept for stop commands)
  * `01` - Fixed

### Checksum (1 byte)

* **Position:** Final byte of packet
* **Behavior:** Matches `(sum of all previous bytes) & 0xFF` in most cases, but not always.
* **Status:** **SEND HELP** (see section below)

---

## 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 01 d5
```

* Zone 8 = `8000 ...`
* Volume = `03`, Repeats = `00` (infinite)
* Melody = `09`
* Checksum = `D5`

### Stop All Zones

```
4d454c 001a 0100 24ff 5002 ffff ffff ffff ffff ffff ffff 0f 01 07
```

* 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 = `07`

---

## Checksum Problem

While many packets obey a simple rule:

```python
checksum = sum(packet[:-1]) & 0xFF
```

... others **diverge** due to what appears to be a variable offset or conditional logic. Several hypotheses have been explored:

* Static or conditional offset subtracted from the sum
* Offset based on specific bytes (e.g., command, zone byte)
* Very small chance of a lookup table (LUT) approach per command (dont think so though since IP buttons have only 256KB RAM)

### Consequences

If the checksum is wrong, the Bodet PSA system and its components obviously ignore the packet. Hence generating your own commands reliably is **not yet possible** unless mimicking an exact known good packet.

This makes full integration with modern systems (for triggering Bodet audio via automation) dependent on further reverse engineering.

---

## Please Help me !!!

If you have firmware dumps, better knowladge of UDP and reverse engeneering checksums or just generally more insights, feel free to contribute 
