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