changeset 744:2dcfad8a3ed0

make-imeisv utility written
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 19 Oct 2020 06:35:35 +0000
parents 88a1c8af39ac
children 9e3b1ef1f440
files .hgignore miscutil/Makefile miscutil/make-imeisv.c
diffstat 3 files changed, 81 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sun Oct 11 21:20:48 2020 +0000
+++ b/.hgignore	Mon Oct 19 06:35:35 2020 +0000
@@ -37,6 +37,7 @@
 ^miscutil/fc-tch2fr$
 ^miscutil/fc-vm2hex$
 ^miscutil/imei-luhn$
+^miscutil/make-imeisv$
 ^miscutil/mokosrec2bin$
 ^miscutil/srec-regions$
 
--- a/miscutil/Makefile	Sun Oct 11 21:20:48 2020 +0000
+++ b/miscutil/Makefile	Mon Oct 19 06:35:35 2020 +0000
@@ -1,7 +1,7 @@
 CC=	gcc
 CFLAGS=	-O2
 PROGS=	fc-fr2tch fc-gsm2vm fc-pulse-dtr fc-pulse-rts fc-rgbconv fc-serterm \
-	fc-tch2fr fc-vm2hex imei-luhn mokosrec2bin srec-regions
+	fc-tch2fr fc-vm2hex imei-luhn make-imeisv mokosrec2bin srec-regions
 SCRIPTS=c139explore pirexplore
 
 INSTALL_PREFIX=	/opt/freecalypso
@@ -45,6 +45,9 @@
 imei-luhn:	imei-luhn.c
 	${CC} ${CFLAGS} -o $@ $@.c
 
+make-imeisv:	make-imeisv.c
+	${CC} ${CFLAGS} -o $@ $@.c
+
 mokosrec2bin:	mokosrec2bin.c
 	${CC} ${CFLAGS} -o $@ $@.c
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/miscutil/make-imeisv.c	Mon Oct 19 06:35:35 2020 +0000
@@ -0,0 +1,76 @@
+/*
+ * This utility constructs a 16-digit IMEISV from a 15-digit IMEI
+ * (which must have a valid Luhn check digit) and a 2-digit SV field.
+ * It is intended for use in shell scripts.
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+parse_imei_arg(input, buf)
+	char *input, *buf;
+{
+	char *cp;
+	int i;
+
+	cp = input;
+	if (!isdigit(*cp)) {
+inv:		fprintf(stderr,
+			"error: IMEI argument must have 15 decimal digits\n");
+		exit(1);
+	}
+	for (i = 0; i < 15; i++) {
+		if (ispunct(*cp))
+			cp++;
+		if (!isdigit(*cp))
+			goto inv;
+		buf[i] = *cp++;
+	}
+	if (*cp)
+		goto inv;
+}
+
+check_luhn(digits)
+	char *digits;
+{
+	int i, dig, sum;
+
+	sum = 0;
+	for (i = 0; i < 14; i++) {
+		dig = digits[i] - '0';
+		if (i & 1) {
+			dig *= 2;
+			if (dig > 9)
+				dig -= 9;
+		}
+		sum += dig;
+	}
+	dig = sum % 10;
+	if (dig)
+		dig = 10 - dig;
+	if (digits[14] != dig + '0') {
+		fprintf(stderr, "error: given IMEI fails Luhn check\n");
+		exit(1);
+	}
+}
+
+main(argc, argv)
+	char **argv;
+{
+	char imeibuf[15];
+
+	if (argc != 3) {
+		fprintf(stderr, "usage: %s IMEI SV\n", argv[0]);
+		exit(1);
+	}
+	parse_imei_arg(argv[1], imeibuf);
+	check_luhn(imeibuf);
+	if (!isdigit(argv[2][0]) || !isdigit(argv[2][1]) || argv[2][2]) {
+		fprintf(stderr,
+			"error: SV argument must have 2 decimal digits\n");
+		exit(1);
+	}
+	printf("%.8s-%.6s-%s\n", imeibuf, imeibuf + 8, argv[2]);
+	exit(0);
+}