view ee2232/ee2232-gen.c @ 162:72eac15f0917

fc-simtool and fc-uicc-tool moved once again to fc-sim-tools
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 14 Mar 2021 17:36:43 +0000
parents 252e3d37b9e5
children
line wrap: on
line source

#include <sys/types.h>
#include <ctype.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <stdlib.h>

u_short vid = 0x0403, pid = 0x6010;
char *manuf, *product;
u_char byte00 = 0x08, byte01 = 0x08;
u_char byte08 = 0x80, byte0A = 0x00;
unsigned maxpower = 100;
u_short usb_version = 0x0200;

u_short eeprom[64];
unsigned eeprom_string_ptr = 0x0B;

read_config_file(filename)
	char *filename;
{
	FILE *inf;
	char linebuf[1024];
	int lineno;
	char *cp, *np;

	inf = fopen(filename, "r");
	if (!inf) {
		perror(filename);
		exit(1);
	}
	for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) {
		cp = index(linebuf, '\n');
		if (!cp) {
			fprintf(stderr,
				"%s line %d: too long or unterminated\n",
				filename, lineno);
			exit(1);
		}
		*cp = '\0';
		for (cp = linebuf; isspace(*cp); cp++)
			;
		if (*cp == '\0' || *cp == '#')
			continue;
		for (np = cp; *cp && !isspace(*cp); cp++)
			;
		if (*cp)
			*cp++ = '\0';
		while (isspace(*cp))
			cp++;
		if (*cp == '\0' || *cp == '#') {
			fprintf(stderr,
				"%s line %d: \"%s\" setting without argument\n",
				filename, lineno, np);
			exit(1);
		}
		if (!strcmp(np, "vid"))
			vid = strtoul(cp, 0, 16);
		else if (!strcmp(np, "pid"))
			pid = strtoul(cp, 0, 16);
		else if (!strcmp(np, "manuf"))
			manuf = strdup(cp);
		else if (!strcmp(np, "product"))
			product = strdup(cp);
		else if (!strcmp(np, "byte00"))
			byte00 = strtoul(cp, 0, 16);
		else if (!strcmp(np, "byte01"))
			byte01 = strtoul(cp, 0, 16);
		else if (!strcmp(np, "byte08"))
			byte08 = strtoul(cp, 0, 16);
		else if (!strcmp(np, "byte0A"))
			byte0A = strtoul(cp, 0, 16);
		else if (!strcmp(np, "maxpower"))
			maxpower = strtoul(cp, 0, 10);
		else if (!strcmp(np, "usbver"))
			usb_version = strtoul(cp, 0, 16);
		else {
			fprintf(stderr, "%s line %d: unknown \"%s\" setting\n",
				filename, lineno, np);
			exit(1);
		}
	}
	fclose(inf);
	if (!manuf) {
		fprintf(stderr, "error: manuf not set in %s\n", filename);
		exit(1);
	}
	if (!product) {
		fprintf(stderr, "error: product not set in %s\n", filename);
		exit(1);
	}
}

write_string(str)
	char *str;
{
	unsigned longlen, startptr;

	longlen = strlen(str) * 2 + 2;
	startptr = eeprom_string_ptr;
	eeprom[eeprom_string_ptr++] = 0x0300 | longlen;
	while (*str)
		eeprom[eeprom_string_ptr++] = *str++;
	return (longlen << 8) | 0x80 | (startptr << 1);
}

fill_eeprom(serial)
	char *serial;
{
	u_char byte09;

	if (serial)
		byte0A |= 0x08;
	else
		byte0A &= 0xF7;
	byte09 = maxpower / 2;
	eeprom[0] = (byte01 << 8) | byte00;
	eeprom[1] = vid;
	eeprom[2] = pid;
	eeprom[3] = 0x0500;
	eeprom[4] = (byte09 << 8) | byte08;
	eeprom[5] = byte0A;
	eeprom[6] = usb_version;
	eeprom[7] = write_string(manuf);
	eeprom[8] = write_string(product);
	if (serial)
		eeprom[9] = write_string(serial);
	else
		eeprom[9] = 0;
	eeprom[10] = 0x46;
}

do_checksum()
{
	u_short chksum = 0xAAAA;
	unsigned n;

	for (n = 0; n < 63; n++) {
		chksum ^= eeprom[n];
		chksum = (chksum << 1) | (chksum >> 15);
	}
	eeprom[63] = chksum;
}

emit_output()
{
	unsigned n, col;

	for (n = 0; n < 64; n++) {
		col = n & 7;
		if (col == 0)
			printf("%02X:", n * 2);
		printf(" %04X", eeprom[n]);
		if (col == 7)
			putchar('\n');
	}
}

main(argc, argv)
	char **argv;
{
	if (argc < 2 || argc > 3) {
		fprintf(stderr, "usage: %s config-file [serial-num]\n",
			argv[0]);
		exit(1);
	}
	read_config_file(argv[1]);
	fill_eeprom(argv[2]);
	do_checksum();
	emit_output();
	exit(0);
}