Skip to main content

cs2pppp

A small, zero-dependency (stdlib-only) Python client for the CS2 Network PPPP stack used by CS2-style IoT cameras.

cs2pppp is a stdlib Python client for the CS2 PPPP wire protocol and CS2-style app JSON, where directory servers are always supplied by the caller.

It speaks the protocol wire formats:

  • Directory lookup / Online–Offline–InvalidId probe
  • UDP session (HELLO → wake → relay or direct punch → RDY → ALIVE → DRW)
  • CS2 app-channel JSON framing on the DRW command channel
  • High-level device helpers: login, get info, optional snapshot

What it is not

  • Not an A9/iLnk/Yi LAN library — those forks are out of scope.
  • Not an admin/JWT client, IMEI→DID cloud lookup, or DID generator.
  • It ships no directory IPs, InitStrings, cloud domains, or credentials. You always provide the directory servers.

Install

pip install cs2pppp

Python ≥ 3.9. No required dependencies. (Snapshot decoding uses a system ffmpeg if you call it — not needed for probe/session/info.)

Providing directory servers

There are no built-in defaults. Supply servers when constructing the client.

Get them however you like — commonly by decoding an InitString you already have (e.g. from your own app config), or from an environment variable:

import os
from cs2pppp import Cs2Client, decode_init_string

# Option A: from env
servers = os.environ["CS2_SERVERS"].split(",")   # "ip1,ip2,ip3"
client = Cs2Client(servers=servers)

# Option B: decode a user-supplied InitString blob
decoded = decode_init_string(my_init_blob)       # never bundled by this lib
assert decoded.lib_ok
client = Cs2Client(servers=decoded.servers)

Structured config and a custom port are also supported:

from cs2pppp import Cs2Client, DirectoryConfig
client = Cs2Client(directory=DirectoryConfig(servers=("203.0.113.10",), port=32100))

Providing protocol tables

This library ships no byte tables. The InitString decode LUT and the two cipher tables are the caller's responsibility — supply them the same way you supply directory servers. Provide them from your own configuration and inject them once:

import cs2pppp
cs2pppp.configure_tables(
    lut="...",         # 54 bytes, hex or bytes  — used by decode_init_string
    prop_table="...",  # 256 bytes               — session handshake (0xF9)
    crc_table="...",   # 64 bytes                — crc_enc/crc_dec (research)
)

Or via environment variables (hex): CS2PPPP_LUT, CS2PPPP_PROP_TABLE, CS2PPPP_CRC_TABLE. A function that needs a table you did not supply raises ConfigError. You only need prop_table for a live session, lut for decode_init_string, and crc_table for the CRC research helpers.

Probe

status = client.probe("G100000ZKMNP")
print(status)                 # e.g. "online (0x00 via 203.0.113.10)"
print(status.online, status.offline, status.invalid_id, status.raw_code)
Wire Meaning
0x00 Online
0xFE Offline
0xFF InvalidId
0xFD InvalidPrefix

Device session

# High-level device (context manager opens/closes the UDP session)
with client.device("G100000ZKMNP", password="123456") as dev:
    info = dev.get_info()          # dict from GetDevInfo (+ related)
    # dev.login()                  # already done if password given at open
    # dev.snapshot("out.jpg")      # optional; needs ffmpeg on PATH

# Low-level session
with client.session("G100000ZKMNP") as sess:
    sess.alive()
    replies = sess.request_json({"cmd": "GetDevInfo"})
    sess.send_json({"cmd": "LoginDev", "pwd": "123456"})
    raw = sess.recv(timeout=2.0)

The relay path is preferred by default (direct hole-punch often fails on CGNAT). Pass prefer="direct" to try the direct punch first.

DID helpers (format only)

from cs2pppp import parse_did, normalize_did, virtual_to_real, real_to_virtual

normalize_did("G100000ZKMNP")     # "GHBB-100000-ZKMNP" (wire/real form)
virtual_to_real("G100000ZKMNP")   # "GHBB-100000-ZKMNP"
parse_did("GHBB-100000-ZKMNP")    # Did(real=..., virtual=..., network="mykj", ...)

The PREFIX_MAP (virtual letter → real prefix, e.g. F→FHBB) is exported as data — it is protocol identity format, not a server list. There is no offline check-digit generator: this library never claims a DID will be accepted by a directory server.

Security notes

  • The PPPP transport "encryption" is weak obfuscation. cs2pppp.crypto exposes research helpers (derive_key, xor_apply, recover_key, crack_key, crc_enc/crc_dec) for analysing captures. They are not required for normal use.
  • The SSD@cs2-network. session key is a universal, hardcoded protocol constant, not a secret.
  • Prefer devices you own. DIDs and passwords are sensitive — treat them like credentials.

Not affiliated

This project is not affiliated with CS2 Network or any device vendor. Names are used only to describe protocol compatibility.

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cs2pppp-0.1.0.tar.gz (27.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cs2pppp-0.1.0-py3-none-any.whl (30.2 kB view details)

Uploaded Python 3

File details

Details for the file cs2pppp-0.1.0.tar.gz.

File metadata

  • Download URL: cs2pppp-0.1.0.tar.gz
  • Upload date:
  • Size: 27.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for cs2pppp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f015ccbfd49915d04357b0eafe6f2a10fbfa4830c1a3e8ba9d6c4223024f3051
MD5 547585f7558c8984715785487c92a5f4
BLAKE2b-256 34da14b033910d71e30323f967b20901f1b04b49ab2590d6608e60cafb17303a

See more details on using hashes here.

Provenance

The following attestation bundles were made for cs2pppp-0.1.0.tar.gz:

Publisher: publish.yml on wmarquardt/cs2-pppp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cs2pppp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: cs2pppp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 30.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for cs2pppp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a87917696ecd252eb387a6a391d9c97707534550a55bea6a4a9042a5372ef368
MD5 ae48ab77cec8e7d7b12aef07b5198b47
BLAKE2b-256 dee3d7c8d28f79d27c6d46c192739e4c2353e8872b51b936a4f32ac5ef541fe5

See more details on using hashes here.

Provenance

The following attestation bundles were made for cs2pppp-0.1.0-py3-none-any.whl:

Publisher: publish.yml on wmarquardt/cs2-pppp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.2.11

2 files

0.2.10

2 files

0.2.9

2 files

0.2.8

2 files

0.2.7

2 files

0.2.5

2 files

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page