| #include "../nec_apdu.h" |
| #include "sp_des.h" |
| #include "sp_constant.h" |
| #include "sp_util.h" |
| #include "sp_card.h" |
| |
| static uint8* prcv_buff = NULL; |
| static uint8 rcv_len = 0; |
| |
| uint16 sp_select_sfi(uint8 sfi[2]) |
| { |
| uint16 ret; |
| uint8 cmd_buff[10]; |
| |
| cmd_buff[0] = 0x00; //CLA |
| cmd_buff[1] = 0xA4; //INS |
| cmd_buff[2] = 0x00; //P1 |
| cmd_buff[3] = 0x00; //P2 |
| cmd_buff[4] = 0x02; //Lc |
| memcpy(cmd_buff + 5, sfi, 2); |
| |
| ret = card_cpu_exchange(cmd_buff, 2 + 5, 0, &prcv_buff, &rcv_len); |
| if(ret != RETCODE_OK) |
| { |
| return ret; |
| } |
| return 0; |
| } |
| |
| uint16 sp_select_adf(void) |
| { |
| uint16 ret; |
| uint8 cmd_buff[] = {"\x00\xA4\x04\x00\x0F\xD1\x56\x00\x00\x01\xBD\xF0\xCA\xCB\xB4\xEF\xD6\xA7\xB8\xB6"}; |
| ret = card_cpu_exchange(cmd_buff, sizeof(cmd_buff) - 1, 0, &prcv_buff, &rcv_len); |
| if(ret != RETCODE_OK) |
| { |
| return ret; |
| } |
| return 0; |
| } |
| |
| uint8 sp_card_request(sp_card_t* cardpcd) |
| { |
| |
| uint8 sak; |
| uint8 snr[8]; |
| |
| if(!card_request(&sak, snr)) |
| { |
| if((sak & 0x20)) |
| { |
| if(!card_cpu_mode()) |
| { |
| Delay_ms(200); |
| if(sp_select_sfi("\x3f\x00") == 0) |
| { |
| sp_select_adf(); |
| cardpcd->cardphyid[0] = snr[0]; |
| cardpcd->cardphyid[1] = snr[1]; |
| cardpcd->cardphyid[2] = snr[2]; |
| cardpcd->cardphyid[3] = snr[3]; |
| cardpcd->cardtype = TAG_TYPE_CPU; |
| return 0; |
| } |
| } |
| } |
| else |
| { |
| cardpcd->cardtype = TAG_TYPE_UNKONWN; |
| return 1; |
| } |
| } |
| return 1; |
| } |
| |
| int8 sp_check_cpu_exist(void) |
| { |
| return card_cpu_exist(); |
| } |
| |
| static uint16 sp_select_adf15() |
| { |
| uint16 ret = 0; |
| uint8* temp_buff = NULL; |
| uint8 buff_len = 0; |
| uint8 cmd_buff[] = {"\x00\xA4\x00\x00\x02\x3F\x00"}; |
| ret = card_cpu_exchange(cmd_buff, sizeof(cmd_buff)-1, 0, &temp_buff, &buff_len); |
| if(ret != RETCODE_OK) |
| { |
| return ret; |
| } |
| return 0; |
| } |
| |
| static uint16 sp_read_binary_file(uint8 out[]) |
| { |
| uint16 ret = 0; |
| uint8* temp_buff = NULL; |
| uint8 buff_len = 0; |
| uint8 cmd_buff[5] = {"\x00\xB0\x95\x00\x47"}; |
| ret = card_cpu_exchange(cmd_buff, sizeof(cmd_buff), 0, &temp_buff, &buff_len); |
| if(ret != RETCODE_OK) |
| { |
| return ret; |
| } |
| MEMCPY(out, temp_buff, buff_len); |
| return 0; |
| } |
| static uint16 sp_cpu_read(sp_card_t* card) |
| { |
| uint16 ret = 0; |
| uint8 buff[72]; |
| uint8 offset = 0; |
| MEMCLEAR(buff, sizeof(buff)); |
| ret = sp_select_adf15(); |
| if(ret) |
| { |
| return ret; |
| |
| } |
| ret = sp_read_binary_file(buff); |
| if(ret) |
| { |
| return ret; |
| } |
| MEMCLEAR(card->citizen_cardno, sizeof(card->citizen_cardno)); |
| offset += 31; |
| MEMCPY(card->citizen_cardno, buff+offset, sizeof(card->citizen_cardno)); |
| offset += 12; |
| offset += 18; |
| MEMCPY(card->expiredate, buff+offset, 4); |
| return ret; |
| } |
| |
| uint16 sp_card_read(sp_card_t* card) |
| { |
| switch(card->cardtype) |
| { |
| case TAG_TYPE_CPU: |
| return sp_cpu_read(card); |
| default: |
| return 1; |
| } |
| } |