lpdump.c

/* [<][>]
[^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following functions.
  1. mydump
  2. show_latency
  3. show_pmminfo
  4. show_idminfo
  5. sinfo
  6. printserviceinfo
  7. dump_service
  8. enum_service
  9. 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;
}

/* [<][>][^][v][top][bottom][index][help] */