blob: 5825cb63bf819a0c67b47cac87de52f60bd24569 [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;
169
170 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;
464 len = utf8len((unsigned char *) Data);
465
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 }
562 if (UDC == NULL || utf8len(UDC) <= room) {
563 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
583 int len = utf8len(UDC);
584
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) {
593 real_size = utf8_get_size(UDC + index, room);
594 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 {
598 real_size = utf8_get_size(UDC + index, len - i);
599 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;
699 int index;
700
701 result = (char *) malloc(sizeof(char) * 400);
702 buf = result;
703
704/* // 短信中心
705 ret = SCAEncoding(SCA);
706 index = strlen(ret);
707 sprintf(buf, "%s", ret);
708 printf("buf:%s\n",buf);
709 buf += index;
710
711*/
712 // 协议数据单元类型
713 if (udhs == NULL || udhs->count == 0) {
714 ret = PDUTypeEncoding(false);
715 sprintf(buf, "%s", ret);
716 buf += strlen(ret);
717 }
718 else {
719 ret = PDUTypeEncoding(true);
720 sprintf(buf, "%s", ret);
721 buf += strlen(ret);
722 }
723 // 消息参考值
724 ret = MREncoding();
725 sprintf(buf, "%s", ret);
726 buf += strlen(ret);
727 // 接收方SME地址
728 ret = DAEncoding(DA);
729 sprintf(buf, "%s", ret);
730 buf += strlen(ret);
731 // 协议标识
732 ret = PIDEncoding();
733 sprintf(buf, "%s", ret);
734 buf += strlen(ret);
735 // 编码方案
736 ret = DCSEncoding(UC, DCS);
737 sprintf(buf, "%s", ret);
738 buf += strlen(ret);
739 // 有效期
740 sprintf(buf, "%s", mVP);
741 buf += strlen(mVP);
742
743 // 用户数据长度及内容
744 ret = UDEncoding(UC, udhs, DCS);
745 sprintf(buf, "%s", ret);
746
747 return result;
748}
749
750char *SCAEncoding(char *SCA) {
751
752 if (SCA == NULL || strcmp(SCA, "") == 0) {
753 // 表示使用SIM卡内部的设置值,该值通过AT+CSCA指令设置
754 return "00";
755 }
756
757 char *result;
758 char *buf;
759 int len;
760 len = strlen(SCA);
761 result = (char *) malloc((len + 5) * sizeof(char));
762 buf = result;
763
764 int index = 0;
765 if (SCA[0] == '+') {
766 // 国际号码
767 sprintf(buf, "%02X", len / 2 + 1);
768 buf += 2;
769 sprintf(buf, "91");
770 buf += 2;
771 index = 1;
772 }
773 else {
774 // 国内号码
775 sprintf(buf, "%02X", len / 2 + 1);
776 buf += 2;
777 sprintf(buf, "81");
778 buf += 2;
779 }
780 // SCA地址编码
781 for (; index < len; index += 2) {
782 if (index == len - 1) {
783 // 补“F”凑成偶数个
784 sprintf(buf++, "F");
785 sprintf(buf++, "%c", SCA[index]);
786
787 }
788 else {
789 sprintf(buf++, "%c", SCA[index + 1]);
790 sprintf(buf++, "%c", SCA[index]);
791 }
792 }
793
794 return result;
795}
796
797char *PDUTypeEncoding(bool UDH) {
798 // 信息类型指示(Message Type Indicator)
799 // 01 SMS-SUBMIT(MS -> SMSC)
800 int PDUType = 0x11; // 508TLC change
801// int PDUType = 0x01;
802 char *result;
803 result = (char *) malloc(3 * sizeof(char));
804
805 // 用户数据头标识(User Data Header Indicator)
806 if (UDH) {
807 PDUType |= 0x40;
808 }
809 // 有效期格式(Validity Period Format)
810 if (strlen(mVP) == 2) {
811 // VP段以整型形式提供(相对的)
812 PDUType |= 0x10;
813 }
814 else if (strlen(mVP) == 14) {
815 // VP段以8位组的一半(semi-octet)形式提供(绝对的)
816 PDUType |= 0x18;
817 }
818
819 // 请求状态报告(Status Report Request)
820 if (mSRR) {
821 // 请求状态报告
822 PDUType |= 0x20;
823 }
824
825 // 拒绝复本(Reject Duplicate)
826 if (mRD) {
827 PDUType |= 0x04;
828 }
829 sprintf(result, "%02X", PDUType);
830 return result;
831}
832
833char *MREncoding() {
834 // 由手机设置
835 return "00";
836}
837
838char *DAEncoding(char *DA) {
839 if (DA == NULL || strcmp(DA, "") == 0) {
840 // 地址长度0,地址类型未知
841 return "0080";
842 }
843 char *result, *buf;
844 int len = strlen(DA);
845 int index;
846
847 result = (char *) malloc(sizeof(char) * (len + 5));
848 buf = result;
849
850 if (DA[0] == '+') {
851 // 国际号码
852 // 地址长度编码
853 sprintf(buf, "%02X", len - 1);
854 buf += 2;
855 // 地址类型
856 sprintf(buf, "91");
857 buf += 2;
858 index = 1;
859 }
860 else {
861 // 国内号码
862 // 地址长度编码
863 sprintf(buf, "%02X", len);
864 buf += 2;
865 // 地址类型
866 sprintf(buf, "81");
867 buf += 2;
868 }
869
870 for (; index < len; index += 2) {
871 // 号码部分奇偶位对调
872 if (index == len - 1) {
873 sprintf(buf++, "F");
874 sprintf(buf++, "%c", DA[index]);
875 }
876 else {
877 sprintf(buf++, "%c", DA[index + 1]);
878 sprintf(buf++, "%c", DA[index]);
879 }
880 }
881 return result;
882
883}
884
885char *PIDEncoding() {
886 return "00";
887}
888
889char *DCSEncoding(char *UD, enum EnumDCS DCS) {
890 if (DCS == BIT7) {
891 // 7-Bit编码
892 return "00";
893 }
894 else {
895 // UCS2编码
896 return "0800";
897 }
898}
899
900char *UDEncoding(char *UD, struct UDHS *udhs, enum EnumDCS DCS) {
901 int UDHL;
902
903 char *result;
904
905 // 用户数据头编码
906 char *header = UDHEncoding(udhs, &UDHL);
907
908 // 用户数据内容编码
909 int UDCL;
910 char *body;
911
912 body = UDCEncoding(UD, &UDCL, UDHL, DCS);
913
914 // 用户数据区长度
915 int UDL;
916 if (DCS == BIT7) {
917 // 7-Bit编码
918 UDL = (UDHL * 8 + 6) / 7 + UDCL;
919 }
920 else {
921 // UCS2编码或者8-Bit编码
922 UDL = UDHL + UDCL;
923 }
924
925 int len = strlen(header) + strlen(body) + 2;
926 result = (char *) malloc(sizeof(char) * (len + 1));
927 sprintf(result, "%02X%s%s", UDL, header, body);
928
929 return result;
930
931}
932
933char *UDHEncoding(struct UDHS *udhs, int *UDHL) {
934
935 *UDHL = 0;
936
937 if (udhs == NULL || udhs->count == 0)
938 return "";
939 int i = 0;
940 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;
951
952 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;
970
971}
972
973char *UDCEncoding(char *UDC, int *UDCL, int UDHL, enum EnumDCS DCS) {
974 if (UDC == NULL || strcmp(UDC, "") == 0) {
975 *UDCL = 0;
976 return "";
977 }
978
979 if (DCS == BIT7) {
980 // 7-Bit编码,需要参考用户数据头长度,已保证7-Bit边界对齐
981 return BIT7Pack(BIT7Encoding(UDC, UDCL), UDHL);
982 }
983 else {
984 // UCS2编码
985
986 int len = utf8len((unsigned char*)UDC);
987 int len2;
988 unsigned short *code;
989
990 code = (unsigned short*)malloc(sizeof(unsigned short) * len);
991 utf8toutf16((unsigned char*)UDC, code, len, &len2);
992 *UDCL = len * 2;
993 char *result = (char *) malloc(sizeof(char) * (*UDCL * 2 + 1));
994 char *buf = result;
995
996 int i = 0;
997 for (i = 0; i < len; i++) {
998 sprintf(buf, "%04X", code[i]);
999 buf += 4;
1000 }
1001 free(code);
1002 return result;
1003 }
1004}
1005
1006struct ByteArray *BIT7Encoding(char *UDC, int *Septets) {
1007 struct ByteArray *result;
1008
1009 int len = strlen(UDC);
1010
1011 result = (struct ByteArray *) malloc(sizeof(struct ByteArray));
1012 result->len = 0;
1013 result->array = (char *) malloc(sizeof(char) * (len * 2 + 1));
1014 *Septets = 0;
1015
1016 int i = 0;
1017 for (i = 0; i < len; i++) {
1018 u_int16_t code = (u_int16_t) UDC[i];
1019 if (isBIT7Same(code)) {
1020 // 编码不变
1021 result->array[(*Septets)++] = code;
1022 }
1023 else {
1024 u_int16_t value = map_get_value(UCS2ToBIT7, map_size(UCS2ToBIT7), code);
1025 if (value >= 0) {
1026 if (value > 0xFF) {
1027 // 转义序列
1028 result->array[(*Septets)++] = value >> 8;
1029 result->array[(*Septets)++] = value & 0xFF;
1030 }
1031 else {
1032 result->array[(*Septets)++] = value;
1033 }
1034 }
1035 else {
1036 // 未知字符
1037 result->array[(*Septets)++] = (u_int16_t) '?';
1038 }
1039 }
1040 }
1041 // 重新调整大小
1042 result->len = *Septets;
1043
1044 return result;
1045}
1046
1047char *BIT7Pack(struct ByteArray *Bit7Array, int UDHL) {
1048 // 7Bit对齐需要的填充位
1049 int fillBits = (UDHL * 8 + 6) / 7 * 7 - (UDHL * 8);
1050
1051 // 压缩字节数
1052 int len = Bit7Array->len;
1053 int packLen = (len * 7 + fillBits + 7) / 8;
1054 char *result;
1055 char *buf;
1056
1057 result = (char *) malloc(sizeof(char) * (packLen * 2 + 1));
1058 buf = result;
1059
1060 int left = 0;
1061 int i = 0;
1062 for (i = 0; i < len; i++) {
1063 // 每8个字节压缩成7个字节
1064 int32_t Value = Bit7Array->array[i];
1065 int32_t index = (i + 8 - fillBits) % 8;
1066 if (index == 0) {
1067 left = Value;
1068 }
1069 else {
1070 int32_t n = ((Value << (8 - index)) | left) & 0xFF;
1071 sprintf(buf, "%02X", n);
1072 buf += 2;
1073 left = Value >> index;
1074 }
1075 }
1076
1077
1078 if ((len * 7 + fillBits) % 8 != 0) {
1079 // 写入剩余数据
1080 sprintf(buf, "%02X", left);
1081 buf += 2;
1082 }
1083 buf[0] = '\0';
1084 return result;
1085}
1086