comparison libcommon/number_encode.c @ 11:62cdfed70de7

phone number encoding factored out of pb-update code
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 12 Feb 2021 01:08:20 +0000
parents
children 52ec2d3eb851
comparison
equal deleted inserted replaced
10:a76ec3e7da09 11:62cdfed70de7
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)
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 (ndigits & 1)
87 digits[ndigits++] = 0xF;
88 num_digit_bytes = ndigits >> 1;
89 fixp[0] = num_digit_bytes + 1;
90 pack_digit_bytes(digits, fixp + 2, num_digit_bytes);
91 if (*cp == ',') {
92 cp++;
93 if (!isdigit(*cp))
94 goto inv_arg;
95 fixp[1] = strtoul(cp, &endp, 0);
96 if (*endp)
97 goto inv_arg;
98 } else if (*cp)
99 goto inv_arg;
100 return(0);
101 }