# Keepsmile KS03~ Protocol
This document details the reverse-engineered protocol Keepsmile uses to communicate with LED strip lights. These structures were found by creating a BLE server on an ESP32 using the same "KS03~XXXXXXX" identifier and the same service and write characteristic UUIDs. This setup spoofs the ESP32 into looking like a legitimate device, and thus most packets were logged and documented here.
The spoofer source code can be found in this [repository.](https://example.com)
**Changelog:**
```
2024-09-12: Initial release.
```
## UUIDs
Here are the following uuid's related to the device's services and characteristics:
**Service 1** - `00001800-0000-1000-8000-00805f9b34fb`
- Characteristic 1 - `00002a00-0000-1000-8000-00805f9b34fb` (Read)
**Service 2** - `0000afd0-0000-1000-8000-00805f9b34fb`
- Characteristic 1 - `0000afd1-0000-1000-8000-00805f9b34fb` (Write)
- Characteristic 2 - `0000afd2-0000-1000-8000-00805f9b34fb` (Notify)
- Characteristic 3 - `0000afd3-0000-1000-8000-00805f9b34fb` (Read)
**Service 2** and **Characteristic 2** is what Keepsmile uses to communicate and send commands to the device. The following packets and their structure can be found below:
## Bluetooth Packets
Each packet sent to the device starts with an **identifier** byte, and the identifier byte flipped. For example, if the a packet is sent with an id of 0x5F, the structure would look like the following: `5F [...argument bytes] F5`. Additionally, most packets end with a null byte before the final byte.
### Initial Connection
When the app connects to the device, it sends 2 packets:
`5F 01 00 F5`
The next packet is sent immediately after, and changes slightly each time. Strangely, it does not adhere to the usual structure sent above.
`7E 07 83 15 11 15 05 FF EF` (received at _21:17:21.663_)
`7E 07 83 15 12 05 05 FF EF` (received at _21:18:05.523_)
`7E 07 83 15 12 34 05 FF EF` (received at _21:18:52.425_)
`7E 07 83 16 01 06 05 FF EF` (received at _22:01:06.533_)
`7E 07 83 17 05 27 05 FF EF` (received at _23:05:39.540_)
The structure of these packets are currently unknown, and it is worth noting that sending them is not required.
### On / Off
The following packet is used to turn the device on or off:
```c++
struct Operation_t {
uint8_t id = 0x5B;
uint8_t operation; // On - 0xF0, Off - 0x0F
uint8_t unk1 = 0x00;
uint8_t id_end = 0xB5;
};
```
### Custom Color
This packet is sent whenever the lights need to change to a custom color. This same structure is also used when the **rythm** feature is used, sent many times.
```c++
struct ColorCustom_t {
uint8_t id = 0x5A;
uint8_t unk1 = 0x00;
uint8_t unk2 = 0x01;
uint8_t r; // 0 - 255
uint8_t g; // 0 - 255
uint8_t b; // 0 - 255
uint8_t unk3 = 0;
uint8_t brightness; // 0 - 100
uint8_t unk4 = 0x00;
uint8_t id_end = 0xA5;
};
```
### Color Profile
This packet is sent when a color profile is set.
```c++
struct ColorProfile_t {
uint8_t id = 0x5C;
uint8_t unk1 = 0x00;
uint8_t profile; // 0x80 - 0x96
uint8_t speed; // 0 - 100
uint8_t brightness; // 0 - 100
uint8_t unk2 = 0x00;
uint8_t id_end = 0xC5;
};
```
Here are the **23** available color profiles that range from **0x80 to 0x96**:
- Seven color jumping change
- RGB jumping change
- Pulsating Seven colors
- Pulsating RGB
- Pulsating red
- Pulsating green
- Pulsating blue
- Pulsating yellow
- Pulsating cyan
- Pulsating purple
- Pulsating white
- Pulsating red,green
- Pulsating red,blue
- Pulsating green,blue
- Seven color strobe flash
- RGB strobe
- Red strobe flash
- Green strobe flash
- Blue strobe flash
- Yellow strobe flash
- Cyan strobe flash
- Purple strobe flash
- White strobe flash
### Rythm Selection
```c++
struct RythmSelection_t {
uint8_t id = 0x5A;
uint8_t unk1 = 0x0A;
uint8_t mic_type; // Phone mic - 0x0F, device mic - 0xF0
uint8_t type; // 1 - 4
uint8_t speed; // 8 - 1 (8 being the slowest)
uint8_t unk3 = 0x01;
uint8_t id_end = 0xA5;
};
```