Sending UDP time requests

Send a UDP packet to the BBTime server to receive the current time. The packet must be at least 29 bytes (to prevent amplification attacks). The first two bytes identify the device, the rest is the device-specific payload (e.g. trigger data) or zero padding:

Bytes Description
0-1 BB device ID, 2 bytes big-endian (e.g. 0x2300-0x23FF for monitoring devices)
2+ Device payload (e.g. frame_id, bb_status, trigger data) or zero padding

Response format (29 bytes): +CCLK: "YY/MM/DD,HH:MM:SS+ZZ"

Rate limit: 20 responses per minute per source IP.

Host: bbtime.bbserver.eu IPv4: 195.140.252.32 IPv6: 2A01:430:D:0:2CC:E6FF:FEF7:AE65 UDP port: 4444

Linux (netcat/bash)

# 65-byte trigger packet from BB ID 0x2300 (bytes 0-1).
# To use a different BB device, change bytes 1-2 — the high byte (\x23)
# selects monitoring-device family, the low byte is the device instance.
printf '\x23\x00\x01\xff\x00\x77\xff\x45\x05\x00\x19\x37\x12\x34\x56\x78\x90\x12\x23\x25\x58\x42\x16\x92\x02\x01\x00\x01\x20\x1f\x00\xff\xff\x00\x00\x00\x00\x72\x41\x29\x01\x10\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' | nc -u -w1 bbtime.bbserver.eu 4444

# Same packet via socat
printf '\x23\x00\x01\xff\x00\x77\xff\x45\x05\x00\x19\x37\x12\x34\x56\x78\x90\x12\x23\x25\x58\x42\x16\x92\x02\x01\x00\x01\x20\x1f\x00\xff\xff\x00\x00\x00\x00\x72\x41\x29\x01\x10\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' | socat - UDP:bbtime.bbserver.eu:4444

macOS (netcat)

# macOS netcat requires -c to close after response.
# Edit bytes 1-2 ('\x23\x00') to set your BB ID.
printf '\x23\x00\x01\xff\x00\x77\xff\x45\x05\x00\x19\x37\x12\x34\x56\x78\x90\x12\x23\x25\x58\x42\x16\x92\x02\x01\x00\x01\x20\x1f\x00\xff\xff\x00\x00\x00\x00\x72\x41\x29\x01\x10\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' | nc -u -w1 -c bbtime.bbserver.eu 4444

Windows (PowerShell)

$udp = New-Object System.Net.Sockets.UdpClient
# 65-byte trigger packet from BB ID 0x2300.
# Change bytes [0] and [1] to set your BB ID.
$bytes = [byte[]]@(
  0x23, 0x00, 0x01, 0xFF,
  0x00, 0x77, 0xFF, 0x45, 0x05, 0x00, 0x19, 0x37,
  0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
  0x23, 0x25, 0x58, 0x42, 0x16, 0x92,
  0x02, 0x01, 0x00, 0x01, 0x20, 0x1F, 0x00, 0xFF, 0xFF,
  0x00, 0x00, 0x00, 0x00, 0x72, 0x41, 0x29, 0x01, 0x10,
  0xFF, 0xFF, 0xFF,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00
)
$udp.Send($bytes, $bytes.Length, "bbtime.bbserver.eu", 4444)

# Receive time response
$ep = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::Any, 0)
$response = $udp.Receive([ref]$ep)
[System.Text.Encoding]::ASCII.GetString($response)
$udp.Close()

Arduino (ESP8266/ESP32)

#include <WiFiUdp.h>

WiFiUDP udp;
const char* server = "bbtime.bbserver.eu";
const int port = 4444;

// Trigger payload (bytes 2-64). bbId fills bytes 0-1.
const byte TRIGGER_PAYLOAD[63] = {
  0x01, 0xFF,
  0x00, 0x77, 0xFF, 0x45, 0x05, 0x00, 0x19, 0x37,
  0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
  0x23, 0x25, 0x58, 0x42, 0x16, 0x92,
  0x02, 0x01, 0x00, 0x01, 0x20, 0x1F, 0x00, 0xFF, 0xFF,
  0x00, 0x00, 0x00, 0x00, 0x72, 0x41, 0x29, 0x01, 0x10,
  0xFF, 0xFF, 0xFF,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00
};

void sendTrigger(uint16_t bbId) {
  byte packet[65];
  packet[0] = (bbId >> 8) & 0xFF;   // BB ID high byte
  packet[1] = bbId & 0xFF;          // BB ID low byte
  memcpy(packet + 2, TRIGGER_PAYLOAD, sizeof(TRIGGER_PAYLOAD));

  udp.beginPacket(server, port);
  udp.write(packet, sizeof(packet));
  udp.endPacket();

  int packetSize = 0;
  unsigned long start = millis();
  while (!packetSize && millis() - start < 2000) {
    packetSize = udp.parsePacket();
  }
  if (packetSize) {
    char buf[64];
    int len = udp.read(buf, sizeof(buf) - 1);
    buf[len] = '\0';
    // buf contains: +CCLK: "YY/MM/DD,HH:MM:SS+ZZ"
    Serial.println(buf);
  }
}

MicroPython (ESP32/RP2040)

import socket

# 65-byte trigger packet from BB ID 0x2300 (bytes 0-1).
TRIGGER_HEX = (
    '2300'                 # bytes 0-1: BB ID
    '01ff'                 # bytes 2-3: frame_id + bb_status
    '0077ff4505001937'     # bytes 4-11
    '123456789012'         # bytes 12-17 (code)
    '232558421692'         # bytes 18-23
    '0201000120'           # bytes 24-28
    '1f00ffff'             # bytes 29-32
    '00000000'             # bytes 33-36
    '7241290110'           # bytes 37-41
    'ffffff'               # bytes 42-44
    + '00' * 20            # bytes 45-64
)

def send_trigger(server_ip, bb_id=None, port=4444):
    packet = bytearray(bytes.fromhex(TRIGGER_HEX))
    if bb_id is not None:
        packet[0] = (bb_id >> 8) & 0xFF
        packet[1] = bb_id & 0xFF

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.settimeout(2)
    sock.sendto(bytes(packet), (server_ip, port))

    try:
        data, _ = sock.recvfrom(64)
        # data contains: +CCLK: "YY/MM/DD,HH:MM:SS+ZZ"
        print(data.decode())
    except OSError:
        print("Timeout waiting for response")
    finally:
        sock.close()

# Example: send trigger as BB ID 0x2305
send_trigger("bbtime.bbserver.eu", 0x2305)