blob: f245f5ad736d0abe7c083e27ef31db0b07ce9cde [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>
xy.hef1956462024-12-13 21:30:43 -08008#include <sys/timeb.h>
9#include <sys/time.h>
10#include <time.h>
11#include <arpa/inet.h>
12#include <ctype.h>
liubin281ac462023-07-19 14:22:54 +080013#include "mbtk_pdu_sms.h"
14#include "mbtk_alphabet.h"
r.xiaob439c1f2024-11-30 03:29:06 -080015#include "mbtk_log.h"
liubin281ac462023-07-19 14:22:54 +080016
17#define SUB_STR_SIZE 512
18char temp[SUB_STR_SIZE];
lichengzhang8c043332025-07-30 17:43:23 +080019#define MIN(a, b) ((a) < (b) ? (a) : (b))
liubin281ac462023-07-19 14:22:54 +080020// some constant
21
22//长短信信息元素参考号
23enum EnumCSMIEI mCSMIEI;
24// 服务中心地址
25char *mSCA;
26// 请求状态报告
27bool mSRR;
28// 拒绝副本
29bool mRD;
30// 短信有效期
31char *mVP;
32// 长短信信息元素消息参考号
33int mCSMMR;
34
35// initialize PDU constants
36void sms_init()
37{
38 mCSMMR = 0;
39 mRD = false;
40 mSRR = false;
41 mSCA = "";
42 mVP = "";
43 mCSMIEI = BIT8MIEI;
44}
45
46
47char *sub_str(const char *str, int start, int size) {
48 memset(temp, '\0', SUB_STR_SIZE);
49 if (size > 0)
50 strncpy(temp, str + start, size);
51 else if (size < 0)
52 strcpy(temp, str + start);
53
54 return temp;
55}
56
57struct SMS_Struct PDUDecoding(const char *data) {
58
59 struct SMS_Struct sms;
60 int end_index;
61 int PDUType;
62 // 短信中心
63 sms.SCA = SCADecoding(data, &end_index);
64
65 // 协议数据单元类型
66 PDUType = strtol(sub_str(data, end_index, 2), NULL, 16);
67 end_index += 2;
68
69 sms.RP = PDUType & (1 << 7) ? true : false; // 应答路径
70 sms.UDHI = PDUType & (1 << 6) ? true : false; // 用户数据头标识
71 sms.SRI = PDUType & (1 << 5) ? true : false; // 状态报告指示
72 sms.MMS = PDUType & (1 << 2) ? false : true; // 更多信息发送
73 sms.MTI = PDUType & 3; // 信息类型指示
74
75 // 发送方SME的地址
76 sms.OA = OADecoding(data, end_index, &end_index);
77
78 // 协议标识
79 sms.PID = strtol(sub_str(data, end_index, 2), NULL, 16);
80 end_index += 2;
81
82 // 数据编码方案
83 int DCSType = strtol(sub_str(data, end_index, 2), NULL, 16);
84 end_index += 2;
85
86 // 文本压缩指示
87 sms.TC = DCSType & (1 << 5);
88 // 编码字符集
89 sms.DCS = (enum EnumDCS) ((DCSType >> 2) & 3);
90
91 if (DCSType & (1 << 4)) {
92 // 信息类型信息 0:立即显示 1:移动设备特定类型 2:SIM特定类型 3:终端设备特定类型
93 sms.MC = DCSType & 3;
94 }
95 else {
96 // 不含信息类型信息
97 sms.MC = -1;
98 }
99 // 服务中心时间戳(BCD编码)
100 sms.SCTS = SCTSDecoding(data, end_index);
101 end_index += 14;
102
103 // 用户数据头
104 if (sms.UDHI) {
105 sms.UDH = UDHDecoding(data, end_index + 2);
106 }
107 else {
108 sms.UDH = NULL;
109 }
110
111 // 用户数据
112 sms.UD = UserDataDecoding(data, end_index, sms.UDHI, sms.DCS);
113
114 return sms;
115}
116
117
118char *SCADecoding(const char *data, int *EndIndex) {
119 int len;
120
121 char *result;
122 char *buf;
123 int i = 0;
124
125 len = strtol(sub_str(data, 0, 2), NULL, 16);
126 if (len == 0) {
127 *EndIndex = 2;
128 return NULL;
129 }
130
131 *EndIndex = (len + 1) * 2;
132
133 result = (char *) malloc(sizeof(char) * len * 2);
134 //wmemset(result, '0', sizeof(char) * (len * 2 + 1));
135
136 buf = result;
137 len *= 2;
138
139 // 服务中心地址类型
140 if (strncmp(data + 2, "91", 2) == 0) {
141 sprintf(buf++, "+");
142 }
143
144 // 服务中心地
145
146 for (i = 4; i < *EndIndex; i += 2) {
147 sprintf(buf++, "%c", data[i + 1]);
148 sprintf(buf++, "%c", data[i]);
149 }
150
151 // 去掉填充的 'F'
152 if (result[strlen(result) - 1] == L'F') {
153 result[strlen(result) - 1] = L'\0';
154 }
155
156 return result;
157}
158
159char *OADecoding(const char *data, int index, int *EndIndex) {
160 int len;
161 char *result, *buf;
162
163 len = strtol(sub_str(data, index, 2), NULL, 16);
164
165 if (len == 0) {
166 *EndIndex = index + 2;
167 return NULL;
168 }
169
170 *EndIndex = index + 4 + len;
171
172 result = (char *) malloc(sizeof(char) * (len + 2));
173 //wmemset(result, 0, sizeof(char) * (len + 1));
174 buf = result;
b.liu9e8584b2024-11-06 19:21:28 +0800175
liubin281ac462023-07-19 14:22:54 +0800176 if (strncmp(data + index + 2, "91", 2) == 0) {
177 sprintf(buf++, "+");
178 }
179
180 // 电话号码
181 int i = 0;
182 for (i = 0; i < len; i += 2) {
183 sprintf(buf++, "%c", data[index + i + 5]);
184 sprintf(buf++, "%c", data[index + i + 4]);
185
186 }
187
188 if (len % 2 != 0) {
189 result[strlen(result) - 1] = '\0';
190 (*EndIndex)++;
191 }
192 return result;
193}
194
195char *SCTSDecoding(const char *data, int index) {
196
197 char *result;
198
199 result = (char *) malloc(sizeof(char) * 32);
200 sprintf(result, "20%02d-%02d-%02d %02d:%02d:%02d",
201 BCDDecoding(data, index, 0), // 年
202 BCDDecoding(data, index + 2, 0), // 月
203 BCDDecoding(data, index + 4, 0), // 日
204 BCDDecoding(data, index + 6, 0), // 时
205 BCDDecoding(data, index + 8, 0), // 分
206 BCDDecoding(data, index + 10, 0) // 秒
207
208 );
209 return result;
210}
211
212int BCDDecoding(const char *data, int index, bool isMSB) {
213
214 int n1, n10;
215
216 n1 = strtol(sub_str(data, index, 1), NULL, 10);
217 n10 = strtol(sub_str(data, index + 1, 1), NULL, 10);
218
219 if (isMSB) {
220 if (n10 >= 8)
221 return -((n10 - 8) * 10 + n1); // 负值
222 else
223 return n10 * 10 + n1;
224 }
225 else {
226 return n10 * 10 + n1;
227 }
228}
229
230struct UDHS *UDHDecoding(const char *data, int index) {
231
232 int len;
233 struct UDHS *result;
234
235 len = strtol(sub_str(data, index, 2), NULL, 16);
236 index += 2;
237 int i = 0;
238
239 result = (struct UDHS *) malloc(sizeof(struct UDHS));
240 result->UDH = (struct PDUUDH *) malloc(sizeof(struct PDUUDH) * len);
241 result->count = 0;
242 memset(result->UDH, 0, sizeof(struct PDUUDH) * len);
243
244 while (i < len) {
245 // 信息元素标识(Information Element Identifier
246 char IEI = strtol(sub_str(data, index, 2), NULL, 16);
247 index += 2;
248 // 信息元素数据长度(Length of Information Element)
249 int IEDL = strtol(sub_str(data, index, 2), NULL, 16);
250 index += 2;
251 // 信息元素数据(Information Element Data)
252 char *IED = (char *) malloc(sizeof(char) * (IEDL + 1));
253 int j = 0;
254 for (j = 0; j < IEDL; j++) {
255 IED[j] = strtol(sub_str(data, index, 2), NULL, 16);
256 index += 2;
257 }
258 result->UDH[result->count].IEI = IEI;
259 result->UDH[result->count].IED = IED;
260 result->count++;
261 i += IEDL + 2;
262 }
263
264 return result;
265}
266
267char *UserDataDecoding(const char *data, int index, bool UDHI, enum EnumDCS dcs) {
268 char *result = NULL;
269 char *buf;
270
271 // 用户数据区长度
272 int UDL = strtol(sub_str(data, index, 2), NULL, 16);
273 index += 2;
274
275 // 跳过用户数据头
276 int UDHL = 0;
277 if (UDHI) {
278 // 用户数据头长度
279 UDHL = strtol(sub_str(data, index, 2), NULL, 16);
280 UDHL++;
281 index += UDHL << 1;
282
283 }
284
285 // 获取用户数据
286 if (dcs == UCS2) {
287 int len = (UDL - UDHL) >> 1;
288 int utf8_len;
289
290 result = (char *) malloc(sizeof(char) * (len * 3));
291 buf = result;
292 u_int32_t code[2];
293
294 int i = 0;
295 for (i = 0; i < len; i++) {
296 code[0] = strtol(sub_str(data, (i << 2) + index, 4), NULL, 16);
297 code[1] = 0;
298 utf32toutf8((wchar_t*)code, (unsigned char*)buf, len * 3, &utf8_len);
299 buf += utf8_len;
300 }
301
302 buf[0] = '\0';
303 return result;
304 }
305 else if (dcs == BIT7) {
306 int Septets = UDL - (UDHL * 8 + 6) / 7; // 7-Bit编码字符数
307
308 int FillBits = (UDHL * 8 + 6) / 7 * 7 - UDHL * 8; // 填充位数
309 return BIT7Decoding(BIT7Unpack(data, index, Septets, FillBits), Septets);
310 }
311 else {// 8Bit编码
312 // 获取数据长度
313 UDL -= UDHL;
314 result = (char *) malloc(sizeof(char) * (UDL + 1));
315 int i = 0;
316 for (i = 0; i < UDL; i++) {
317 result[i] = strtol(sub_str(data, (i << 1) + index, 2), NULL, 16);
318 }
319 return result;
320 }
321
322 return "Error!";
323}
324
325char *BIT7Unpack(const char *data, int index, int Septets, int FillBits) {
326 char *result;
327
328 result = (char *) malloc(sizeof(char) * (Septets + 1));
329 // 每8个7-Bit编码字符存放到7个字节
330 int PackLen = (Septets * 7 + FillBits + 7) / 8;
331 int n = 0;
332 int left = 0;
333
334// printf("Unapck data = %s\n", data + index);
335// printf("Septets = %d\n", Septets);
336// printf("pack len = %d\n", PackLen);
337// printf("fillbits = %d\n", FillBits);
338
339 int i = 0;
340 for (i = 0; i < PackLen; i++) {
341
342 int Order = (i + (7 - FillBits)) % 7;
343 int Value = strtol(sub_str(data, (i << 1) + index, 2), NULL, 16);
344 if (i != 0 || FillBits == 0) {
345 result[n++] = ((Value << Order) + left) & 0x7F;
346 }
347// printf("left = %d, i = %d, order = %d, value = %d\n", left, i, Order, Value);
348// printf("result[%d] = %d\n", n - 1, result[n - 1]);
349 left = Value >> (7 - Order);
350 if (Order == 6) {
351 if (n == Septets)
352 break;
353 result[n++] = left;
354 //printf("result[%d] = %d\n", n - 1, result[n - 1]);
355 left = 0;
356 }
357 }
358
359 return result;
360}
361
362char *BIT7Decoding(char *BIT7Data, unsigned int size)
363{
364 char *result, *buf;
365
366 result = (char *) malloc(sizeof(char) * (size + 1));
367 buf = result;
368
369 int i = 0;
370 for (i = 0; i < size; i++) {
371 u_int16_t key = BIT7Data[i];
372 if (isBIT7Same(key)) {
373 sprintf(buf++, "%c", key);
374 }
375 else if (map_get_value(BIT7ToUCS2, map_size(BIT7ToUCS2), key) >= 0) {
376 u_int16_t value;
377 if (key == 0x1B) { // 转义字符
378 value = map_get_value(BIT7EToUCS2, map_size(BIT7EToUCS2), BIT7Data[i + 1]);
379 if (i < size - 1 && value > 0) {
380 sprintf(buf++, "%c", value);
381 i++;
382 }
383 else {
384 value = map_get_value(BIT7ToUCS2, map_size(BIT7ToUCS2), key);
385 sprintf(buf++, "%c", value);
386 }
387 }
388 else {
389 //printf("go b\n");
390 value = map_get_value(BIT7ToUCS2, map_size(BIT7ToUCS2), key);
391 //printf("value = %u\n", value);
392 sprintf(buf++, "%c", value);
393
394 }
395 }
396 else {// 异常数据
397 sprintf(buf++, "?");
398 }
399
400 }
401 return result;
402
403}
404
405int isBIT7Same(u_int16_t UCS2) {
406 if ((UCS2 >= 0x61 && UCS2 <= 0x7A) ||
407 (UCS2 >= 0x41 && UCS2 <= 0x5A) ||
408 (UCS2 >= 0x25 && UCS2 <= 0x3F) ||
409 (UCS2 >= 0x20 && UCS2 <= 0x23) ||
410 UCS2 == 0x0A || UCS2 == 0x0D) {
411 return 1;
412 }
413 return 0;
414}
415
416struct PDUS *PDUEncoding(char *SCA, char *DA, char *UDC, struct UDHS *udhs) {
417 enum EnumDCS DCS;
418
419 sms_init();
420
421// if (isGSMString(UDC))
422// DCS = BIT7;
423// else
424 DCS = UCS2;
425
426 return PDUDoEncoding(SCA, DA, UDC, udhs, DCS);
427}
428
429struct PDUS *PDUDoEncoding(char *SCA, char *DA, char *UDC, struct UDHS *udhs, enum EnumDCS DCS) {
430 // 短信拆分
431 struct UDS *uds = UDCSplit(UDC, udhs, DCS);
432 struct PDUS *pdus;
433
434 if (uds == NULL)
435 return NULL;
436 pdus = (struct PDUS *) malloc(sizeof(struct PDUS));
437 pdus->count = 0;
438 pdus->PDU = (char **) malloc(sizeof(char *) * uds->total);
439
440 if (uds->total > 1) {
441 // 长短信
442 int CSMMR = mCSMMR;
443 if (++mCSMMR > 0xFFFF)
444 mCSMMR = 0;
445 // 生成短信编码序列
446 int i = 0;
447 for (i = 0; i < uds->total; i++) {
448 // 更新用户数据头
449 struct UDHS *CSMUDH = UpdateUDH(udhs, CSMMR, uds->total, i);
450 pdus->PDU[i] = SoloPDUEncoding(SCA, DA, uds->Data[i], CSMUDH, DCS);
451 pdus->count++;
452 }
453
454 }
455 else { // 单条短信
456 pdus->PDU[0] = SoloPDUEncoding(SCA, DA, uds->Data[0], udhs, DCS);
457 pdus->count = 1;
458 }
459
460 return pdus;
461}
462
463int isGSMString(char *Data) {
464
465 if (Data == NULL || strcmp(Data, "") == 0)
466 return 1;
467
468 if (is_acsii((unsigned char*)Data) == 0) {
469 int len;
b.liu9e8584b2024-11-06 19:21:28 +0800470 len = utf8len((unsigned char *) Data);
liubin281ac462023-07-19 14:22:54 +0800471
472 u_int16_t *code = (u_int16_t *) malloc(sizeof(u_int16_t) * len);
473 utf8toutf16((unsigned char *) Data, code, len, &len);
474
475 while (*code) {
476 if (!(isBIT7Same(*code) || map_get_value(UCS2ToBIT7, map_size(UCS2ToBIT7), *code) >= 0))
477 return 0;
478 code++;
479 }
480
481 return 1;
482 }
483 else
484 return 1;
485
486}
487
488struct UDS *UDCSplit(char *UDC, struct UDHS *udhs, enum EnumDCS DCS) {
489 int UDHL = getUDHL(udhs);
490 struct UDS *result;
491
492 if (DCS == BIT7) {
493 // 7-Bit编码
494 // 计算剩余房间数
495 int room = BIT7UDL - (UDHL * 8 + 6) / 7;
496 if (room < 1) {
497 if (UDC == NULL || strcmp(UDC, "") == 0) {
498 result = (struct UDS *) malloc(sizeof(struct UDS));
499 result->Data = (char **)malloc(sizeof(char *));
500 result->total = 1;
501 result->Data[0] = UDC;
502 return result;
503 }
504 else
505 return NULL;
506 }
507
508 // 不需要拆分
509 if (SeptetsLength(UDC) <= room) {
510 result = (struct UDS *) malloc(sizeof(struct UDS));
511 result->Data = (char **)malloc(sizeof(char *));
512 result->total = 1;
513 result->Data[0] = UDC;
514 return result;
515 }
516 else // 拆分短信
517 {
518 if (UDHL == 0)
519 UDHL++;
520 if (mCSMIEI == BIT8MIEI)
521 UDHL += 5; // 1字节消息参考号
522 else
523 UDHL += 6; // 2字节消息参考号
524 // 更新剩余房间数
525 room = BIT7UDL - (UDHL * 8 + 6) / 7;
526 if (room < 1)
527 return NULL;
528
529 int i = 0;
530 int len = strlen(UDC);
531
532 result = (struct UDS *) malloc(sizeof(struct UDS));
533 result->total = 0;
534 result->Data = (char **) malloc(MAX_SMS_NR * sizeof(char *));
535
536 while (i < len) {
537 int step = SeptetsToChars(UDC, i, room);
538 if (i + step < len) {
539 result->Data[result->total] = (char *) malloc(sizeof(char) * (step + 1));
540 strcpy(result->Data[result->total++], sub_str(UDC, i, step));
541 }
542 else {
543 result->Data[result->total] = (char *) malloc(sizeof(char) * (len - i + 1));
544 strcpy(result->Data[result->total++], sub_str(UDC, i, -1));
545 }
546
547 i += step;
548
549 }
550 return result;
551
552 }
553 }
554 else { // UCS2编码
555 // 计算剩余房间数
556 int room = (BIT8UDL - UDHL) >> 1;
557 if (room < 1) {
558 if (UDC == NULL || strcmp(UDC, "") == 0) {
559 result = (struct UDS *) malloc(sizeof(struct UDS));
560 result->Data = (char **)malloc(sizeof(char *));
561 result->total = 1;
562 result->Data[0] = UDC;
563 return result;
564 }
565 else
566 return NULL;
567 }
b.liu9e8584b2024-11-06 19:21:28 +0800568 if (UDC == NULL || utf8len((unsigned char *)UDC) <= room) {
liubin281ac462023-07-19 14:22:54 +0800569 result = (struct UDS *) malloc(sizeof(struct UDS));
570 result->Data = (char **)malloc(sizeof(char *));
571 result->total = 1;
572 result->Data[0] = UDC;
573 return result;
574 }
575 else // 需要拆分成多条短信
576 {
577 if (UDHL == 0)
578 UDHL++;
579 if (mCSMIEI == BIT8MIEI)
580 UDHL += 5; // 1字节消息参考号
581 else
582 UDHL += 6; // 2字节消息参考号
583
584 // 更新剩余房间数
585 room = (BIT8UDL - UDHL) >> 1;
586 if (room < 1)
587 return NULL;
588
b.liu9e8584b2024-11-06 19:21:28 +0800589 int len = utf8len((unsigned char *)UDC);
liubin281ac462023-07-19 14:22:54 +0800590
591 result = (struct UDS *) malloc(sizeof(struct UDS));
592 result->total = 0;
593 result->Data = (char **) malloc(MAX_SMS_NR * sizeof(char *));
594 int index = 0;
595 int i = 0;
596 for (i = 0; i < len; i += room) {
597 int real_size;
598 if (i + room < len) {
b.liu9e8584b2024-11-06 19:21:28 +0800599 real_size = utf8_get_size((unsigned char *)UDC + index, room);
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, real_size));
602 }
603 else {
b.liu9e8584b2024-11-06 19:21:28 +0800604 real_size = utf8_get_size((unsigned char *)UDC + index, len - i);
liubin281ac462023-07-19 14:22:54 +0800605 result->Data[result->total] = (char*)malloc(sizeof(char) * (real_size + 1));
606 strcpy(result->Data[result->total++], sub_str(UDC, index, -1));
607 }
608 index += real_size;
609 }
610 return result;
611 }
612
613 }
614}
615
616int getUDHL(struct UDHS *udhs) {
r.xiaob439c1f2024-11-30 03:29:06 -0800617 //在编码处添加用户数据头长度
618 //if (udhs == NULL)
liubin281ac462023-07-19 14:22:54 +0800619 return 0;
620
621 // 加上1字节的用户数据头长度
622 int UDHL = 1;
623 int i = 0;
624 for (i = 0; i < udhs->count; i++) {
625 UDHL += strlen(udhs->UDH[i].IED) + 2;
626 }
627 return UDHL;
628}
629
630int SeptetsLength(char *source) {
631 if (source == NULL || strcmp(source, "") == 0) {
632 return 0;
633 }
634 int len = strlen(source);
635 while (*source) {
636 u_int16_t code = (u_int16_t) *source;
637 if (map_get_value(UCS2ToBIT7, map_size(UCS2ToBIT7), code) > 0xFF) {
638 len++;
639 }
640 source++;
641 }
642 return len;
643}
644
645int SeptetsToChars(char *source, int index, int septets) {
646 if (source == NULL || strcmp(source, "") == 0)
647 return 0;
648 int count = 0;
649 int i;
650
651 for (i = index; i < strlen(source); i++) {
652 u_int16_t code = (u_int16_t) source[i];
653 if (map_get_value(UCS2ToBIT7, map_size(UCS2ToBIT7), code) > 0xFF)
654 count++;
655
656 if (++count >= septets) {
657 if (count == septets)
658 i++;
659 break;
660 }
661 }
662 return i - index;
663}
664
665struct UDHS *UpdateUDH(struct UDHS *udhs, int CSMMR, int total, int index) {
666 struct UDHS *result;
667
668 result = (struct UDHS *) malloc(sizeof(struct UDHS));
669
670 if (udhs == NULL || udhs->count == 0) {
671 result->UDH = (struct PDUUDH *) malloc(sizeof(struct PDUUDH));
672 result->count = 1;
673
674 }
675 else {
676 result->UDH = (struct PDUUDH *) malloc(sizeof(struct PDUUDH) * (udhs->count + 1));
677 result->count = udhs->count + 1;
678 // 复制 UDH
679 memcpy(&result->UDH[1], udhs->UDH, sizeof(struct PDUUDH) * udhs->count);
680 }
681 // 插入第一个位置
682 if (mCSMIEI == BIT8MIEI) {
683 result->UDH[0].IED = (char *) malloc(sizeof(char) * 3);
684 result->UDH[0].count = 3;
685 result->UDH[0].IED[0] = CSMMR & 0xFF;
686 result->UDH[0].IED[1] = total;
687 result->UDH[0].IED[2] = index + 1;
688 result->UDH[0].IEI = 0;
689 }
690 else {
691 result->UDH[0].IED = (char *) malloc(sizeof(char) * 4);
692 result->UDH[0].count = 4;
693 result->UDH[0].IED[0] = (CSMMR >> 8) & 0xFF;
694 result->UDH[0].IED[1] = CSMMR & 0xFF;
695 result->UDH[0].IED[2] = total;
696 result->UDH[0].IED[3] = index + 1;
697 result->UDH[0].IEI = 8;
698 }
699
700 return result;
701}
702
703char *SoloPDUEncoding(char *SCA, char *DA, char *UC, struct UDHS *udhs, enum EnumDCS DCS) {
704 char *result;
705 char *buf, *ret;
liubin281ac462023-07-19 14:22:54 +0800706
707 result = (char *) malloc(sizeof(char) * 400);
708 buf = result;
709
710/* // 短信中心
711 ret = SCAEncoding(SCA);
712 index = strlen(ret);
713 sprintf(buf, "%s", ret);
714 printf("buf:%s\n",buf);
715 buf += index;
716
717*/
718 // 协议数据单元类型
719 if (udhs == NULL || udhs->count == 0) {
720 ret = PDUTypeEncoding(false);
721 sprintf(buf, "%s", ret);
722 buf += strlen(ret);
723 }
724 else {
725 ret = PDUTypeEncoding(true);
726 sprintf(buf, "%s", ret);
727 buf += strlen(ret);
728 }
729 // 消息参考值
730 ret = MREncoding();
731 sprintf(buf, "%s", ret);
732 buf += strlen(ret);
733 // 接收方SME地址
734 ret = DAEncoding(DA);
735 sprintf(buf, "%s", ret);
736 buf += strlen(ret);
737 // 协议标识
738 ret = PIDEncoding();
739 sprintf(buf, "%s", ret);
740 buf += strlen(ret);
741 // 编码方案
742 ret = DCSEncoding(UC, DCS);
743 sprintf(buf, "%s", ret);
744 buf += strlen(ret);
745 // 有效期
746 sprintf(buf, "%s", mVP);
747 buf += strlen(mVP);
748
749 // 用户数据长度及内容
750 ret = UDEncoding(UC, udhs, DCS);
751 sprintf(buf, "%s", ret);
752
753 return result;
754}
755
756char *SCAEncoding(char *SCA) {
757
758 if (SCA == NULL || strcmp(SCA, "") == 0) {
759 // 表示使用SIM卡内部的设置值,该值通过AT+CSCA指令设置
760 return "00";
761 }
762
763 char *result;
764 char *buf;
765 int len;
766 len = strlen(SCA);
767 result = (char *) malloc((len + 5) * sizeof(char));
768 buf = result;
769
770 int index = 0;
771 if (SCA[0] == '+') {
772 // 国际号码
773 sprintf(buf, "%02X", len / 2 + 1);
774 buf += 2;
775 sprintf(buf, "91");
776 buf += 2;
777 index = 1;
778 }
779 else {
780 // 国内号码
781 sprintf(buf, "%02X", len / 2 + 1);
782 buf += 2;
783 sprintf(buf, "81");
784 buf += 2;
785 }
786 // SCA地址编码
787 for (; index < len; index += 2) {
788 if (index == len - 1) {
789 // 补“F”凑成偶数个
790 sprintf(buf++, "F");
791 sprintf(buf++, "%c", SCA[index]);
792
793 }
794 else {
795 sprintf(buf++, "%c", SCA[index + 1]);
796 sprintf(buf++, "%c", SCA[index]);
797 }
798 }
799
800 return result;
801}
802
803char *PDUTypeEncoding(bool UDH) {
804 // 信息类型指示(Message Type Indicator)
805 // 01 SMS-SUBMIT(MS -> SMSC)
806 int PDUType = 0x11; // 508TLC change
807// int PDUType = 0x01;
808 char *result;
809 result = (char *) malloc(3 * sizeof(char));
810
811 // 用户数据头标识(User Data Header Indicator)
812 if (UDH) {
813 PDUType |= 0x40;
814 }
815 // 有效期格式(Validity Period Format)
816 if (strlen(mVP) == 2) {
817 // VP段以整型形式提供(相对的)
818 PDUType |= 0x10;
819 }
820 else if (strlen(mVP) == 14) {
821 // VP段以8位组的一半(semi-octet)形式提供(绝对的)
822 PDUType |= 0x18;
823 }
824
825 // 请求状态报告(Status Report Request)
826 if (mSRR) {
827 // 请求状态报告
828 PDUType |= 0x20;
829 }
830
831 // 拒绝复本(Reject Duplicate)
832 if (mRD) {
833 PDUType |= 0x04;
834 }
835 sprintf(result, "%02X", PDUType);
836 return result;
837}
838
839char *MREncoding() {
840 // 由手机设置
841 return "00";
842}
843
844char *DAEncoding(char *DA) {
845 if (DA == NULL || strcmp(DA, "") == 0) {
846 // 地址长度0,地址类型未知
847 return "0080";
848 }
849 char *result, *buf;
850 int len = strlen(DA);
r.xiaod7048442024-10-17 23:47:30 -0700851 int index = 0;
liubin281ac462023-07-19 14:22:54 +0800852
853 result = (char *) malloc(sizeof(char) * (len + 5));
854 buf = result;
855
856 if (DA[0] == '+') {
857 // 国际号码
858 // 地址长度编码
859 sprintf(buf, "%02X", len - 1);
860 buf += 2;
861 // 地址类型
862 sprintf(buf, "91");
863 buf += 2;
864 index = 1;
865 }
866 else {
867 // 国内号码
868 // 地址长度编码
869 sprintf(buf, "%02X", len);
870 buf += 2;
871 // 地址类型
872 sprintf(buf, "81");
873 buf += 2;
874 }
875
876 for (; index < len; index += 2) {
877 // 号码部分奇偶位对调
878 if (index == len - 1) {
879 sprintf(buf++, "F");
880 sprintf(buf++, "%c", DA[index]);
881 }
882 else {
883 sprintf(buf++, "%c", DA[index + 1]);
884 sprintf(buf++, "%c", DA[index]);
885 }
886 }
887 return result;
888
889}
890
891char *PIDEncoding() {
892 return "00";
893}
894
895char *DCSEncoding(char *UD, enum EnumDCS DCS) {
896 if (DCS == BIT7) {
897 // 7-Bit编码
898 return "00";
899 }
900 else {
901 // UCS2编码
902 return "0800";
903 }
904}
905
906char *UDEncoding(char *UD, struct UDHS *udhs, enum EnumDCS DCS) {
r.xiao60b6eb82024-11-13 00:24:46 -0800907 int UDHL = 0;
liubin281ac462023-07-19 14:22:54 +0800908
909 char *result;
910
911 // 用户数据头编码
912 char *header = UDHEncoding(udhs, &UDHL);
913
914 // 用户数据内容编码
915 int UDCL;
916 char *body;
917
918 body = UDCEncoding(UD, &UDCL, UDHL, DCS);
919
920 // 用户数据区长度
r.xiao60b6eb82024-11-13 00:24:46 -0800921 int UDL = 0;
liubin281ac462023-07-19 14:22:54 +0800922 if (DCS == BIT7) {
923 // 7-Bit编码
924 UDL = (UDHL * 8 + 6) / 7 + UDCL;
925 }
926 else {
927 // UCS2编码或者8-Bit编码
928 UDL = UDHL + UDCL;
929 }
930
931 int len = strlen(header) + strlen(body) + 2;
932 result = (char *) malloc(sizeof(char) * (len + 1));
933 sprintf(result, "%02X%s%s", UDL, header, body);
934
935 return result;
936
937}
938
939char *UDHEncoding(struct UDHS *udhs, int *UDHL) {
940
b.liu9e8584b2024-11-06 19:21:28 +0800941 int i = 0;
liubin281ac462023-07-19 14:22:54 +0800942
943 if (udhs == NULL || udhs->count == 0)
944 return "";
r.xiaob439c1f2024-11-30 03:29:06 -0800945#if 1
946 *UDHL = 5;
947#else
b.liu9e8584b2024-11-06 19:21:28 +0800948 *UDHL = 0;
liubin281ac462023-07-19 14:22:54 +0800949 for (i = 0; i < udhs->count; i++) {
950 *UDHL += udhs->UDH[i].count + 2;
951 }
r.xiaob439c1f2024-11-30 03:29:06 -0800952#endif
liubin281ac462023-07-19 14:22:54 +0800953 char *result;
954 char *buf;
955 result = (char *) malloc(sizeof(char) * ((*UDHL + 1) * 2 + 1));
956 buf = result;
957
958 sprintf(buf, "%02X", *UDHL);
959 buf += 2;
b.liu9e8584b2024-11-06 19:21:28 +0800960
liubin281ac462023-07-19 14:22:54 +0800961 for (i = 0; i < udhs->count; i++) {
r.xiaob439c1f2024-11-30 03:29:06 -0800962 if (i == 0)
963 {
964 // 信息元素标识1字节
965 sprintf(buf, "%02X", udhs->UDH[i].IEI);
966 buf += 2;
967 // 信息元素长度1字节
968 sprintf(buf, "%02X", udhs->UDH[i].count);
969 buf += 2;
970 }
liubin281ac462023-07-19 14:22:54 +0800971 // 信息元素数据
972 int j = 0;
973 for (j = 0; j < udhs->UDH[i].count; j++) {
974 sprintf(buf, "%02X", udhs->UDH[i].IED[j]);
975 buf += 2;
976 }
977
978 }
979 // 加上1字节的用户数据头长度
980 (*UDHL)++;
981 return result;
liubin281ac462023-07-19 14:22:54 +0800982}
983
984char *UDCEncoding(char *UDC, int *UDCL, int UDHL, enum EnumDCS DCS) {
985 if (UDC == NULL || strcmp(UDC, "") == 0) {
986 *UDCL = 0;
987 return "";
988 }
989
990 if (DCS == BIT7) {
991 // 7-Bit编码,需要参考用户数据头长度,已保证7-Bit边界对齐
992 return BIT7Pack(BIT7Encoding(UDC, UDCL), UDHL);
993 }
994 else {
995 // UCS2编码
996
997 int len = utf8len((unsigned char*)UDC);
998 int len2;
999 unsigned short *code;
1000
1001 code = (unsigned short*)malloc(sizeof(unsigned short) * len);
1002 utf8toutf16((unsigned char*)UDC, code, len, &len2);
1003 *UDCL = len * 2;
1004 char *result = (char *) malloc(sizeof(char) * (*UDCL * 2 + 1));
1005 char *buf = result;
1006
1007 int i = 0;
1008 for (i = 0; i < len; i++) {
1009 sprintf(buf, "%04X", code[i]);
1010 buf += 4;
1011 }
1012 free(code);
1013 return result;
1014 }
1015}
1016
1017struct ByteArray *BIT7Encoding(char *UDC, int *Septets) {
1018 struct ByteArray *result;
1019
1020 int len = strlen(UDC);
1021
1022 result = (struct ByteArray *) malloc(sizeof(struct ByteArray));
1023 result->len = 0;
1024 result->array = (char *) malloc(sizeof(char) * (len * 2 + 1));
1025 *Septets = 0;
1026
1027 int i = 0;
1028 for (i = 0; i < len; i++) {
1029 u_int16_t code = (u_int16_t) UDC[i];
1030 if (isBIT7Same(code)) {
1031 // 编码不变
1032 result->array[(*Septets)++] = code;
1033 }
1034 else {
1035 u_int16_t value = map_get_value(UCS2ToBIT7, map_size(UCS2ToBIT7), code);
1036 if (value >= 0) {
1037 if (value > 0xFF) {
1038 // 转义序列
1039 result->array[(*Septets)++] = value >> 8;
1040 result->array[(*Septets)++] = value & 0xFF;
1041 }
1042 else {
1043 result->array[(*Septets)++] = value;
1044 }
1045 }
1046 else {
1047 // 未知字符
1048 result->array[(*Septets)++] = (u_int16_t) '?';
1049 }
1050 }
1051 }
1052 // 重新调整大小
1053 result->len = *Septets;
1054
1055 return result;
1056}
1057
1058char *BIT7Pack(struct ByteArray *Bit7Array, int UDHL) {
1059 // 7Bit对齐需要的填充位
1060 int fillBits = (UDHL * 8 + 6) / 7 * 7 - (UDHL * 8);
1061
1062 // 压缩字节数
1063 int len = Bit7Array->len;
1064 int packLen = (len * 7 + fillBits + 7) / 8;
1065 char *result;
1066 char *buf;
1067
1068 result = (char *) malloc(sizeof(char) * (packLen * 2 + 1));
1069 buf = result;
1070
1071 int left = 0;
1072 int i = 0;
1073 for (i = 0; i < len; i++) {
1074 // 每8个字节压缩成7个字节
1075 int32_t Value = Bit7Array->array[i];
1076 int32_t index = (i + 8 - fillBits) % 8;
1077 if (index == 0) {
1078 left = Value;
1079 }
1080 else {
1081 int32_t n = ((Value << (8 - index)) | left) & 0xFF;
1082 sprintf(buf, "%02X", n);
1083 buf += 2;
1084 left = Value >> index;
1085 }
1086 }
1087
1088
1089 if ((len * 7 + fillBits) % 8 != 0) {
1090 // 写入剩余数据
1091 sprintf(buf, "%02X", left);
1092 buf += 2;
1093 }
1094 buf[0] = '\0';
1095 return result;
1096}
1097
xy.hef1956462024-12-13 21:30:43 -08001098
1099
1100
1101
1102
1103
1104
1105
xy.he0b3a8cf2024-12-13 23:47:25 -08001106#define NOP ('_')
xy.hef1956462024-12-13 21:30:43 -08001107
xy.he0b3a8cf2024-12-13 23:47:25 -08001108static kal_uint8 latin1_to_gsm_table[] =
1109{
1110 //0x00 -, -, -, -, -, -, -, -,
1111 NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
1112 //0x08 -, -, LF, -, -, CR, -, -,
1113 NOP, NOP, 10, NOP, NOP, 13, NOP, NOP,
1114 //0x10 -, -, -, -, -, -, -, -,
1115 NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
1116 //0x18 -, -, -, -, -, -, -, -,
1117 NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
1118 //0x20 ' ', '!', '"', '#', -, '%', '&', ''',
1119 ' ', '!', '"', '#', 0x2, '%', '&', '\'',
1120 //0x28 '(', ')', '*', '+', ',', '-', '.', '/',
1121 '(', ')', '*', '+', ',', '-', '.', '/',
1122 //0x30 '0', '1', '2', '3', '4', '5', '6', '7',
1123 '0', '1', '2', '3', '4', '5', '6', '7',
1124 //0x38 '8', '9', ':', ';', '<', '=', '>', '?',
1125 '8', '9', ':', ';', '<', '=', '>', '?',
1126 //0x40 -, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
1127 0x0, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
1128 //0x48 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
1129 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
1130 //0x50 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
1131 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
1132 //0x58 'X', 'Y', 'Z', -, -, -, -, -,
1133 'X', 'Y', 'Z', NOP, NOP, NOP, NOP,0x11,
1134 //0x60 -, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
1135 NOP, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
1136 //0x68 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
1137 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
1138 //0x70 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
1139 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
1140 //0x78 'x', 'y', 'z', -, -, -, -, -,
1141 'x', 'y', 'z', NOP, NOP, NOP, NOP, NOP,
1142 //0x80 -, -, -, -, -, -, -, -,
1143 NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
1144 //0x88 -, -, -, -, -, -, -, -,
1145 NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
1146 //0x90 -, -, -, -, -, -, -, -,
1147 NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
1148 //0x98 -, -, -, -, -, -, -, -,
1149 NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
1150 //0xA0 -, -, -, -, -, -, -, -,
1151 NOP, 0x40,NOP, 0x1, 0x24,0x3, NOP,0x5F,
1152 //0xA8 -, -, -, -, -, -, -, -,
1153 NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
1154 //0xB0 -, -, -, -, -, -, -, -,
1155 NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP,
1156 //0xB8 -, -, -, -, -, -, -, -,
1157 NOP, NOP, NOP, NOP, NOP, NOP, NOP,0x60,
1158 //0xC0 'A', 'A', 'A', 'A', -, -, -, -,
1159 'A', 'A', 'A', 'A', 0x5B,0xE, 0x1C,0x9,
1160 //0xC8 'E', -, 'E', 'E', 'I', 'I', 'I', 'I',
1161 'E',0x1F, 'E', 'E', 'I', 'I', 'I', 'I',
1162 //0xD0 -, -, 'O', 'O', 'O', 'O', -, -,
1163 NOP,0x5D, 'O', 'O', 'O', 'O',0x5C, NOP,
1164 //0xD8 -, 'U', 'U', 'U', -, -, 'Y', -,
1165 0x0B,'U', 'U', 'U',0x5E, 'Y', NOP,0x1E,
1166 //0xE0 -, 'a', 'a', 'a', -, -, -, -,
1167 0x7F,'a', 'a', 'a',0x7B, 0xF,0x1D, 0x9,
1168 //0xE8 -, -, 'e', 'e', -, 'i', 'i', 'i',
1169 0x4, 0x5, 'e', 'e', 0x7, 'i', 'i', 'i',
1170 //0xF0 -, -, -, 'o', 'o', 'o', -, -,
1171 NOP,0x7D, 0x8, 'o', 'o', 'o',0x7C, NOP,
1172 //0xF8 -, -, 'u', 'u', -, 'y', -, 'y',
1173 0xC, 0x6, 'u', 'u',0x7E, 'y', NOP, 'y'
1174};
xy.hef1956462024-12-13 21:30:43 -08001175
xy.he0b3a8cf2024-12-13 23:47:25 -08001176static Latin1_to_Gsm_ExTable latin1_to_gsm_tableEx[]=
1177{
1178 {'^', 0x14,},
1179 {'{', 0x28,},
1180 {'}', 0x29,},
1181 {'\\',0x2f,},
1182 {'[', 0x3C,},
1183 {'~', 0x3d,},
1184 {']', 0x3e,},
1185 {'|', 0x40,},
1186 {0,0x00,},
1187};
xy.hef1956462024-12-13 21:30:43 -08001188
xy.he0b3a8cf2024-12-13 23:47:25 -08001189static kal_uint8 gsm_to_latin1_table[] =
1190{
1191 //0x00 '@', -, '$', -, -, -, -, -,
1192 '@', 163, '$', 165, 232, 233, 249, 236,
1193 //0x08 -, -, LF, -, -, CR, -, -,
1194 242, 199, 10, 216, 248, 13, 197, 229,
1195 //0x10 -, '_', -, -, -, -, -, -,
1196 NOP, '_', NOP, NOP, NOP, NOP, NOP, NOP,
1197 //0x18 -, -, -, -, -, -, -, -,
1198 NOP, NOP, NOP, NOP, 198, 230, 223, 201,
1199 //0x20 ' ', '!', '"', '#', '?, '%', '&', ''',
1200 ' ', '!', '"', '#', 164, '%', '&', '\'',
1201 //0x28 '(', ')', '*', '+', ',', '-', '.', '/',
1202 '(', ')', '*', '+', ',', '-', '.', '/',
1203 //0x30 '0', '1', '2', '3', '4', '5', '6', '7',
1204 '0', '1', '2', '3', '4', '5', '6', '7',
1205 //0x38 '8', '9', ':', ';', '<', '=', '>', '?',
1206 '8', '9', ':', ';', '<', '=', '>', '?',
1207 //0x40 -, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
1208 161, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
1209 //0x48 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
1210 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
1211 //0x50 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
1212 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
1213 //0x58 'X', 'Y', 'Z', -, -, -, -, -,
1214 'X', 'Y', 'Z', 196, 214, 209, 220, 167,
1215 //0x60 -, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
1216 191, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
1217 //0x68 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
1218 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
1219 //0x70 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
1220 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
1221 //0x78 'x', 'y', 'z', -, -, -, -, -,
1222 'x', 'y', 'z', 228, 246, 241, 252, 224
1223};
xy.hef1956462024-12-13 21:30:43 -08001224
1225int hexChar_To_Int(char c)
1226{
1227 if (c >= '0' && c <= '9')
1228 return (c - '0');
1229 if (c >= 'A' && c <= 'F')
1230 return (c - 'A' + 10);
1231 if (c >= 'a' && c <= 'f')
1232 return (c - 'a' + 10);
1233
1234 return 0;
1235}
1236
1237
1238void hexString_To_Bytes(char *in, int inLength, char *out)
1239{
1240 int i;
1241
1242 if (in == NULL || out == NULL)
1243 {
1244 return;
1245 }
1246
1247 for (i = 0 ; i < inLength ; i += 2)
1248 {
1249 out[i/2] = (char)((hexChar_To_Int(in[i]) << 4)
1250 | hexChar_To_Int(in[i+1]));
1251 }
1252}
1253
1254/* RFC3629 chapter 4. Syntax of UTF-8 Byte Sequences */
1255static kal_int32 is_legal_utf8(const UTF8 *start, kal_int32 len)
1256{
1257 UTF8 tmp = 0;
1258 const UTF8 *ptr = start + len;
1259
1260 switch (len) {
1261 default:
1262 return FALSE;
1263
1264 case 4:
1265 tmp = *--ptr;
1266 if (tmp < 0x80 || tmp > 0xBF) {
1267 return FALSE;
1268 }
1269
1270 case 3:
1271 tmp = *--ptr;
1272 if (tmp < 0x80 || tmp > 0xBF) {
1273 return FALSE;
1274 }
1275
1276 case 2:
1277 tmp = *--ptr;
1278 if (tmp > 0xBF) {
1279 return FALSE;
1280 }
1281
1282 switch (*start) {
1283 case 0xE0:
1284 if (tmp < 0xA0) {
1285 return FALSE;
1286 }
1287 break;
1288
1289 case 0xED:
1290 if (tmp > 0x9F) {
1291 return FALSE;
1292 }
1293 break;
1294
1295 case 0xF0:
1296 if (tmp < 0x90) {
1297 return FALSE;
1298 }
1299 break;
1300
1301 case 0xF4:
1302 if (tmp > 0x8F) {
1303 return FALSE;
1304 }
1305 break;
1306
1307 default:
1308 if (tmp < 0x80) {
1309 return FALSE;
1310 }
1311 break;
1312 }
1313
1314 case 1:
1315 if (*start >= 0x80 && *start < 0xC2) {
1316 return FALSE;
1317 }
1318 }
1319
1320 if (*start > 0xF4) {
1321 return FALSE;
1322 }
1323
1324 return TRUE;
1325}
1326
1327kal_int32 kal_utf16_to_utf8(UTF8 *dest, const UTF16 *src, kal_int32 size)
1328{
1329 kal_int32 result = STATUS_SUCCESS;
1330 const UTF16 *start = src;
1331 const UTF16 *end = src;
1332 const UTF32 TAIL_MASK = 0xBF;
1333 const UTF32 TAIL_MARK = 0x80;
1334
1335 UTF8 *target = dest;
1336
1337 if (!src) { return STATUS_NULL_POINTER; }
1338 while (*end) {
1339 end++;
1340 }
1341
1342 while (start < end) {
1343 UTF32 tmp = 0;
1344 unsigned long bytes = 0;
1345
1346 tmp = *start++;
1347 //LOGE("tmp = [%X]\n", tmp);
1348 /* */
1349 if (tmp >= SUR_HIGH_START && tmp <= SUR_HIGH_END) {
1350 if (start < end) {
1351 UTF32 tmp2 = *start;
1352 if (tmp2 >= SUR_LOW_START && tmp2 <= SUR_LOW_END) {
1353 tmp = ((tmp - SUR_HIGH_START) << UTF16_HALF_SHIFT)
1354 + (tmp2 - SUR_LOW_START) + UTF16_HALF_BASE;
1355 start++;
1356 } else {
1357 result = STATUS_ILLEGAL_UTF16;
1358 break;
1359 }
1360 } else {
1361 result = STATUS_MEM_EXHAUSTED;
1362 break;
1363 }
1364 } else if (tmp >= SUR_LOW_START && tmp <= SUR_LOW_END) {
1365 result = STATUS_ILLEGAL_UTF16;
1366 break;
1367 }
1368
1369 if (tmp < (UTF32)0x80) {
1370 bytes = 1;
1371 } else if (tmp < (UTF32)0x800) {
1372 bytes = 2;
1373 } else if (tmp < (UTF32)0x10000) {
1374 bytes = 3;
1375 } else if (tmp < (UTF32)0x110000) {
1376 bytes = 4;
1377 } else {
1378 result = STATUS_ILLEGAL_UTF16;
1379 break;
1380 }
1381
1382 if (target && size > 0) {
1383 size -= bytes;
1384 if (0 >= size) {
1385 break;
1386 }
1387
1388 switch (bytes) {
1389 case 4:
1390 *(target + 3) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
1391 tmp >>= 6;
1392 case 3:
1393 *(target + 2) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
1394 tmp >>= 6;
1395 case 2:
1396 *(target + 1) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
1397 tmp >>= 6;
1398 case 1:
1399 *target = (UTF8)(tmp | first_byte_mark[bytes]);
1400 }
1401 target += bytes;
1402 }
1403 result += bytes;
1404 }
1405
1406 if (target)
1407 *target = 0;
1408
1409 return result;
1410}
1411
1412kal_int32 kal_ext_ascii_to_utf8(UTF8 *dest, const kal_uint8 *src, kal_int32 size)
1413{
1414 kal_int32 result = STATUS_SUCCESS;
1415 const kal_uint8 *start = src, *end = src;
1416 const UTF32 TAIL_MASK = 0xBF;
1417 const UTF32 TAIL_MARK = 0x80;
1418 UTF8 *target = dest;
1419
1420 if (!src) { return STATUS_NULL_POINTER; }
1421 while (*end) {
1422 end++;
1423 }
1424
1425 while (start < end) {
1426 UTF32 tmp = 0;
1427 unsigned long bytes = 0;
1428
1429 tmp = *start++;
1430
1431 if (tmp < (UTF32)0x80) {
1432 bytes = 1;
1433 } else {
1434 bytes = 2;
1435 }
1436
1437 if (target && size > 0) {
1438 size -= bytes;
1439 if (size <= 0) {
1440 break;
1441 }
1442
1443 switch (bytes) {
1444 case 2:
1445 *(target + 1) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
1446 tmp >>= 6;
1447 case 1:
1448 *target = (UTF8)(tmp | first_byte_mark[bytes]);
1449 }
1450 target += bytes;
1451 }
1452 result += bytes;
1453 }
1454
1455 if (target) {
1456 *target = 0;
1457 }
1458
1459 return result;
1460}
1461
1462kal_int32 kal_utf8_to_utf16(UTF16 *dest,
1463 const UTF8 *src,
1464 kal_int32 size)
1465{
1466 kal_int32 result = STATUS_SUCCESS;
1467 const UTF8 *start = src;
1468 const UTF8 *end = src;
1469 UTF16 *target = dest;
1470
1471 while(*end) {
1472 end++;
1473 }
1474
1475 while (start < end) {
1476 unsigned long tmp = 0;
1477 unsigned int extra_bytes = utf8_tailing_bytes[*start];
1478 //UTF8 *next = start + extra_bytes + 1;
1479
1480 if (target && target >= dest + size) {
1481 result = STATUS_MEM_EXHAUSTED;
1482 break;
1483 }
1484
1485 if (start + extra_bytes >= end) {
1486 result = STATUS_MEM_EXHAUSTED;
1487 break;
1488 }
1489
1490 if (!is_legal_utf8(start, extra_bytes + 1)) {
1491 result = STATUS_ILLEGAL_UTF8;
1492 break;
1493 }
1494
1495 switch (extra_bytes) {
1496 case 5:
1497 tmp += *start++;
1498 tmp <<= 6; /* illegal UTF8 */
1499 case 4:
1500 tmp += *start++;
1501 tmp <<= 6; /* illegal UTF8 */
1502 case 3:
1503 tmp += *start++;
1504 tmp <<= 6;
1505 case 2:
1506 tmp += *start++;
1507 tmp <<= 6;
1508 case 1:
1509 tmp += *start++;
1510 tmp <<= 6;
1511 case 0:
1512 tmp += *start++;
1513 }
1514
1515 tmp -= utf8_offsets[extra_bytes];
1516
1517 if (tmp <= MAX_UNI_BMP) {
1518 if (tmp >= SUR_HIGH_START && tmp <= SUR_LOW_END) {
1519 result = STATUS_ILLEGAL_UTF8;
1520 break;
1521 } else {
1522 if (target) {
1523 *target++ = (UTF16)tmp;
1524 }
1525
1526 result++;
1527 }
1528 } else if (tmp > MAX_UTF16) {
1529 result = STATUS_ILLEGAL_UTF8;
1530 break;
1531 } else {
1532 if (target && target + 1 >= dest + size) {
1533 result = STATUS_MEM_EXHAUSTED;
1534 break;
1535 }
1536
1537 tmp -= UTF16_HALF_BASE;
1538
1539 if (target) {
1540 *target++ = (UTF16)((tmp >> UTF16_HALF_SHIFT) + SUR_HIGH_START);
1541 *target++ = (UTF16)((tmp & UTF16_HALF_MASK) + SUR_LOW_START);
1542 }
1543
1544 result += 2;
1545 }
1546 }
1547
1548 if (target) {
1549 *target = 0;
1550 }
1551
1552 return result;
1553}
1554
1555static kal_int32 _mdapi_sms_set_timestamp(mdapi_sms_record_t *sms)
1556{
1557 struct tm *p;
1558 kal_int32 y = 0;
1559
1560 struct timeval tv;
1561 struct timezone tz;
1562
1563 gettimeofday (&tv, &tz);
1564
1565 sms->time[6] = tz.tz_minuteswest;
1566
1567 p = localtime(&tv.tv_sec);
1568 y = 1900 + p->tm_year;
1569 sms->time[0] = y % 100;
1570 sms->time[1] = 1 + p->tm_mon;
1571 sms->time[2] = p->tm_mday;
1572 sms->time[3] = p->tm_hour;
1573 sms->time[4] = p->tm_min;
1574 sms->time[5] = p->tm_sec;
1575
1576 LOGE("sms time: %d-%02d-%02d %02d:%02d:%02d\n", y, sms->time[1],sms->time[2],sms->time[3],sms->time[4], sms->time[5]);
1577 LOGE("timezone = %d\n", sms->time[6]);
1578
1579 return MDAPI_RET_SUCCESS;
1580}
1581
1582kal_uint8 lookup_latin1_to_gsm_ex_table(kal_int8 character)
1583{
1584 int i;
1585 for( i=0; latin1_to_gsm_tableEx[i].symbol != 0; i++) {
1586 if (character == latin1_to_gsm_tableEx[i].symbol)
1587 return latin1_to_gsm_tableEx[i].value;
1588 }
1589 return 255;
1590}
1591
1592
1593
1594
1595void _smsbuf_byte_align(smsbuf_t *buf)
1596{
1597 if (buf->curbyte > buf->finalbyte) {
1598 return;
1599 }
1600 if (buf->curbit != 0) {
1601 buf->curbit = 0;
1602 buf->curbyte++;
1603 }
1604}
1605
1606void _smsbuf_init(smsbuf_t *buf)
1607{
1608 buf->curbyte = buf->smsbuf;
1609 buf->curbit = 0;
1610 memset(buf->smsbuf, 0, sizeof(buf->smsbuf));
1611 buf->finalbyte = buf->curbyte + sizeof(buf->smsbuf);
1612}
1613
1614void _smsbuf_set1bit(smsbuf_t *buf, kal_uint8 b)
1615{
1616 if (buf->curbyte > buf->finalbyte)
1617 return;
1618
1619 if (b != 0)
1620 *buf->curbyte |= (1 << buf->curbit);
1621
1622 buf->curbit++;
1623 if (buf->curbit == 8) {
1624 buf->curbit = 0;
1625 buf->curbyte++;
1626 }
1627}
1628
1629void _smsbuf_set_multi_bits(smsbuf_t *buf, kal_uint32 value, kal_uint8 bit_num)
1630{
1631 kal_int32 i = 0;
1632
1633 for (i = 0; i < bit_num; i++) {
1634 _smsbuf_set1bit(buf, (value & (1 << i)) != 0);
1635 }
1636}
1637
1638void _smsbuf_set_octet(smsbuf_t *buf, kal_uint8 c)
1639{
1640 _smsbuf_byte_align(buf);
1641 *(buf->curbyte) = c;
1642 buf->curbyte++;
1643}
1644
1645void _smsbuf_septet_align(smsbuf_t *buf)
1646{
1647 if (buf->curbyte > buf->finalbyte)
1648 return;
1649 while (((buf->curbyte - buf->septet_start) * 8 + buf->curbit) % 7 != 0)
1650 _smsbuf_set1bit(buf, 0);
1651}
1652
1653void _smsbuf_set_septet_start(smsbuf_t *buf)
1654{
1655 _smsbuf_byte_align(buf);
1656 buf->septet_start = buf->curbyte;
1657}
1658
1659void _smsbuf_set_string(smsbuf_t *buf, kal_int8 *str, kal_int32 size)
1660{
1661 kal_int32 i = 0;
1662 _smsbuf_septet_align(buf);
1663
1664 //LOGE("%s, %s, %d. string is:[%s],size is:[%d]", __FILE__, __FUNCTION__, __LINE__, (char*)str, size);
1665 while (*str && size) {
1666 /* change the iso8859latin1 charactor to gsm support charactor */
1667 //LOGE("%s, %s, %d. character is:[%d]-[0x%x]", __FILE__, __FUNCTION__, __LINE__, (int)*str,*str);
1668 kal_uint8 c = lookup_latin1_to_gsm_ex_table(*str);
1669 if(c != 255)
1670 {
1671 //LOGE("extent table!");
1672 for (i = 0; i < 7; i++) {
1673 _smsbuf_set1bit(buf, ((1 << i) & 0x1b) != 0);
1674 }
1675 size--;
1676 } else {
1677 c = latin1_to_gsm_table[(kal_uint8)*str];
1678 }
1679 //LOGE("%s, %s, %d. character is:[%d]-[0x%x]", __FILE__, __FUNCTION__, __LINE__, (int)c,c);
1680 str++;
1681 size--;
1682 for (i = 0; i < 7; i++) {
1683 _smsbuf_set1bit(buf, ((1 << i) & c) != 0);
1684 //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%X]", buf->curbit, *buf->curbyte);
1685 }
1686 //LOGE(KAL_LOG_INFO, LOG_TAG, "size = [%d] c = [%c]", size, c);
1687 }
1688}
1689
1690void _smsbuf_set_addr(smsbuf_t *buf, kal_int8 *str)
1691{
1692 _smsbuf_byte_align(buf);
1693
1694 while (*str) {
1695 kal_uint8 c = *str;
1696
1697 if (*str == '*') {
1698 c = 0xa;
1699 } else if (*str == '#') {
1700 c = 0xb;
1701 } else if (*str == 'p') {
1702 c = 0xc;
1703 } else if (*str == 'w') {
1704 c = 0xd;
1705 } else if (*str == '+') {
1706 c = 0xe;
1707 } else {
1708 c = *str - '0';
1709 }
1710
1711 if (buf->curbit == 0) {
1712 *buf->curbyte = c;
1713 buf->curbit = 4;
1714 } else {
1715 *buf->curbyte |= (c << 4);
1716 buf->curbyte++;
1717 buf->curbit = 0;
1718 }
1719
1720 str++;
1721 }
1722
1723 if (buf->curbit == 4) {
1724 *buf->curbyte |= 0xF0;
1725 buf->curbyte++;
1726 buf->curbit = 0;
1727 }
1728}
1729
1730
1731kal_int32 _smsbuf_hex_string(smsbuf_t *buf, kal_int8 *output, kal_int32 size)
1732{
1733 kal_int32 len = 0;
1734 kal_uint8 *str = buf->smsbuf;
1735
1736 _smsbuf_byte_align(buf);
1737 while (str != buf->curbyte && (size - len) > 3) {
1738 len += snprintf(output + len, size - len, "%02X", *str);
1739 str++;
1740 }
1741
1742 return len;
1743}
1744
1745kal_int32 _mdapi_sms_get_msg_num(const char *msg, int charset, kal_int32 *msg_num, kal_int32 *msg_len)
1746{
1747 LOGE("%s, %s, %d, send sms content = [%s]",__FILE__, __FUNCTION__, __LINE__, msg);
1748 *msg_num = 0;
1749 *msg_len = 0;
1750 kal_int32 max_len = 0;
1751
1752 if (charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
1753 *msg_len = strlen(msg);
1754
1755 //special char
1756 kal_int32 extenSize =0;
1757 kal_char* point = (kal_char*)msg;
1758 kal_int32 size = *msg_len;
1759 while (*point && size) {
1760 kal_uint8 c = lookup_latin1_to_gsm_ex_table((kal_int8)*point);
1761 if(c != 255)
1762 extenSize++;
1763 point++;
1764 size--;
1765 }
1766 //special char
1767 if (*msg_len + extenSize > 160) {
1768 *msg_num = (*msg_len + extenSize + MAX_7BIT_MSG_LEN - 1) / MAX_7BIT_MSG_LEN;
1769 max_len = MAX_7BIT_MSG_LEN;
1770 } else {
1771 *msg_num = 1;
1772 }
1773
1774 if (*msg_num > MAX_CONCATENATED_MSG) {
1775 LOGE("message is too long. msg_len[%d], msg_num[%d], max_len[%d]", *msg_len, *msg_num, max_len);
1776 return MDAPI_RET_ERROR;
1777 }
1778 LOGE("%s, %s, %d, 7bit msg_len = [%d] ,msg_num=[%d]", __FILE__, __FUNCTION__, __LINE__, *msg_len, *msg_num);
1779 } else if (charset == MDAPI_SMS_CHARSET_UCS2) {
1780 //UTF16 *dest = NULL;
1781 *msg_len = kal_utf8_to_utf16(NULL, (const UTF8 *)msg, 0);
1782 if (*msg_len > 70) {
1783 *msg_num = (*msg_len + MAX_UCS2_MSG_LEN - 1) / MAX_UCS2_MSG_LEN;
1784 max_len = MAX_UCS2_MSG_LEN * 2;
1785 } else {
1786 *msg_num = 1;
1787 }
1788
1789 if (*msg_num > MAX_CONCATENATED_MSG) {
1790 LOGE("message is too long. msg_len[%d], msg_num[%d], max_len[%d]", msg_len, msg_num, max_len);
1791 return MDAPI_RET_ERROR;
1792 }
1793 } else if (charset == MDAPI_SMS_CHARSET_GSM_8BIT) {
1794 *msg_len = strlen(msg);
1795 if(*msg_len > (140 * 2))
1796 {
1797 *msg_num = (*msg_len + MAX_8BIT_MSG_LEN - 1) / MAX_8BIT_MSG_LEN;
1798 max_len = MAX_8BIT_MSG_LEN;
1799
1800 if (*msg_num > MAX_CONCATENATED_MSG) {
1801 LOGE("message is too long. msg_len[%d], msg_num[%d], max_len[%d]", *msg_len, *msg_num, max_len);
1802 return MDAPI_RET_ERROR;
1803 }
1804 }
1805 else {
1806 *msg_num = 1;
1807 }
1808 } else{
1809 LOGE("Not support charset");
1810 return MDAPI_RET_ERROR;
1811 }
1812
1813 return MDAPI_RET_SUCCESS;
1814}
1815
1816kal_int32 _mdapi_sms_encode_addr(smsbuf_t *buf, kal_int8 *smsc, kal_int32 type)
1817{
1818 kal_int32 len = strlen(smsc);
1819 kal_int8 *str = smsc;
1820
1821 kal_uint8 addr_plane = SMS_NP_ISDNTEL;
1822 kal_uint8 addr_type = SMS_TON_UNKNOWN;
1823
1824 if (len <= 0) {
1825 /* use default sca for sms message */
1826 _smsbuf_set_octet(buf, 0);
1827 return 1;;
1828 }
1829
1830 if (len > 255) {
1831 LOGE("input number is too long. len[%d] smsc[%s] ", len, smsc);
1832 return 0;
1833 }
1834
1835 /* check the type of address */
1836 while (*str) {
1837 if (!isdigit(*str) && *str != '+' && *str != '*'
1838 && *str != '#' && *str != 'p' && *str != 'w')
1839 addr_type = SMS_TON_ALPHANUMERIC;
1840 str++;
1841 }
1842
1843 if (smsc[0] == '+' && addr_type != SMS_TON_ALPHANUMERIC) {
1844 addr_type = SMS_TON_INTERNATIONAL;
1845 /* */
1846 str = &smsc[1];
1847 len--;
1848 } else {
1849 str = smsc;
1850 }
1851
1852 /* set len */
1853 if (type == SMS_ENCODE_SCA)
1854 _smsbuf_set_octet(buf, len / 2 + len % 2 + 1);
1855 else {
1856 _smsbuf_set_octet(buf, len);
1857 }
1858
1859 LOGE("%02X, %d ", *(buf->curbyte), buf->curbyte - buf->smsbuf);
1860
1861 _smsbuf_set_multi_bits(buf, addr_plane, 4);
1862 _smsbuf_set_multi_bits(buf, addr_type, 3);
1863 _smsbuf_set1bit(buf, 1);
1864
1865 LOGE("%02X, %d ", *(buf->curbyte), buf->curbyte - buf->smsbuf);
1866
1867 if (addr_type == SMS_TON_ALPHANUMERIC) {
1868 _smsbuf_set_septet_start(buf);
1869 _smsbuf_set_string(buf, str, len);
1870 } else {
1871 _smsbuf_set_addr(buf, str);
1872 }
1873
1874 _smsbuf_byte_align(buf);
1875
1876 return buf->curbyte - buf->smsbuf;
1877}
1878
1879kal_int32 _mdapi_sms_encode_pdu(mdapi_sms_record_t *sms,
1880 kal_int8 *smsc,
1881 mdapi_sms_settings_t *settings,
1882 kal_char *start,
1883 kal_int32 send_size,
1884 kal_uint8 *udh,
1885 kal_char *output,
1886 kal_int32 out_len,
1887 kal_int32 *sca_out_len)
1888{
1889 smsbuf_t smsbuf;
1890 kal_int32 udh_len = 0;
1891 kal_int32 len = 0;
1892 kal_int32 sca_len = 0;
1893
1894 if (udh) {
1895 udh_len = udh[0];
1896 } else {
1897 udh_len = 0;
1898 }
1899
1900 memset(&smsbuf, 0, sizeof(smsbuf));
1901 _smsbuf_init(&smsbuf);
1902
1903 /* SMSC */
1904 sca_len = _mdapi_sms_encode_addr(&smsbuf, smsc, SMS_ENCODE_SCA);
1905
1906 /* Encode PDU Type */
1907 {
1908 _smsbuf_byte_align(&smsbuf);
1909
1910 /* Message Type Indicator */
1911 _smsbuf_set_multi_bits(&smsbuf, SMS_SUBMIT, 2);
1912 //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
1913 /* Reject Duplicate */
1914 _smsbuf_set1bit(&smsbuf, 0);
1915 //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
1916 /* Validity Period Format */
1917 _smsbuf_set_multi_bits(&smsbuf, settings->vpf, 2);
1918 //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
1919
1920 /* Status Report Request */
1921 if (settings->srr)
1922 _smsbuf_set1bit(&smsbuf, 1);
1923 else
1924 _smsbuf_set1bit(&smsbuf, 0);
1925 //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
1926
1927 /* User Data Header Indicator */
1928 if (udh_len)
1929 _smsbuf_set1bit(&smsbuf, 1);
1930 else
1931 _smsbuf_set1bit(&smsbuf, 0);
1932
1933 //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
1934
1935 /* Replay Path */
1936 _smsbuf_set1bit(&smsbuf, settings->rp);
1937
1938 //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
1939 }
1940
1941 /* Encode MR */
1942 {
1943 /* Message Reference Count, Long Message should use this */
1944 _smsbuf_set_octet(&smsbuf, 0);
1945 }
1946
1947 /* Encode OA/DA */
1948 _mdapi_sms_encode_addr(&smsbuf, sms->phone_number, SMS_ENCODE_OADA);
1949
1950 /* Encode Protocol Identifier */
1951 _smsbuf_set_octet(&smsbuf, 0x00);
1952
1953 /* Encode DCS */
1954 {
1955 /* Bit 0,1, Class */
1956 _smsbuf_set_multi_bits(&smsbuf, sms->sms_class, 2);
1957 /* Bit 2,3, Class */
1958 _smsbuf_set_multi_bits(&smsbuf, sms->charset, 2);
1959 /* Bit 4 */
1960 _smsbuf_set1bit(&smsbuf, 0);
1961 /* Bit 5 */
1962 /* No text compressed */
1963 _smsbuf_set1bit(&smsbuf, 0);
1964 /* Bit 6, 7 */
1965 _smsbuf_set_multi_bits(&smsbuf, 0, 0);
1966 }
1967 //_smsbuf_byte_align(&smsbuf);
1968
1969 /* Validity Period */
1970 {
1971 if (settings->vpf == SMS_VPF_ABSOLUTE) {
1972 // TODO: add absolute validity period
1973
1974 } else if (settings->vpf == SMS_VPF_RELATIVE) {
1975 // TODO: add validity period support
1976 kal_uint8 validity_period = 0xAA;
1977 _smsbuf_set_octet(&smsbuf, validity_period);
1978 }
1979 }
1980
1981 /* User Data Header */
1982 {
1983 if (udh_len) {
1984 kal_int32 i = 0;
1985 if (sms->charset == MDAPI_SMS_CHARSET_UCS2) {
1986 _smsbuf_set_octet(&smsbuf, 1 + udh_len + send_size);
1987 } else if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
1988 _smsbuf_set_octet(&smsbuf, (((1 + udh_len) * 8 + 6) / 7) + send_size);
1989 } else if (sms->charset == MDAPI_SMS_CHARSET_GSM_8BIT) {
1990 _smsbuf_set_octet(&smsbuf, 1 + udh_len + send_size/2);
1991 }
1992
1993 /* set the start byte of septet(7bits) align */
1994 _smsbuf_set_septet_start(&smsbuf);
1995 for (i = 0; i < udh_len + 1; i++) {
1996 _smsbuf_set_octet(&smsbuf, udh[i]);
1997 }
1998 } else {
1999 if(sms->charset == MDAPI_SMS_CHARSET_GSM_8BIT)
2000 {
2001 _smsbuf_set_octet(&smsbuf, send_size/2);
2002 }
2003 else
2004 {
2005 _smsbuf_set_octet(&smsbuf, send_size);
2006 }
2007
2008 /* set the start byte of septet(7bits) align */
2009 _smsbuf_set_septet_start(&smsbuf);
2010 }
2011 }
2012
2013 /* Get the Hex String */
2014 len = _smsbuf_hex_string(&smsbuf, output, out_len);
2015 LOGE("encoded pdu = (%s), len = (%d) ", output, len);
2016
2017 /* Set User Data */
2018 if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
2019 //_sms_iso8859latin1_to_gsm(start, gsm, *size + 1);
2020 _smsbuf_set_string(&smsbuf, start, send_size);
2021 } else if(sms->charset == MDAPI_SMS_CHARSET_GSM_8BIT) {
2022 kal_int32 i = 0;
2023 char outhex[MAX_PDU_SIZE] = {0};
2024 hexString_To_Bytes(start, send_size, outhex);
2025 for (i = 0; i < send_size/2; i++) {
2026 _smsbuf_set_octet(&smsbuf, outhex[i]);
2027 }
2028 } else {
2029 kal_int32 i = 0;
2030 for (i = 0; i < send_size; i += 2) {
2031 kal_uint16 tmp = 0;
2032 kal_uint8 *ptr = (kal_uint8 *)&tmp;
2033
2034 *ptr = *(start + i);
2035 *(ptr + 1) = *(start + i + 1);
2036 tmp = htons(tmp);
2037 _smsbuf_set_octet(&smsbuf, *(ptr));
2038 _smsbuf_set_octet(&smsbuf, *(ptr + 1));
2039 }
2040 }
2041
2042 /* Get the Hex String */
2043 len = _smsbuf_hex_string(&smsbuf, output, out_len);
2044 *sca_out_len = sca_len * 2;
2045 LOGE("start = [%p] size = [%d] encoded pdu = (%s), len = (%d)", start, send_size, output, len);
2046
2047 return len;
2048}
2049
2050
2051
2052
2053
2054int smsPduEncode(const char *smsc, const char *da_num, const char *msg, int charset,
2055 char *smsc_pdu, char **pdu)
2056{
2057 mdapi_sms_record_t record;
2058 mdapi_sms_settings_t sms_settings;
2059 //kal_int32 status = MDAPI_RET_ERROR;
2060 kal_int32 msg_num = 0;
2061 kal_int32 msg_len = 0;
2062 kal_int32 max_len = 0;
2063 kal_char *msg_content = NULL;
2064 kal_int32 out_len = 0;
2065 kal_int8 output[MAX_PDU_SIZE] = {0};
2066 kal_int32 sca_out_len;
2067 mdapi_sms_record_t *sms = &record;
2068
2069 memset(sms, 0, sizeof(mdapi_sms_record_t));
2070
2071 snprintf(sms->phone_number, sizeof(sms->phone_number), "%s", da_num);
2072 sms->msg_content = (kal_char *)msg;
2073 sms->charset = charset;
2074
2075 sms_settings.rd = 1;
2076 sms_settings.vpf = SMS_VPF_RELATIVE;
2077 sms_settings.srr = 1;
2078 sms_settings.rp = 0;
2079 sms_settings.validity_period = 0;
2080
2081 // status = _mdapi_sms_get_msg_num(msg, charset, &msg_num, &msg_len);
2082
2083 /*if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
2084 msg_content = sms->msg_content;
2085 } else if (sms->charset == MDAPI_SMS_CHARSET_UCS2) {
2086 UTF16 *dest = NULL;
2087 msg_content = (kal_char *)malloc((msg_len + 1) * sizeof(UTF16));
2088 dest = (UTF16 *)msg_content;
2089 msg_len = kal_utf8_to_utf16(dest, (const UTF8 *)sms->msg_content, (msg_len + 1) * sizeof(UTF16));
2090 if (msg_len <= 0) {
2091 free(msg_content);
2092 msg_content = NULL;
2093 return MDAPI_RET_ERROR;
2094 }
2095 msg_len *= 2;
2096 LOGE("ucs2 msg_len = [%d] ,msg_num=[%d] ", msg_len,msg_num);
2097 }else {
2098 LOGE("Not support charset");
2099 return MDAPI_RET_ERROR;
2100 }*/
2101 if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
2102 msg_len = strlen(sms->msg_content);
2103
2104 //for special char
2105 kal_int32 extenTotalSize =0;
2106 //kal_int32 i = 0;
2107 kal_char* point = sms->msg_content;
2108 LOGE("XXX msg len %d \n",msg_len);
2109 kal_int32 size = msg_len;
2110 while (*point && size) {
2111 kal_uint8 c = lookup_latin1_to_gsm_ex_table((kal_int8)*point);
2112 if(c != 255){
2113 extenTotalSize++;
2114 }
2115 point++;
2116 size--;
2117 }
2118 //for specail char
2119 msg_len += extenTotalSize;
2120 LOGE("XXX msg_len %d extenTotalSize %d \n",msg_len,extenTotalSize);
2121 if (msg_len > 160) {
2122 msg_num = (msg_len + MAX_7BIT_MSG_LEN - 1) / MAX_7BIT_MSG_LEN;
2123 max_len = MAX_7BIT_MSG_LEN;
2124 } else {
2125 msg_num = 1;
2126 }
2127
2128 if (msg_num > MAX_CONCATENATED_MSG) {
2129 LOGE("message is too long. msg_len[%d], msg_num[%d]", msg_len, msg_num);
2130 return MDAPI_RET_ERROR;
2131 }
2132 LOGE("7bit msg_len = [%d] ,msg_num=[%d]", msg_len,msg_num);
2133 msg_content = sms->msg_content;
2134 } else if (sms->charset == MDAPI_SMS_CHARSET_UCS2) {
2135 UTF16 *dest = NULL;
2136 msg_len = kal_utf8_to_utf16(NULL, (const UTF8 *)sms->msg_content, 0);
2137 if (msg_len > 70) {
2138 msg_num = (msg_len + MAX_UCS2_MSG_LEN - 1) / MAX_UCS2_MSG_LEN;
2139 max_len = MAX_UCS2_MSG_LEN * 2;
2140 } else {
2141 msg_num = 1;
2142 }
2143
2144 if (msg_num > MAX_CONCATENATED_MSG) {
2145 LOGE("message is too long. msg_len[%d], msg_num[%d]", msg_len, msg_num);
2146 return MDAPI_RET_ERROR;
2147 }
2148
2149 msg_content = (kal_char *)malloc((msg_len + 1) * sizeof(UTF16));
2150 dest = (UTF16 *)msg_content;
2151 msg_len = kal_utf8_to_utf16(dest, (const UTF8 *)sms->msg_content, (msg_len + 1) * sizeof(UTF16));
2152 if (msg_len <= 0) {
2153 free(msg_content);
2154 msg_content = NULL;
2155 return MDAPI_RET_ERROR;
2156 }
2157 msg_len *= 2;
2158 LOGE("ucs2 msg_len = [%d] ,msg_num=[%d] ", msg_len,msg_num);
2159 } else if (sms->charset == MDAPI_SMS_CHARSET_GSM_8BIT) {
2160 msg_len = strlen(sms->msg_content);
2161 msg_content = sms->msg_content;
2162 if (msg_len > (140 * 2)) {
2163 msg_num = (msg_len + MAX_8BIT_MSG_LEN - 1) / MAX_8BIT_MSG_LEN;
2164 max_len = MAX_8BIT_MSG_LEN;
2165 } else {
2166 msg_num = 1;
2167 }
2168
2169 if (msg_num > MAX_CONCATENATED_MSG) {
2170 LOGE("message is too long. msg_len[%d], msg_num[%d]", msg_len, msg_num);
2171 return MDAPI_RET_ERROR;
2172 }
2173 LOGE("8bit msg_len = [%d] ,msg_num=[%d] ", msg_len,msg_num);
2174 }else {
2175 LOGE("Not support charset");
2176 return MDAPI_RET_ERROR;
2177 }
2178
2179 // set sms record
2180 _mdapi_sms_set_timestamp(sms);
2181 if (msg_num == 1) {
2182 out_len = _mdapi_sms_encode_pdu(sms, (kal_int8 *)smsc, &sms_settings, msg_content, msg_len, NULL, output, sizeof(output), &sca_out_len);
2183 memcpy(smsc_pdu, output, sca_out_len);
2184 //LOGE("%s, %s, %d, returned encoded smsc_pdu:%s", __FILE__, __FUNCTION__, __LINE__, smsc_pdu);
2185 //LOGE("%s, %s, %d, output + sca_out_len:%s, out_len - sca_out_len: %d", __FILE__, __FUNCTION__, __LINE__, output + sca_out_len, out_len - sca_out_len);
2186
2187 //LOGE("%s, %s, %d, pdu:%s sizeof(pdu[0])=%d", __FILE__, __FUNCTION__, __LINE__, pdu[0], sizeof(pdu[0]));
2188
2189 memset(pdu[0], 0, MAX_PDU_SIZE);
2190 LOGE("%s, %s, %d, pdu:%s", __FILE__, __FUNCTION__, __LINE__, pdu[0]);
2191 strncpy(pdu[0], output + sca_out_len, out_len - sca_out_len);
2192 LOGE("%s, %s, %d, returned encoded pdu:%s\n, len=%d", __FILE__, __FUNCTION__, __LINE__, pdu[0], strlen(pdu[0]));
2193 } else {
2194 // send long sms
2195 kal_int32 index = 0;
2196 kal_int32 offset = 0;
2197 static kal_uint8 concat_msgid;
2198 concat_msgid += (rand() + 1) % 256;
2199 LOGE("start send one long msg, total has %d part msg", msg_num);
2200 for (index = 0; index < msg_num; index++) {
2201 kal_uint8 udh[] = {5, 0, 3, concat_msgid, msg_num, index + 1};
2202 kal_uint32 size = 0;
2203 kal_int8 *start = NULL;
2204 size = msg_len > max_len ? max_len : msg_len;
2205 msg_len -= size;
2206 start = msg_content + offset;
2207 int exterSize = 0;
2208 if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT){
2209 char* point = start;
2210 int calsize = size;
2211 while (*point && calsize) {
2212 kal_uint8 c = lookup_latin1_to_gsm_ex_table((kal_int8)*point);
2213 if(c != 255){
2214 exterSize++;
2215 calsize--;
2216 }
2217 point++;
2218 calsize--;
2219 }
2220 }
2221 offset = offset + size - exterSize;
2222 //calculate offset
2223 LOGE(" msg_len %d size %d offset %d exterSize %d", msg_len,size ,offset,exterSize);
2224 out_len = _mdapi_sms_encode_pdu(sms, (kal_int8 *)smsc, &sms_settings, start, size, udh, output, sizeof(output), &sca_out_len);
2225 memcpy(smsc_pdu, output, sca_out_len);
2226 memset(pdu[index], 0, MAX_PDU_SIZE);
2227 memcpy(pdu[index], output + sca_out_len, out_len - sca_out_len);
2228 }
2229 }
2230 if (sms->charset == MDAPI_SMS_CHARSET_UCS2) {
2231 if(msg_content != NULL)
2232 free(msg_content);
2233 }
2234 return MDAPI_RET_SUCCESS;
2235}
2236
2237
2238
2239//decode
2240static unsigned char
2241internal_mdapi_hex2int(char *s) {
2242 int ret = 0;
2243 int len = 2, i = 0;
2244 while (i < len) {
2245 if (s[i] == 0) {
2246 return -1;
2247 } else if (s[i] >= 'a' && s[i] <= 'f') {
2248 ret = (s[i] - 'a' + 10) + (ret << 4);
2249 } else if (s[i] >= 'A' && s[i] <= 'F') {
2250 ret = (s[i] - 'A' + 10) + (ret << 4);
2251 } else if (s[i] >= '0' && s[i] <= '9') {
2252 ret = (s[i] - '0') + (ret << 4);
2253 } else {
2254 return -1;
2255 }
2256 i++;
2257 }
2258 return ret;
2259}
2260
2261int internal_mdapi_sms_7bit_decode(char * message, char * output, int output_size, int padding_bits, int octect)
2262{
2263 int i = 0, len = 0;
2264 char * ptr = message;
2265 int output_len = 0;
2266 int cur_val = 0;
2267 int val = 0;
2268 int last_val = 0;//used to save last 1 octet
2269 int offset;
2270
2271 if( padding_bits < 0||padding_bits > 6 )
2272 {
2273 return 0;
2274 }
2275 //Calc how many octets are there
2276 len = strlen(message) >> 1;
2277
2278 for(i = 0; i < len - 1; i++){
2279 offset = i % 0x7;
2280 //Add padding bit, realign to septets.
2281 cur_val = ((internal_mdapi_hex2int(ptr)>>padding_bits)&0xFF)+((internal_mdapi_hex2int(ptr+2)<<(8-padding_bits))&0xFF);
2282 val = ((cur_val << offset) & 0x7F)+((last_val >> (8 - offset))&0xFF);
2283 last_val = cur_val;
2284 //printf("val raw = 0x%X, val = 0x%X\n", val, gsm_to_latin1_table[(kal_uint8)(val & 0xFF)]);
2285 output[output_len++] = (char)gsm_to_latin1_table[(kal_uint8)(val & 0xFF)];
2286 if (output_len == output_size - 1) {
2287 output[output_len] = 0;
2288 return output_len;
2289 }
2290
2291 if(offset == 6){
2292 val = ((cur_val>>1)&0x7F) ;
2293 //printf("val raw = 0x%X, val = 0x%X\n", val, gsm_to_latin1_table[(kal_uint8)(val & 0xFF)]);
2294 output[output_len++] = (char)gsm_to_latin1_table[(kal_uint8)(val & 0xFF)];
2295 if (output_len == output_size - 1) {
2296 output[output_len] = 0;
2297 return output_len;
2298 }
2299 }
2300 ptr += 2;
2301 }
2302
2303 /* decode the last octet */
2304 cur_val = (internal_mdapi_hex2int(ptr) >> padding_bits) & 0xFF;
2305 offset = i % 7;
2306 val = ((cur_val << offset) & 0x7F)+((last_val >> (8 - offset))&0xFF);
2307 //printf("val raw = 0x%X, val = 0x%X\n", val, gsm_to_latin1_table[(kal_uint8)(val & 0xFF)]);
2308 output[output_len++] = (char)gsm_to_latin1_table[(kal_uint8)(val & 0xFF)];
2309 if (output_len == output_size - 1) {
2310 output[output_len] = 0;
2311 return output_len;
2312 }
2313
2314 //printf("output = [%s], output_len = [%d]\n", output, output_len);
2315 if(offset == 6){
2316 val = ((cur_val >> 1) & 0x7F);
2317 //printf("val raw = 0x%X, val = 0x%X\n", val, gsm_to_latin1_table[(kal_uint8)(val & 0xFF)]);
2318 if (val || octect) {
2319 output[output_len++] = (char)gsm_to_latin1_table[(kal_uint8)(val & 0xFF)];
2320 if (output_len == output_size - 1) {
2321 output[output_len] = 0;
2322 return output_len;
2323 }
2324 }
2325 }
2326 output[output_len] = 0;
2327
2328 return output_len;
2329}
2330
2331
2332
2333
2334
2335
2336
2337int internal_mdapi_address_decode(char *number, char *output, int output_size, int type) {
2338 // 81 90 21 43 65 87 --> 0912345678
2339 LOGE("%s, %s, %d", __FILE__, __FUNCTION__, __LINE__);
2340
2341 int len = 0;
2342 int output_len = 0;
2343 int val = 0;
2344 char *ptr = number;
2345 int padding_bit = 0;//To identify the number is even or odd
2346 //LOGE("before internal_mdapi_hex2int(ptr), ptr :%s",ptr);
2347 // Length
2348 len = internal_mdapi_hex2int(ptr);
2349 //LOGE("after internal_mdapi_hex2int(ptr), ptr :%s",ptr);
2350 ptr += 2;
2351 //LOGE("after +=2, ptr :%s",ptr);
2352
2353 if (len == 0) {
2354 return 2;
2355 } else if (len < 0) {
2356 return -1;
2357 }
2358
2359 if (type) {
2360 len = (len) << 1;
2361 } else {
2362 len += 2;
2363 }
2364
2365 LOGE("Address length = %d ", len);
2366
2367 // Type-of-address
2368 val = internal_mdapi_hex2int(ptr);
2369 ptr += 2;
2370 len -= 2;
2371 if (val == 0x91) {
2372 // international number
2373 output_len += snprintf(output+output_len, output_size-output_len-1, "+");
2374 } else if (val == 0x81) {
2375 // national number
2376 } else if ((val & 0x50) == 0x50 ){
2377 // alphabet number
2378 } else {
2379 LOGE("Invalid type-of-address : %02X " , val);
2380 }
2381
2382 // decode alphabet number
2383 if (0x50 == (val & 0x50)) {
2384 kal_int32 octect = (((len * 4) / 7 ) % 8 == 0) ? 1 : 0;
2385 kal_char * tmp = (kal_char * )malloc(len + 1);
2386 if (!tmp) {
2387 LOGE("Invalid type-of-address : %02X ", val);
2388 return -1;
2389 }
2390 memcpy(tmp, ptr, len);
2391 tmp[len] = 0;
2392 output_len += internal_mdapi_sms_7bit_decode(tmp, output, output_size - output_len - 1, 0, octect);
2393 free(tmp);
2394 tmp = NULL;
2395 } else {
2396 do {
2397 if (len > 1) {
2398 if (*ptr == 'F') {
2399 output_len += snprintf(output + output_len, output_size - output_len - 1, "%c", *(ptr + 1));
2400 } else {
2401 output_len += snprintf(output + output_len, output_size - output_len - 1, "%c%c", *(ptr + 1), *(ptr));
2402 }
2403
2404 len -= 2;
2405 ptr += 2;
2406 } else {
2407 output_len += snprintf(output + output_len, output_size - output_len - 1, "%c", *(ptr + 1));
2408 len -= 1;
2409 ptr += 1;
2410 padding_bit = 1;
2411 }
2412 } while (len > 0);
2413 }
2414
2415 return (ptr-number+padding_bit);
2416}
2417
2418
2419static kal_int32 _mdapi_sms_decode_pdu(mdapi_sms_record_t *sms,
2420 kal_int8 *smsc,
2421 kal_int8 *content,
2422 kal_int32 content_size,
2423 kal_int32 *record_size,
2424 kal_int32 *curr_pack,
2425 kal_int32 *total_pack)
2426{
2427
2428
2429 kal_int32 ret = 0;
2430
2431 kal_int8 *ptr = content;
2432 kal_int32 udh = 0;
2433
2434 /*
2435 * Service Centre address informaction element
2436 */
2437 LOGE("%s, %s, %d, ptr_len: %d, ptr: %s\n", __FILE__,__FUNCTION__, __LINE__, content_size, ptr);
2438 ret = internal_mdapi_address_decode(ptr, smsc, 512, 1);
2439 if (ret <= 0) {
2440 LOGE("can't get SMSC address");
2441 return MDAPI_RET_ERROR;
2442 }
2443 ptr += ret;
2444 LOGE("SMSC = [%s]\n", smsc);
lichengzhangd01f0742025-08-19 18:04:41 +08002445
xy.hef1956462024-12-13 21:30:43 -08002446 /* Protocol Data Unit Type(PDU Type) */
2447 {
2448 kal_int32 pdu_type = internal_mdapi_hex2int(ptr);
2449 if ((pdu_type & 0x03) == SMS_DELIVER) {
2450 sms->msg_type = MDAPI_SMS_NORMAL_MSG;
2451 } else if ((pdu_type & 0x03) == SMS_STATUS_REPORT){
2452 sms->msg_type = MDAPI_SMS_MSG_REPORT;
2453 } else {
2454 LOGE("unkown PDU type = %02X(%02X), content = %s", pdu_type, pdu_type & 0x03, content);
2455 return MDAPI_RET_ERROR;
2456 }
2457
2458 if ((pdu_type & 0x40) == 0x40) {
2459 udh = 1; /* find UDH header */
2460 }
2461
2462 LOGE("PDU Type = [%d]\n", pdu_type);
2463 }
2464 ptr += 2;
2465
2466 /* decode originator address(OA) destination address(DA)*/
2467 ret = internal_mdapi_address_decode(ptr, sms->phone_number, sizeof(sms->phone_number), 0);
2468 if (ret <= 0) {
2469 LOGE("can't get sender address");
2470 return MDAPI_RET_ERROR;
2471 }
2472 ptr += ret;
2473 LOGE("sender = [%s]\n", sms->phone_number);
2474
2475 /* protocol identifiler(PID) */
2476 ptr += 2;
2477
2478 /* Data Coding Scheme (DCS) */
2479 {
2480 //kal_int32 text_compressed = 0;
2481 kal_int32 dcs = 0;
2482
2483 dcs = internal_mdapi_hex2int(ptr);
2484 if (dcs < 0) {
2485 LOGE("can't get the DCS\n");
2486 return MDAPI_RET_ERROR;
2487 }
2488
2489 if ( (dcs & 0xC0) == 0x00) {
2490 /* General Data Coding indication */
2491 if (dcs & 0x20) {
2492 //text_compressed = 1;
2493 }
2494
2495 if (dcs & 0x10) {
2496 sms->sms_class = dcs & 0xF;
2497 }
2498
2499 if (dcs & 0x04) {
2500 sms->charset = MDAPI_SMS_CHARSET_GSM_8BIT;
2501
2502 } else if (dcs & 0x08) {
2503 sms->charset = MDAPI_SMS_CHARSET_UCS2;
2504 } else {
2505 sms->charset = MDAPI_SMS_CHARSET_GSM_7BIT;
2506 }
2507 } else {
2508 LOGE("un-supported dcs type\n");
2509 return MDAPI_RET_ERROR;
2510 }
2511 ptr += 2;
2512 }
2513
2514 /* Time */
2515 {
2516 kal_int32 i = 0;
2517 kal_int8 tmp[4] = {0};
2518 kal_uint8 time[7] = {0};
2519 char temp_buff[64] = {0};
2520
2521 for (i = 0; i < 7; i++) {
2522 tmp[0] = *(ptr + 1);
2523 tmp[1] = *ptr;
2524 tmp[2] = 0;
2525 time[i] = strtoul(tmp, 0, 10);
2526 ptr += 2;
2527 }
2528
2529 if (time[0] < 80) {
2530 time[0] += 100;
2531 }
2532
2533 memset(temp_buff, 0, sizeof(temp_buff));
2534 snprintf(temp_buff, sizeof(temp_buff), "%04u-%02u-%02u %02u:%02u:%02u",time[0] + 1900, time[1], time[2], time[3], time[4], time[5]);
2535 strncpy(sms->time, temp_buff, sizeof(sms->time));
2536
2537 //snprintf(sms->time, sizeof(sms->time), "%04u-%02u-%02u %02u:%02u:%02u", time[0] + 1900, time[1], time[2], time[3], time[4], time[5]);
2538
2539 LOGE("sms time = [%s]\n", sms->time);
2540 }
2541 {
2542 kal_int32 i = 0;
2543 kal_int32 udh_len = 0;
2544 kal_int32 data_len = 0;
2545 kal_int32 buf_len = 0;
2546 kal_int32 octect = 0;
2547
2548 data_len = internal_mdapi_hex2int(ptr);
2549 ptr += 2;
2550
2551 /* parse UDH header, to parse log SMS header */
2552 if (udh) {
2553 kal_int8 *ptr_udh = NULL;
2554 udh_len = internal_mdapi_hex2int(ptr);
2555 ptr += 2;
2556 ptr_udh = ptr;
2557 while (i < udh_len) {
2558 kal_int32 iei = 0;
2559 kal_int32 iei_len = 0;
2560
2561 iei = internal_mdapi_hex2int(ptr);
2562 ptr += 2;
2563 iei_len = internal_mdapi_hex2int(ptr);
2564 ptr += 2;
2565
2566 if (iei != 0x00 && iei != 0x08) {
2567 ptr += (iei_len) * 2;
2568 i += 2 + iei_len;
2569 continue;
2570 }
2571
2572 if (iei == 0x00) {
2573 sms->ref_num = internal_mdapi_hex2int(ptr);
2574 ptr += 2;
2575 } else {
2576 sms->ref_num = ((internal_mdapi_hex2int(ptr) & 0xFF) << 8)
2577 | (internal_mdapi_hex2int(ptr + 2) & 0xFF);
2578 ptr += 4;
2579 }
2580 /*lei modify for gsw 2022/5/12*/
2581 sms->total_pack = internal_mdapi_hex2int(ptr);
lichengzhangd01f0742025-08-19 18:04:41 +08002582 LOGE("sms->total_pack = [%d]", sms->total_pack);
xy.hef1956462024-12-13 21:30:43 -08002583 *total_pack = sms->total_pack;
2584 sms->curr_pack = internal_mdapi_hex2int(ptr+2);
2585 LOGE("sms->curr_pack = [%d]", sms->curr_pack);
2586 *curr_pack = sms->curr_pack;
2587 /*lei modify for gsw 2022/5/12*/
2588 break;
2589 }
2590
2591 ptr = ptr_udh + (udh_len) * 2;
2592 }
2593
2594 LOGE("sms->charset = [%d] \n", sms->charset);
2595 switch (sms->charset) {
2596 case MDAPI_SMS_CHARSET_GSM_7BIT:
2597 octect = (data_len % 8 == 0) ? 1 : 0;
2598 // decode 7bit
2599 if (1 == udh) {
2600 kal_int32 padding_bits = ((udh_len + 1) * 8) % 7;
2601 if (padding_bits) {
2602 padding_bits = 7 - padding_bits;
2603 }
2604 data_len = internal_mdapi_sms_7bit_decode(ptr, sms->msg_content, content_size, padding_bits, octect);
2605 } else {
2606 data_len = internal_mdapi_sms_7bit_decode(ptr, sms->msg_content, content_size, 0, octect);
2607 }
2608
2609 *(sms->msg_content + data_len++) = '\0';
2610 *(sms->msg_content + data_len++) = '\0';
2611
2612 *record_size = data_len;
2613 break;
2614
2615 case MDAPI_SMS_CHARSET_GSM_8BIT:
lichengzhang8c043332025-07-30 17:43:23 +08002616 kal_int32 utf8_len = 0;
2617 kal_uint8* binary_data = NULL;
2618 kal_char* utf8_buffer = NULL;
lichengzhangd01f0742025-08-19 18:04:41 +08002619 if (sms->curr_pack != 0)
2620 data_len -= (udh_len + 1);
2621 LOGE("leng:%d\n",data_len);
lichengzhang8c043332025-07-30 17:43:23 +08002622 // 分配二进制缓冲区
2623 binary_data = malloc(data_len);
2624 if (!binary_data) {
2625 LOGE("Memory allocation failed for 8bit data");
2626 return MDAPI_RET_ERROR;
xy.hef1956462024-12-13 21:30:43 -08002627 }
lichengzhang8c043332025-07-30 17:43:23 +08002628
2629 // 将十六进制PDU转换为二进制数据
2630 kal_int32 bin_index = 0;
2631 for (i = 0; i < data_len; i++) {
2632 kal_int32 hex_val = internal_mdapi_hex2int(ptr);
2633 if (hex_val < 0 || hex_val > 255) {
2634 free(binary_data);
2635 LOGE("Invalid hex value in 8bit PDU at position %d", i);
xy.hef1956462024-12-13 21:30:43 -08002636 return MDAPI_RET_ERROR;
2637 }
lichengzhang8c043332025-07-30 17:43:23 +08002638 binary_data[bin_index++] = (kal_uint8)hex_val;
2639 ptr += 2;
xy.hef1956462024-12-13 21:30:43 -08002640 }
lichengzhang8c043332025-07-30 17:43:23 +08002641
2642 // 分配UTF-8缓冲区(最大可能大小)
2643 utf8_buffer = malloc(data_len * 3 + 1);
2644 if (!utf8_buffer) {
2645 free(binary_data);
2646 LOGE("Memory allocation failed for UTF-8 buffer");
2647 return MDAPI_RET_ERROR;
2648 }
2649
2650 // 转换二进制数据到UTF-8
2651 kal_int32 buf_pos = 0;
2652 for (i = 0; i < data_len; i++) {
2653 kal_uint8 tmp[2] = {binary_data[i], 0};
2654 kal_int32 converted = kal_ext_ascii_to_utf8(
2655 (UTF8*)(utf8_buffer + buf_pos),
2656 tmp,
2657 (data_len * 3) - buf_pos
2658 );
2659
2660 if (converted <= 0) {
2661 LOGE("Character conversion failed at position %d", i);
2662 break;
2663 }
2664 buf_pos += converted;
2665 }
2666 utf8_buffer[buf_pos] = '\0';
2667 utf8_len = buf_pos;
2668
2669 // 复制到输出缓冲区
2670 kal_int32 copy_size = MIN(utf8_len, *record_size - 1);
2671 memcpy(sms->msg_content, utf8_buffer, copy_size);
2672 sms->msg_content[copy_size] = '\0';
2673 *record_size = copy_size;
2674
2675 // 清理临时内存
2676 free(binary_data);
2677 free(utf8_buffer);
2678
lichengzhangd01f0742025-08-19 18:04:41 +08002679 LOGE("8bit msg decoded: len=%d, content=%s",
2680 copy_size, sms->msg_content);
xy.hef1956462024-12-13 21:30:43 -08002681 break;
2682
2683 case MDAPI_SMS_CHARSET_UCS2:
2684 buf_len = 0;
2685
2686 if( 1 == udh ) {
2687 data_len -= (udh_len + 1);
2688 }
2689
2690 sms->msg_content[0] = '\0';
2691
2692 for (i=0 ; i < data_len ; i = i + 2) {
2693 UTF16 tmp[2] = {0, 0};
2694 kal_uint8 *tmp_ptr = (kal_uint8 *)tmp;
2695
2696 tmp_ptr[0] = internal_mdapi_hex2int(ptr);
2697 ptr += 2;
2698 tmp_ptr[1] = internal_mdapi_hex2int(ptr);
2699 ptr += 2;
2700 tmp[0] = ntohs(tmp[0]);
2701 //LOGE(KAL_LOG_INFO, LOG_TAG, "tmp = [%04X]", tmp);
2702
2703 buf_len += kal_utf16_to_utf8((UTF8 *)(sms->msg_content + buf_len), tmp, *record_size - buf_len);
2704 if (*record_size - buf_len < 0) {
2705 return MDAPI_RET_ERROR;
2706 }
2707 }
2708
2709 *(sms->msg_content + buf_len++) = '\0';
2710 *(sms->msg_content + buf_len++) = '\0';
2711
2712 *record_size = buf_len;
2713
2714
2715 break;
2716
2717 default:
2718 return MDAPI_RET_ERROR;
2719 }
2720 }
2721
2722 sms->position = MDAPI_SMS_POS_INBOX;
2723 return MDAPI_RET_SUCCESS;
2724}
2725
2726
2727int smsPduDecode(const char *pdu_str, int pdu_len,
2728 char *da_num, char *smsc, char *msg, int *charset, int *curr_pack, int *total_pack, char *date)
2729{
2730 kal_char msg_tmp[MAX_PDU_SIZE] = {0};
2731 mdapi_sms_record_t record;
2732 kal_int32 status = MDAPI_RET_ERROR;
2733 kal_int32 out_len = 210;
2734
2735 LOGE("%s\n",__FILE__);
2736 LOGE("%s\n",__FUNCTION__);
2737 LOGE("%d\n",__LINE__);
2738 LOGE("%d\n",pdu_len);
2739 LOGE("%s\n",pdu_str);
2740
2741 record.msg_content = msg_tmp;
2742 /*lei modify for gsw 2022/5/11*/
2743 status = _mdapi_sms_decode_pdu(&record, smsc, (kal_int8 *)pdu_str,
2744 pdu_len, &out_len, curr_pack, total_pack);
2745 /*lei modify for gsw 2022/5/11*/
2746 if(status == MDAPI_RET_SUCCESS) {
2747 memcpy(da_num, record.phone_number, strlen(record.phone_number));
lichengzhang8c043332025-07-30 17:43:23 +08002748 memcpy(msg, record.msg_content, out_len);
xy.hef1956462024-12-13 21:30:43 -08002749 *charset = record.charset;
2750 memcpy(date, record.time, strlen(record.time));
2751
2752 #if 0
2753 /*lei modify for gsw 2022/5/11*/
2754 *curr_pack = record.curr_pack;
2755 *total_pack = record.total_pack;
2756 /*lei modify for gsw 2022/5/11*/
2757 #endif
2758 } else {
2759 LOGE("PDU decode error");
2760 }
2761
2762 return status;
r.xiao18d95372024-12-30 23:32:51 -08002763}
2764
lichengzhangd01f0742025-08-19 18:04:41 +08002765
r.xiao18d95372024-12-30 23:32:51 -08002766void ArrayToStr(unsigned char *Buff, unsigned int BuffLen, char *OutputStr)
2767{
2768 int i = 0;
2769 char TempBuff[1024 * 2 +1] = {0};
2770 char strBuff[1024 * 2 +1] = {0};
2771
2772 for(i = 0; i<BuffLen;i++)
2773 {
2774 sprintf(TempBuff,"%02x",(unsigned char)Buff[i]);
2775 strncat(strBuff,TempBuff,BuffLen*2);
2776 }
2777 strncpy(OutputStr, strBuff, BuffLen*2);
2778 return;
xy.hef1956462024-12-13 21:30:43 -08002779}