lpdump.c
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following functions.
- mydump
- show_latency
- show_pmminfo
- show_idminfo
- sinfo
- printserviceinfo
- dump_service
- enum_service
- main
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "libpasori.h"
void
mydump(uint8 *p,int size){
/* [<][>][^][v][top][bottom][index][help] */
int i;
for (i=0;i!=size;i++){
printf("%02X",p[i]);
}
}
void
show_latency(uint8 d){
/* [<][>][^][v][top][bottom][index][help] */
int A,B,E;
float f;
A = d & 7;
B = (d >> 3) & 7;
E = d >> 6;
B++;
A++;
f = 1 << (E*2);
f = 0.302 * f;
printf("%02.3f + %02.3f *n ms \n",A*f,B*f);
}
void
show_pmminfo(uint8* pmm){
/* [<][>][^][v][top][bottom][index][help] */
printf("# ---PMm Info (JICSAP V2 TypeC) ---\n");
printf("# IC CODE : %02X %02X\n",pmm[0],pmm[1]);
printf("# MAX Latency Info\n");
printf("# Request service :");
show_latency(pmm[2]);
printf("# Request responce :");
show_latency(pmm[3]);
printf("# AuthenticationN :");
show_latency(pmm[4]);
printf("# Read :");
show_latency(pmm[5]);
printf("# Write :");
show_latency(pmm[6]);
printf("# Register/Change System Block:");
show_latency(pmm[7]);
}
void
show_idminfo(uint8* idm){
/* [<][>][^][v][top][bottom][index][help] */
time_t mtime;
time_t ntime;
struct tm fepoc;
signed int d;
fepoc.tm_sec = 0;
fepoc.tm_min = 0;
fepoc.tm_hour = 0;
fepoc.tm_mday = 1;
fepoc.tm_mon = 0;
fepoc.tm_year = 100;
fepoc.tm_isdst = 0;
mtime = mktime(&fepoc);
ntime = time(NULL);
d = idm[4] + idm[5] * 0x100;
if(d & 0x8000){
d = 0 - (0x10000 - d );
}
mtime += d * 24 * 60 * 60;
fepoc = *localtime(&mtime); /* FIXME:structure copy */
printf("# lpdump : %s",ctime(&ntime));
printf("# --- IDm info (FeliCa) ---\n");
printf("# Manufacture Date = %d/%d/%d\n",fepoc.tm_year+1900,fepoc.tm_mon+1,fepoc.tm_mday);
printf("# SN = %d\n",idm[6]+idm[7]*0x100);
printf("# Manufacture Code = %04X\n",idm[0]+idm[1]*0x100);
printf("# Equip. Code = %04X\n",idm[2]+idm[3]*0x100);
}
struct __tag__sinfo{
int c;
char *d;
};
typedef struct __tag__sinfo sinfo;
/* [<][>][^][v][top][bottom][index][help] */
const sinfo sifo[] = {
{ 0 , " Area Code " },
{ 4 , " Ramdom Access R/W " },
{ 5 , " Random Access Read only " },
{ 6 , " Cyclic Access R/W " },
{ 7 , " Cyclic Access Read only " },
{ 8 , " Purse (Direct) " },
{ 9 , " Purse (Cashback/decrement)" },
{ 10, " Purse (Decrement) " },
{ 11, " Purse (Read Only) " },
{ -1, " INVALID or UNKNOWN "}
};
void
printserviceinfo(felica *f,uint16 s){
/* [<][>][^][v][top][bottom][index][help] */
int i;
printf("# ");
mydump(f->IDm,8);
printf(":%04X:%04X #%03d",f->systemcode,s,s>>6);
for(i=0;i!=10;i++){
if ( ((s >> 1) & 0xf) == sifo[i].c ) break;
}
printf("%s",sifo[i].d);
if( ! (s&1) ){
printf(" (PROTECTED) ");
}
printf("\n");
}
void
dump_service(felica *f){
/* [<][>][^][v][top][bottom][index][help] */
uint8 cmd[256];
uint8 resp[256];
uint8 b[16];
uint16 area_start[60];
uint16 area_end[60];
uint16 area_count;
uint16 servicecode[128];
int servicecode_area[128];
uint16 servicecode_count;
uint16 t;
uint16 idx;
int i,j;
area_count = 0;
servicecode_count = 0;
idx = 0;
while(1){
cmd[0] = 0x0a;
memcpy(&cmd[1],f->IDm,8);
cmd[9] = L8(idx);
cmd[10] = H8(idx);
pasori_write(f->p,cmd,11);
pasori_read(f->p,resp,255);
if(resp[9] == 0xff) break;
t = resp[9] + resp[10] * 0x100;
if(!(t&0x3e)){
area_start[area_count] = t;
area_end[area_count] = resp[11] + resp[12] * 0x100;
area_count++;
}else{
servicecode[servicecode_count] = t;
servicecode_count++;
}
idx++;
}
/* print header */
printf("# card IDm = ");
mydump(f->IDm,8);
printf("\n# card PMm = ");
mydump(f->PMm,8);
for(i=0;i!=area_count;i++){
printf("\n# AREA #%d = %04X - %04X",i,area_start[i],area_end[i]);
}
printf("\n");
/* dump services */
for(i=0;i!=servicecode_count;i++){
printserviceinfo(f,servicecode[i]);
if(servicecode[i]&1){
j = 0;
while(!felica_read_without_encryption02(f,servicecode[i],0,j,b)){
printf(" ");
mydump(f->IDm,8);
printf(":");
printf("%04X:%04X:%04X:",f->systemcode,servicecode[i],j);
mydump(b,16);
printf("\n");
j++;
}
}
}
}
void
enum_service(felica *f){
/* [<][>][^][v][top][bottom][index][help] */
felica *ff;
uint8 cmd[256];
uint8 resp[256];
uint16 sc[4];
int sc_count;
int i,j;
cmd[0] = 0x0c;
memcpy(&cmd[1],f->IDm,8);
pasori_write(f->p,cmd,9);
pasori_read(f->p,resp,255);
sc_count = resp[9];
for(i=0;i!=sc_count;i++){
sc[i] = resp[10+(i*2)] + resp[11+(i*2)] * 0x100;
}
for(i=0;i!=sc_count;i++){
ff = felica_polling(f->p,sc[i],0,0);
printf("# FELICA SYSTEM_CODE = %04X\n",sc[i]);
dump_service(ff);
free(ff);
}
}
int
main(void){
/* [<][>][^][v][top][bottom][index][help] */
pasori* p;
felica* f;
int i;
int m;
uint8 b[16];
p = pasori_open(NULL);
if(!p){
printf("error\n");
exit(-1);
}
pasori_init(p);
f = felica_polling(p,POLLING_ANY,0,0);
if(f){
show_idminfo(f->IDm);
show_pmminfo(f->PMm);
enum_service(f);
}
free(f);
pasori_close(p);
return 0;
}