FreeCalypso > hg > sms-coding-utils
comparison gen-pdu/message.c @ 9:003660a57f99
new program sms-gen-tpdu
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 05 Aug 2023 07:43:45 +0000 |
parents | |
children | 17dd30989c0b |
comparison
equal
deleted
inserted
replaced
8:265b8103530c | 9:003660a57f99 |
---|---|
1 /* | |
2 * This module implements TPDU encoding of actual messages, after all | |
3 * settings have been captured. | |
4 */ | |
5 | |
6 #include <sys/types.h> | |
7 #include <ctype.h> | |
8 #include <stdio.h> | |
9 #include <stdlib.h> | |
10 #include <string.h> | |
11 #include <strings.h> | |
12 #include "error.h" | |
13 | |
14 extern int dir_mo, include_sca; | |
15 extern u_char sc_addr[12], user_addr[12]; | |
16 extern u_char mr_byte, pid_byte, dcs_byte; | |
17 extern u_char scts_buf[7]; | |
18 extern int is_septet, scts_is_set; | |
19 | |
20 extern int input_lineno; | |
21 | |
22 static void | |
23 emit_first_octet(udhi) | |
24 { | |
25 u_char fo; | |
26 | |
27 if (dir_mo) | |
28 fo = 1; | |
29 else | |
30 fo = 0; | |
31 if (udhi) | |
32 fo |= 0x40; | |
33 printf("%02X", fo); | |
34 } | |
35 | |
36 static void | |
37 make_pdu(udl, ud_buf, ud_octets, udhi) | |
38 u_char *ud_buf; | |
39 unsigned udl, ud_octets; | |
40 { | |
41 if (include_sca) | |
42 emit_hex_out(sc_addr, sc_addr[0] + 1, stdout); | |
43 emit_first_octet(udhi); | |
44 if (dir_mo) | |
45 printf("%02X", mr_byte); | |
46 emit_hex_out(user_addr, ((user_addr[0] + 1) >> 1) + 2, stdout); | |
47 printf("%02X", pid_byte); | |
48 printf("%02X", dcs_byte); | |
49 if (!dir_mo) { | |
50 if (!scts_is_set) | |
51 set_auto_scts(); | |
52 emit_hex_out(scts_buf, 7, stdout); | |
53 } | |
54 printf("%02X", udl); | |
55 emit_hex_out(ud_buf, ud_octets, stdout); | |
56 putchar('\n'); | |
57 } | |
58 | |
59 static void | |
60 cmd_msg_common(arg, udhi) | |
61 char *arg; | |
62 { | |
63 u_char input[160], ud7[160], octbuf[140]; | |
64 unsigned input_len, udhl, udhl1, udh_chars, plain_chars; | |
65 unsigned udl, udl_octets; | |
66 | |
67 for (input_len = 0; ; input_len++) { | |
68 while (isspace(*arg)) | |
69 arg++; | |
70 if (!*arg) | |
71 break; | |
72 if (!isxdigit(arg[0]) || !isxdigit(arg[1])) { | |
73 fprintf(stderr, ERR_PREFIX "invalid hex string\n", | |
74 input_lineno); | |
75 exit(1); | |
76 } | |
77 if (input_len >= 160) { | |
78 toolong: fprintf(stderr, ERR_PREFIX "hex string is too long\n", | |
79 input_lineno); | |
80 exit(1); | |
81 } | |
82 input[input_len] = (decode_hex_digit(arg[0]) << 4) | | |
83 decode_hex_digit(arg[1]); | |
84 arg += 2; | |
85 } | |
86 if (!is_septet && input_len > 140) | |
87 goto toolong; | |
88 if (udhi) { | |
89 if (!input_len) { | |
90 fprintf(stderr, ERR_PREFIX | |
91 "empty message is invalid with UDHI\n", | |
92 input_lineno); | |
93 exit(1); | |
94 } | |
95 udhl = input[0]; | |
96 udhl1 = udhl + 1; | |
97 if (udhl1 > input_len) { | |
98 fprintf(stderr, ERR_PREFIX "UDHL exceeds UD length\n", | |
99 input_lineno); | |
100 exit(1); | |
101 } | |
102 } | |
103 if (!is_septet) { | |
104 make_pdu(input_len, input, input_len, udhi); | |
105 return; | |
106 } | |
107 if (udhi) | |
108 udh_chars = (udhl1 * 8 + 6) / 7; | |
109 else { | |
110 udhl1 = 0; | |
111 udh_chars = 0; | |
112 } | |
113 plain_chars = input_len - udhl1; | |
114 udl = udh_chars + plain_chars; | |
115 if (udl > 160) { | |
116 fprintf(stderr, ERR_PREFIX | |
117 "message exceeds 160 septets after UDH\n", | |
118 input_lineno); | |
119 exit(1); | |
120 } | |
121 udl_octets = (udl * 7 + 7) / 8; | |
122 bzero(ud7, 160); | |
123 bcopy(input + udhl1, ud7 + udh_chars, plain_chars); | |
124 gsm7_pack(ud7, octbuf, udl_octets); | |
125 if (udhi) | |
126 bcopy(input, octbuf, udhl1); | |
127 make_pdu(udl, ud7, udl_octets, udhi); | |
128 } | |
129 | |
130 void | |
131 cmd_msg_plain(argc, argv) | |
132 char **argv; | |
133 { | |
134 cmd_msg_common(argv[1], 0); | |
135 } | |
136 | |
137 void | |
138 cmd_msg_udh(argc, argv) | |
139 char **argv; | |
140 { | |
141 cmd_msg_common(argv[1], 1); | |
142 } |