# HG changeset patch # User Mychaela Falconia # Date 1613092100 0 # Node ID 62cdfed70de71dd1333986dec2877c1bd9be1783 # Parent a76ec3e7da09f0ccc0f35c31ae69f6cb7182b32b phone number encoding factored out of pb-update code diff -r a76ec3e7da09 -r 62cdfed70de7 libcommon/Makefile --- a/libcommon/Makefile Fri Feb 12 00:47:04 2021 +0000 +++ b/libcommon/Makefile Fri Feb 12 01:08:20 2021 +0000 @@ -2,7 +2,7 @@ CFLAGS= -O2 -I/usr/include/PCSC OBJS= alpha_decode.o alpha_valid.o apdu.o atr.o cardconnect.o chkblank.o \ dumpdirfunc.o exit.o hexdump.o hexread.o hexstr.o names.o \ - number_decode.o pbdumpfunc.o pinentry.o revnibbles.o + number_decode.o number_encode.o pbdumpfunc.o pinentry.o revnibbles.o LIB= libcommon.a all: ${LIB} diff -r a76ec3e7da09 -r 62cdfed70de7 libcommon/number_encode.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libcommon/number_encode.c Fri Feb 12 01:08:20 2021 +0000 @@ -0,0 +1,101 @@ +/* + * This module implements functions for encoding phone numbers. + */ + +#include +#include +#include +#include + +digit_char_to_gsm(ch) +{ + switch (ch) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return (ch - '0'); + case '*': + return 0xA; + case '#': + return 0xB; + case 'a': + case 'b': + case 'c': + return (ch - 'a' + 0xC); + case 'A': + case 'B': + case 'C': + return (ch - 'A' + 0xC); + } + return (-1); +} + +void +pack_digit_bytes(digits, dest, num_digit_bytes) + u_char *digits, *dest; + unsigned num_digit_bytes; +{ + u_char *sp, *dp; + unsigned n; + + sp = digits; + dp = dest; + for (n = 0; n < num_digit_bytes; n++) { + *dp++ = sp[0] | (sp[1] << 4); + sp += 2; + } +} + +encode_phone_number_arg(arg, fixp) + char *arg; + u_char *fixp; +{ + u_char digits[20]; + unsigned ndigits, num_digit_bytes; + char *cp, *endp; + int c; + + cp = arg; + if (*cp == '+') { + fixp[1] = 0x91; + cp++; + } else + fixp[1] = 0x81; + if (digit_char_to_gsm(*cp) < 0) { +inv_arg: fprintf(stderr, "error: invalid phone number argument\n"); + return(-1); + } + for (ndigits = 0; ; ndigits++) { + c = digit_char_to_gsm(*cp); + if (c < 0) + break; + cp++; + if (ndigits >= 20) { + fprintf(stderr, "error: too many number digits\n"); + return(-1); + } + digits[ndigits] = c; + } + if (ndigits & 1) + digits[ndigits++] = 0xF; + num_digit_bytes = ndigits >> 1; + fixp[0] = num_digit_bytes + 1; + pack_digit_bytes(digits, fixp + 2, num_digit_bytes); + if (*cp == ',') { + cp++; + if (!isdigit(*cp)) + goto inv_arg; + fixp[1] = strtoul(cp, &endp, 0); + if (*endp) + goto inv_arg; + } else if (*cp) + goto inv_arg; + return(0); +} diff -r a76ec3e7da09 -r 62cdfed70de7 simtool/pbupdate.c --- a/simtool/pbupdate.c Fri Feb 12 00:47:04 2021 +0000 +++ b/simtool/pbupdate.c Fri Feb 12 01:08:20 2021 +0000 @@ -45,53 +45,6 @@ 0x0C, 0x06, 0xFF, 0xFF, 0x7E, 0xFF, 0xFF, 0xFF }; -static -digit_char_to_gsm(ch) -{ - switch (ch) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return (ch - '0'); - case '*': - return 0xA; - case '#': - return 0xB; - case 'a': - case 'b': - case 'c': - return (ch - 'a' + 0xC); - case 'A': - case 'B': - case 'C': - return (ch - 'A' + 0xC); - } - return (-1); -} - -static void -pack_digit_bytes(digits, dest, num_digit_bytes) - u_char *digits, *dest; - unsigned num_digit_bytes; -{ - u_char *sp, *dp; - unsigned n; - - sp = digits; - dp = dest; - for (n = 0; n < num_digit_bytes; n++) { - *dp++ = sp[0] | (sp[1] << 4); - sp += 2; - } -} - static char * decode_qstring_alpha(cp, record, maxlen, filename_for_errs, lineno_for_errs) char *cp, *filename_for_errs; @@ -316,54 +269,6 @@ } static -decode_number_arg(arg, fixp) - char *arg; - u_char *fixp; -{ - u_char digits[20]; - unsigned ndigits, num_digit_bytes; - char *cp, *endp; - int c; - - cp = arg; - if (*cp == '+') { - fixp[1] = 0x91; - cp++; - } else - fixp[1] = 0x81; - if (digit_char_to_gsm(*cp) < 0) { -inv_arg: fprintf(stderr, "error: invalid phone number argument\n"); - return(-1); - } - for (ndigits = 0; ; ndigits++) { - c = digit_char_to_gsm(*cp); - if (c < 0) - break; - cp++; - if (ndigits >= 20) { - fprintf(stderr, "error: too many number digits\n"); - return(-1); - } - digits[ndigits] = c; - } - if (ndigits & 1) - digits[ndigits++] = 0xF; - num_digit_bytes = ndigits >> 1; - fixp[0] = num_digit_bytes + 1; - pack_digit_bytes(digits, fixp + 2, num_digit_bytes); - if (*cp == ',') { - cp++; - if (!isdigit(*cp)) - goto inv_arg; - fixp[1] = strtoul(cp, &endp, 0); - if (*endp) - goto inv_arg; - } else if (*cp) - goto inv_arg; - return(0); -} - -static decode_alphatag_arg(arg, record, maxlen) char *arg; u_char *record; @@ -438,7 +343,7 @@ } memset(record, 0xFF, curfile_record_len); fixp = record + curfile_record_len - 14; - rc = decode_number_arg(argv[3], fixp); + rc = encode_phone_number_arg(argv[3], fixp); if (rc < 0) return(rc); if (argv[4]) { @@ -496,7 +401,7 @@ } memset(record, 0xFF, curfile_record_len); fixp = record + curfile_record_len - 14; - rc = decode_number_arg(argv[3], fixp); + rc = encode_phone_number_arg(argv[3], fixp); if (rc < 0) return(rc); rc = decode_alphatag_arg_hex(argv[4], record, curfile_record_len - 14);