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 }