# Changelog All notable changes to this project are documented here. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] ### Added - **Phase-2 profile generation.** `create_esim_profile` now emits a structured profile package with real 3GPP encodings instead of a loose JSON mock: - `enc_iccid` — EF_ICCID encoding (nibble-swapped BCD, 10-byte, 0xF padded) per 3GPP TS 31.102 §4.2.1. - `enc_imsi` — EF_IMSI encoding (length octet + parity nibble + nibble-swapped BCD) per 3GPP TS 31.102 §4.2.2. - `build_lpa_activation_code` — SGP.22 LPA activation string (`LPA:1$$`) so the profile carries a device-consumable activation reference. - `CHANGELOG.md`. ### Changed - Profile package `type` is now `profile-package-v2`; it embeds the raw credentials plus the encoded EF byte values and the LPA activation code. ### Fixed - `generate_imsi` hardcoded a 10-digit MSIN, producing invalid 16-digit IMSIs for a 3-digit MNC (e.g. MCC 302 / MNC 720). MSIN length is now `15 - len(mcc) - len(mnc)`. - `check_rate_limit` compared timestamps as strings across mismatched formats (SQLite `CURRENT_TIMESTAMP` vs Python `isoformat`), making the rate-limit window unreliable. Both sides are now normalized via SQLite `datetime()`. ### Notes - Full SGP.22 SIMalliance Interoperable Profile (SAIP / ASN.1 UPP) generation via osmocom pySim remains the follow-up step; it needs an SM-DP+ / LPA to be installed onto consumer devices over the air. The current package targets programmable SIMs and core-network sync. ## [0.1.0] — 2026-07-01 ### Added - Initial Phase-1 closed-loop eSIM provisioning stack: Flask API, SQLite subscriber store, credential generator (IMSI/Ki/OPc/ICCID), Open5GS and free5gc core adapters, captive portal, operational scripts, systemd units, network configs, and a test suite.