blob: 553c69158da47357e7b388077e30834b731d6452 [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];
19
20// 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
1106
1107
1108
1109
1110int hexChar_To_Int(char c)
1111{
1112 if (c >= '0' && c <= '9')
1113 return (c - '0');
1114 if (c >= 'A' && c <= 'F')
1115 return (c - 'A' + 10);
1116 if (c >= 'a' && c <= 'f')
1117 return (c - 'a' + 10);
1118
1119 return 0;
1120}
1121
1122
1123void hexString_To_Bytes(char *in, int inLength, char *out)
1124{
1125 int i;
1126
1127 if (in == NULL || out == NULL)
1128 {
1129 return;
1130 }
1131
1132 for (i = 0 ; i < inLength ; i += 2)
1133 {
1134 out[i/2] = (char)((hexChar_To_Int(in[i]) << 4)
1135 | hexChar_To_Int(in[i+1]));
1136 }
1137}
1138
1139/* RFC3629 chapter 4. Syntax of UTF-8 Byte Sequences */
1140static kal_int32 is_legal_utf8(const UTF8 *start, kal_int32 len)
1141{
1142 UTF8 tmp = 0;
1143 const UTF8 *ptr = start + len;
1144
1145 switch (len) {
1146 default:
1147 return FALSE;
1148
1149 case 4:
1150 tmp = *--ptr;
1151 if (tmp < 0x80 || tmp > 0xBF) {
1152 return FALSE;
1153 }
1154
1155 case 3:
1156 tmp = *--ptr;
1157 if (tmp < 0x80 || tmp > 0xBF) {
1158 return FALSE;
1159 }
1160
1161 case 2:
1162 tmp = *--ptr;
1163 if (tmp > 0xBF) {
1164 return FALSE;
1165 }
1166
1167 switch (*start) {
1168 case 0xE0:
1169 if (tmp < 0xA0) {
1170 return FALSE;
1171 }
1172 break;
1173
1174 case 0xED:
1175 if (tmp > 0x9F) {
1176 return FALSE;
1177 }
1178 break;
1179
1180 case 0xF0:
1181 if (tmp < 0x90) {
1182 return FALSE;
1183 }
1184 break;
1185
1186 case 0xF4:
1187 if (tmp > 0x8F) {
1188 return FALSE;
1189 }
1190 break;
1191
1192 default:
1193 if (tmp < 0x80) {
1194 return FALSE;
1195 }
1196 break;
1197 }
1198
1199 case 1:
1200 if (*start >= 0x80 && *start < 0xC2) {
1201 return FALSE;
1202 }
1203 }
1204
1205 if (*start > 0xF4) {
1206 return FALSE;
1207 }
1208
1209 return TRUE;
1210}
1211
1212kal_int32 kal_utf16_to_utf8(UTF8 *dest, const UTF16 *src, kal_int32 size)
1213{
1214 kal_int32 result = STATUS_SUCCESS;
1215 const UTF16 *start = src;
1216 const UTF16 *end = src;
1217 const UTF32 TAIL_MASK = 0xBF;
1218 const UTF32 TAIL_MARK = 0x80;
1219
1220 UTF8 *target = dest;
1221
1222 if (!src) { return STATUS_NULL_POINTER; }
1223 while (*end) {
1224 end++;
1225 }
1226
1227 while (start < end) {
1228 UTF32 tmp = 0;
1229 unsigned long bytes = 0;
1230
1231 tmp = *start++;
1232 //LOGE("tmp = [%X]\n", tmp);
1233 /* */
1234 if (tmp >= SUR_HIGH_START && tmp <= SUR_HIGH_END) {
1235 if (start < end) {
1236 UTF32 tmp2 = *start;
1237 if (tmp2 >= SUR_LOW_START && tmp2 <= SUR_LOW_END) {
1238 tmp = ((tmp - SUR_HIGH_START) << UTF16_HALF_SHIFT)
1239 + (tmp2 - SUR_LOW_START) + UTF16_HALF_BASE;
1240 start++;
1241 } else {
1242 result = STATUS_ILLEGAL_UTF16;
1243 break;
1244 }
1245 } else {
1246 result = STATUS_MEM_EXHAUSTED;
1247 break;
1248 }
1249 } else if (tmp >= SUR_LOW_START && tmp <= SUR_LOW_END) {
1250 result = STATUS_ILLEGAL_UTF16;
1251 break;
1252 }
1253
1254 if (tmp < (UTF32)0x80) {
1255 bytes = 1;
1256 } else if (tmp < (UTF32)0x800) {
1257 bytes = 2;
1258 } else if (tmp < (UTF32)0x10000) {
1259 bytes = 3;
1260 } else if (tmp < (UTF32)0x110000) {
1261 bytes = 4;
1262 } else {
1263 result = STATUS_ILLEGAL_UTF16;
1264 break;
1265 }
1266
1267 if (target && size > 0) {
1268 size -= bytes;
1269 if (0 >= size) {
1270 break;
1271 }
1272
1273 switch (bytes) {
1274 case 4:
1275 *(target + 3) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
1276 tmp >>= 6;
1277 case 3:
1278 *(target + 2) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
1279 tmp >>= 6;
1280 case 2:
1281 *(target + 1) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
1282 tmp >>= 6;
1283 case 1:
1284 *target = (UTF8)(tmp | first_byte_mark[bytes]);
1285 }
1286 target += bytes;
1287 }
1288 result += bytes;
1289 }
1290
1291 if (target)
1292 *target = 0;
1293
1294 return result;
1295}
1296
1297kal_int32 kal_ext_ascii_to_utf8(UTF8 *dest, const kal_uint8 *src, kal_int32 size)
1298{
1299 kal_int32 result = STATUS_SUCCESS;
1300 const kal_uint8 *start = src, *end = src;
1301 const UTF32 TAIL_MASK = 0xBF;
1302 const UTF32 TAIL_MARK = 0x80;
1303 UTF8 *target = dest;
1304
1305 if (!src) { return STATUS_NULL_POINTER; }
1306 while (*end) {
1307 end++;
1308 }
1309
1310 while (start < end) {
1311 UTF32 tmp = 0;
1312 unsigned long bytes = 0;
1313
1314 tmp = *start++;
1315
1316 if (tmp < (UTF32)0x80) {
1317 bytes = 1;
1318 } else {
1319 bytes = 2;
1320 }
1321
1322 if (target && size > 0) {
1323 size -= bytes;
1324 if (size <= 0) {
1325 break;
1326 }
1327
1328 switch (bytes) {
1329 case 2:
1330 *(target + 1) = (UTF8)((tmp | TAIL_MARK) & TAIL_MASK);
1331 tmp >>= 6;
1332 case 1:
1333 *target = (UTF8)(tmp | first_byte_mark[bytes]);
1334 }
1335 target += bytes;
1336 }
1337 result += bytes;
1338 }
1339
1340 if (target) {
1341 *target = 0;
1342 }
1343
1344 return result;
1345}
1346
1347kal_int32 kal_utf8_to_utf16(UTF16 *dest,
1348 const UTF8 *src,
1349 kal_int32 size)
1350{
1351 kal_int32 result = STATUS_SUCCESS;
1352 const UTF8 *start = src;
1353 const UTF8 *end = src;
1354 UTF16 *target = dest;
1355
1356 while(*end) {
1357 end++;
1358 }
1359
1360 while (start < end) {
1361 unsigned long tmp = 0;
1362 unsigned int extra_bytes = utf8_tailing_bytes[*start];
1363 //UTF8 *next = start + extra_bytes + 1;
1364
1365 if (target && target >= dest + size) {
1366 result = STATUS_MEM_EXHAUSTED;
1367 break;
1368 }
1369
1370 if (start + extra_bytes >= end) {
1371 result = STATUS_MEM_EXHAUSTED;
1372 break;
1373 }
1374
1375 if (!is_legal_utf8(start, extra_bytes + 1)) {
1376 result = STATUS_ILLEGAL_UTF8;
1377 break;
1378 }
1379
1380 switch (extra_bytes) {
1381 case 5:
1382 tmp += *start++;
1383 tmp <<= 6; /* illegal UTF8 */
1384 case 4:
1385 tmp += *start++;
1386 tmp <<= 6; /* illegal UTF8 */
1387 case 3:
1388 tmp += *start++;
1389 tmp <<= 6;
1390 case 2:
1391 tmp += *start++;
1392 tmp <<= 6;
1393 case 1:
1394 tmp += *start++;
1395 tmp <<= 6;
1396 case 0:
1397 tmp += *start++;
1398 }
1399
1400 tmp -= utf8_offsets[extra_bytes];
1401
1402 if (tmp <= MAX_UNI_BMP) {
1403 if (tmp >= SUR_HIGH_START && tmp <= SUR_LOW_END) {
1404 result = STATUS_ILLEGAL_UTF8;
1405 break;
1406 } else {
1407 if (target) {
1408 *target++ = (UTF16)tmp;
1409 }
1410
1411 result++;
1412 }
1413 } else if (tmp > MAX_UTF16) {
1414 result = STATUS_ILLEGAL_UTF8;
1415 break;
1416 } else {
1417 if (target && target + 1 >= dest + size) {
1418 result = STATUS_MEM_EXHAUSTED;
1419 break;
1420 }
1421
1422 tmp -= UTF16_HALF_BASE;
1423
1424 if (target) {
1425 *target++ = (UTF16)((tmp >> UTF16_HALF_SHIFT) + SUR_HIGH_START);
1426 *target++ = (UTF16)((tmp & UTF16_HALF_MASK) + SUR_LOW_START);
1427 }
1428
1429 result += 2;
1430 }
1431 }
1432
1433 if (target) {
1434 *target = 0;
1435 }
1436
1437 return result;
1438}
1439
1440static kal_int32 _mdapi_sms_set_timestamp(mdapi_sms_record_t *sms)
1441{
1442 struct tm *p;
1443 kal_int32 y = 0;
1444
1445 struct timeval tv;
1446 struct timezone tz;
1447
1448 gettimeofday (&tv, &tz);
1449
1450 sms->time[6] = tz.tz_minuteswest;
1451
1452 p = localtime(&tv.tv_sec);
1453 y = 1900 + p->tm_year;
1454 sms->time[0] = y % 100;
1455 sms->time[1] = 1 + p->tm_mon;
1456 sms->time[2] = p->tm_mday;
1457 sms->time[3] = p->tm_hour;
1458 sms->time[4] = p->tm_min;
1459 sms->time[5] = p->tm_sec;
1460
1461 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]);
1462 LOGE("timezone = %d\n", sms->time[6]);
1463
1464 return MDAPI_RET_SUCCESS;
1465}
1466
1467kal_uint8 lookup_latin1_to_gsm_ex_table(kal_int8 character)
1468{
1469 int i;
1470 for( i=0; latin1_to_gsm_tableEx[i].symbol != 0; i++) {
1471 if (character == latin1_to_gsm_tableEx[i].symbol)
1472 return latin1_to_gsm_tableEx[i].value;
1473 }
1474 return 255;
1475}
1476
1477
1478
1479
1480void _smsbuf_byte_align(smsbuf_t *buf)
1481{
1482 if (buf->curbyte > buf->finalbyte) {
1483 return;
1484 }
1485 if (buf->curbit != 0) {
1486 buf->curbit = 0;
1487 buf->curbyte++;
1488 }
1489}
1490
1491void _smsbuf_init(smsbuf_t *buf)
1492{
1493 buf->curbyte = buf->smsbuf;
1494 buf->curbit = 0;
1495 memset(buf->smsbuf, 0, sizeof(buf->smsbuf));
1496 buf->finalbyte = buf->curbyte + sizeof(buf->smsbuf);
1497}
1498
1499void _smsbuf_set1bit(smsbuf_t *buf, kal_uint8 b)
1500{
1501 if (buf->curbyte > buf->finalbyte)
1502 return;
1503
1504 if (b != 0)
1505 *buf->curbyte |= (1 << buf->curbit);
1506
1507 buf->curbit++;
1508 if (buf->curbit == 8) {
1509 buf->curbit = 0;
1510 buf->curbyte++;
1511 }
1512}
1513
1514void _smsbuf_set_multi_bits(smsbuf_t *buf, kal_uint32 value, kal_uint8 bit_num)
1515{
1516 kal_int32 i = 0;
1517
1518 for (i = 0; i < bit_num; i++) {
1519 _smsbuf_set1bit(buf, (value & (1 << i)) != 0);
1520 }
1521}
1522
1523void _smsbuf_set_octet(smsbuf_t *buf, kal_uint8 c)
1524{
1525 _smsbuf_byte_align(buf);
1526 *(buf->curbyte) = c;
1527 buf->curbyte++;
1528}
1529
1530void _smsbuf_septet_align(smsbuf_t *buf)
1531{
1532 if (buf->curbyte > buf->finalbyte)
1533 return;
1534 while (((buf->curbyte - buf->septet_start) * 8 + buf->curbit) % 7 != 0)
1535 _smsbuf_set1bit(buf, 0);
1536}
1537
1538void _smsbuf_set_septet_start(smsbuf_t *buf)
1539{
1540 _smsbuf_byte_align(buf);
1541 buf->septet_start = buf->curbyte;
1542}
1543
1544void _smsbuf_set_string(smsbuf_t *buf, kal_int8 *str, kal_int32 size)
1545{
1546 kal_int32 i = 0;
1547 _smsbuf_septet_align(buf);
1548
1549 //LOGE("%s, %s, %d. string is:[%s],size is:[%d]", __FILE__, __FUNCTION__, __LINE__, (char*)str, size);
1550 while (*str && size) {
1551 /* change the iso8859latin1 charactor to gsm support charactor */
1552 //LOGE("%s, %s, %d. character is:[%d]-[0x%x]", __FILE__, __FUNCTION__, __LINE__, (int)*str,*str);
1553 kal_uint8 c = lookup_latin1_to_gsm_ex_table(*str);
1554 if(c != 255)
1555 {
1556 //LOGE("extent table!");
1557 for (i = 0; i < 7; i++) {
1558 _smsbuf_set1bit(buf, ((1 << i) & 0x1b) != 0);
1559 }
1560 size--;
1561 } else {
1562 c = latin1_to_gsm_table[(kal_uint8)*str];
1563 }
1564 //LOGE("%s, %s, %d. character is:[%d]-[0x%x]", __FILE__, __FUNCTION__, __LINE__, (int)c,c);
1565 str++;
1566 size--;
1567 for (i = 0; i < 7; i++) {
1568 _smsbuf_set1bit(buf, ((1 << i) & c) != 0);
1569 //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%X]", buf->curbit, *buf->curbyte);
1570 }
1571 //LOGE(KAL_LOG_INFO, LOG_TAG, "size = [%d] c = [%c]", size, c);
1572 }
1573}
1574
1575void _smsbuf_set_addr(smsbuf_t *buf, kal_int8 *str)
1576{
1577 _smsbuf_byte_align(buf);
1578
1579 while (*str) {
1580 kal_uint8 c = *str;
1581
1582 if (*str == '*') {
1583 c = 0xa;
1584 } else if (*str == '#') {
1585 c = 0xb;
1586 } else if (*str == 'p') {
1587 c = 0xc;
1588 } else if (*str == 'w') {
1589 c = 0xd;
1590 } else if (*str == '+') {
1591 c = 0xe;
1592 } else {
1593 c = *str - '0';
1594 }
1595
1596 if (buf->curbit == 0) {
1597 *buf->curbyte = c;
1598 buf->curbit = 4;
1599 } else {
1600 *buf->curbyte |= (c << 4);
1601 buf->curbyte++;
1602 buf->curbit = 0;
1603 }
1604
1605 str++;
1606 }
1607
1608 if (buf->curbit == 4) {
1609 *buf->curbyte |= 0xF0;
1610 buf->curbyte++;
1611 buf->curbit = 0;
1612 }
1613}
1614
1615
1616kal_int32 _smsbuf_hex_string(smsbuf_t *buf, kal_int8 *output, kal_int32 size)
1617{
1618 kal_int32 len = 0;
1619 kal_uint8 *str = buf->smsbuf;
1620
1621 _smsbuf_byte_align(buf);
1622 while (str != buf->curbyte && (size - len) > 3) {
1623 len += snprintf(output + len, size - len, "%02X", *str);
1624 str++;
1625 }
1626
1627 return len;
1628}
1629
1630kal_int32 _mdapi_sms_get_msg_num(const char *msg, int charset, kal_int32 *msg_num, kal_int32 *msg_len)
1631{
1632 LOGE("%s, %s, %d, send sms content = [%s]",__FILE__, __FUNCTION__, __LINE__, msg);
1633 *msg_num = 0;
1634 *msg_len = 0;
1635 kal_int32 max_len = 0;
1636
1637 if (charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
1638 *msg_len = strlen(msg);
1639
1640 //special char
1641 kal_int32 extenSize =0;
1642 kal_char* point = (kal_char*)msg;
1643 kal_int32 size = *msg_len;
1644 while (*point && size) {
1645 kal_uint8 c = lookup_latin1_to_gsm_ex_table((kal_int8)*point);
1646 if(c != 255)
1647 extenSize++;
1648 point++;
1649 size--;
1650 }
1651 //special char
1652 if (*msg_len + extenSize > 160) {
1653 *msg_num = (*msg_len + extenSize + MAX_7BIT_MSG_LEN - 1) / MAX_7BIT_MSG_LEN;
1654 max_len = MAX_7BIT_MSG_LEN;
1655 } else {
1656 *msg_num = 1;
1657 }
1658
1659 if (*msg_num > MAX_CONCATENATED_MSG) {
1660 LOGE("message is too long. msg_len[%d], msg_num[%d], max_len[%d]", *msg_len, *msg_num, max_len);
1661 return MDAPI_RET_ERROR;
1662 }
1663 LOGE("%s, %s, %d, 7bit msg_len = [%d] ,msg_num=[%d]", __FILE__, __FUNCTION__, __LINE__, *msg_len, *msg_num);
1664 } else if (charset == MDAPI_SMS_CHARSET_UCS2) {
1665 //UTF16 *dest = NULL;
1666 *msg_len = kal_utf8_to_utf16(NULL, (const UTF8 *)msg, 0);
1667 if (*msg_len > 70) {
1668 *msg_num = (*msg_len + MAX_UCS2_MSG_LEN - 1) / MAX_UCS2_MSG_LEN;
1669 max_len = MAX_UCS2_MSG_LEN * 2;
1670 } else {
1671 *msg_num = 1;
1672 }
1673
1674 if (*msg_num > MAX_CONCATENATED_MSG) {
1675 LOGE("message is too long. msg_len[%d], msg_num[%d], max_len[%d]", msg_len, msg_num, max_len);
1676 return MDAPI_RET_ERROR;
1677 }
1678 } else if (charset == MDAPI_SMS_CHARSET_GSM_8BIT) {
1679 *msg_len = strlen(msg);
1680 if(*msg_len > (140 * 2))
1681 {
1682 *msg_num = (*msg_len + MAX_8BIT_MSG_LEN - 1) / MAX_8BIT_MSG_LEN;
1683 max_len = MAX_8BIT_MSG_LEN;
1684
1685 if (*msg_num > MAX_CONCATENATED_MSG) {
1686 LOGE("message is too long. msg_len[%d], msg_num[%d], max_len[%d]", *msg_len, *msg_num, max_len);
1687 return MDAPI_RET_ERROR;
1688 }
1689 }
1690 else {
1691 *msg_num = 1;
1692 }
1693 } else{
1694 LOGE("Not support charset");
1695 return MDAPI_RET_ERROR;
1696 }
1697
1698 return MDAPI_RET_SUCCESS;
1699}
1700
1701kal_int32 _mdapi_sms_encode_addr(smsbuf_t *buf, kal_int8 *smsc, kal_int32 type)
1702{
1703 kal_int32 len = strlen(smsc);
1704 kal_int8 *str = smsc;
1705
1706 kal_uint8 addr_plane = SMS_NP_ISDNTEL;
1707 kal_uint8 addr_type = SMS_TON_UNKNOWN;
1708
1709 if (len <= 0) {
1710 /* use default sca for sms message */
1711 _smsbuf_set_octet(buf, 0);
1712 return 1;;
1713 }
1714
1715 if (len > 255) {
1716 LOGE("input number is too long. len[%d] smsc[%s] ", len, smsc);
1717 return 0;
1718 }
1719
1720 /* check the type of address */
1721 while (*str) {
1722 if (!isdigit(*str) && *str != '+' && *str != '*'
1723 && *str != '#' && *str != 'p' && *str != 'w')
1724 addr_type = SMS_TON_ALPHANUMERIC;
1725 str++;
1726 }
1727
1728 if (smsc[0] == '+' && addr_type != SMS_TON_ALPHANUMERIC) {
1729 addr_type = SMS_TON_INTERNATIONAL;
1730 /* */
1731 str = &smsc[1];
1732 len--;
1733 } else {
1734 str = smsc;
1735 }
1736
1737 /* set len */
1738 if (type == SMS_ENCODE_SCA)
1739 _smsbuf_set_octet(buf, len / 2 + len % 2 + 1);
1740 else {
1741 _smsbuf_set_octet(buf, len);
1742 }
1743
1744 LOGE("%02X, %d ", *(buf->curbyte), buf->curbyte - buf->smsbuf);
1745
1746 _smsbuf_set_multi_bits(buf, addr_plane, 4);
1747 _smsbuf_set_multi_bits(buf, addr_type, 3);
1748 _smsbuf_set1bit(buf, 1);
1749
1750 LOGE("%02X, %d ", *(buf->curbyte), buf->curbyte - buf->smsbuf);
1751
1752 if (addr_type == SMS_TON_ALPHANUMERIC) {
1753 _smsbuf_set_septet_start(buf);
1754 _smsbuf_set_string(buf, str, len);
1755 } else {
1756 _smsbuf_set_addr(buf, str);
1757 }
1758
1759 _smsbuf_byte_align(buf);
1760
1761 return buf->curbyte - buf->smsbuf;
1762}
1763
1764kal_int32 _mdapi_sms_encode_pdu(mdapi_sms_record_t *sms,
1765 kal_int8 *smsc,
1766 mdapi_sms_settings_t *settings,
1767 kal_char *start,
1768 kal_int32 send_size,
1769 kal_uint8 *udh,
1770 kal_char *output,
1771 kal_int32 out_len,
1772 kal_int32 *sca_out_len)
1773{
1774 smsbuf_t smsbuf;
1775 kal_int32 udh_len = 0;
1776 kal_int32 len = 0;
1777 kal_int32 sca_len = 0;
1778
1779 if (udh) {
1780 udh_len = udh[0];
1781 } else {
1782 udh_len = 0;
1783 }
1784
1785 memset(&smsbuf, 0, sizeof(smsbuf));
1786 _smsbuf_init(&smsbuf);
1787
1788 /* SMSC */
1789 sca_len = _mdapi_sms_encode_addr(&smsbuf, smsc, SMS_ENCODE_SCA);
1790
1791 /* Encode PDU Type */
1792 {
1793 _smsbuf_byte_align(&smsbuf);
1794
1795 /* Message Type Indicator */
1796 _smsbuf_set_multi_bits(&smsbuf, SMS_SUBMIT, 2);
1797 //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
1798 /* Reject Duplicate */
1799 _smsbuf_set1bit(&smsbuf, 0);
1800 //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
1801 /* Validity Period Format */
1802 _smsbuf_set_multi_bits(&smsbuf, settings->vpf, 2);
1803 //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
1804
1805 /* Status Report Request */
1806 if (settings->srr)
1807 _smsbuf_set1bit(&smsbuf, 1);
1808 else
1809 _smsbuf_set1bit(&smsbuf, 0);
1810 //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
1811
1812 /* User Data Header Indicator */
1813 if (udh_len)
1814 _smsbuf_set1bit(&smsbuf, 1);
1815 else
1816 _smsbuf_set1bit(&smsbuf, 0);
1817
1818 //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
1819
1820 /* Replay Path */
1821 _smsbuf_set1bit(&smsbuf, settings->rp);
1822
1823 //LOGE(KAL_LOG_INFO, LOG_TAG, "curbit = [%d] curbyte=[%02X]", smsbuf.curbit, *smsbuf.curbyte);
1824 }
1825
1826 /* Encode MR */
1827 {
1828 /* Message Reference Count, Long Message should use this */
1829 _smsbuf_set_octet(&smsbuf, 0);
1830 }
1831
1832 /* Encode OA/DA */
1833 _mdapi_sms_encode_addr(&smsbuf, sms->phone_number, SMS_ENCODE_OADA);
1834
1835 /* Encode Protocol Identifier */
1836 _smsbuf_set_octet(&smsbuf, 0x00);
1837
1838 /* Encode DCS */
1839 {
1840 /* Bit 0,1, Class */
1841 _smsbuf_set_multi_bits(&smsbuf, sms->sms_class, 2);
1842 /* Bit 2,3, Class */
1843 _smsbuf_set_multi_bits(&smsbuf, sms->charset, 2);
1844 /* Bit 4 */
1845 _smsbuf_set1bit(&smsbuf, 0);
1846 /* Bit 5 */
1847 /* No text compressed */
1848 _smsbuf_set1bit(&smsbuf, 0);
1849 /* Bit 6, 7 */
1850 _smsbuf_set_multi_bits(&smsbuf, 0, 0);
1851 }
1852 //_smsbuf_byte_align(&smsbuf);
1853
1854 /* Validity Period */
1855 {
1856 if (settings->vpf == SMS_VPF_ABSOLUTE) {
1857 // TODO: add absolute validity period
1858
1859 } else if (settings->vpf == SMS_VPF_RELATIVE) {
1860 // TODO: add validity period support
1861 kal_uint8 validity_period = 0xAA;
1862 _smsbuf_set_octet(&smsbuf, validity_period);
1863 }
1864 }
1865
1866 /* User Data Header */
1867 {
1868 if (udh_len) {
1869 kal_int32 i = 0;
1870 if (sms->charset == MDAPI_SMS_CHARSET_UCS2) {
1871 _smsbuf_set_octet(&smsbuf, 1 + udh_len + send_size);
1872 } else if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
1873 _smsbuf_set_octet(&smsbuf, (((1 + udh_len) * 8 + 6) / 7) + send_size);
1874 } else if (sms->charset == MDAPI_SMS_CHARSET_GSM_8BIT) {
1875 _smsbuf_set_octet(&smsbuf, 1 + udh_len + send_size/2);
1876 }
1877
1878 /* set the start byte of septet(7bits) align */
1879 _smsbuf_set_septet_start(&smsbuf);
1880 for (i = 0; i < udh_len + 1; i++) {
1881 _smsbuf_set_octet(&smsbuf, udh[i]);
1882 }
1883 } else {
1884 if(sms->charset == MDAPI_SMS_CHARSET_GSM_8BIT)
1885 {
1886 _smsbuf_set_octet(&smsbuf, send_size/2);
1887 }
1888 else
1889 {
1890 _smsbuf_set_octet(&smsbuf, send_size);
1891 }
1892
1893 /* set the start byte of septet(7bits) align */
1894 _smsbuf_set_septet_start(&smsbuf);
1895 }
1896 }
1897
1898 /* Get the Hex String */
1899 len = _smsbuf_hex_string(&smsbuf, output, out_len);
1900 LOGE("encoded pdu = (%s), len = (%d) ", output, len);
1901
1902 /* Set User Data */
1903 if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
1904 //_sms_iso8859latin1_to_gsm(start, gsm, *size + 1);
1905 _smsbuf_set_string(&smsbuf, start, send_size);
1906 } else if(sms->charset == MDAPI_SMS_CHARSET_GSM_8BIT) {
1907 kal_int32 i = 0;
1908 char outhex[MAX_PDU_SIZE] = {0};
1909 hexString_To_Bytes(start, send_size, outhex);
1910 for (i = 0; i < send_size/2; i++) {
1911 _smsbuf_set_octet(&smsbuf, outhex[i]);
1912 }
1913 } else {
1914 kal_int32 i = 0;
1915 for (i = 0; i < send_size; i += 2) {
1916 kal_uint16 tmp = 0;
1917 kal_uint8 *ptr = (kal_uint8 *)&tmp;
1918
1919 *ptr = *(start + i);
1920 *(ptr + 1) = *(start + i + 1);
1921 tmp = htons(tmp);
1922 _smsbuf_set_octet(&smsbuf, *(ptr));
1923 _smsbuf_set_octet(&smsbuf, *(ptr + 1));
1924 }
1925 }
1926
1927 /* Get the Hex String */
1928 len = _smsbuf_hex_string(&smsbuf, output, out_len);
1929 *sca_out_len = sca_len * 2;
1930 LOGE("start = [%p] size = [%d] encoded pdu = (%s), len = (%d)", start, send_size, output, len);
1931
1932 return len;
1933}
1934
1935
1936
1937
1938
1939int smsPduEncode(const char *smsc, const char *da_num, const char *msg, int charset,
1940 char *smsc_pdu, char **pdu)
1941{
1942 mdapi_sms_record_t record;
1943 mdapi_sms_settings_t sms_settings;
1944 //kal_int32 status = MDAPI_RET_ERROR;
1945 kal_int32 msg_num = 0;
1946 kal_int32 msg_len = 0;
1947 kal_int32 max_len = 0;
1948 kal_char *msg_content = NULL;
1949 kal_int32 out_len = 0;
1950 kal_int8 output[MAX_PDU_SIZE] = {0};
1951 kal_int32 sca_out_len;
1952 mdapi_sms_record_t *sms = &record;
1953
1954 memset(sms, 0, sizeof(mdapi_sms_record_t));
1955
1956 snprintf(sms->phone_number, sizeof(sms->phone_number), "%s", da_num);
1957 sms->msg_content = (kal_char *)msg;
1958 sms->charset = charset;
1959
1960 sms_settings.rd = 1;
1961 sms_settings.vpf = SMS_VPF_RELATIVE;
1962 sms_settings.srr = 1;
1963 sms_settings.rp = 0;
1964 sms_settings.validity_period = 0;
1965
1966 // status = _mdapi_sms_get_msg_num(msg, charset, &msg_num, &msg_len);
1967
1968 /*if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
1969 msg_content = sms->msg_content;
1970 } else if (sms->charset == MDAPI_SMS_CHARSET_UCS2) {
1971 UTF16 *dest = NULL;
1972 msg_content = (kal_char *)malloc((msg_len + 1) * sizeof(UTF16));
1973 dest = (UTF16 *)msg_content;
1974 msg_len = kal_utf8_to_utf16(dest, (const UTF8 *)sms->msg_content, (msg_len + 1) * sizeof(UTF16));
1975 if (msg_len <= 0) {
1976 free(msg_content);
1977 msg_content = NULL;
1978 return MDAPI_RET_ERROR;
1979 }
1980 msg_len *= 2;
1981 LOGE("ucs2 msg_len = [%d] ,msg_num=[%d] ", msg_len,msg_num);
1982 }else {
1983 LOGE("Not support charset");
1984 return MDAPI_RET_ERROR;
1985 }*/
1986 if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT) {
1987 msg_len = strlen(sms->msg_content);
1988
1989 //for special char
1990 kal_int32 extenTotalSize =0;
1991 //kal_int32 i = 0;
1992 kal_char* point = sms->msg_content;
1993 LOGE("XXX msg len %d \n",msg_len);
1994 kal_int32 size = msg_len;
1995 while (*point && size) {
1996 kal_uint8 c = lookup_latin1_to_gsm_ex_table((kal_int8)*point);
1997 if(c != 255){
1998 extenTotalSize++;
1999 }
2000 point++;
2001 size--;
2002 }
2003 //for specail char
2004 msg_len += extenTotalSize;
2005 LOGE("XXX msg_len %d extenTotalSize %d \n",msg_len,extenTotalSize);
2006 if (msg_len > 160) {
2007 msg_num = (msg_len + MAX_7BIT_MSG_LEN - 1) / MAX_7BIT_MSG_LEN;
2008 max_len = MAX_7BIT_MSG_LEN;
2009 } else {
2010 msg_num = 1;
2011 }
2012
2013 if (msg_num > MAX_CONCATENATED_MSG) {
2014 LOGE("message is too long. msg_len[%d], msg_num[%d]", msg_len, msg_num);
2015 return MDAPI_RET_ERROR;
2016 }
2017 LOGE("7bit msg_len = [%d] ,msg_num=[%d]", msg_len,msg_num);
2018 msg_content = sms->msg_content;
2019 } else if (sms->charset == MDAPI_SMS_CHARSET_UCS2) {
2020 UTF16 *dest = NULL;
2021 msg_len = kal_utf8_to_utf16(NULL, (const UTF8 *)sms->msg_content, 0);
2022 if (msg_len > 70) {
2023 msg_num = (msg_len + MAX_UCS2_MSG_LEN - 1) / MAX_UCS2_MSG_LEN;
2024 max_len = MAX_UCS2_MSG_LEN * 2;
2025 } else {
2026 msg_num = 1;
2027 }
2028
2029 if (msg_num > MAX_CONCATENATED_MSG) {
2030 LOGE("message is too long. msg_len[%d], msg_num[%d]", msg_len, msg_num);
2031 return MDAPI_RET_ERROR;
2032 }
2033
2034 msg_content = (kal_char *)malloc((msg_len + 1) * sizeof(UTF16));
2035 dest = (UTF16 *)msg_content;
2036 msg_len = kal_utf8_to_utf16(dest, (const UTF8 *)sms->msg_content, (msg_len + 1) * sizeof(UTF16));
2037 if (msg_len <= 0) {
2038 free(msg_content);
2039 msg_content = NULL;
2040 return MDAPI_RET_ERROR;
2041 }
2042 msg_len *= 2;
2043 LOGE("ucs2 msg_len = [%d] ,msg_num=[%d] ", msg_len,msg_num);
2044 } else if (sms->charset == MDAPI_SMS_CHARSET_GSM_8BIT) {
2045 msg_len = strlen(sms->msg_content);
2046 msg_content = sms->msg_content;
2047 if (msg_len > (140 * 2)) {
2048 msg_num = (msg_len + MAX_8BIT_MSG_LEN - 1) / MAX_8BIT_MSG_LEN;
2049 max_len = MAX_8BIT_MSG_LEN;
2050 } else {
2051 msg_num = 1;
2052 }
2053
2054 if (msg_num > MAX_CONCATENATED_MSG) {
2055 LOGE("message is too long. msg_len[%d], msg_num[%d]", msg_len, msg_num);
2056 return MDAPI_RET_ERROR;
2057 }
2058 LOGE("8bit msg_len = [%d] ,msg_num=[%d] ", msg_len,msg_num);
2059 }else {
2060 LOGE("Not support charset");
2061 return MDAPI_RET_ERROR;
2062 }
2063
2064 // set sms record
2065 _mdapi_sms_set_timestamp(sms);
2066 if (msg_num == 1) {
2067 out_len = _mdapi_sms_encode_pdu(sms, (kal_int8 *)smsc, &sms_settings, msg_content, msg_len, NULL, output, sizeof(output), &sca_out_len);
2068 memcpy(smsc_pdu, output, sca_out_len);
2069 //LOGE("%s, %s, %d, returned encoded smsc_pdu:%s", __FILE__, __FUNCTION__, __LINE__, smsc_pdu);
2070 //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);
2071
2072 //LOGE("%s, %s, %d, pdu:%s sizeof(pdu[0])=%d", __FILE__, __FUNCTION__, __LINE__, pdu[0], sizeof(pdu[0]));
2073
2074 memset(pdu[0], 0, MAX_PDU_SIZE);
2075 LOGE("%s, %s, %d, pdu:%s", __FILE__, __FUNCTION__, __LINE__, pdu[0]);
2076 strncpy(pdu[0], output + sca_out_len, out_len - sca_out_len);
2077 LOGE("%s, %s, %d, returned encoded pdu:%s\n, len=%d", __FILE__, __FUNCTION__, __LINE__, pdu[0], strlen(pdu[0]));
2078 } else {
2079 // send long sms
2080 kal_int32 index = 0;
2081 kal_int32 offset = 0;
2082 static kal_uint8 concat_msgid;
2083 concat_msgid += (rand() + 1) % 256;
2084 LOGE("start send one long msg, total has %d part msg", msg_num);
2085 for (index = 0; index < msg_num; index++) {
2086 kal_uint8 udh[] = {5, 0, 3, concat_msgid, msg_num, index + 1};
2087 kal_uint32 size = 0;
2088 kal_int8 *start = NULL;
2089 size = msg_len > max_len ? max_len : msg_len;
2090 msg_len -= size;
2091 start = msg_content + offset;
2092 int exterSize = 0;
2093 if (sms->charset == MDAPI_SMS_CHARSET_GSM_7BIT){
2094 char* point = start;
2095 int calsize = size;
2096 while (*point && calsize) {
2097 kal_uint8 c = lookup_latin1_to_gsm_ex_table((kal_int8)*point);
2098 if(c != 255){
2099 exterSize++;
2100 calsize--;
2101 }
2102 point++;
2103 calsize--;
2104 }
2105 }
2106 offset = offset + size - exterSize;
2107 //calculate offset
2108 LOGE(" msg_len %d size %d offset %d exterSize %d", msg_len,size ,offset,exterSize);
2109 out_len = _mdapi_sms_encode_pdu(sms, (kal_int8 *)smsc, &sms_settings, start, size, udh, output, sizeof(output), &sca_out_len);
2110 memcpy(smsc_pdu, output, sca_out_len);
2111 memset(pdu[index], 0, MAX_PDU_SIZE);
2112 memcpy(pdu[index], output + sca_out_len, out_len - sca_out_len);
2113 }
2114 }
2115 if (sms->charset == MDAPI_SMS_CHARSET_UCS2) {
2116 if(msg_content != NULL)
2117 free(msg_content);
2118 }
2119 return MDAPI_RET_SUCCESS;
2120}
2121
2122
2123
2124//decode
2125static unsigned char
2126internal_mdapi_hex2int(char *s) {
2127 int ret = 0;
2128 int len = 2, i = 0;
2129 while (i < len) {
2130 if (s[i] == 0) {
2131 return -1;
2132 } else if (s[i] >= 'a' && s[i] <= 'f') {
2133 ret = (s[i] - 'a' + 10) + (ret << 4);
2134 } else if (s[i] >= 'A' && s[i] <= 'F') {
2135 ret = (s[i] - 'A' + 10) + (ret << 4);
2136 } else if (s[i] >= '0' && s[i] <= '9') {
2137 ret = (s[i] - '0') + (ret << 4);
2138 } else {
2139 return -1;
2140 }
2141 i++;
2142 }
2143 return ret;
2144}
2145
2146int internal_mdapi_sms_7bit_decode(char * message, char * output, int output_size, int padding_bits, int octect)
2147{
2148 int i = 0, len = 0;
2149 char * ptr = message;
2150 int output_len = 0;
2151 int cur_val = 0;
2152 int val = 0;
2153 int last_val = 0;//used to save last 1 octet
2154 int offset;
2155
2156 if( padding_bits < 0||padding_bits > 6 )
2157 {
2158 return 0;
2159 }
2160 //Calc how many octets are there
2161 len = strlen(message) >> 1;
2162
2163 for(i = 0; i < len - 1; i++){
2164 offset = i % 0x7;
2165 //Add padding bit, realign to septets.
2166 cur_val = ((internal_mdapi_hex2int(ptr)>>padding_bits)&0xFF)+((internal_mdapi_hex2int(ptr+2)<<(8-padding_bits))&0xFF);
2167 val = ((cur_val << offset) & 0x7F)+((last_val >> (8 - offset))&0xFF);
2168 last_val = cur_val;
2169 //printf("val raw = 0x%X, val = 0x%X\n", val, gsm_to_latin1_table[(kal_uint8)(val & 0xFF)]);
2170 output[output_len++] = (char)gsm_to_latin1_table[(kal_uint8)(val & 0xFF)];
2171 if (output_len == output_size - 1) {
2172 output[output_len] = 0;
2173 return output_len;
2174 }
2175
2176 if(offset == 6){
2177 val = ((cur_val>>1)&0x7F) ;
2178 //printf("val raw = 0x%X, val = 0x%X\n", val, gsm_to_latin1_table[(kal_uint8)(val & 0xFF)]);
2179 output[output_len++] = (char)gsm_to_latin1_table[(kal_uint8)(val & 0xFF)];
2180 if (output_len == output_size - 1) {
2181 output[output_len] = 0;
2182 return output_len;
2183 }
2184 }
2185 ptr += 2;
2186 }
2187
2188 /* decode the last octet */
2189 cur_val = (internal_mdapi_hex2int(ptr) >> padding_bits) & 0xFF;
2190 offset = i % 7;
2191 val = ((cur_val << offset) & 0x7F)+((last_val >> (8 - offset))&0xFF);
2192 //printf("val raw = 0x%X, val = 0x%X\n", val, gsm_to_latin1_table[(kal_uint8)(val & 0xFF)]);
2193 output[output_len++] = (char)gsm_to_latin1_table[(kal_uint8)(val & 0xFF)];
2194 if (output_len == output_size - 1) {
2195 output[output_len] = 0;
2196 return output_len;
2197 }
2198
2199 //printf("output = [%s], output_len = [%d]\n", output, output_len);
2200 if(offset == 6){
2201 val = ((cur_val >> 1) & 0x7F);
2202 //printf("val raw = 0x%X, val = 0x%X\n", val, gsm_to_latin1_table[(kal_uint8)(val & 0xFF)]);
2203 if (val || octect) {
2204 output[output_len++] = (char)gsm_to_latin1_table[(kal_uint8)(val & 0xFF)];
2205 if (output_len == output_size - 1) {
2206 output[output_len] = 0;
2207 return output_len;
2208 }
2209 }
2210 }
2211 output[output_len] = 0;
2212
2213 return output_len;
2214}
2215
2216
2217
2218
2219
2220
2221
2222int internal_mdapi_address_decode(char *number, char *output, int output_size, int type) {
2223 // 81 90 21 43 65 87 --> 0912345678
2224 LOGE("%s, %s, %d", __FILE__, __FUNCTION__, __LINE__);
2225
2226 int len = 0;
2227 int output_len = 0;
2228 int val = 0;
2229 char *ptr = number;
2230 int padding_bit = 0;//To identify the number is even or odd
2231 //LOGE("before internal_mdapi_hex2int(ptr), ptr :%s",ptr);
2232 // Length
2233 len = internal_mdapi_hex2int(ptr);
2234 //LOGE("after internal_mdapi_hex2int(ptr), ptr :%s",ptr);
2235 ptr += 2;
2236 //LOGE("after +=2, ptr :%s",ptr);
2237
2238 if (len == 0) {
2239 return 2;
2240 } else if (len < 0) {
2241 return -1;
2242 }
2243
2244 if (type) {
2245 len = (len) << 1;
2246 } else {
2247 len += 2;
2248 }
2249
2250 LOGE("Address length = %d ", len);
2251
2252 // Type-of-address
2253 val = internal_mdapi_hex2int(ptr);
2254 ptr += 2;
2255 len -= 2;
2256 if (val == 0x91) {
2257 // international number
2258 output_len += snprintf(output+output_len, output_size-output_len-1, "+");
2259 } else if (val == 0x81) {
2260 // national number
2261 } else if ((val & 0x50) == 0x50 ){
2262 // alphabet number
2263 } else {
2264 LOGE("Invalid type-of-address : %02X " , val);
2265 }
2266
2267 // decode alphabet number
2268 if (0x50 == (val & 0x50)) {
2269 kal_int32 octect = (((len * 4) / 7 ) % 8 == 0) ? 1 : 0;
2270 kal_char * tmp = (kal_char * )malloc(len + 1);
2271 if (!tmp) {
2272 LOGE("Invalid type-of-address : %02X ", val);
2273 return -1;
2274 }
2275 memcpy(tmp, ptr, len);
2276 tmp[len] = 0;
2277 output_len += internal_mdapi_sms_7bit_decode(tmp, output, output_size - output_len - 1, 0, octect);
2278 free(tmp);
2279 tmp = NULL;
2280 } else {
2281 do {
2282 if (len > 1) {
2283 if (*ptr == 'F') {
2284 output_len += snprintf(output + output_len, output_size - output_len - 1, "%c", *(ptr + 1));
2285 } else {
2286 output_len += snprintf(output + output_len, output_size - output_len - 1, "%c%c", *(ptr + 1), *(ptr));
2287 }
2288
2289 len -= 2;
2290 ptr += 2;
2291 } else {
2292 output_len += snprintf(output + output_len, output_size - output_len - 1, "%c", *(ptr + 1));
2293 len -= 1;
2294 ptr += 1;
2295 padding_bit = 1;
2296 }
2297 } while (len > 0);
2298 }
2299
2300 return (ptr-number+padding_bit);
2301}
2302
2303
2304static kal_int32 _mdapi_sms_decode_pdu(mdapi_sms_record_t *sms,
2305 kal_int8 *smsc,
2306 kal_int8 *content,
2307 kal_int32 content_size,
2308 kal_int32 *record_size,
2309 kal_int32 *curr_pack,
2310 kal_int32 *total_pack)
2311{
2312
2313
2314 kal_int32 ret = 0;
2315
2316 kal_int8 *ptr = content;
2317 kal_int32 udh = 0;
2318
2319 /*
2320 * Service Centre address informaction element
2321 */
2322 LOGE("%s, %s, %d, ptr_len: %d, ptr: %s\n", __FILE__,__FUNCTION__, __LINE__, content_size, ptr);
2323 ret = internal_mdapi_address_decode(ptr, smsc, 512, 1);
2324 if (ret <= 0) {
2325 LOGE("can't get SMSC address");
2326 return MDAPI_RET_ERROR;
2327 }
2328 ptr += ret;
2329 LOGE("SMSC = [%s]\n", smsc);
2330
2331 /* Protocol Data Unit Type(PDU Type) */
2332 {
2333 kal_int32 pdu_type = internal_mdapi_hex2int(ptr);
2334 if ((pdu_type & 0x03) == SMS_DELIVER) {
2335 sms->msg_type = MDAPI_SMS_NORMAL_MSG;
2336 } else if ((pdu_type & 0x03) == SMS_STATUS_REPORT){
2337 sms->msg_type = MDAPI_SMS_MSG_REPORT;
2338 } else {
2339 LOGE("unkown PDU type = %02X(%02X), content = %s", pdu_type, pdu_type & 0x03, content);
2340 return MDAPI_RET_ERROR;
2341 }
2342
2343 if ((pdu_type & 0x40) == 0x40) {
2344 udh = 1; /* find UDH header */
2345 }
2346
2347 LOGE("PDU Type = [%d]\n", pdu_type);
2348 }
2349 ptr += 2;
2350
2351 /* decode originator address(OA) destination address(DA)*/
2352 ret = internal_mdapi_address_decode(ptr, sms->phone_number, sizeof(sms->phone_number), 0);
2353 if (ret <= 0) {
2354 LOGE("can't get sender address");
2355 return MDAPI_RET_ERROR;
2356 }
2357 ptr += ret;
2358 LOGE("sender = [%s]\n", sms->phone_number);
2359
2360 /* protocol identifiler(PID) */
2361 ptr += 2;
2362
2363 /* Data Coding Scheme (DCS) */
2364 {
2365 //kal_int32 text_compressed = 0;
2366 kal_int32 dcs = 0;
2367
2368 dcs = internal_mdapi_hex2int(ptr);
2369 if (dcs < 0) {
2370 LOGE("can't get the DCS\n");
2371 return MDAPI_RET_ERROR;
2372 }
2373
2374 if ( (dcs & 0xC0) == 0x00) {
2375 /* General Data Coding indication */
2376 if (dcs & 0x20) {
2377 //text_compressed = 1;
2378 }
2379
2380 if (dcs & 0x10) {
2381 sms->sms_class = dcs & 0xF;
2382 }
2383
2384 if (dcs & 0x04) {
2385 sms->charset = MDAPI_SMS_CHARSET_GSM_8BIT;
2386
2387 } else if (dcs & 0x08) {
2388 sms->charset = MDAPI_SMS_CHARSET_UCS2;
2389 } else {
2390 sms->charset = MDAPI_SMS_CHARSET_GSM_7BIT;
2391 }
2392 } else {
2393 LOGE("un-supported dcs type\n");
2394 return MDAPI_RET_ERROR;
2395 }
2396 ptr += 2;
2397 }
2398
2399 /* Time */
2400 {
2401 kal_int32 i = 0;
2402 kal_int8 tmp[4] = {0};
2403 kal_uint8 time[7] = {0};
2404 char temp_buff[64] = {0};
2405
2406 for (i = 0; i < 7; i++) {
2407 tmp[0] = *(ptr + 1);
2408 tmp[1] = *ptr;
2409 tmp[2] = 0;
2410 time[i] = strtoul(tmp, 0, 10);
2411 ptr += 2;
2412 }
2413
2414 if (time[0] < 80) {
2415 time[0] += 100;
2416 }
2417
2418 memset(temp_buff, 0, sizeof(temp_buff));
2419 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]);
2420 strncpy(sms->time, temp_buff, sizeof(sms->time));
2421
2422 //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]);
2423
2424 LOGE("sms time = [%s]\n", sms->time);
2425 }
2426 {
2427 kal_int32 i = 0;
2428 kal_int32 udh_len = 0;
2429 kal_int32 data_len = 0;
2430 kal_int32 buf_len = 0;
2431 kal_int32 octect = 0;
2432
2433 data_len = internal_mdapi_hex2int(ptr);
2434 ptr += 2;
2435
2436 /* parse UDH header, to parse log SMS header */
2437 if (udh) {
2438 kal_int8 *ptr_udh = NULL;
2439 udh_len = internal_mdapi_hex2int(ptr);
2440 ptr += 2;
2441 ptr_udh = ptr;
2442 while (i < udh_len) {
2443 kal_int32 iei = 0;
2444 kal_int32 iei_len = 0;
2445
2446 iei = internal_mdapi_hex2int(ptr);
2447 ptr += 2;
2448 iei_len = internal_mdapi_hex2int(ptr);
2449 ptr += 2;
2450
2451 if (iei != 0x00 && iei != 0x08) {
2452 ptr += (iei_len) * 2;
2453 i += 2 + iei_len;
2454 continue;
2455 }
2456
2457 if (iei == 0x00) {
2458 sms->ref_num = internal_mdapi_hex2int(ptr);
2459 ptr += 2;
2460 } else {
2461 sms->ref_num = ((internal_mdapi_hex2int(ptr) & 0xFF) << 8)
2462 | (internal_mdapi_hex2int(ptr + 2) & 0xFF);
2463 ptr += 4;
2464 }
2465 /*lei modify for gsw 2022/5/12*/
2466 sms->total_pack = internal_mdapi_hex2int(ptr);
2467 LOGE("sms->total_pack = [%d]", sms->curr_pack);
2468 *total_pack = sms->total_pack;
2469 sms->curr_pack = internal_mdapi_hex2int(ptr+2);
2470 LOGE("sms->curr_pack = [%d]", sms->curr_pack);
2471 *curr_pack = sms->curr_pack;
2472 /*lei modify for gsw 2022/5/12*/
2473 break;
2474 }
2475
2476 ptr = ptr_udh + (udh_len) * 2;
2477 }
2478
2479 LOGE("sms->charset = [%d] \n", sms->charset);
2480 switch (sms->charset) {
2481 case MDAPI_SMS_CHARSET_GSM_7BIT:
2482 octect = (data_len % 8 == 0) ? 1 : 0;
2483 // decode 7bit
2484 if (1 == udh) {
2485 kal_int32 padding_bits = ((udh_len + 1) * 8) % 7;
2486 if (padding_bits) {
2487 padding_bits = 7 - padding_bits;
2488 }
2489 data_len = internal_mdapi_sms_7bit_decode(ptr, sms->msg_content, content_size, padding_bits, octect);
2490 } else {
2491 data_len = internal_mdapi_sms_7bit_decode(ptr, sms->msg_content, content_size, 0, octect);
2492 }
2493
2494 *(sms->msg_content + data_len++) = '\0';
2495 *(sms->msg_content + data_len++) = '\0';
2496
2497 *record_size = data_len;
2498 break;
2499
2500 case MDAPI_SMS_CHARSET_GSM_8BIT:
2501 sms->msg_content = ptr;
2502 content_size = strlen(sms->msg_content);
2503 #if 0
2504 if( 1 == udh ) {
2505 data_len -= (udh_len + 1);
2506 }
2507 if (data_len >= *record_size - 2) {
2508 data_len = *record_size - 2;
2509 }
2510
2511 sms->msg_content[0] = '\0';
2512 for (i = 0 ; i < data_len ; i++) {
2513 kal_uint8 tmp[2] = {0, 0};
2514
2515 tmp[0] = internal_mdapi_hex2int(ptr);
2516 ptr += 2;
2517
2518 buf_len += kal_ext_ascii_to_utf8((UTF8 *)(sms->msg_content + buf_len), tmp, *record_size - buf_len);
2519 if (*record_size - buf_len < 0) {
2520 return MDAPI_RET_ERROR;
2521 }
2522 }
2523
2524 *(sms->msg_content + buf_len++) = '\0';
2525 *(sms->msg_content + buf_len++) = '\0';
2526
2527 *record_size = buf_len;
2528
2529 //LOGE(KAL_LOG_INFO, LOG_TAG, "is utf8 = [%d]", is_utf8_sequence((UTF8 *)sms->msg_content, (UTF8 *)sms->msg_content + data_len - 2));
2530 #endif
2531 break;
2532
2533 case MDAPI_SMS_CHARSET_UCS2:
2534 buf_len = 0;
2535
2536 if( 1 == udh ) {
2537 data_len -= (udh_len + 1);
2538 }
2539
2540 sms->msg_content[0] = '\0';
2541
2542 for (i=0 ; i < data_len ; i = i + 2) {
2543 UTF16 tmp[2] = {0, 0};
2544 kal_uint8 *tmp_ptr = (kal_uint8 *)tmp;
2545
2546 tmp_ptr[0] = internal_mdapi_hex2int(ptr);
2547 ptr += 2;
2548 tmp_ptr[1] = internal_mdapi_hex2int(ptr);
2549 ptr += 2;
2550 tmp[0] = ntohs(tmp[0]);
2551 //LOGE(KAL_LOG_INFO, LOG_TAG, "tmp = [%04X]", tmp);
2552
2553 buf_len += kal_utf16_to_utf8((UTF8 *)(sms->msg_content + buf_len), tmp, *record_size - buf_len);
2554 if (*record_size - buf_len < 0) {
2555 return MDAPI_RET_ERROR;
2556 }
2557 }
2558
2559 *(sms->msg_content + buf_len++) = '\0';
2560 *(sms->msg_content + buf_len++) = '\0';
2561
2562 *record_size = buf_len;
2563
2564
2565 break;
2566
2567 default:
2568 return MDAPI_RET_ERROR;
2569 }
2570 }
2571
2572 sms->position = MDAPI_SMS_POS_INBOX;
2573 return MDAPI_RET_SUCCESS;
2574}
2575
2576
2577int smsPduDecode(const char *pdu_str, int pdu_len,
2578 char *da_num, char *smsc, char *msg, int *charset, int *curr_pack, int *total_pack, char *date)
2579{
2580 kal_char msg_tmp[MAX_PDU_SIZE] = {0};
2581 mdapi_sms_record_t record;
2582 kal_int32 status = MDAPI_RET_ERROR;
2583 kal_int32 out_len = 210;
2584
2585 LOGE("%s\n",__FILE__);
2586 LOGE("%s\n",__FUNCTION__);
2587 LOGE("%d\n",__LINE__);
2588 LOGE("%d\n",pdu_len);
2589 LOGE("%s\n",pdu_str);
2590
2591 record.msg_content = msg_tmp;
2592 /*lei modify for gsw 2022/5/11*/
2593 status = _mdapi_sms_decode_pdu(&record, smsc, (kal_int8 *)pdu_str,
2594 pdu_len, &out_len, curr_pack, total_pack);
2595 /*lei modify for gsw 2022/5/11*/
2596 if(status == MDAPI_RET_SUCCESS) {
2597 memcpy(da_num, record.phone_number, strlen(record.phone_number));
2598 memcpy(msg, record.msg_content, strlen(record.msg_content));
2599 *charset = record.charset;
2600 memcpy(date, record.time, strlen(record.time));
2601
2602 #if 0
2603 /*lei modify for gsw 2022/5/11*/
2604 *curr_pack = record.curr_pack;
2605 *total_pack = record.total_pack;
2606 /*lei modify for gsw 2022/5/11*/
2607 #endif
2608 } else {
2609 LOGE("PDU decode error");
2610 }
2611
2612 return status;
2613}