BlogSMPP mang OTA — Tài liệu tham chiếu đầy đủ
Bố cục bài viết
Trang này
Ngày tạo
18/08/2026
Cập nhật
Lượt xem
26
Đọc
12m
SMPP mang OTA — Tài liệu tham chiếu đầy đủ
Tổng hợp cấu trúc một bản tin SMPP
submit_smmang OTA Command Packet, map đủ 4 tầng: SMPP → SMS TPDU (TP-PID…) → OTA Command Packet → APDU. Kèm ví dụ byte thật, kiểm tra chéo mọi trường độ dài.
0. Bức tranh 4 tầng lồng nhau
┌─ TẦNG 1: SMPP submit_sm (ESME → SMSC, chạy trên TCP/IP) ──────────┐
│ Header 16 byte + Body (source, dest, protocol_id, data_coding…) │
│ ┌─ TẦNG 2: SMS TPDU (SMSC dựng ra, chở qua SS7/MAP) ───────────┐ │
│ │ TP-PID, TP-DCS, TP-UDHI, TP-UD … │ │
│ │ ┌─ TẦNG 3: OTA Command Packet (TS 23.048/31.115) ────────┐ │ │
│ │ │ CPL CHL SPI KIc KID TAR CNTR PCNTR [CC] │ │ │
│ │ │ ┌─ TẦNG 4: APDU (ISO 7816-4) ────────────────────┐ │ │ │
│ │ │ │ SELECT / UPDATE BINARY … (lệnh thật cho SIM) │ │ │ │
│ │ │ └────────────────────────────────────────────────┘ │ │ │
│ │ └───────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────────┘
Nguyên tắc lồng nhau: SMPP là xe tải, SMS/UDH là nhãn “giao cho SIM”, OTA là kiện hàng niêm phong, APDU là món đồ bên trong.
1. VÍ DỤ XUYÊN SUỐT
Kịch bản: hệ thống OTA ghi lại tên nhà mạng hiển thị (file EF_SPN = 6F46)
trên SIM của thuê bao 84981111111. Gói không bảo mật (no-security) cho dễ đọc.
PDU đầy đủ (hex)
0000005900000004000000000000010A0005004F544153657276657200
0101383439383131313131313100407F0000000100F60024
027000001F0D00000000A1B2C3000000000100A0A40000026F46A0D60000050056494554
short_message (hex)
027000001F0D00000000A1B2C3000000000100A0A40000026F46A0D60000050056494554
sm_length= 36 (0x24)command_length= 89
2. Bảng A — TẦNG 1: SMPP PDU (Header + Body)
| Trường | Byte | Giá trị ví dụ | Ý nghĩa |
|---|---|---|---|
| command_length | 4 | 00 00 00 59 | 89 — tổng độ dài, tự tính |
| command_id | 4 | 00 00 00 04 | submit_sm |
| command_status | 4 | 00 00 00 00 | 0 trong request |
| sequence_number | 4 | 00 00 01 0A | 266 — vé ghép với response |
| service_type | C-str | 00 | rỗng |
| source_addr_ton/npi | 2 | 05 00 | 05 = Alphanumeric (brandname) |
| source_addr | C-str | "OTAServer" 00 | nguồn |
| dest_addr_ton/npi | 2 | 01 01 | quốc tế / E.164 |
| destination_addr | C-str | "84981111111" 00 | UE A chứa SIM |
| esm_class | 1 | 40 | bật UDHI → map sang TP-UDHI |
| protocol_id | 1 | 7F | → TP-PID |
| priority_flag | 1 | 00 | thường |
| schedule_delivery_time | C-str | 00 | gửi ngay |
| validity_period | C-str | 00 | mặc định |
| registered_delivery | 1 | 01 | xin DLR/PoR |
| replace_if_present | 1 | 00 | không thay |
| data_coding | 1 | F6 | → TP-DCS |
| sm_default_msg_id | 1 | 00 | không dùng |
| sm_length | 1 | 24 | 36 — độ dài short_message, tự tính |
| short_message | 36 | (bảng C) | UDH + OTA |
3. Bảng B — Map SMPP → SMS TPDU (chỗ TP-PID nằm) ★
SMPP không truyền SMS thô. SMSC lấy trường SMPP dựng thành SMS-DELIVER TPDU,
rồi nhét TPDU vào tham số SM-RP-UI của MAP MT-ForwardSM để chở qua SS7.
| Trường SMPP | Giá trị | → Trường SMS (TS 23.040) | Giá trị | Vai trò |
|---|---|---|---|---|
| protocol_id | 7F | TP-PID | 7F | “SIM Data Download” — dữ liệu cho SIM |
| data_coding | F6 | TP-DCS | F6 | 8-bit + message class 2 = riêng cho SIM |
| esm_class bit6 | 40 | TP-UDHI | bit = 1 | TP-UD mở đầu bằng UDH |
| destination_addr | 8498… | TP-DA | 0B 91 48 89…F1 | Số nhận, semi-octet đảo |
| source_addr | OTAServer | TP-OA | (SMSC dựng) | Số/tên gửi |
| short_message | 027000… | TP-UD | 027000… | UDH + payload |
| sm_length | 24 | TP-UDL | 24 | Độ dài User Data |
Bộ ba “gửi cho SIM, không hiện màn hình”:
TP-PID = 7F+TP-DCS class 2+TP-UDHI = 1. Thiếu một là phone xử lý sai.
Vị trí TP-PID trong MAP MT-ForwardSM
MAP: MT-ForwardSM ← phong bì định tuyến (IMSI, địa chỉ SMSC…)
└─ SM-RP-UI ← tham số chở payload
└─ SMS-DELIVER TPDU ← lá thư
├─ TP-PID = 7F ★
├─ TP-DCS = F6
└─ TP-UD = UDH + OTA
MAP MT-ForwardSM tự nó không có “trường TP-PID”; TP-PID nằm trong TPDU được đóng gói nguyên khối trong SM-RP-UI.
4. Bảng C — TẦNG 2→3: bóc short_message từng byte
02 70 00 | 00 1F | 0D | 00 00 | 00 | 00 | A1 B2 C3 | 00 00 00 00 01 | 00 | A0A40000026F46 | A0D60000050056494554
| Offset | Byte | Tầng | Trường | Ý nghĩa |
|---|---|---|---|---|
| 0 | 02 | SMS/UDH | UDHL | UDH dài 2 byte |
| 1 | 70 | SMS/UDH | IEI | Command Packet (chiều về = 71) |
| 2 | 00 | SMS/UDH | IEDL | không dữ liệu phụ |
| 3–4 | 00 1F | OTA | CPL | 31 — độ dài phần còn lại |
| 5 | 0D | OTA | CHL | 13 — độ dài header bảo mật |
| 6–7 | 00 00 | OTA | SPI | không mã hoá, không ký |
| 8 | 00 | OTA | KIc | chỉ số khoá mã hoá |
| 9 | 00 | OTA | KID | chỉ số khoá chữ ký |
| 10–12 | A1 B2 C3 | OTA | TAR | applet đích trên SIM |
| 13–17 | 00 00 00 00 01 | OTA | CNTR | chống phát lại = 1 |
| 18 | 00 | OTA | PCNTR | 0 byte đệm |
| 19–25 | A0A40000026F46 | APDU | SELECT | bảng E |
| 26–35 | A0D6…56494554 | APDU | UPDATE | bảng E |
Kiểm tra chéo: 3 (UDH) + 2 (CPL) + 31 (CPL khai) = 36 = sm_length ✓ ·
CHL = SPI..PCNTR = 2+1+1+3+5+1 = 13 ✓
5. Bảng D — TẦNG 3: các trường OTA Command Packet (TS 23.048 / 31.115)
| Trường | Độ dài | Bắt buộc? | Ghi chú |
|---|---|---|---|
| CPL | 2 | có | = số byte đứng sau CPL |
| CHL | 1 | có | = SPI đến hết CC |
| SPI | 2 | có | chính sách bảo mật (bảng F) |
| KIc | 1 | có | chỉ số + thuật toán mã hoá |
| KID | 1 | có | chỉ số + thuật toán chữ ký |
| TAR | 3 | có | địa chỉ applet; 000000 = card manager |
| CNTR | 5 | có | chống phát lại |
| PCNTR | 1 | có | số byte padding |
| RC/CC/DS | 0..n | tuỳ SPI | chữ ký; rỗng nếu no-security |
| Secured Data | biến đổi | có | APDU hoặc dữ liệu applet |
6. Bảng E — TẦNG 4: bóc APDU (ISO 7816-4 / TS 51.011)
| APDU | CLA | INS | P1 | P2 | Lc | Data | Nghĩa |
|---|---|---|---|---|---|---|---|
A0 A4 00 00 02 6F46 | A0 GSM | A4 SELECT | 00 | 00 | 02 | 6F46 | Mở file EF_SPN (tên nhà mạng) |
A0 D6 00 00 05 00 56494554 | A0 | D6 UPDATE BINARY | 00 | 00 | 05 | 00+“VIET” | Ghi 5 byte từ đầu file |
Ghi chú CLA: SIM 2G dùng
A0; USIM 3G/4G dùng00.
Vài file EF thường gặp
| Mã | File | Nội dung |
|---|---|---|
6F46 | EF_SPN | Tên nhà mạng hiển thị |
6F07 | EF_IMSI | Số nhận dạng thuê bao |
6F3A | EF_ADN | Danh bạ trên SIM |
6F30 | EF_PLMNsel | Danh sách mạng ưu tiên |
6FAD | EF_AD | Dữ liệu quản trị |
7. Bảng F — Giải mã SPI / KIc / KID khi BẬT bảo mật
| Trường | Bit | Ý nghĩa khi = 1 |
|---|---|---|
| SPI byte 1 | b0–b1 | 01 = có RC, 10 = có CC, 11 = có DS (chữ ký) |
| SPI byte 1 | b2 | có mã hoá |
| SPI byte 1 | b3–b4 | kiểm tra CNTR (chống phát lại) |
| SPI byte 2 | b0 | yêu cầu PoR |
| SPI byte 2 | b1–b2 | PoR có CC/DS |
| KIc | b0–b1 | thuật toán: 01=DES, 10=AES |
| KIc | b2–b3 | chế độ (00=CBC…) |
| KIc | b4–b7 | chỉ số bộ khoá |
| KID | như KIc | dùng cho khoá chữ ký |
Khoá thật (giá trị DES/AES) nạp vào SIM lúc cá thể hoá, chỉ có ở SIM và hệ thống quản lý khoá của nhà mạng — không bao giờ truyền trên mạng.
8. Bảng G — Chuỗi phản hồi
| Bản tin | Chiều | Nội dung | Ý nghĩa |
|---|---|---|---|
| submit_sm_resp | SMSC → ESME | seq 010A, status 0, message_id | SMSC đã nhận, chưa nói gì về SIM |
| PoR (Response Packet) | SIM → OTA | UDH 71, TAR, CNTR, status | Kết quả thật trên SIM |
Mã status PoR hay gặp: 00 thành công · 01 sai CC/RC · 02 sai CNTR ·
06 TAR không tồn tại.
9. Bảng H — Đối chiếu 2 kịch bản OTA
| Ghi file (RFM) | Kích SIM gửi SMS (Warehouse) | |
|---|---|---|
| TAR | 000000 card manager | applet riêng, vd B00010 |
| Secured Data chứa | APDU (A0A4, A0D6) | số UE B + text (dữ liệu applet) |
| SIM làm gì | ghi vào file EF | phát proactive SEND SHORT MESSAGE |
| APDU tầng ME↔SIM | ENVELOPE giao gói | ENVELOPE + FETCH + TERMINAL RESPONSE |
Ví dụ kịch bản Warehouse (gửi “He Thong Binh Thuong” tới UE B 84982222222)
Gói OTA trên dây (lớp 1):
short_message =
02 70 00 UDH: Command Packet
00 2E CPL = 46
0D CHL = 13
00 00 00 00 SPI, KIc, KID
B0 00 10 TAR = applet Warehouse
00 00 00 00 01 CNTR = 1
00 PCNTR
── Secured Data (applet đọc) ──
0B độ dài số UE B = 11
38 34 39 38 32 32 32 32 32 32 32 "84982222222" (ASCII)
48 65 20 54 68 6F 6E 67 … "He Thong Binh Thuong"
Proactive command applet tự dựng (lớp 2):
D0 2C Proactive command, 44 byte
81 03 01 13 00 Command details: type 13 = SEND SHORT MESSAGE
82 02 81 83 Device identities: SIM → Network
8B 21 <SMS-SUBMIT> SMS TPDU tới UE B
01 00 SMS-SUBMIT, TP-MR
0B 91 48 89 22 22 22 F2 TP-DA = 84982222222 (semi-octet đảo)
00 04 14 TP-PID, TP-DCS(8-bit), TP-UDL=20
48 65 20 … "He Thong Binh Thuong"
Luồng APDU tầng ME↔SIM:
1. ME→SIM : A0 C2 00 00 Lc … ENVELOPE (giao OTA vào SIM)
2. SIM→ME : SW = 91 2E (có proactive command 46 byte)
3. ME→SIM : A0 12 00 00 2E FETCH → nhận D0 2C … SEND SHORT MESSAGE
→ điện thoại A phát SMS tới UE B
4. ME→SIM : A0 14 00 00 Lc … TERMINAL RESPONSE (result 83 01 00 = OK)
10. Nguyên tắc mã hoá số điện thoại (TS 23.040 §9.1.2.5)
| Số nằm ở đâu | Quy tắc |
|---|---|
| Trường địa chỉ SMS (TP-DA / TP-OA / SCA, Address TLV, SMS TPDU) | BẮT BUỘC: length(số chữ số) + TON/NPI + semi-octet đảo nibble + đệm F nếu lẻ |
| Secured Data (dữ liệu ứng dụng của applet) | TỰ DO: ASCII / BCD / nhị phân — server và applet tự thống nhất |
Ví dụ 84982222222 (11 số, quốc tế):
0B (11) + 91 (quốc tế/E.164) + đảo 84→48, 98→89, …, 2F→F2
= 0B 91 48 89 22 22 22 F2
Ngoại lệ: TON = alphanumeric (101, vd “OTAServer”) → Address-Value là chuỗi
đóng gói GSM 7-bit, không phải BCD đảo.
11. Ba quy tắc vàng
- Bộ định tuyến “gửi cho SIM” —
protocol_id(→TP-PID) = 7F,data_coding(→TP-DCS) = class 2,esm_class(→TP-UDHI) = bật— nằm ở tầng SMPP/SMS, KHÔNG thuộc gói OTA. - OTA bắt đầu sau UDH (từ byte CPL); và
sm_length,CPL,CHL,command_lengthphải luôn tự nhất quán. - Đảo nibble + đệm F chỉ áp dụng cho trường địa chỉ SMS (TS 23.040); trong Secured Data thì format do applet quy định.
12. protocol_id ↔ TP-PID — quan hệ chi tiết
protocol_id (SMPP) và TP-PID (SMS) là hai tên cho cùng một byte ý nghĩa.
SMPP được thiết kế phản chiếu SMS TPDU nên SMSC dịch gần như một-đổi-một:
| SMPP (SMSC nhận) | SMS-DELIVER TPDU (SMSC gửi qua MAP) | Quan hệ |
|---|---|---|
protocol_id 7F | TP-PID 7F | copy thẳng |
data_coding F6 | TP-DCS F6 | copy thẳng |
| esm_class bit UDHI | TP-UDHI bit | ánh xạ bit |
| short_message | TP-UD | copy thẳng |
| destination_addr | TP-DA | đổi sang semi-octet đảo |
Chiều ngược (MO / PoR): MSC bọc SMS-SUBMIT TPDU vào MO-ForwardSM → SMSC →
deliver_sm, protocol_id lấy lại từ TP-PID.
Tài liệu tổng hợp cho mục đích học tập. Các giá trị timestamp (TP-SCTS) và địa chỉ SMSC trong ví dụ ENVELOPE là minh hoạ; cấu trúc TLV và số byte thì chính xác.