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 } |
