Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

CometTextel — Python (thin FFI)

Thin ctypes binding to the same C ABI as the C SDK and CometTextel.NET (c_api.h).
This is not a second native library: it runtime-loads comettextel.dll / libcomettextel.so.

Covers PDU helpers and GsmModem (open / send / list / delete).
Hardware modem tests are optional; smoke tests run without a device.

Python

Layout

sdk/python/
├── comettextel/              # package (ctypes + PDU + modem)
├── examples/
│   ├── pdu_example.py        # encode / decode + self-check
│   └── modem_example.py      # list / send / delete
├── tests/
│   ├── test_pdu.py
│   └── test_modem.py
└── README.md

Prerequisites

Item Detail
Python 3.10+ (3.13 verified)
Native C SDK shared library (comettextel.dll or libcomettextel.so)
Modem (optional) AT modem in PDU mode (e.g. COM3, /dev/ttyUSB0)

Download comettextel-c-sdk-* from CI Artifacts or a GitHub Release, or use a local CMake build.

Finding the library

Search order:

  1. Explicit path passed to comettextel.pdu.load_library(...)
  2. Environment variable COMETTEXTEL_LIB (shared-library file or a directory containing it — including versioned Linux sonames such as libcomettextel.so.1.3.0)
  3. Wheel-embedded _native/<platform>/ (CI platform wheels)
  4. Current working directory
  5. Nearby build / artifact folders (build-c-sdk/Release, artifact/comettextel-c-sdk-*/…)
# Windows
$env:COMETTEXTEL_LIB = "D:\path\to\comettextel.dll"
# Linux
export COMETTEXTEL_LIB=/path/to/libcomettextel.so

Wheels

CI builds platform wheels that embed the matching C ABI shared library:

Artifact Tag
comettextel-python-wheel-windows win_amd64
comettextel-python-wheel-linux linux_x86_64

Local pack (after a C SDK stage):

python sdk/python/scripts/stage_native.py --from artifact/comettextel-c-sdk-windows-x64
python -m pip install build
python -m build --wheel --outdir dist sdk/python
python sdk/python/scripts/stage_native.py --clean
pip install dist/comettextel-*.whl

Editable / source installs without a staged _native still need COMETTEXTEL_LIB or a nearby build.

PDU example

cd sdk\python
python examples\pdu_example.py
python examples\pdu_example.py 886912345678 "Hello" 886932000000
python examples\pdu_example.py 886912345678 "測試中文簡訊" 886932000000

Modem example

python examples\modem_example.py list COM3
python examples\modem_example.py send COM3 886932000000 886912345678 "Hello"
python examples\modem_example.py delete COM3 1

list rejoins complete concatenated SMS sets (concat_seq == 0 / Message.is_reassembled_concat).

Tests

cd sdk\python
pip install pytest
pytest -q

API sketch

from comettextel import DCS_UCS2, GsmModem, decode, encode_submit_segments

parts = encode_submit_segments("886912345678", "Hello", "886932000000", DCS_UCS2)
msg = decode(parts[0])

with GsmModem() as modem:
    modem.open("COM3", 115200)
    modem.send("886912345678", "Hello from Python", smsc="886932000000")
    for m in modem.list():
        print(m.index, m.peer_address, m.user_data, m.is_reassembled_concat)

All text at the native boundary is UTF-8. Do not reimplement PDU codecs in Python; if the C ABI changes, update this package only.

GSM 7-bit (DCS_GSM7)

Maps UTF-8 through GSM 03.38 (default alphabet + ESC extension). Examples: []{}\~^|€.
Unsupported glyphs (e.g. Chinese) raise CometTextelError / encode status — use DCS_UCS2.
Extension characters consume two septets; concat auto-split will not break an ESC pair.

from comettextel import DCS_GSM7, decode, decode_status_report, encode_submit

hex_pdu = encode_submit("886912345678", "Cost: 10€ [ok]", "886932000000", DCS_GSM7)
print(decode(hex_pdu).user_data)

Status reports can be decoded separately:

report = decode_status_report(
    "00022A0C91889621436587215070418045232150704180452300"
)
print(report.message_reference, hex(report.tp_status), report.recipient_address)

api_version() reports the native C ABI feature version. A legacy DLL without the version export is treated as version 1; Status Report decoding then raises CometTextelError with Status.UNSUPPORTED while existing APIs remain usable.

Validity Period / Status Report

The default submit APIs omit TP-VP, allowing the SMSC to apply its default validity period. To set a GSM relative TP-VP, pass an octet from 0 to 255; 0 means five minutes. request_status_report=True sets TP-SRR:

hex_pdu = encode_submit(
    "886912345678", "OTP 123456", "886932000000", DCS_GSM7,
    relative_validity_period=0x8F,
    request_status_report=True,
)

The same keyword arguments are available on encode_submit_segments() and GsmModem.send(). After requesting a report, call modem.poll_status_report() (C ABI v3) to drain +CDS URCs. modem.run_at_command("AT+CSQ\\r") (C ABI v3) runs generic AT queries with URC demux during the wait. Older native libraries raise Status.UNSUPPORTED for that method while other APIs remain usable.

See also