view loadtools/flprotreg.c @ 915:71edc12b1aa7

doc/Rvinterf-tools: document new rvinterf -v option
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 29 Dec 2022 23:59:00 +0000
parents cf7bd5e705ed
children
line wrap: on
line source

/*
 * This module implements commands dealing with Intel flash protection
 * register, which holds the IMEI on Compal phones.
 */

#include <sys/types.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include "flash.h"

extern struct flash_bank_info flash_bank_info[2];

flashcmd_protreg(argc, argv, bank)
	char **argv;
{
	struct flash_bank_info *bi;
	uint16_t data[9];
	int rc;

	if (argc > 2) {
		fprintf(stderr, "error: too many arguments\n");
		return(-1);
	}
	if (flash_detect(bank, 0) < 0)
		return(-1);
	bi = flash_bank_info + bank;
	rc = bi->ops->read_prot_reg(bi, data);
	if (rc)
		return(rc);
	printf("Lock word: %04X\n", data[0]);
	printf("Factory words: %04X %04X %04X %04X\n", data[1], data[2],
		data[3], data[4]);
	printf("User words: %04X %04X %04X %04X\n", data[5], data[6], data[7],
		data[8]);
	return(0);
}

static int
compute_cd(digits)
	u_char *digits;
{
	int i, dig, sum;

	sum = 0;
	for (i = 0; i < 14; i++) {
		dig = digits[i];
		if (i & 1) {
			dig *= 2;
			if (dig > 9)
				dig -= 9;
		}
		sum += dig;
	}
	dig = sum % 10;
	if (dig)
		dig = 10 - dig;
	return dig;
}

static void
format_imei(digits, strout)
	u_char *digits;
	char *strout;
{
	int i;
	char *dp;

	dp = strout;
	for (i = 0; i < 15; i++) {
		if (i == 8 || i == 14)
			*dp++ = '-';
		*dp++ = digits[i] + '0';
	}
	*dp = '\0';
}

flashcmd_compal_imei(argc, argv, bank)
	char **argv;
{
	struct flash_bank_info *bi;
	uint16_t data[9];
	u_char nibbles[16], *dp;
	char imei_str[18];
	int rc, i, j;
	FILE *of;

	if (argc > 3) {
		fprintf(stderr, "error: too many arguments\n");
		return(-1);
	}
	if (flash_detect(bank, 0) < 0)
		return(-1);
	bi = flash_bank_info + bank;
	rc = bi->ops->read_prot_reg(bi, data);
	if (rc)
		return(rc);
	dp = nibbles;
	for (i = 0; i < 4; i++) {
		rc = data[i + 5];
		for (j = 0; j < 4; j++) {
			*dp++ = rc & 0xF;
			rc >>= 4;
		}
	}
	for (i = 1; i < 16; i++) {
		if (nibbles[i] > 9) {
bad_imei:		fprintf(stderr, "No Compal IMEI found\n");
			return(-1);
		}
	}
	if (compute_cd(nibbles+1) != nibbles[15])
		goto bad_imei;
	format_imei(nibbles+1, imei_str);
	puts(imei_str);
	if (argc < 3)
		return(0);
	of = fopen(argv[2], "w");
	if (!of) {
		perror(argv[2]);
		return(-1);
	}
	fprintf(of, "%s\n", imei_str);
	fclose(of);
	printf("Saved to %s\n", argv[2]);
	return(0);
}