azrael
02-04-2005, 19:49
hi, found this on a very interesting site
/*
* fakesim.c - part of Fake SIM application
*
* Copyright (C) 2003 BLADOX, s.r.o.
*
* 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 2, or (at your option) any
* later version.
*
#include <stdlib.h>
#include <string.h>
/*
TODO
do not reactivate active
*/
/* *INDENT-OFF* */
lc_char PROGMEM lc_Fake_sim[]={
LC_EN("Fake SIM")
LC_END
};
lc_char PROGMEM lc_Default[]={
LC_EN("Default")
LC_END
};
lc_char PROGMEM lc_Activate[]={
LC_EN("Activate")
LC_END
};
lc_char PROGMEM lc_Name[]={
LC_EN("Name:")
LC_END
};
lc_char PROGMEM lc_Ki[]={
LC_UN("Ki:")
LC_END
};
lc_char PROGMEM lc_IMSI[]={
LC_UN("IMSI:")
LC_END
};
/* *INDENT-ON* */
void A3A8 (u8 key[16], u8 rand[16], u8 simoutput[12]);
u8 PROGMEM ef_imsi_path[] = { 0x3F, 0x00, 0x7F, 0x20, 0x6F, 0x07 };
typedef struct _Fake_sim
{
u8 imsi[9];
u8 ki[16];
}
Fake_sim;
typedef struct _sims_mem
{
SEdge *sims;
Fake_sim *cur_sim;
}
sims_mem;
SEdge *sims;
Fake_sim *cur_sim;
u8 *get_resp_gsm;
u8 PROGMEM _ef_imsi[] = {
0x00, 0x00, 0x00, 0x09, 0x6F, 0x07, 0x04, 0x00,
0x14, 0x00, 0x14, 0x01, 0x01, 0x00, 0x00
};
void fake_sim_file (File_apdu_data * fa)
{
u8 i;
dbsp ("FAKE_SIM_FILE\n");
dbsp ("EF ");
dbih (fa->ef);
dbc ('\n');
if (fa->ins == ME_CMD_SELECT)
{
u16 ef = (fa->data[0] << 8) | fa->data[1];
if (ef == 0x6F07)
{
dbsp ("FAKE_IMSI_SELECT\n");
fa->data[0] = 0x9F;
fa->data[1] = 0x0F;
}
return;
}
if (fa->prev_ins == ME_CMD_SELECT && fa->ef == 0x6F07)
{
dbsp ("FAKE_IMSI\n");
if (fa->ins == ME_CMD_GET_RESPONSE)
{
memcpy (fa->data, _ef_imsi, sizeof (_ef_imsi));
fa->data[fa->p3] = 0x90;
fa->data[fa->p3 + 1] = 0x00;
}
if (fa->ins == ME_CMD_READ_BINARY)
{
memcpy (fa->data, &cur_sim->imsi, 9);
fa->data[fa->p3] = 0x90;
fa->data[fa->p3 + 1] = 0x00;
}
}
if (fa->prev_ins == ME_CMD_RUN_GSM_ALGORITHM
&& fa->ins == ME_CMD_GET_RESPONSE)
{
dbsp ("FAKE_GSM_GET_RESP\n");
memcpy (fa->data, get_resp_gsm, 0x0c);
fa->data[0x0c] = 0x90;
fa->data[0x0d] = 0x00;
free (get_resp_gsm);
get_resp_gsm = NULL;
}
}
void run_gsm (File_apdu_data * fa)
{
u8 key[16];
u8 i;
u8 s[16];
dbsp (">fake_sim_run_gsm\n");
memcpy (s, fa->data, 16);
get_resp_gsm = malloc (12);
for (i = 0; i < 16; i++)
key[i] = rb (&cur_sim->ki[i]);
#ifdef DEBUG
dbsp ("KEY :");
for (i = 0; i < 16; i++)
{
dbch (key[i]);
dbc (' ');
}
dbc ('\n');
#endif
A3A8 (key, s, get_resp_gsm);
#ifdef DEBUG
dbsp ("RES :");
for (i = 0; i < 16; i++)
{
dbch (get_resp_gsm[i]);
dbc (' ');
}
dbc ('\n');
#endif
//buf for get_resp
fa->data[0] = 0x9f;
fa->data[1] = 0x0c;
dbsp ("<fake_sim_run_gsm\n");
}
b16 hextoint (char x)
{
if (x >= 'a' && x <= 'f')
return x - 'a' + 10;
else if (x >= 'A' && x <= 'F')
return x - 'A' + 10;
else if (x >= '0' && x <= '9')
return x - '0';
return -1;
}
SNodeP fake_sim_n;
SNodeP fake_sim_n_3;
SNodeP fake_sim_n_4;
SNodeP fake_sim_n_5;
SNodeP fake_sim_n_6;
u8 fake_sim_ctx (SCtx * ctx, u8 action)
{
if (action == APP_ENTER)
{
dbsp (">fake_sim_ctx\n");
spider_append_r (ctx, &fake_sim_n_5);
spider_append_r (ctx, &fake_sim_n_3);
dbsp ("<fake_sim_ctx\n");
}
else if (action == APP_LEAVE)
{
spider_clear_r (ctx);
}
}
u8 *insert_sim (u8 * name, u8 imsi[9], u8 ki[16])
{
Fake_sim *s;
SNode *n;
SEdge *e;
u8 *t;
u8 l = strlen (name) + 1;
sims_mem *p;
dbsp (">insert_sim\n");
s = emalloc (sizeof (Fake_sim));
if (s == NULL)
return NULL;
n = emalloc (sizeof (SNode));
if (n == NULL)
goto X1;
e = emalloc (sizeof (SEdge));
if (e == NULL)
goto X2;
t = emalloc (l);
if (t == NULL)
goto X3;
memcpy (&s->imsi, imsi, 9);
memcpy (&s->ki, ki, 16);
memcpy (t, name, l);
ww (&n->text, t);
ww (&n->cb, fake_sim_ctx);
ww (&n->p, s);
ww (&e->f, &fake_sim_n);
ww (&e->t, n);
wb (&e->source, MEM_F_P | MEM_T_E);
ww (&e->next, sims);
sims = e;
p = app_data ();
ww (&p->sims, sims);
dbsp ("<insert_sim\n");
return s;
X3:
dbsp ("<insert_sim_3\n");
efree (e);
X2:
dbsp ("<insert_sim_2\n");
efree (n);
X1:
dbsp ("<insert_sim_1\n");
efree (s);
return NULL;
}
u8 fake_sim_new (SCtx * ctx, u8 action)
{
if (action == APP_ENTER)
{
u8 i, j, k;
u8 name[16];
u8 imsi[9];
u8 ki[16];
u8 *res;
b16 x;
// name
res = get_input (locale (lc_Name), 1, 15, NULL, Q_GET_INPUT_ALPHABET);
if (res == ENULL)
return APP_END;
if (res == NULL)
return APP_BACK;
j = res[0] - 1;
res++; //len
res++; //dcs
memcpy (name, res, j);
name[j] = '\0';
// IMSI
X3:
res = get_input (locale (lc_IMSI), 18, 18, NULL, Q_GET_INPUT_ALPHABET);
if (res == ENULL)
return APP_END;
if (res == NULL)
return APP_BACK;
j = res[0] - 1;
res++; //len
res++; //dcs
for (i = 0; i < 9; i++)
{
x = hextoint (res[2 * i]);
if (x == -1)
{
perror (ERR_BAD_INPUT);
goto X3;
}
j = x << 4;
x = hextoint (res[2 * i + 1]);
if (x == -1)
{
perror (ERR_BAD_INPUT);
goto X3;
}
k = x;
imsi[i] = j | k;
}
// Ki
X4:
res = get_input (locale (lc_Ki), 32, 32, NULL, Q_GET_INPUT_ALPHABET);
if (res == ENULL)
return APP_END;
if (res == NULL)
return APP_BACK;
j = res[0] - 1;
res++; //len
res++; //dcs
for (i = 0; i < 16; i++)
{
x = hextoint (res[2 * i]);
if (x == -1)
{
perror (ERR_BAD_INPUT);
goto X3;
}
j = x << 4;
x = hextoint (res[2 * i + 1]);
if (x == -1)
{
perror (ERR_BAD_INPUT);
goto X3;
}
k = x;
ki[i] = j | k;
}
// SMSC...
res = insert_sim (name, imsi, ki);
if (res == NULL)
perror (ERR_NO_EEPROM);
else
ctx->eE = sims;
return APP_BACK;
}
}
u8 fake_sim_activate_default (SCtx * ctx, u8 action)
{
if (action == APP_ENTER)
{
unreg_file (ef_imsi_path, 3);
unreg_action (ACTION_RUN_GSM_ALGORITHM);
cur_sim = 0;
ww (&((sims_mem *) app_data ())->cur_sim, cur_sim);
change_imsi ();
return APP_BACK;
}
}
u8 fake_sim_delete (SCtx * ctx, u8 action)
{
}
u8 fake_sim_activate (SCtx * ctx, u8 action)
{
if (action == APP_ENTER)
{
if (cur_sim == 0)
{
reg_file (ef_imsi_path, 3);
reg_action (ACTION_RUN_GSM_ALGORITHM);
}
cur_sim = rw (&ctx->parent->f->p);
ww (&((sims_mem *) app_data ())->cur_sim, cur_sim);
change_imsi ();
return APP_BACK;
}
}
u8 fake_sim_view (SCtx * ctx, u8 action)
{
if (action == APP_ENTER)
{
u8 *s = buf_B ();
u8 *r = s;
u8 i;
u8 l;
Fake_sim *sim;
sim = rw (&ctx->parent->f->p);
r = sprints (r, locale (lc_IMSI));
r = sprintc (r, '\n');
for (i = 0; i < 9; i++)
{
r = sprintch (r, rb (&sim->imsi[i]));
}
r = sprintc (r, '\n');
r = sprints (r, locale (lc_Ki));
r = sprintc (r, '\n');
for (i = 0; i < 16; i++)
{
r = sprintch (r, rb (&sim->ki[i]));
}
r = sprintc (r, '\0');
if (display_text (s, NULL) == APP_END)
return APP_END;
return APP_BACK;
}
}
u8 fake_sim_edit (SCtx * ctx, u8 action)
{
}
SNodeP fake_sim_n = { lc_Fake_sim, NULL };
SNodeP fake_sim_n_1 = { LC_NEW, fake_sim_new };
SNodeP fake_sim_n_2 = { lc_Default, NULL };
SNodeP fake_sim_n_3 = { lc_Activate, fake_sim_activate };
SNodeP fake_sim_n_4 =
{ LC_DELETE, not_implemented /*fake_sim_delete */ };
SNodeP fake_sim_n_5 = { LC_VIEW, fake_sim_view };
SNodeP fake_sim_n_6 = { LC_EDIT, not_implemented /*fake_sim_edit */ };
SNodeP fake_sim_n_7 = { lc_Activate, fake_sim_activate_default };
SEdgeP fake_sim_edges_p[]={
{&fake_sim_n,&fake_sim_n_1}, // Fake_sim->New
{&fake_sim_n,&fake_sim_n_2}, // Fake_sim->Default
{&fake_sim_n_2,&fake_sim_n_7}, // Default->Activate
NULL
};
void fake_sim (void *x)
{
SCtx *c = spider_init ();
if (c == NULL)
return;
c->n = &fake_sim_n;
c->eP = &fake_sim_edges_p;
c->eE = sims;
spider (c);
}
void turbo_handler (u8 action, void *data)
{
switch (action)
{
case ACTION_APP_REGISTER:
{
sims_mem *p = emalloc (sizeof (sims_mem));
sims = 0;
ww (&p->sims, 0);
ww (&p->cur_sim, 0);
reg_app_data (p);
}
break;
case ACTION_APP_UNREGISTER:
{
SEdge *e = sims;
SNode *n;
while (e != NULL)
{
n = rw (&e->t);
efree (rw (&n->p));
efree (rw (&n->text));
efree (n);
sims = e;
e = rw (&sims->next);
efree (sims);
}
}
break;
case ACTION_APP_INIT:
{
sims_mem *p = app_data ();
sims = rw (&p->sims);
cur_sim = rw (&p->cur_sim);
if (cur_sim)
{
reg_file (ef_imsi_path, 3);
reg_action (ACTION_RUN_GSM_ALGORITHM);
}
}
break;
case ACTION_INSERT_MENU:
insert_menu (locale (lc_Fake_sim));
break;
case ACTION_MENU_SELECTION:
stk_thread (fake_sim, NULL);
break;
case ACTION_RUN_GSM_ALGORITHM:
run_gsm (data);
break;
case ACTION_FILE_APDU:
fake_sim_file (data);
break;
default:
break;
}
}
@ sir graham: do you think it helps for your implementation on funcard :-)
/*
* fakesim.c - part of Fake SIM application
*
* Copyright (C) 2003 BLADOX, s.r.o.
*
* 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 2, or (at your option) any
* later version.
*
#include <stdlib.h>
#include <string.h>
/*
TODO
do not reactivate active
*/
/* *INDENT-OFF* */
lc_char PROGMEM lc_Fake_sim[]={
LC_EN("Fake SIM")
LC_END
};
lc_char PROGMEM lc_Default[]={
LC_EN("Default")
LC_END
};
lc_char PROGMEM lc_Activate[]={
LC_EN("Activate")
LC_END
};
lc_char PROGMEM lc_Name[]={
LC_EN("Name:")
LC_END
};
lc_char PROGMEM lc_Ki[]={
LC_UN("Ki:")
LC_END
};
lc_char PROGMEM lc_IMSI[]={
LC_UN("IMSI:")
LC_END
};
/* *INDENT-ON* */
void A3A8 (u8 key[16], u8 rand[16], u8 simoutput[12]);
u8 PROGMEM ef_imsi_path[] = { 0x3F, 0x00, 0x7F, 0x20, 0x6F, 0x07 };
typedef struct _Fake_sim
{
u8 imsi[9];
u8 ki[16];
}
Fake_sim;
typedef struct _sims_mem
{
SEdge *sims;
Fake_sim *cur_sim;
}
sims_mem;
SEdge *sims;
Fake_sim *cur_sim;
u8 *get_resp_gsm;
u8 PROGMEM _ef_imsi[] = {
0x00, 0x00, 0x00, 0x09, 0x6F, 0x07, 0x04, 0x00,
0x14, 0x00, 0x14, 0x01, 0x01, 0x00, 0x00
};
void fake_sim_file (File_apdu_data * fa)
{
u8 i;
dbsp ("FAKE_SIM_FILE\n");
dbsp ("EF ");
dbih (fa->ef);
dbc ('\n');
if (fa->ins == ME_CMD_SELECT)
{
u16 ef = (fa->data[0] << 8) | fa->data[1];
if (ef == 0x6F07)
{
dbsp ("FAKE_IMSI_SELECT\n");
fa->data[0] = 0x9F;
fa->data[1] = 0x0F;
}
return;
}
if (fa->prev_ins == ME_CMD_SELECT && fa->ef == 0x6F07)
{
dbsp ("FAKE_IMSI\n");
if (fa->ins == ME_CMD_GET_RESPONSE)
{
memcpy (fa->data, _ef_imsi, sizeof (_ef_imsi));
fa->data[fa->p3] = 0x90;
fa->data[fa->p3 + 1] = 0x00;
}
if (fa->ins == ME_CMD_READ_BINARY)
{
memcpy (fa->data, &cur_sim->imsi, 9);
fa->data[fa->p3] = 0x90;
fa->data[fa->p3 + 1] = 0x00;
}
}
if (fa->prev_ins == ME_CMD_RUN_GSM_ALGORITHM
&& fa->ins == ME_CMD_GET_RESPONSE)
{
dbsp ("FAKE_GSM_GET_RESP\n");
memcpy (fa->data, get_resp_gsm, 0x0c);
fa->data[0x0c] = 0x90;
fa->data[0x0d] = 0x00;
free (get_resp_gsm);
get_resp_gsm = NULL;
}
}
void run_gsm (File_apdu_data * fa)
{
u8 key[16];
u8 i;
u8 s[16];
dbsp (">fake_sim_run_gsm\n");
memcpy (s, fa->data, 16);
get_resp_gsm = malloc (12);
for (i = 0; i < 16; i++)
key[i] = rb (&cur_sim->ki[i]);
#ifdef DEBUG
dbsp ("KEY :");
for (i = 0; i < 16; i++)
{
dbch (key[i]);
dbc (' ');
}
dbc ('\n');
#endif
A3A8 (key, s, get_resp_gsm);
#ifdef DEBUG
dbsp ("RES :");
for (i = 0; i < 16; i++)
{
dbch (get_resp_gsm[i]);
dbc (' ');
}
dbc ('\n');
#endif
//buf for get_resp
fa->data[0] = 0x9f;
fa->data[1] = 0x0c;
dbsp ("<fake_sim_run_gsm\n");
}
b16 hextoint (char x)
{
if (x >= 'a' && x <= 'f')
return x - 'a' + 10;
else if (x >= 'A' && x <= 'F')
return x - 'A' + 10;
else if (x >= '0' && x <= '9')
return x - '0';
return -1;
}
SNodeP fake_sim_n;
SNodeP fake_sim_n_3;
SNodeP fake_sim_n_4;
SNodeP fake_sim_n_5;
SNodeP fake_sim_n_6;
u8 fake_sim_ctx (SCtx * ctx, u8 action)
{
if (action == APP_ENTER)
{
dbsp (">fake_sim_ctx\n");
spider_append_r (ctx, &fake_sim_n_5);
spider_append_r (ctx, &fake_sim_n_3);
dbsp ("<fake_sim_ctx\n");
}
else if (action == APP_LEAVE)
{
spider_clear_r (ctx);
}
}
u8 *insert_sim (u8 * name, u8 imsi[9], u8 ki[16])
{
Fake_sim *s;
SNode *n;
SEdge *e;
u8 *t;
u8 l = strlen (name) + 1;
sims_mem *p;
dbsp (">insert_sim\n");
s = emalloc (sizeof (Fake_sim));
if (s == NULL)
return NULL;
n = emalloc (sizeof (SNode));
if (n == NULL)
goto X1;
e = emalloc (sizeof (SEdge));
if (e == NULL)
goto X2;
t = emalloc (l);
if (t == NULL)
goto X3;
memcpy (&s->imsi, imsi, 9);
memcpy (&s->ki, ki, 16);
memcpy (t, name, l);
ww (&n->text, t);
ww (&n->cb, fake_sim_ctx);
ww (&n->p, s);
ww (&e->f, &fake_sim_n);
ww (&e->t, n);
wb (&e->source, MEM_F_P | MEM_T_E);
ww (&e->next, sims);
sims = e;
p = app_data ();
ww (&p->sims, sims);
dbsp ("<insert_sim\n");
return s;
X3:
dbsp ("<insert_sim_3\n");
efree (e);
X2:
dbsp ("<insert_sim_2\n");
efree (n);
X1:
dbsp ("<insert_sim_1\n");
efree (s);
return NULL;
}
u8 fake_sim_new (SCtx * ctx, u8 action)
{
if (action == APP_ENTER)
{
u8 i, j, k;
u8 name[16];
u8 imsi[9];
u8 ki[16];
u8 *res;
b16 x;
// name
res = get_input (locale (lc_Name), 1, 15, NULL, Q_GET_INPUT_ALPHABET);
if (res == ENULL)
return APP_END;
if (res == NULL)
return APP_BACK;
j = res[0] - 1;
res++; //len
res++; //dcs
memcpy (name, res, j);
name[j] = '\0';
// IMSI
X3:
res = get_input (locale (lc_IMSI), 18, 18, NULL, Q_GET_INPUT_ALPHABET);
if (res == ENULL)
return APP_END;
if (res == NULL)
return APP_BACK;
j = res[0] - 1;
res++; //len
res++; //dcs
for (i = 0; i < 9; i++)
{
x = hextoint (res[2 * i]);
if (x == -1)
{
perror (ERR_BAD_INPUT);
goto X3;
}
j = x << 4;
x = hextoint (res[2 * i + 1]);
if (x == -1)
{
perror (ERR_BAD_INPUT);
goto X3;
}
k = x;
imsi[i] = j | k;
}
// Ki
X4:
res = get_input (locale (lc_Ki), 32, 32, NULL, Q_GET_INPUT_ALPHABET);
if (res == ENULL)
return APP_END;
if (res == NULL)
return APP_BACK;
j = res[0] - 1;
res++; //len
res++; //dcs
for (i = 0; i < 16; i++)
{
x = hextoint (res[2 * i]);
if (x == -1)
{
perror (ERR_BAD_INPUT);
goto X3;
}
j = x << 4;
x = hextoint (res[2 * i + 1]);
if (x == -1)
{
perror (ERR_BAD_INPUT);
goto X3;
}
k = x;
ki[i] = j | k;
}
// SMSC...
res = insert_sim (name, imsi, ki);
if (res == NULL)
perror (ERR_NO_EEPROM);
else
ctx->eE = sims;
return APP_BACK;
}
}
u8 fake_sim_activate_default (SCtx * ctx, u8 action)
{
if (action == APP_ENTER)
{
unreg_file (ef_imsi_path, 3);
unreg_action (ACTION_RUN_GSM_ALGORITHM);
cur_sim = 0;
ww (&((sims_mem *) app_data ())->cur_sim, cur_sim);
change_imsi ();
return APP_BACK;
}
}
u8 fake_sim_delete (SCtx * ctx, u8 action)
{
}
u8 fake_sim_activate (SCtx * ctx, u8 action)
{
if (action == APP_ENTER)
{
if (cur_sim == 0)
{
reg_file (ef_imsi_path, 3);
reg_action (ACTION_RUN_GSM_ALGORITHM);
}
cur_sim = rw (&ctx->parent->f->p);
ww (&((sims_mem *) app_data ())->cur_sim, cur_sim);
change_imsi ();
return APP_BACK;
}
}
u8 fake_sim_view (SCtx * ctx, u8 action)
{
if (action == APP_ENTER)
{
u8 *s = buf_B ();
u8 *r = s;
u8 i;
u8 l;
Fake_sim *sim;
sim = rw (&ctx->parent->f->p);
r = sprints (r, locale (lc_IMSI));
r = sprintc (r, '\n');
for (i = 0; i < 9; i++)
{
r = sprintch (r, rb (&sim->imsi[i]));
}
r = sprintc (r, '\n');
r = sprints (r, locale (lc_Ki));
r = sprintc (r, '\n');
for (i = 0; i < 16; i++)
{
r = sprintch (r, rb (&sim->ki[i]));
}
r = sprintc (r, '\0');
if (display_text (s, NULL) == APP_END)
return APP_END;
return APP_BACK;
}
}
u8 fake_sim_edit (SCtx * ctx, u8 action)
{
}
SNodeP fake_sim_n = { lc_Fake_sim, NULL };
SNodeP fake_sim_n_1 = { LC_NEW, fake_sim_new };
SNodeP fake_sim_n_2 = { lc_Default, NULL };
SNodeP fake_sim_n_3 = { lc_Activate, fake_sim_activate };
SNodeP fake_sim_n_4 =
{ LC_DELETE, not_implemented /*fake_sim_delete */ };
SNodeP fake_sim_n_5 = { LC_VIEW, fake_sim_view };
SNodeP fake_sim_n_6 = { LC_EDIT, not_implemented /*fake_sim_edit */ };
SNodeP fake_sim_n_7 = { lc_Activate, fake_sim_activate_default };
SEdgeP fake_sim_edges_p[]={
{&fake_sim_n,&fake_sim_n_1}, // Fake_sim->New
{&fake_sim_n,&fake_sim_n_2}, // Fake_sim->Default
{&fake_sim_n_2,&fake_sim_n_7}, // Default->Activate
NULL
};
void fake_sim (void *x)
{
SCtx *c = spider_init ();
if (c == NULL)
return;
c->n = &fake_sim_n;
c->eP = &fake_sim_edges_p;
c->eE = sims;
spider (c);
}
void turbo_handler (u8 action, void *data)
{
switch (action)
{
case ACTION_APP_REGISTER:
{
sims_mem *p = emalloc (sizeof (sims_mem));
sims = 0;
ww (&p->sims, 0);
ww (&p->cur_sim, 0);
reg_app_data (p);
}
break;
case ACTION_APP_UNREGISTER:
{
SEdge *e = sims;
SNode *n;
while (e != NULL)
{
n = rw (&e->t);
efree (rw (&n->p));
efree (rw (&n->text));
efree (n);
sims = e;
e = rw (&sims->next);
efree (sims);
}
}
break;
case ACTION_APP_INIT:
{
sims_mem *p = app_data ();
sims = rw (&p->sims);
cur_sim = rw (&p->cur_sim);
if (cur_sim)
{
reg_file (ef_imsi_path, 3);
reg_action (ACTION_RUN_GSM_ALGORITHM);
}
}
break;
case ACTION_INSERT_MENU:
insert_menu (locale (lc_Fake_sim));
break;
case ACTION_MENU_SELECTION:
stk_thread (fake_sim, NULL);
break;
case ACTION_RUN_GSM_ALGORITHM:
run_gsm (data);
break;
case ACTION_FILE_APDU:
fake_sim_file (data);
break;
default:
break;
}
}
@ sir graham: do you think it helps for your implementation on funcard :-)