blob: c00a924aee90fb9621f24c698e312be29e71e3cb [file] [log] [blame]
liubin281ac462023-07-19 14:22:54 +08001//
2// Created by hitmoon on 15-12-9.
3//
4
5#include <stddef.h>
6#include <stdlib.h>
7#include <stdio.h>
8#include "mbtk_pdu_sms.h"
9#include "mbtk_alphabet.h"
10
11#define SUB_STR_SIZE 512
12char temp[SUB_STR_SIZE];
13
14// some constant
15
16//长短信信息元素参考号
17enum EnumCSMIEI mCSMIEI;
18// 服务中心地址
19char *mSCA;
20// 请求状态报告
21bool mSRR;
22// 拒绝副本
23bool mRD;
24// 短信有效期
25char *mVP;
26// 长短信信息元素消息参考号
27int mCSMMR;
28
29// initialize PDU constants
30void sms_init()
31{
32 mCSMMR = 0;
33 mRD = false;
34 mSRR = false;
35 mSCA = "";
36 mVP = "";
37 mCSMIEI = BIT8MIEI;
38}
39
40
41char *sub_str(const char *str, int start, int size) {
42 memset(temp, '\0', SUB_STR_SIZE);
43 if (size > 0)
44 strncpy(temp, str + start, size);
45 else if (size < 0)
46 strcpy(temp, str + start);
47
48 return temp;
49}
50
51struct SMS_Struct PDUDecoding(const char *data) {
52
53 struct SMS_Struct sms;
54 int end_index;
55 int PDUType;
56 // 短信中心
57 sms.SCA = SCADecoding(data, &end_index);
58
59 // 协议数据单元类型
60 PDUType = strtol(sub_str(data, end_index, 2), NULL, 16);
61 end_index += 2;
62
63 sms.RP = PDUType & (1 << 7) ? true : false; // 应答路径
64 sms.UDHI = PDUType & (1 << 6) ? true : false; // 用户数据头标识
65 sms.SRI = PDUType & (1 << 5) ? true : false; // 状态报告指示
66 sms.MMS = PDUType & (1 << 2) ? false : true; // 更多信息发送
67 sms.MTI = PDUType & 3; // 信息类型指示
68
69 // 发送方SME的地址
70 sms.OA = OADecoding(data, end_index, &end_index);
71
72 // 协议标识
73 sms.PID = strtol(sub_str(data, end_index, 2), NULL, 16);
74 end_index += 2;
75
76 // 数据编码方案
77 int DCSType = strtol(sub_str(data, end_index, 2), NULL, 16);
78 end_index += 2;
79
80 // 文本压缩指示
81 sms.TC = DCSType & (1 << 5);
82 // 编码字符集
83 sms.DCS = (enum EnumDCS) ((DCSType >> 2) & 3);
84
85 if (DCSType & (1 << 4)) {
86 // 信息类型信息 0:立即显示 1:移动设备特定类型 2:SIM特定类型 3:终端设备特定类型
87 sms.MC = DCSType & 3;
88 }
89 else {
90 // 不含信息类型信息
91 sms.MC = -1;
92 }
93 // 服务中心时间戳(BCD编码)
94 sms.SCTS = SCTSDecoding(data, end_index);
95 end_index += 14;
96
97 // 用户数据头
98 if (sms.UDHI) {
99 sms.UDH = UDHDecoding(data, end_index + 2);
100 }
101 else {
102 sms.UDH = NULL;
103 }
104
105 // 用户数据
106 sms.UD = UserDataDecoding(data, end_index, sms.UDHI, sms.DCS);
107
108 return sms;
109}
110
111
112char *SCADecoding(const char *data, int *EndIndex) {
113 int len;
114
115 char *result;
116 char *buf;
117 int i = 0;
118
119 len = strtol(sub_str(data, 0, 2), NULL, 16);
120 if (len == 0) {
121 *EndIndex = 2;
122 return NULL;
123 }
124
125 *EndIndex = (len + 1) * 2;
126
127 result = (char *) malloc(sizeof(char) * len * 2);
128 //wmemset(result, '0', sizeof(char) * (len * 2 + 1));
129
130 buf = result;
131 len *= 2;
132
133 // 服务中心地址类型
134 if (strncmp(data + 2, "91", 2) == 0) {
135 sprintf(buf++, "+");
136 }
137
138 // 服务中心地
139
140 for (i = 4; i < *EndIndex; i += 2) {
141 sprintf(buf++, "%c", data[i + 1]);
142 sprintf(buf++, "%c", data[i]);
143 }
144
145 // 去掉填充的 'F'
146 if (result[strlen(result) - 1] == L'F') {
147 result[strlen(result) - 1] = L'\0';
148 }
149
150 return result;
151}
152
153char *OADecoding(const char *data, int index, int *EndIndex) {
154 int len;
155 char *result, *buf;
156
157 len = strtol(sub_str(data, index, 2), NULL, 16);
158
159 if (len == 0) {
160 *EndIndex = index + 2;
161 return NULL;
162 }
163
164 *EndIndex = index + 4 + len;
165
166 result = (char *) malloc(sizeof(char) * (len + 2));
167 //wmemset(result, 0, sizeof(char) * (len + 1));
168 buf = result;
b.liu9e8584b2024-11-06 19:21:28 +0800169
liubin281ac462023-07-19 14:22:54 +0800170 if (strncmp(data + index + 2, "91", 2) == 0) {
171 sprintf(buf++, "+");
172 }
173
174 // 电话号码
175 int i = 0;
176 for (i = 0; i < len; i += 2) {
177 sprintf(buf++, "%c", data[index + i + 5]);
178 sprintf(buf++, "%c", data[index + i + 4]);
179
180 }
181
182 if (len % 2 != 0) {
183 result[strlen(result) - 1] = '\0';
184 (*EndIndex)++;
185 }
186 return result;
187}
188
189char *SCTSDecoding(const char *data, int index) {
190
191 char *result;
192
193 result = (char *) malloc(sizeof(char) * 32);
194 sprintf(result, "20%02d-%02d-%02d %02d:%02d:%02d",
195 BCDDecoding(data, index, 0), // 年
196 BCDDecoding(data, index + 2, 0), // 月
197 BCDDecoding(data, index + 4, 0), // 日
198 BCDDecoding(data, index + 6, 0), // 时
199 BCDDecoding(data, index + 8, 0), // 分
200 BCDDecoding(data, index + 10, 0) // 秒
201
202 );
203 return result;
204}
205
206int BCDDecoding(const char *data, int index, bool isMSB) {
207
208 int n1, n10;
209
210 n1 = strtol(sub_str(data, index, 1), NULL, 10);
211 n10 = strtol(sub_str(data, index + 1, 1), NULL, 10);
212
213 if (isMSB) {
214 if (n10 >= 8)
215 return -((n10 - 8) * 10 + n1); // 负值
216 else
217 return n10 * 10 + n1;
218 }
219 else {
220 return n10 * 10 + n1;
221 }
222}
223
224struct UDHS *UDHDecoding(const char *data, int index) {
225
226 int len;
227 struct UDHS *result;
228
229 len = strtol(sub_str(data, index, 2), NULL, 16);
230 index += 2;
231 int i = 0;
232
233 result = (struct UDHS *) malloc(sizeof(struct UDHS));
234 result->UDH = (struct PDUUDH *) malloc(sizeof(struct PDUUDH) * len);
235 result->count = 0;
236 memset(result->UDH, 0, sizeof(struct PDUUDH) * len);
237
238 while (i < len) {
239 // 信息元素标识(Information Element Identifier
240 char IEI = strtol(sub_str(data, index, 2), NULL, 16);
241 index += 2;
242 // 信息元素数据长度(Length of Information Element)
243 int IEDL = strtol(sub_str(data, index, 2), NULL, 16);
244 index += 2;
245 // 信息元素数据(Information Element Data)
246 char *IED = (char *) malloc(sizeof(char) * (IEDL + 1));
247 int j = 0;
248 for (j = 0; j < IEDL; j++) {
249 IED[j] = strtol(sub_str(data, index, 2), NULL, 16);
250 index += 2;
251 }
252 result->UDH[result->count].IEI = IEI;
253 result->UDH[result->count].IED = IED;
254 result->count++;
255 i += IEDL + 2;
256 }
257
258 return result;
259}
260
261char *UserDataDecoding(const char *data, int index, bool UDHI, enum EnumDCS dcs) {
262 char *result = NULL;
263 char *buf;
264
265 // 用户数据区长度
266 int UDL = strtol(sub_str(data, index, 2), NULL, 16);
267 index += 2;
268
269 // 跳过用户数据头
270 int UDHL = 0;
271 if (UDHI) {
272 // 用户数据头长度
273 UDHL = strtol(sub_str(data, index, 2), NULL, 16);
274 UDHL++;
275 index += UDHL << 1;
276
277 }
278
279 // 获取用户数据
280 if (dcs == UCS2) {
281 int len = (UDL - UDHL) >> 1;
282 int utf8_len;
283
284 result = (char *) malloc(sizeof(char) * (len * 3));
285 buf = result;
286 u_int32_t code[2];
287
288 int i = 0;
289 for (i = 0; i < len; i++) {
290 code[0] = strtol(sub_str(data, (i << 2) + index, 4), NULL, 16);
291 code[1] = 0;
292 utf32toutf8((wchar_t*)code, (unsigned char*)buf, len * 3, &utf8_len);
293 buf += utf8_len;
294 }
295
296 buf[0] = '\0';
297 return result;
298 }
299 else if (dcs == BIT7) {
300 int Septets = UDL - (UDHL * 8 + 6) / 7; // 7-Bit编码字符数
301
302 int FillBits = (UDHL * 8 + 6) / 7 * 7 - UDHL * 8; // 填充位数
303 return BIT7Decoding(BIT7Unpack(data, index, Septets, FillBits), Septets);
304 }
305 else {// 8Bit编码
306 // 获取数据长度
307 UDL -= UDHL;
308 result = (char *) malloc(sizeof(char) * (UDL + 1));
309 int i = 0;
310 for (i = 0; i < UDL; i++) {
311 result[i] = strtol(sub_str(data, (i << 1) + index, 2), NULL, 16);
312 }
313 return result;
314 }
315
316 return "Error!";
317}
318
319char *BIT7Unpack(const char *data, int index, int Septets, int FillBits) {
320 char *result;
321
322 result = (char *) malloc(sizeof(char) * (Septets + 1));
323 // 每8个7-Bit编码字符存放到7个字节
324 int PackLen = (Septets * 7 + FillBits + 7) / 8;
325 int n = 0;
326 int left = 0;
327
328// printf("Unapck data = %s\n", data + index);
329// printf("Septets = %d\n", Septets);
330// printf("pack len = %d\n", PackLen);
331// printf("fillbits = %d\n", FillBits);
332
333 int i = 0;
334 for (i = 0; i < PackLen; i++) {
335
336 int Order = (i + (7 - FillBits)) % 7;
337 int Value = strtol(sub_str(data, (i << 1) + index, 2), NULL, 16);
338 if (i != 0 || FillBits == 0) {
339 result[n++] = ((Value << Order) + left) & 0x7F;
340 }
341// printf("left = %d, i = %d, order = %d, value = %d\n", left, i, Order, Value);
342// printf("result[%d] = %d\n", n - 1, result[n - 1]);
343 left = Value >> (7 - Order);
344 if (Order == 6) {
345 if (n == Septets)
346 break;
347 result[n++] = left;
348 //printf("result[%d] = %d\n", n - 1, result[n - 1]);
349 left = 0;
350 }
351 }
352
353 return result;
354}
355
356char *BIT7Decoding(char *BIT7Data, unsigned int size)
357{
358 char *result, *buf;
359
360 result = (char *) malloc(sizeof(char) * (size + 1));
361 buf = result;
362
363 int i = 0;
364 for (i = 0; i < size; i++) {
365 u_int16_t key = BIT7Data[i];
366 if (isBIT7Same(key)) {
367 sprintf(buf++, "%c", key);
368 }
369 else if (map_get_value(BIT7ToUCS2, map_size(BIT7ToUCS2), key) >= 0) {
370 u_int16_t value;
371 if (key == 0x1B) { // 转义字符
372 value = map_get_value(BIT7EToUCS2, map_size(BIT7EToUCS2), BIT7Data[i + 1]);
373 if (i < size - 1 && value > 0) {
374 sprintf(buf++, "%c", value);
375 i++;
376 }
377 else {
378 value = map_get_value(BIT7ToUCS2, map_size(BIT7ToUCS2), key);
379 sprintf(buf++, "%c", value);
380 }
381 }
382 else {
383 //printf("go b\n");
384 value = map_get_value(BIT7ToUCS2, map_size(BIT7ToUCS2), key);
385 //printf("value = %u\n", value);
386 sprintf(buf++, "%c", value);
387
388 }
389 }
390 else {// 异常数据
391 sprintf(buf++, "?");
392 }
393
394 }
395 return result;
396
397}
398
399int isBIT7Same(u_int16_t UCS2) {
400 if ((UCS2 >= 0x61 && UCS2 <= 0x7A) ||
401 (UCS2 >= 0x41 && UCS2 <= 0x5A) ||
402 (UCS2 >= 0x25 && UCS2 <= 0x3F) ||
403 (UCS2 >= 0x20 && UCS2 <= 0x23) ||
404 UCS2 == 0x0A || UCS2 == 0x0D) {
405 return 1;
406 }
407 return 0;
408}
409
410struct PDUS *PDUEncoding(char *SCA, char *DA, char *UDC, struct UDHS *udhs) {
411 enum EnumDCS DCS;
412
413 sms_init();
414
415// if (isGSMString(UDC))
416// DCS = BIT7;
417// else
418 DCS = UCS2;
419
420 return PDUDoEncoding(SCA, DA, UDC, udhs, DCS);
421}
422
423struct PDUS *PDUDoEncoding(char *SCA, char *DA, char *UDC, struct UDHS *udhs, enum EnumDCS DCS) {
424 // 短信拆分
425 struct UDS *uds = UDCSplit(UDC, udhs, DCS);
426 struct PDUS *pdus;
427
428 if (uds == NULL)
429 return NULL;
430 pdus = (struct PDUS *) malloc(sizeof(struct PDUS));
431 pdus->count = 0;
432 pdus->PDU = (char **) malloc(sizeof(char *) * uds->total);
433
434 if (uds->total > 1) {
435 // 长短信
436 int CSMMR = mCSMMR;
437 if (++mCSMMR > 0xFFFF)
438 mCSMMR = 0;
439 // 生成短信编码序列
440 int i = 0;
441 for (i = 0; i < uds->total; i++) {
442 // 更新用户数据头
443 struct UDHS *CSMUDH = UpdateUDH(udhs, CSMMR, uds->total, i);
444 pdus->PDU[i] = SoloPDUEncoding(SCA, DA, uds->Data[i], CSMUDH, DCS);
445 pdus->count++;
446 }
447
448 }
449 else { // 单条短信
450 pdus->PDU[0] = SoloPDUEncoding(SCA, DA, uds->Data[0], udhs, DCS);
451 pdus->count = 1;
452 }
453
454 return pdus;
455}
456
457int isGSMString(char *Data) {
458
459 if (Data == NULL || strcmp(Data, "") == 0)
460 return 1;
461
462 if (is_acsii((unsigned char*)Data) == 0) {
463 int len;
b.liu9e8584b2024-11-06 19:21:28 +0800464 len = utf8len((unsigned char *) Data);
liubin281ac462023-07-19 14:22:54 +0800465
466 u_int16_t *code = (u_int16_t *) malloc(sizeof(u_int16_t) * len);
467 utf8toutf16((unsigned char *) Data, code, len, &len);
468
469 while (*code) {
470 if (!(isBIT7Same(*code) || map_get_value(UCS2ToBIT7, map_size(UCS2ToBIT7), *code) >= 0))
471 return 0;
472 code++;
473 }
474
475 return 1;
476 }
477 else
478 return 1;
479
480}
481
482struct UDS *UDCSplit(char *UDC, struct UDHS *udhs, enum EnumDCS DCS) {
483 int UDHL = getUDHL(udhs);
484 struct UDS *result;
485
486 if (DCS == BIT7) {
487 // 7-Bit编码
488 // 计算剩余房间数
489 int room = BIT7UDL - (UDHL * 8 + 6) / 7;
490 if (room < 1) {
491 if (UDC == NULL || strcmp(UDC, "") == 0) {
492 result = (struct UDS *) malloc(sizeof(struct UDS));
493 result->Data = (char **)malloc(sizeof(char *));
494 result->total = 1;
495 result->Data[0] = UDC;
496 return result;
497 }
498 else
499 return NULL;
500 }
501
502 // 不需要拆分
503 if (SeptetsLength(UDC) <= room) {
504 result = (struct UDS *) malloc(sizeof(struct UDS));
505 result->Data = (char **)malloc(sizeof(char *));
506 result->total = 1;
507 result->Data[0] = UDC;
508 return result;
509 }
510 else // 拆分短信
511 {
512 if (UDHL == 0)
513 UDHL++;
514 if (mCSMIEI == BIT8MIEI)
515 UDHL += 5; // 1字节消息参考号
516 else
517 UDHL += 6; // 2字节消息参考号
518 // 更新剩余房间数
519 room = BIT7UDL - (UDHL * 8 + 6) / 7;
520 if (room < 1)
521 return NULL;
522
523 int i = 0;
524 int len = strlen(UDC);
525
526 result = (struct UDS *) malloc(sizeof(struct UDS));
527 result->total = 0;
528 result->Data = (char **) malloc(MAX_SMS_NR * sizeof(char *));
529
530 while (i < len) {
531 int step = SeptetsToChars(UDC, i, room);
532 if (i + step < len) {
533 result->Data[result->total] = (char *) malloc(sizeof(char) * (step + 1));
534 strcpy(result->Data[result->total++], sub_str(UDC, i, step));
535 }
536 else {
537 result->Data[result->total] = (char *) malloc(sizeof(char) * (len - i + 1));
538 strcpy(result->Data[result->total++], sub_str(UDC, i, -1));
539 }
540
541 i += step;
542
543 }
544 return result;
545
546 }
547 }
548 else { // UCS2编码
549 // 计算剩余房间数
550 int room = (BIT8UDL - UDHL) >> 1;
551 if (room < 1) {
552 if (UDC == NULL || strcmp(UDC, "") == 0) {
553 result = (struct UDS *) malloc(sizeof(struct UDS));
554 result->Data = (char **)malloc(sizeof(char *));
555 result->total = 1;
556 result->Data[0] = UDC;
557 return result;
558 }
559 else
560 return NULL;
561 }
b.liu9e8584b2024-11-06 19:21:28 +0800562 if (UDC == NULL || utf8len((unsigned char *)UDC) <= room) {
liubin281ac462023-07-19 14:22:54 +0800563 result = (struct UDS *) malloc(sizeof(struct UDS));
564 result->Data = (char **)malloc(sizeof(char *));
565 result->total = 1;
566 result->Data[0] = UDC;
567 return result;
568 }
569 else // 需要拆分成多条短信
570 {
571 if (UDHL == 0)
572 UDHL++;
573 if (mCSMIEI == BIT8MIEI)
574 UDHL += 5; // 1字节消息参考号
575 else
576 UDHL += 6; // 2字节消息参考号
577
578 // 更新剩余房间数
579 room = (BIT8UDL - UDHL) >> 1;
580 if (room < 1)
581 return NULL;
582
b.liu9e8584b2024-11-06 19:21:28 +0800583 int len = utf8len((unsigned char *)UDC);
liubin281ac462023-07-19 14:22:54 +0800584
585 result = (struct UDS *) malloc(sizeof(struct UDS));
586 result->total = 0;
587 result->Data = (char **) malloc(MAX_SMS_NR * sizeof(char *));
588 int index = 0;
589 int i = 0;
590 for (i = 0; i < len; i += room) {
591 int real_size;
592 if (i + room < len) {
b.liu9e8584b2024-11-06 19:21:28 +0800593 real_size = utf8_get_size((unsigned char *)UDC + index, room);
liubin281ac462023-07-19 14:22:54 +0800594 result->Data[result->total] = (char*)malloc(sizeof(char) * (real_size + 1));
595 strcpy(result->Data[result->total++],sub_str(UDC, index, real_size));
596 }
597 else {
b.liu9e8584b2024-11-06 19:21:28 +0800598 real_size = utf8_get_size((unsigned char *)UDC + index, len - i);
liubin281ac462023-07-19 14:22:54 +0800599 result->Data[result->total] = (char*)malloc(sizeof(char) * (real_size + 1));
600 strcpy(result->Data[result->total++], sub_str(UDC, index, -1));
601 }
602 index += real_size;
603 }
604 return result;
605 }
606
607 }
608}
609
610int getUDHL(struct UDHS *udhs) {
611 if (udhs == NULL)
612 return 0;
613
614 // 加上1字节的用户数据头长度
615 int UDHL = 1;
616 int i = 0;
617 for (i = 0; i < udhs->count; i++) {
618 UDHL += strlen(udhs->UDH[i].IED) + 2;
619 }
620 return UDHL;
621}
622
623int SeptetsLength(char *source) {
624 if (source == NULL || strcmp(source, "") == 0) {
625 return 0;
626 }
627 int len = strlen(source);
628 while (*source) {
629 u_int16_t code = (u_int16_t) *source;
630 if (map_get_value(UCS2ToBIT7, map_size(UCS2ToBIT7), code) > 0xFF) {
631 len++;
632 }
633 source++;
634 }
635 return len;
636}
637
638int SeptetsToChars(char *source, int index, int septets) {
639 if (source == NULL || strcmp(source, "") == 0)
640 return 0;
641 int count = 0;
642 int i;
643
644 for (i = index; i < strlen(source); i++) {
645 u_int16_t code = (u_int16_t) source[i];
646 if (map_get_value(UCS2ToBIT7, map_size(UCS2ToBIT7), code) > 0xFF)
647 count++;
648
649 if (++count >= septets) {
650 if (count == septets)
651 i++;
652 break;
653 }
654 }
655 return i - index;
656}
657
658struct UDHS *UpdateUDH(struct UDHS *udhs, int CSMMR, int total, int index) {
659 struct UDHS *result;
660
661 result = (struct UDHS *) malloc(sizeof(struct UDHS));
662
663 if (udhs == NULL || udhs->count == 0) {
664 result->UDH = (struct PDUUDH *) malloc(sizeof(struct PDUUDH));
665 result->count = 1;
666
667 }
668 else {
669 result->UDH = (struct PDUUDH *) malloc(sizeof(struct PDUUDH) * (udhs->count + 1));
670 result->count = udhs->count + 1;
671 // 复制 UDH
672 memcpy(&result->UDH[1], udhs->UDH, sizeof(struct PDUUDH) * udhs->count);
673 }
674 // 插入第一个位置
675 if (mCSMIEI == BIT8MIEI) {
676 result->UDH[0].IED = (char *) malloc(sizeof(char) * 3);
677 result->UDH[0].count = 3;
678 result->UDH[0].IED[0] = CSMMR & 0xFF;
679 result->UDH[0].IED[1] = total;
680 result->UDH[0].IED[2] = index + 1;
681 result->UDH[0].IEI = 0;
682 }
683 else {
684 result->UDH[0].IED = (char *) malloc(sizeof(char) * 4);
685 result->UDH[0].count = 4;
686 result->UDH[0].IED[0] = (CSMMR >> 8) & 0xFF;
687 result->UDH[0].IED[1] = CSMMR & 0xFF;
688 result->UDH[0].IED[2] = total;
689 result->UDH[0].IED[3] = index + 1;
690 result->UDH[0].IEI = 8;
691 }
692
693 return result;
694}
695
696char *SoloPDUEncoding(char *SCA, char *DA, char *UC, struct UDHS *udhs, enum EnumDCS DCS) {
697 char *result;
698 char *buf, *ret;
liubin281ac462023-07-19 14:22:54 +0800699
700 result = (char *) malloc(sizeof(char) * 400);
701 buf = result;
702
703/* // 短信中心
704 ret = SCAEncoding(SCA);
705 index = strlen(ret);
706 sprintf(buf, "%s", ret);
707 printf("buf:%s\n",buf);
708 buf += index;
709
710*/
711 // 协议数据单元类型
712 if (udhs == NULL || udhs->count == 0) {
713 ret = PDUTypeEncoding(false);
714 sprintf(buf, "%s", ret);
715 buf += strlen(ret);
716 }
717 else {
718 ret = PDUTypeEncoding(true);
719 sprintf(buf, "%s", ret);
720 buf += strlen(ret);
721 }
722 // 消息参考值
723 ret = MREncoding();
724 sprintf(buf, "%s", ret);
725 buf += strlen(ret);
726 // 接收方SME地址
727 ret = DAEncoding(DA);
728 sprintf(buf, "%s", ret);
729 buf += strlen(ret);
730 // 协议标识
731 ret = PIDEncoding();
732 sprintf(buf, "%s", ret);
733 buf += strlen(ret);
734 // 编码方案
735 ret = DCSEncoding(UC, DCS);
736 sprintf(buf, "%s", ret);
737 buf += strlen(ret);
738 // 有效期
739 sprintf(buf, "%s", mVP);
740 buf += strlen(mVP);
741
742 // 用户数据长度及内容
743 ret = UDEncoding(UC, udhs, DCS);
744 sprintf(buf, "%s", ret);
745
746 return result;
747}
748
749char *SCAEncoding(char *SCA) {
750
751 if (SCA == NULL || strcmp(SCA, "") == 0) {
752 // 表示使用SIM卡内部的设置值,该值通过AT+CSCA指令设置
753 return "00";
754 }
755
756 char *result;
757 char *buf;
758 int len;
759 len = strlen(SCA);
760 result = (char *) malloc((len + 5) * sizeof(char));
761 buf = result;
762
763 int index = 0;
764 if (SCA[0] == '+') {
765 // 国际号码
766 sprintf(buf, "%02X", len / 2 + 1);
767 buf += 2;
768 sprintf(buf, "91");
769 buf += 2;
770 index = 1;
771 }
772 else {
773 // 国内号码
774 sprintf(buf, "%02X", len / 2 + 1);
775 buf += 2;
776 sprintf(buf, "81");
777 buf += 2;
778 }
779 // SCA地址编码
780 for (; index < len; index += 2) {
781 if (index == len - 1) {
782 // 补“F”凑成偶数个
783 sprintf(buf++, "F");
784 sprintf(buf++, "%c", SCA[index]);
785
786 }
787 else {
788 sprintf(buf++, "%c", SCA[index + 1]);
789 sprintf(buf++, "%c", SCA[index]);
790 }
791 }
792
793 return result;
794}
795
796char *PDUTypeEncoding(bool UDH) {
797 // 信息类型指示(Message Type Indicator)
798 // 01 SMS-SUBMIT(MS -> SMSC)
799 int PDUType = 0x11; // 508TLC change
800// int PDUType = 0x01;
801 char *result;
802 result = (char *) malloc(3 * sizeof(char));
803
804 // 用户数据头标识(User Data Header Indicator)
805 if (UDH) {
806 PDUType |= 0x40;
807 }
808 // 有效期格式(Validity Period Format)
809 if (strlen(mVP) == 2) {
810 // VP段以整型形式提供(相对的)
811 PDUType |= 0x10;
812 }
813 else if (strlen(mVP) == 14) {
814 // VP段以8位组的一半(semi-octet)形式提供(绝对的)
815 PDUType |= 0x18;
816 }
817
818 // 请求状态报告(Status Report Request)
819 if (mSRR) {
820 // 请求状态报告
821 PDUType |= 0x20;
822 }
823
824 // 拒绝复本(Reject Duplicate)
825 if (mRD) {
826 PDUType |= 0x04;
827 }
828 sprintf(result, "%02X", PDUType);
829 return result;
830}
831
832char *MREncoding() {
833 // 由手机设置
834 return "00";
835}
836
837char *DAEncoding(char *DA) {
838 if (DA == NULL || strcmp(DA, "") == 0) {
839 // 地址长度0,地址类型未知
840 return "0080";
841 }
842 char *result, *buf;
843 int len = strlen(DA);
r.xiaod7048442024-10-17 23:47:30 -0700844 int index = 0;
liubin281ac462023-07-19 14:22:54 +0800845
846 result = (char *) malloc(sizeof(char) * (len + 5));
847 buf = result;
848
849 if (DA[0] == '+') {
850 // 国际号码
851 // 地址长度编码
852 sprintf(buf, "%02X", len - 1);
853 buf += 2;
854 // 地址类型
855 sprintf(buf, "91");
856 buf += 2;
857 index = 1;
858 }
859 else {
860 // 国内号码
861 // 地址长度编码
862 sprintf(buf, "%02X", len);
863 buf += 2;
864 // 地址类型
865 sprintf(buf, "81");
866 buf += 2;
867 }
868
869 for (; index < len; index += 2) {
870 // 号码部分奇偶位对调
871 if (index == len - 1) {
872 sprintf(buf++, "F");
873 sprintf(buf++, "%c", DA[index]);
874 }
875 else {
876 sprintf(buf++, "%c", DA[index + 1]);
877 sprintf(buf++, "%c", DA[index]);
878 }
879 }
880 return result;
881
882}
883
884char *PIDEncoding() {
885 return "00";
886}
887
888char *DCSEncoding(char *UD, enum EnumDCS DCS) {
889 if (DCS == BIT7) {
890 // 7-Bit编码
891 return "00";
892 }
893 else {
894 // UCS2编码
895 return "0800";
896 }
897}
898
899char *UDEncoding(char *UD, struct UDHS *udhs, enum EnumDCS DCS) {
900 int UDHL;
901
902 char *result;
903
904 // 用户数据头编码
905 char *header = UDHEncoding(udhs, &UDHL);
906
907 // 用户数据内容编码
908 int UDCL;
909 char *body;
910
911 body = UDCEncoding(UD, &UDCL, UDHL, DCS);
912
913 // 用户数据区长度
914 int UDL;
915 if (DCS == BIT7) {
916 // 7-Bit编码
917 UDL = (UDHL * 8 + 6) / 7 + UDCL;
918 }
919 else {
920 // UCS2编码或者8-Bit编码
921 UDL = UDHL + UDCL;
922 }
923
924 int len = strlen(header) + strlen(body) + 2;
925 result = (char *) malloc(sizeof(char) * (len + 1));
926 sprintf(result, "%02X%s%s", UDL, header, body);
927
928 return result;
929
930}
931
932char *UDHEncoding(struct UDHS *udhs, int *UDHL) {
933
b.liu9e8584b2024-11-06 19:21:28 +0800934 int i = 0;
liubin281ac462023-07-19 14:22:54 +0800935
936 if (udhs == NULL || udhs->count == 0)
937 return "";
b.liu9e8584b2024-11-06 19:21:28 +0800938
939 *UDHL = 0;
liubin281ac462023-07-19 14:22:54 +0800940 for (i = 0; i < udhs->count; i++) {
941 *UDHL += udhs->UDH[i].count + 2;
942 }
943
944 char *result;
945 char *buf;
946 result = (char *) malloc(sizeof(char) * ((*UDHL + 1) * 2 + 1));
947 buf = result;
948
949 sprintf(buf, "%02X", *UDHL);
950 buf += 2;
b.liu9e8584b2024-11-06 19:21:28 +0800951
liubin281ac462023-07-19 14:22:54 +0800952 for (i = 0; i < udhs->count; i++) {
953 // 信息元素标识1字节
954 sprintf(buf, "%02X", udhs->UDH[i].IEI);
955 buf += 2;
956 // 信息元素长度1字节
957 sprintf(buf, "%02X", udhs->UDH[i].count);
958 buf += 2;
959 // 信息元素数据
960 int j = 0;
961 for (j = 0; j < udhs->UDH[i].count; j++) {
962 sprintf(buf, "%02X", udhs->UDH[i].IED[j]);
963 buf += 2;
964 }
965
966 }
967 // 加上1字节的用户数据头长度
968 (*UDHL)++;
969 return result;
liubin281ac462023-07-19 14:22:54 +0800970}
971
972char *UDCEncoding(char *UDC, int *UDCL, int UDHL, enum EnumDCS DCS) {
973 if (UDC == NULL || strcmp(UDC, "") == 0) {
974 *UDCL = 0;
975 return "";
976 }
977
978 if (DCS == BIT7) {
979 // 7-Bit编码,需要参考用户数据头长度,已保证7-Bit边界对齐
980 return BIT7Pack(BIT7Encoding(UDC, UDCL), UDHL);
981 }
982 else {
983 // UCS2编码
984
985 int len = utf8len((unsigned char*)UDC);
986 int len2;
987 unsigned short *code;
988
989 code = (unsigned short*)malloc(sizeof(unsigned short) * len);
990 utf8toutf16((unsigned char*)UDC, code, len, &len2);
991 *UDCL = len * 2;
992 char *result = (char *) malloc(sizeof(char) * (*UDCL * 2 + 1));
993 char *buf = result;
994
995 int i = 0;
996 for (i = 0; i < len; i++) {
997 sprintf(buf, "%04X", code[i]);
998 buf += 4;
999 }
1000 free(code);
1001 return result;
1002 }
1003}
1004
1005struct ByteArray *BIT7Encoding(char *UDC, int *Septets) {
1006 struct ByteArray *result;
1007
1008 int len = strlen(UDC);
1009
1010 result = (struct ByteArray *) malloc(sizeof(struct ByteArray));
1011 result->len = 0;
1012 result->array = (char *) malloc(sizeof(char) * (len * 2 + 1));
1013 *Septets = 0;
1014
1015 int i = 0;
1016 for (i = 0; i < len; i++) {
1017 u_int16_t code = (u_int16_t) UDC[i];
1018 if (isBIT7Same(code)) {
1019 // 编码不变
1020 result->array[(*Septets)++] = code;
1021 }
1022 else {
1023 u_int16_t value = map_get_value(UCS2ToBIT7, map_size(UCS2ToBIT7), code);
1024 if (value >= 0) {
1025 if (value > 0xFF) {
1026 // 转义序列
1027 result->array[(*Septets)++] = value >> 8;
1028 result->array[(*Septets)++] = value & 0xFF;
1029 }
1030 else {
1031 result->array[(*Septets)++] = value;
1032 }
1033 }
1034 else {
1035 // 未知字符
1036 result->array[(*Septets)++] = (u_int16_t) '?';
1037 }
1038 }
1039 }
1040 // 重新调整大小
1041 result->len = *Septets;
1042
1043 return result;
1044}
1045
1046char *BIT7Pack(struct ByteArray *Bit7Array, int UDHL) {
1047 // 7Bit对齐需要的填充位
1048 int fillBits = (UDHL * 8 + 6) / 7 * 7 - (UDHL * 8);
1049
1050 // 压缩字节数
1051 int len = Bit7Array->len;
1052 int packLen = (len * 7 + fillBits + 7) / 8;
1053 char *result;
1054 char *buf;
1055
1056 result = (char *) malloc(sizeof(char) * (packLen * 2 + 1));
1057 buf = result;
1058
1059 int left = 0;
1060 int i = 0;
1061 for (i = 0; i < len; i++) {
1062 // 每8个字节压缩成7个字节
1063 int32_t Value = Bit7Array->array[i];
1064 int32_t index = (i + 8 - fillBits) % 8;
1065 if (index == 0) {
1066 left = Value;
1067 }
1068 else {
1069 int32_t n = ((Value << (8 - index)) | left) & 0xFF;
1070 sprintf(buf, "%02X", n);
1071 buf += 2;
1072 left = Value >> index;
1073 }
1074 }
1075
1076
1077 if ((len * 7 + fillBits) % 8 != 0) {
1078 // 写入剩余数据
1079 sprintf(buf, "%02X", left);
1080 buf += 2;
1081 }
1082 buf[0] = '\0';
1083 return result;
1084}
1085