FreeCalypso > hg > fc-pcsc-tools
comparison libutil/number_encode.c @ 157:f064dbcc5f41
libutil split from libcommon
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 26 Feb 2021 20:19:58 +0000 |
parents | libcommon/number_encode.c@52ec2d3eb851 |
children |
comparison
equal
deleted
inserted
replaced
156:5f1f3f6fd865 | 157:f064dbcc5f41 |
---|---|
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 } |