Moved C-Netz "Speicherkarte" to "extra" directory and improved it.
parent
e18f7dbc1f
commit
0b6a5d19cb
|
@ -69,7 +69,7 @@ src/tv/osmotv
|
|||
src/radio/osmoradio
|
||||
src/datenklo/datenklo
|
||||
src/zeitansage/zeitansage
|
||||
sim/cnetz_sim
|
||||
extra/cnetz_memory_card_generator
|
||||
src/test/test_filter
|
||||
src/test/test_sendevolumenregler
|
||||
src/test/test_compandor
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
AUTOMAKE_OPTIONS = foreign
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
SUBDIRS = src sim
|
||||
SUBDIRS = src extra
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ AC_OUTPUT(
|
|||
src/zeitansage/Makefile
|
||||
src/test/Makefile
|
||||
src/Makefile
|
||||
sim/Makefile
|
||||
extra/Makefile
|
||||
Makefile)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
AM_CPPFLAGS = -Wall -Wextra -g $(all_includes)
|
||||
|
||||
bin_PROGRAMS = \
|
||||
cnetz_memory_card_generator
|
||||
|
||||
cnetz_memory_card_generator_SOURCES = \
|
||||
main.c
|
||||
cnetz_memory_card_generator_LDADD = \
|
||||
$(COMMON_LA) \
|
||||
$(top_builddir)/src/libdebug/libdebug.a \
|
||||
$(top_builddir)/src/liboptions/liboptions.a
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
This is a generator for the C-Netz Sim Card
|
||||
"Berechtigungskarte als Speicherkarte". (memory card)
|
||||
|
||||
In the sub directory "simulator" you find an Arduino Sketch to simulate a memory card.
|
||||
|
||||
In the sub directory "programmer" you find an Arduino Sketch to program an SLE4428 card.
|
||||
|
||||
NOTE:
|
||||
This will only work with old phones that were released before the CPU SIM was released.
|
||||
The Smart Card "Berechtigungskarte als Prozessorkarte" is implemented at src/sim.
|
||||
|
||||
|
||||
Run cnetz_memory_card_generator:
|
||||
|
||||
# ./extra/cnetz_memory_card_generator
|
||||
Usage: ./cnetz_memory_card_generator <futln_nat> <futln_fuvst> <futln_rest> <sicherungscode> <sonderheitsschluessel>
|
||||
|
||||
# ./extra/cnetz_memory_card_generator 2222002
|
||||
|
||||
Magic Data 011..015 = 30 (0x1e)
|
||||
Magic Data 018..020 = 7
|
||||
Magic Data 021..023 = 2
|
||||
FUTLN NAT = 2
|
||||
FUTLN FUVST = 2
|
||||
FUTLN REST = 22002
|
||||
Sicherungscode=12345
|
||||
Sonderheitenschluessel=0 (0x0000)
|
||||
Wartungsschluessel=65535 (0xffff)
|
||||
|
||||
Binary data: (LSB first)
|
||||
0xff, 0xf7, 0x5c, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4b, 0x90,
|
||||
0x5f, 0x25, 0x07, 0x0c, 0x00, 0x00, 0xfe, 0xfd,
|
||||
0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
|
||||
After generation, the hex data can be copied to the data array of programmer/programmer.ino or simulator/simulator.ino
|
||||
|
||||
If you use the programmer, connect an SLE4428 or compatible as inicated at the pin definition of programmer.ino.
|
||||
|
||||
Note: The SLE card must not have protected serial number area. (ATR area)
|
||||
Also the card must show all 416 written bits via ATR, not only 32 bits.
|
||||
|
||||
If you use the Arduino as emulator, connect the card reader as indicated at the pin definition of simulator.ino
|
||||
|
||||
Tested:
|
||||
Works with BSA 51
|
||||
Does not work with all other phones I have.
|
||||
|
||||
Test cards and monitor cards for BSA 51:
|
||||
# ./extra/cnetz_memory_card_generator --special-key 898 2222002
|
||||
# ./extra/cnetz_memory_card_generator --special-key 899 2222002
|
||||
# ./extra/cnetz_memory_card_generator --magic1 0x1d --special-key 0x900 --maintenance-key 0xa139 2222002
|
||||
# ./extra/cnetz_memory_card_generator --magic1 0x1d --special-key 0x901 --maintenance-key 0xa139 2222002
|
||||
|
|
@ -0,0 +1,257 @@
|
|||
/* SIM Card for C-Netz "Berechtigungskarte als Speicherkarte"
|
||||
*
|
||||
* (C) 2016 by Andreas Eversberg <jolly@eversberg.eu>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <../src/libdebug/debug.h>
|
||||
#include <../src/liboptions/options.h>
|
||||
|
||||
int num_kanal = 1;
|
||||
static uint8_t magic1 = 0x1e;
|
||||
static uint8_t magic2 = 0x7;
|
||||
static uint8_t magic3 = 0x2;
|
||||
static const char *futln;
|
||||
static uint8_t futln_nat;
|
||||
static uint8_t futln_fuvst;
|
||||
static uint16_t futln_rest;
|
||||
static uint16_t sicherungscode = 12345;
|
||||
static uint16_t sonderheitenschluessel = 0;
|
||||
static uint16_t wartungsschluessel = 0xffff;
|
||||
|
||||
/* return 1, if 1-bits are odd, so parity becomes even */
|
||||
static int gen_parity(uint8_t *bits)
|
||||
{
|
||||
int i;
|
||||
uint8_t parity = 0;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
parity ^= (bits[i] & 1);
|
||||
|
||||
return parity;
|
||||
}
|
||||
|
||||
static uint8_t *gen_memory(uint8_t magic1, uint8_t magic2, uint8_t magic3, uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, uint16_t sicherungscode, uint16_t sonderheitenschluessel, uint16_t wartungsschluessel)
|
||||
{
|
||||
static uint8_t memory[416];
|
||||
int i;
|
||||
|
||||
/* meaningless data */
|
||||
for (i = 0; i <= 10; i++)
|
||||
memory[i] = 1;
|
||||
|
||||
/* magic data */
|
||||
for (i = 11; i <= 15; i++)
|
||||
memory[i] = (magic1 >> (i - 11)) & 1;
|
||||
|
||||
/* meaningless data */
|
||||
for (i = 16; i <= 17; i++)
|
||||
memory[i] = 0;
|
||||
|
||||
/* magic data */
|
||||
for (i = 18; i <= 20; i++)
|
||||
memory[i] = (magic2 >> (i - 18)) & 1;
|
||||
|
||||
/* magic data */
|
||||
for (i = 21; i <= 23; i++)
|
||||
memory[i] = (magic3 >> (i - 21)) & 1;
|
||||
|
||||
/* meaningless data */
|
||||
for (i = 24; i <= 113; i++)
|
||||
memory[i] = 1;
|
||||
|
||||
/* number */
|
||||
for (i = 114; i <= 116; i++)
|
||||
memory[i] = (futln_nat >> (i - 114)) & 1;
|
||||
for (i = 117; i <= 121; i++)
|
||||
memory[i] = (futln_fuvst >> (i - 117)) & 1;
|
||||
memory[122] = gen_parity(memory + 114);
|
||||
for (i = 123; i <= 130; i++)
|
||||
memory[i] = (futln_rest >> (i - 123)) & 1;
|
||||
memory[131] = gen_parity(memory + 123);
|
||||
for (i = 132; i <= 139; i++)
|
||||
memory[i] = (futln_rest >> (i - 132 + 8)) & 1;
|
||||
memory[140] = gen_parity(memory + 132);
|
||||
|
||||
/* sicherungscode */
|
||||
for (i = 141; i <= 148; i++)
|
||||
memory[i] = (sicherungscode >> (i - 141)) & 1;
|
||||
memory[149] = gen_parity(memory + 141);
|
||||
for (i = 150; i <= 157; i++)
|
||||
memory[i] = (sicherungscode >> (i - 150 + 8)) & 1;
|
||||
memory[158] = gen_parity(memory + 150);
|
||||
|
||||
/* sonderheitenschluessel */
|
||||
for (i = 159; i <= 166; i++)
|
||||
memory[i] = (sonderheitenschluessel >> (i - 159)) & 1;
|
||||
memory[167] = gen_parity(memory + 159);
|
||||
for (i = 168; i <= 175; i++)
|
||||
memory[i] = (sonderheitenschluessel >> (i - 168 + 8)) & 1;
|
||||
memory[176] = gen_parity(memory + 168);
|
||||
|
||||
/* wartungschluessel */
|
||||
for (i = 177; i <= 184; i++)
|
||||
memory[i] = (wartungsschluessel >> (i - 177)) & 1;
|
||||
memory[185] = gen_parity(memory + 177);
|
||||
for (i = 186; i <= 193; i++)
|
||||
memory[i] = (wartungsschluessel >> (i - 186 + 8)) & 1;
|
||||
memory[194] = gen_parity(memory + 186);
|
||||
|
||||
/* meaningless data */
|
||||
for (i = 195; i <= 351; i++)
|
||||
memory[i] = 1;
|
||||
|
||||
/* all zero */
|
||||
for (i = 352; i <= 415; i++)
|
||||
memory[i] = 0;
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
void print_help(const char *arg0)
|
||||
{
|
||||
printf("Usage: %s [options] <subscriber number>\n", arg0);
|
||||
/* - - */
|
||||
printf("General options:\n");
|
||||
printf(" -h --help\n");
|
||||
printf(" This help\n");
|
||||
printf(" -1 --magic1 <value>\n");
|
||||
printf(" Magic value for bits 011-015 (default = 0x%02x)\n", magic1);
|
||||
printf(" -2 --magic2 <value>\n");
|
||||
printf(" Magic value for bits 018-021 (default = 0x%x)\n", magic2);
|
||||
printf(" -3 --magic3 <value>\n");
|
||||
printf(" Magic value for bits 022-024 (default = 0x%x)\n", magic3);
|
||||
printf(" -C --security-code \n");
|
||||
printf(" Security code (\"Sicherungscode\") (default = %d)\n", sicherungscode);
|
||||
printf(" -S --special-key \n");
|
||||
printf(" Special key (\"Sonderheitenschluessel\") (default = %d)\n", sonderheitenschluessel);
|
||||
printf(" -W --maintenance-key \n");
|
||||
printf(" Maintenance key (\"Wartungsschluessel\") (default = %d)\n", wartungsschluessel);
|
||||
printf("\nSubscriber number:\n");
|
||||
printf(" Give 7 (8) digits of C-Netz subscriber number (FUTLN) without prefix.\n");
|
||||
}
|
||||
|
||||
void add_options(void)
|
||||
{
|
||||
option_add('h', "help", 0);
|
||||
option_add('1', "magic1", 1);
|
||||
option_add('2', "magic2", 2);
|
||||
option_add('3', "magic3", 3);
|
||||
option_add('C', "security-code", 1);
|
||||
option_add('S', "special-key", 1);
|
||||
option_add('W', "maintenance-key", 1);
|
||||
};
|
||||
|
||||
int handle_options(int short_option, int argi, char **argv)
|
||||
{
|
||||
switch (short_option) {
|
||||
case 'h':
|
||||
print_help(argv[0]);
|
||||
return 0;
|
||||
case '1':
|
||||
magic1 = strtoul(argv[argi], NULL, 0);
|
||||
break;
|
||||
case '2':
|
||||
magic2 = strtoul(argv[argi], NULL, 0);
|
||||
break;
|
||||
case '3':
|
||||
magic3 = strtoul(argv[argi], NULL, 0);
|
||||
break;
|
||||
case 'C':
|
||||
sicherungscode = strtoul(argv[argi], NULL, 0);
|
||||
break;
|
||||
case 'S':
|
||||
sonderheitenschluessel = strtoul(argv[argi], NULL, 0);
|
||||
break;
|
||||
case 'W':
|
||||
wartungsschluessel = strtoul(argv[argi], NULL, 0);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int argi;
|
||||
int i;
|
||||
|
||||
debuglevel = DEBUG_INFO;
|
||||
|
||||
add_options();
|
||||
|
||||
/* parse command line */
|
||||
argi = options_command_line(argc, argv, handle_options);
|
||||
if (argi <= 0)
|
||||
return argi;
|
||||
|
||||
/* get subscriber number */
|
||||
if (argi >= argc) {
|
||||
fprintf(stderr, "Expecting subscriber number, use '-h' for help!\n");
|
||||
return 0;
|
||||
}
|
||||
futln = argv[argi];
|
||||
if (strlen(futln) == 7) {
|
||||
futln_nat = *futln++ - '0';
|
||||
futln_fuvst = *futln++ - '0';
|
||||
} else if (strlen(futln) == 8) {
|
||||
futln_nat = *futln++ - '0';
|
||||
futln_fuvst = (*futln++ - '0') * 10;
|
||||
futln_fuvst += *futln++ - '0';
|
||||
} else {
|
||||
inval_sub:
|
||||
fprintf(stderr, "Invalid subscriber number, use '-h' for help!\n");
|
||||
return 0;
|
||||
}
|
||||
futln_rest = (*futln++ - '0') * 10000;
|
||||
futln_rest += (*futln++ - '0') * 1000;
|
||||
futln_rest += (*futln++ - '0') * 100;
|
||||
futln_rest += (*futln++ - '0') * 10;
|
||||
futln_rest += *futln++ - '0';
|
||||
if (futln_nat > 7 || futln_fuvst > 31)
|
||||
goto inval_sub;
|
||||
|
||||
printf("\n");
|
||||
printf("Magic Data 011..015 = %d (0x%02x)\n", magic1, magic1);
|
||||
printf("Magic Data 018..020 = %d\n", magic2);
|
||||
printf("Magic Data 021..023 = %d\n", magic3);
|
||||
printf("FUTLN NAT = %d\n", futln_nat);
|
||||
printf("FUTLN FUVST = %d\n", futln_fuvst);
|
||||
printf("FUTLN REST = %d\n", futln_rest);
|
||||
printf("Sicherungscode=%d\n", sicherungscode);
|
||||
printf("Sonderheitenschluessel=%d (0x%04x)\n", sonderheitenschluessel, sonderheitenschluessel);
|
||||
printf("Wartungsschluessel=%d (0x%04x)\n", wartungsschluessel, wartungsschluessel);
|
||||
printf("\nBinary data: (LSB first)\n");
|
||||
|
||||
uint8_t *bits = gen_memory(magic1, magic2, magic3, futln_nat, futln_fuvst, futln_rest, sicherungscode, sonderheitenschluessel, wartungsschluessel);
|
||||
for (i = 0; i < 52; i++) {
|
||||
printf("0x%02x, ", bits[0] + (bits[1] << 1) + (bits[2] << 2) + (bits[3] << 3) + (bits[4] << 4) + (bits[5] << 5) + (bits[6] << 6) + (bits[7] << 7));
|
||||
bits += 8;
|
||||
if ((i & 7) == 7)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
/* SIM card for ATMEL
|
||||
*
|
||||
* (C) 2020 by Andreas Eversberg <jolly@eversberg.eu>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if defined(__AVR_ATtiny85__)
|
||||
#define RST_PIN 2
|
||||
#define CLK_PIN 3
|
||||
#define DATA_PIN 4
|
||||
#error UNTESTED!
|
||||
#else
|
||||
#define CLK_PIN 5
|
||||
#define RST_PIN 6
|
||||
#define DATA_PIN 7
|
||||
#endif
|
||||
|
||||
uint8_t card_data[] = {
|
||||
|
||||
0xff, 0xf7, 0x5c, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4b, 0x90,
|
||||
0x5f, 0x25, 0x07, 0x0c, 0x00, 0x00, 0xfe, 0xfd,
|
||||
0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
};
|
||||
|
||||
volatile uint8_t *rst_in, *clk_in, *data_in, *data_out, *data_mode;
|
||||
uint8_t rst_bit, clk_bit, data_bit;
|
||||
|
||||
void setup()
|
||||
{
|
||||
volatile uint8_t *out, *mode;
|
||||
uint8_t port;
|
||||
|
||||
rst_bit = digitalPinToBitMask(RST_PIN);
|
||||
port = digitalPinToPort(RST_PIN);
|
||||
mode = portModeRegister(port);
|
||||
out = portOutputRegister(port);
|
||||
rst_in = portInputRegister(port);
|
||||
*mode &= ~rst_bit; /* input */
|
||||
*out |= rst_bit; /* pullup */
|
||||
|
||||
clk_bit = digitalPinToBitMask(CLK_PIN);
|
||||
port = digitalPinToPort(CLK_PIN);
|
||||
mode = portModeRegister(port);
|
||||
out = portOutputRegister(port);
|
||||
clk_in = portInputRegister(port);
|
||||
*mode &= ~clk_bit; /* input */
|
||||
*out |= clk_bit; /* pullup */
|
||||
|
||||
data_bit = digitalPinToBitMask(DATA_PIN);
|
||||
port = digitalPinToPort(DATA_PIN);
|
||||
data_mode = portModeRegister(port);
|
||||
data_out = portOutputRegister(port);
|
||||
data_in = portInputRegister(port);
|
||||
*data_mode |= data_bit; /* output */
|
||||
}
|
||||
|
||||
uint8_t byte_count;
|
||||
uint8_t bit_count;
|
||||
|
||||
void loop()
|
||||
{
|
||||
reset:
|
||||
byte_count = 0;
|
||||
bit_count = 0;
|
||||
|
||||
/* wait for reset pulse */
|
||||
while (!(*rst_in & rst_bit));
|
||||
/* now we have reset, so we wait for clock pulse */
|
||||
while (!(*clk_in & clk_bit)) {
|
||||
/* if we lost reset, go to start */
|
||||
if (!(*rst_in & rst_bit))
|
||||
goto reset;
|
||||
}
|
||||
while ((*clk_in & clk_bit)) {
|
||||
/* if we lost reset, go to start */
|
||||
if (!(*rst_in & rst_bit))
|
||||
goto reset;
|
||||
}
|
||||
while ((*rst_in & rst_bit));
|
||||
|
||||
next_bit:
|
||||
/* present bit */
|
||||
if ((card_data[byte_count] >> bit_count) & 1)
|
||||
*data_out |= data_bit; /* high */
|
||||
else
|
||||
*data_out &= ~data_bit; /* low */
|
||||
if (++bit_count == 8) {
|
||||
bit_count = 0;
|
||||
if (++byte_count == sizeof(card_data)) {
|
||||
goto reset;
|
||||
}
|
||||
}
|
||||
|
||||
/* wait for clock pulse */
|
||||
while (!(*clk_in & clk_bit)) {
|
||||
/* reset counter if reset was detected */
|
||||
if ((*rst_in & rst_bit)) {
|
||||
goto reset;
|
||||
}
|
||||
}
|
||||
while ((*clk_in & clk_bit)) {
|
||||
/* reset counter if reset was detected */
|
||||
if ((*rst_in & rst_bit)) {
|
||||
goto reset;
|
||||
}
|
||||
}
|
||||
goto next_bit;
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
AM_CPPFLAGS = -Wall -Wextra -g $(all_includes)
|
||||
|
||||
bin_PROGRAMS = \
|
||||
cnetz_sim
|
||||
|
||||
cnetz_sim_SOURCES = \
|
||||
sim.c
|
||||
cnetz_sim_LDADD = \
|
||||
$(COMMON_LA)
|
||||
|
15
sim/README
15
sim/README
|
@ -1,15 +0,0 @@
|
|||
This is a generator for the C-Netz Sim Card
|
||||
"Berechtigungskarte als Speicherkarte".
|
||||
|
||||
The Smart Card "Berechtigungskarte als Prozessorkarte" is not supported.
|
||||
|
||||
After generation, the hex data can be copied to the data array of simcard.ino
|
||||
and written to an SLE4428 or compatible.
|
||||
|
||||
Note: The SLE card must not have protected serial number area. (ATR area)
|
||||
Also the card must show all 416 written bits via ATR, not only 32 bits.
|
||||
|
||||
Tested:
|
||||
Works with BSA 51
|
||||
Does not work with all other phones I have.
|
||||
|
144
sim/sim.c
144
sim/sim.c
|
@ -1,144 +0,0 @@
|
|||
/* SIM Card for C-Netz "Berechtigungskarte als Speicherkarte"
|
||||
*
|
||||
* (C) 2016 by Andreas Eversberg <jolly@eversberg.eu>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* return 1, if 1-bits are odd, so parity becomes even */
|
||||
static int gen_parity(uint8_t *bits)
|
||||
{
|
||||
int i;
|
||||
uint8_t parity = 0;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
parity ^= (bits[i] & 1);
|
||||
|
||||
return parity;
|
||||
}
|
||||
|
||||
static uint8_t *gen_memory(uint8_t futln_nat, uint8_t futln_fuvst, uint16_t futln_rest, uint16_t sicherungscode, uint16_t sonderheitsschluessel)
|
||||
{
|
||||
static uint8_t memory[416];
|
||||
int i;
|
||||
|
||||
/* meaningless data */
|
||||
for (i = 0; i <= 10; i++)
|
||||
memory[i] = 1;
|
||||
|
||||
/* magic data */
|
||||
memory[11] = 0;
|
||||
memory[12] = 1;
|
||||
memory[13] = 1;
|
||||
memory[14] = 1;
|
||||
memory[15] = 1;
|
||||
|
||||
/* meaningless data */
|
||||
for (i = 16; i <= 17; i++)
|
||||
memory[i] = 0;
|
||||
|
||||
/* magic data */
|
||||
memory[18] = 1;
|
||||
memory[19] = 1;
|
||||
memory[20] = 1;
|
||||
|
||||
/* magic data */
|
||||
memory[21] = 0;
|
||||
memory[22] = 1;
|
||||
memory[23] = 0;
|
||||
|
||||
/* meaningless data */
|
||||
for (i = 24; i <= 113; i++)
|
||||
memory[i] = 1;
|
||||
|
||||
/* number */
|
||||
for (i = 114; i <= 116; i++)
|
||||
memory[i] = (futln_nat >> (i - 114)) & 1;
|
||||
for (i = 117; i <= 121; i++)
|
||||
memory[i] = (futln_fuvst >> (i - 117)) & 1;
|
||||
memory[122] = gen_parity(memory + 114);
|
||||
for (i = 123; i <= 130; i++)
|
||||
memory[i] = (futln_rest >> (i - 123)) & 1;
|
||||
memory[131] = gen_parity(memory + 123);
|
||||
for (i = 132; i <= 139; i++)
|
||||
memory[i] = (futln_rest >> (i - 132 + 8)) & 1;
|
||||
memory[140] = gen_parity(memory + 132);
|
||||
|
||||
/* sicherungscode */
|
||||
for (i = 141; i <= 148; i++)
|
||||
memory[i] = (sicherungscode >> (i - 141)) & 1;
|
||||
memory[149] = gen_parity(memory + 141);
|
||||
for (i = 150; i <= 157; i++)
|
||||
memory[i] = (sicherungscode >> (i - 150 + 8)) & 1;
|
||||
memory[158] = gen_parity(memory + 150);
|
||||
|
||||
/* sonderheitsschluessel */
|
||||
for (i = 159; i <= 166; i++)
|
||||
memory[i] = (sonderheitsschluessel >> (i - 159)) & 1;
|
||||
memory[167] = gen_parity(memory + 159);
|
||||
for (i = 168; i <= 175; i++)
|
||||
memory[i] = (sonderheitsschluessel >> (i - 168 + 8)) & 1;
|
||||
memory[176] = gen_parity(memory + 168);
|
||||
|
||||
/* meaningless data */
|
||||
for (i = 177; i <= 351; i++)
|
||||
memory[i] = 1;
|
||||
|
||||
/* all zero */
|
||||
for (i = 352; i <= 415; i++)
|
||||
memory[i] = 0;
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
if (argc <= 5) {
|
||||
printf("Usage: %s <futln_nat> <futln_fuvst> <futln_rest> <sicherungscode> <sonderheitsschluessel>\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
int i;
|
||||
uint8_t futln_nat = atoi(argv[1]);
|
||||
uint8_t futln_fuvst = atoi(argv[2]);
|
||||
uint16_t futln_rest = atoi(argv[3]);
|
||||
uint16_t sicherungscode = atoi(argv[4]);
|
||||
uint16_t sonderheitsschluessel = atoi(argv[5]);
|
||||
printf("nat=%d\n", futln_nat);
|
||||
printf("fufvt=%d\n", futln_fuvst);
|
||||
printf("rest=%d\n", futln_rest);
|
||||
printf("sicherungscode=%d\n", sicherungscode);
|
||||
printf("sonderheitsschluessel=%d\n", sonderheitsschluessel);
|
||||
|
||||
printf("Telefonnummer: %d%d%05d\n", futln_nat, futln_fuvst, futln_rest);
|
||||
|
||||
uint8_t *bits = gen_memory(futln_nat, futln_fuvst, futln_rest, sicherungscode, sonderheitsschluessel);
|
||||
for (i = 0; i < 52; i++) {
|
||||
//printf("%d %d %d %d %d %d %d %d\n", bits[0], bits[1], bits[2] ,bits[3] ,bits[4] ,bits[5] ,bits[6] ,bits[7]);
|
||||
printf("0x%02x, ", bits[0] + (bits[1] << 1) + (bits[2] << 2) + (bits[3] << 3) + (bits[4] << 4) + (bits[5] << 5) + (bits[6] << 6) + (bits[7] << 7));
|
||||
//printf("\n");
|
||||
bits += 8;
|
||||
if ((i & 7) == 7)
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue