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

```python
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.

---
##

# Bodet Harmony IP Button Configuration Protocol Analysis

## Quick Start Guide - How to Configure IP Buttons

### Protocol Basics
The Bodet Harmony button configuration uses TCP port 5666 with a simple text+binary protocol:

1. **Connect** to device on TCP port 5666
2. **Send** text command: `bou 1 get-att\nMelodys\n54321\n\x00` to get current config
3. **Receive** 184 bytes: 14-byte text header + 170-byte binary configuration 
4. **Modify** the 170-byte binary config as needed
5. **Send** text command: `bou 1 set-att\nMelodys\n54321\n` + modified 170-byte config
6. **Receive** confirmation: `bou 2 set-att\nack\n\x00`

### Configuration Structure (170 bytes)
- **Bytes 140-143**: Melody numbers (hex values = decimal melody IDs)
- **Bytes 150-153**: Repeat counts (01-04, 00=infinite)
- **Bytes 154-159**: Button enable flags (01=on, 00=off) 
- **Bytes 160-166**: Volume levels (01-08)
- **Bytes 167-169**: Alarm mode flags (01=alarm, 00=normal melody)

### Zone Configuration (Complex Multi-Zone)
For multi-zone targeting (like Button 1: Zones 1,2,4,8,16):
- Uses bitfield encoding in zone section (bytes ~12-139)
- Example: `8b80` = zones 1+2+4+8+16 combined
- `0300` = zones 1+2 only

### Authentication
- Always use: `Melodys` as ecosystem ID
- Always use: `54321` as authentication token
- These appear to be static/unchangeable

## Overview

This document analyzes the TCP-based configuration protocol used by Bodet Harmony button devices. The protocol operates on **port 5666** and uses a text-based command structure for device configuration.

## Protocol Structure

### Connection Flow
1. **GET Configuration**: Software requests current device configuration
2. **Device Response**: Button device sends current settings as binary payload
3. **SET Configuration**: Software sends new configuration 
4. **ACK Response**: Device acknowledges configuration change

### Command Format

Commands follow a text-based structure:
bou [ID] [command]\n[parameters]\n[binary_data]

## Command Analysis

### GET-ATT Command (Get Attributes)

**Request from Software:**
626f752031206765742d6174740a4d656c6f6479730a35343332310a00

**Decoded:**
bou 1 get-att\nMelodys\n54321\n\x00

- `bou 1` = Most likely Button 1 on the Device 
- `get-att` = Get attributes command
- `Melodys` = Device Ecosystem (Melody IP)
- `54321` = Could be device ID, firmware version, or authentication token
- `\x00` = Null terminator

### Device Configuration Response

Possible Settings that can well be set per button :
Action type : On or Off
Melody Number : 1-30
Number of Repeats : 1-4 (Or maybe 0 for Infinite Repetition like with Sigma master clock and is grayed out if infinite repeats is selected)
Volume : 1-8
Repeat Continuously : Yes or No
Alarm : Yes or No
All zones (radio button)
All Selected Zones (ranges from zone 1 to 100 of which each individually can be turned on or off)

**Raw Response (170 bytes):**
626f752032206765742d6174740a01000101010201010101010101010100000000000020000000000000000000000000200000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a191b04050607080000000101010101060606050505050500000000000000000a00

Known set Parameters for each button :
Button 1 :I
Action type : On
Melody Number : 26
Repeates -
Volume : 6
Repeat Continuously : Yes
Alarm : No
All Selected zones : Zone 6 only

**Decoded Header:**
bou 2 get-att\n[170 bytes of binary configuration data]

#### Configuration Data Structure (Binary Payload Analysis)

The 170-byte payload appears to contain:

**Bytes 0-12: Button Configuration Matrix**
01000101010201010101010101000000000020000000000000000000000000200000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

This looks like a button mapping matrix where:
- Each button can be configured with different behaviors
- Values like `01`, `02` might represent different button types or actions
- `20` (0x20 = 32 decimal) could be zone assignments or timing values

**Bytes 140-156: Device Settings**
1a191b04050607080000000101010101060606050505050500000000000000000a00

Breaking this down:
- `1a191b` = Could be firmware version (26.25.27 in decimal) (this is 100% the melody Number! we have Button 1 : Melody 26, Button 2 : Melody 25, Button 3 : Melody 27, Button 4 : all off)
- `04050607080000` = Possibly button assignments or melody IDs (could also just be dummy data maybe ?)
- `000101010101` = Enable/disable flags for 6 buttons (but we only have 4 ????)
- `060606050505050` = Volume levels or repeat counts for each button (i mean we have not one vol 5 action fyi)
- `0a00` = Footer/checksum

### SET-ATT Command (Set Attributes)

**Configuration Change Request:**
626f752031207365742d6174740a4d656c6f6479730a35343332310a[184 bytes config data]

**Decoded:**
bou 1 set-att\nMelodys\n54321\n[new configuration data]

The configuration data in SET commands is similar to GET responses but may include:
- Updated button mappings
- New zone assignments  
- Modified volume/repeat settings

### ACK Response

**Device Acknowledgment:**
626f752032207365742d6174740a61636b0a00

**Decoded:**
bou 2 set-att\nack\n\x00

Simple acknowledgment that configuration was applied successfully.

## Deep Analysis of Configuration Examples

### Example 1 - All Alarm Mode with 4 Repeats

**Configuration String:**
626f752031207365742d6174740a4d656c6f6479730a35343332310a010001010101010101010000000000000000200000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008090a0b050607080404040401010101080808080505050501010101000000000a00

**Button Configuration:**
- All 4 buttons: Action ON, Alarm YES, Volume 8, 4 Repeats, All Zones
- Melody Numbers: 8, 9, 10, 11 (buttons 1-4 respectively)

**Key Binary Fields:**
- Melody section: `08090a0b` = melodies 8,9,10,11 in decimal
- Repeat section: `04040404` = 4 repeats for all buttons
- Volume section: `08080808` = volume 8 for all buttons
- Zone configuration shows "All Zones" pattern

### Example 2 - Varying Repeat Counts

**Configuration String:**
626f752031207365742d6174740a4d656c6f6479730a35343332310a010001010101010101010000000000000000200000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008090a0b050607080102030401010101080808080505050501010101000000000a00

**Button Configuration:**
- All 4 buttons: Action ON, Alarm YES, Volume 8, All Zones
- Repeat counts: 1,2,3,4 (buttons 1-4 respectively)
- Same melody numbers: 8,9,10,11

**Key Discovery:**
- Repeat section: `01020304` = individual repeat counts per button
- All other fields remain identical to Example 1
- Demonstrates granular repeat control

### Example 3 - Alarm Mode Disabled

**Configuration String:**
626f752031207365742d6174740a4d656c6f6479730a35343332310a010001010101010101010000000000000000200000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008090a0b050607080102030401010101080808080505050500000000000000000a00

**Button Configuration:**
- Same as Example 2 but all buttons changed from Alarm YES to normal melodies
- Repeat counts maintained: 1,2,3,4
- Volume 8 maintained for all buttons

**Key Difference:**
- Alarm mode section shows change from `01010101` to `00000000`
- Demonstrates alarm/melody mode toggle capability

### Example 4 - Zone 6 Targeting

**Configuration String:**
626f752031207365742d6174740a4d656c6f6479730a35343332310a010001010101010101010101010100000000200000000000000000000000002000000000000000000000000020000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008090a0b050607080102030401010101080808080505050500000000000000000a00

**Button Configuration:**
- Same as Example 3 but all buttons now target Zone 6 only instead of All Zones
- Normal melody mode maintained
- Same repeat and volume settings

**Zone Configuration Change:**
- Zone targeting pattern changes from "All Zones" to specific Zone 6 pattern
- Shows single zone targeting capability

### Example 5 - Complex Multi-Zone Configuration

**Configuration String:**
626f752031207365742d6174740a4d656c6f6479730a35343332310a0100010101010101010101010101000000008b8000000000000000000000008b0000000000000000000000000b000000000000000000000000030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008090a0b050607080102030401010101080808080505050500000000000000000a00

**Button Configuration:**
- Button 1: Zones 1,2,4,8,16
- Button 2: Zones 1,2,4,8  
- Button 3: Zones 1,2,4
- Button 4: Zones 1,2

**Zone Encoding Analysis:**
- `8b80` = Button 1 zones (1+2+4+8+16 = zones with bits set)
- `8b00` = Button 2 zones (1+2+4+8)
- `0b00` = Button 3 zones (1+2+4)
- `0300` = Button 4 zones (1+2)

**Critical Discovery - Zone Bitfield Encoding:**
The zone configuration uses a bitfield where:
- Each zone is represented by a specific bit position
- Multiple zones can be combined by OR-ing bits
- Demonstrates advanced multi-zone targeting capability

## Configuration Protocol Structure Analysis

### Binary Payload Structure (170 bytes)

**Header Section (14 bytes):**
`bou 1 set-att\nMelodys\n54321\n`

**Configuration Data (170 bytes):**
1. **Button Enable Flags** (bytes 0-11): Button on/off states
2. **Zone Configuration** (bytes 12-139): Complex bitfield for zone targeting
3. **Melody Numbers** (bytes 140-143): `08090a0b` = melodies 8,9,10,11
4. **System Data** (bytes 144-149): `050607080` = unknown system parameters, static accross multiple devices
5. **Repeat Counts** (bytes 150-153): Individual repeat settings per button
6. **Enable Flags** (bytes 154-159): `010101` = button enable confirmations
7. **Volume Levels** (bytes 160-166): Volume settings per button
8. **Additional Flags** (bytes 167-169): Mode/alarm settings
9. **Footer** (bytes 170-171): `0a00` = configuration checksum?

## Key Protocol Insights

1. **Granular Control**: Individual buttons can have different repeat counts, volumes, and zone targets
2. **Zone Flexibility**: Supports both "All Zones" and complex multi-zone configurations
3. **Alarm Mode Toggle**: Buttons can switch between normal melody and alarm modes
4. **Binary Efficiency**: Uses bitfields for zone targeting, enabling complex configurations
5. **Configuration Validation**: Footer checksum ensures data integrity

## Security Implications

1. **Static Authentication**: "54321" token appears unchangeable across all examples
2. **Predictable Structure**: Configuration format easily reverse-engineered
3. **Zone Manipulation**: Unauthorized zone reconfiguration possible
4. **Volume/Alarm Abuse**: Settings could be modified for disruptive purposes
5. **Multi-Zone Targeting**: Complex zone combinations enable wide-area effects

## Implementation Requirements

For programmatic configuration:
1. **TCP Connection**: Connect to device port 5666
2. **Command Structure**: Use "bou 1 set-att" format with proper authentication
3. **Binary Encoding**: Handle 170-byte configuration structure correctly
4. **Zone Bitfields**: Implement zone encoding for multi-target configurations
5. **Validation**: Include proper footer checksums for data integrity

## Conclusion

The Bodet Harmony configuration protocol provides comprehensive control over button behavior through a well-structured binary format. The examples demonstrate sophisticated zone targeting capabilities and granular per-button control. However, the static authentication and predictable structure present security concerns that require network-level protections.


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

