FreeCalypso > hg > fc-pcsc-tools
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 } |
