comparison libutil/number_encode.c @ 6:86b4f288862d

libutil: functions for encoding MSISDN record
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 22 Feb 2021 00:41:12 +0000
parents
children
comparison
equal deleted inserted replaced
5:acb4d86e6ed7 6:86b4f288862d
1 /*
2 * This module implements functions for encoding phone numbers.
3 */
4
5 #include <sys/types.h>
6 #include <ctype.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 digit_char_to_gsm(ch)
11 {
12 switch (ch) {
13 case '0':
14 case '1':
15 case '2':
16 case '3':
17 case '4':
18 case '5':
19 case '6':
20 case '7':
21 case '8':
22 case '9':
23 return (ch - '0');
24 case '*':
25 return 0xA;
26 case '#':
27 return 0xB;
28 case 'a':
29 case 'b':
30 case 'c':
31 return (ch - 'a' + 0xC);
32 case 'A':
33 case 'B':
34 case 'C':
35 return (ch - 'A' + 0xC);
36 }
37 return (-1);
38 }
39
40 void
41 pack_digit_bytes(digits, dest, num_digit_bytes)
42 u_char *digits, *dest;
43 unsigned num_digit_bytes;
44 {
45 u_char *sp, *dp;
46 unsigned n;
47
48 sp = digits;
49 dp = dest;
50 for (n = 0; n < num_digit_bytes; n++) {
51 *dp++ = sp[0] | (sp[1] << 4);
52 sp += 2;
53 }
54 }
55
56 encode_phone_number_arg(arg, fixp, mode)
57 char *arg;
58 u_char *fixp;
59 {
60 u_char digits[20];
61 unsigned ndigits, num_digit_bytes;
62 char *cp, *endp;
63 int c;
64
65 cp = arg;
66 if (*cp == '+') {
67 fixp[1] = 0x91;
68 cp++;
69 } else
70 fixp[1] = 0x81;
71 if (digit_char_to_gsm(*cp) < 0) {
72 inv_arg: fprintf(stderr, "error: invalid phone number argument\n");
73 return(-1);
74 }
75 for (ndigits = 0; ; ndigits++) {
76 c = digit_char_to_gsm(*cp);
77 if (c < 0)
78 break;
79 cp++;
80 if (ndigits >= 20) {
81 fprintf(stderr, "error: too many number digits\n");
82 return(-1);
83 }
84 digits[ndigits] = c;
85 }
86 if (mode)
87 fixp[0] = ndigits;
88 if (ndigits & 1)
89 digits[ndigits++] = 0xF;
90 num_digit_bytes = ndigits >> 1;
91 if (!mode)
92 fixp[0] = num_digit_bytes + 1;
93 pack_digit_bytes(digits, fixp + 2, num_digit_bytes);
94 if (*cp == ',') {
95 cp++;
96 if (!isdigit(*cp))
97 goto inv_arg;
98 fixp[1] = strtoul(cp, &endp, 0);
99 if (*endp)
100 goto inv_arg;
101 } else if (*cp)
102 goto inv_arg;
103 return(0);
104 }