📄 simd.c
字号:
* txData: address of the tx buffer including the command header and optional tx data
* txSize: size of data to be transfer including command buffer(5 bytes):(Lc+5) and
will be updated by real transfered data count.
* rxData: address of the rx buffer
* rxSize: expect received data size not including the sw1 and sw2 and will be updataed
by the real received data coung
*
* RETURNS
* kal_uint16: status bytes of (sw1<<8|sw2), and 0 to indicate a physical error detected
by the driver such as timeout.
*
* GLOBALS AFFECTED
*
*************************************************************************/
sim_status L1sim_Cmd_Layer(kal_uint8 *txData,kal_uint32 *txSize,kal_uint8 *rxData, kal_uint32 *rxSize)
{
kal_bool warn, case4, sim_card;
kal_uint8 sw1, sw2, error, gp, rs, *tx;
kal_uint8 sim_get_resp_sim[] = {0xa0, 0xc0, 0x00, 0x00, 0x00 }; // 0xa0: SIM, 0x00: USIM
sim_status status, status_w = 0;
kal_uint32 rx_len;
// sim_protocol_app_enum p = SimCard.app_proto;
dbg_print("L1sim_Cmd_Layer\r\n");
rx_len = *rxSize;
if(SimCard.cmd_case == usim_case_4)
{
case4 = KAL_TRUE;
*txSize -= 1;
*rxSize = 0;
}
else
case4 = KAL_FALSE;
tx = txData;
status = L1sim_Cmd(tx, (kal_uint16)*txSize, rxData, (kal_uint16*)rxSize, &error);
rs = SW1_RESEND_USIM;
//if(SIM_PROTOCOL == p)
if(txData[0] == 0xA0) // some usim will compatiable with SIM after received 0xa0....
{
gp = SW1_GET_RESP_SIM;
sim_get_resp_sim[0] = GET_RESP_CLA_SIM;
sim_card = KAL_TRUE;
}
else
{ // USIM_PROTOCOL (0x61 and 0x6c are only for case2 and case4
gp = SW1_GET_RESP_USIM;
sim_get_resp_sim[0] = GET_RESP_CLA_USIM;
sim_card = KAL_FALSE;
}
warn = KAL_FALSE;
for(;;)
{
if(error == KAL_TRUE)
return STATUS_FAIL;
sw1 = status>>8;
sw2 = status&0xff;
if(sw1 == gp)
{ // get response 0x61
dbg_print("get response %x \r\n", sw1);
if(rxData == NULL)
{
dbg_print("!!! ERR NULL rx buffer \r\n");
return status;
}
tx = sim_get_resp_sim;
if( rx_len != 0 && sw2 > rx_len )
sw2 = rx_len;
*rxSize = sw2;
tx[LEN_INDEX] = sw2;
status = L1sim_Cmd(tx, LEN_OF_CMD, rxData, (kal_uint16*)rxSize, &error);
if(error == KAL_TRUE)
return STATUS_FAIL;
if(sim_card)
break;
}
else if(!sim_card && sw1 == rs)
{ // resend the previous cmd 0x6c
dbg_print("resend command %x \r\n", sw1);
if(rxData == NULL)
{
dbg_print("!!! ERR NULL rx buffer");
return status;
}
tx[LEN_INDEX] = sw2;
*rxSize = sw2;
status = L1sim_Cmd(tx, LEN_OF_CMD, rxData, (kal_uint16*)rxSize, &error);
}
else if(!sim_card && case4 &&
(sw1 == SW1_WARN1 || sw1== SW1_WARN2|| (status != STATUS_OK && (sw1&0xf0 == 0x90))))
{ // warning status
dbg_print("warning status %x \r\n", sw1);
warn = KAL_TRUE;
status_w = status;
tx = sim_get_resp_sim;
tx[LEN_INDEX] = 0;
*rxSize = 0;
status = L1sim_Cmd(tx, LEN_OF_CMD, rxData, (kal_uint16*)rxSize, &error);
}
else
{ // command complete
dbg_print("command complete %x \r\n", status);
ASSERT(*rxSize <= 256);
if(warn == KAL_TRUE)
return status_w;
return status;
}
}
return status;
}
//================================ Layer type SIM driver end ==================================
//================================SIM test code==================================
#ifdef DEVDRV_TEST
kal_uint8 Volt;
kal_uint8 resVolt;
AtrStruct ATRInfo;
#if 1
void PinCheck(kal_uint8 *inputdata,kal_uint16 *res)
{
kal_uint8 cmd[50],j;
kal_uint16 rec;
kal_uint16 SW;
kal_uint8 parity_err;
cmd[0]= 0xa0;
cmd[1]= 0x20;
cmd[2]= 0x0;
cmd[3]= 0x01;
cmd[4]= 0x08;
for (j=0;j<8;j++)
{
cmd[j+5]= *(inputdata+j);
}
//SIM_Command(&sim_cmd);
rec = 0;
SW = L1sim_Cmd(cmd,13,NULL,&rec, &parity_err);
if (parity_err)
{
//////dbg_print("Parity Error\r\n");
}
//////dbg_print("PinCheck SW=%x\r\n",SW);
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
}
void SelectFile(kal_uint8 *inputdata,kal_uint16 *res)
{
kal_uint8 cmd[50];
kal_uint16 rec;
kal_uint8 parity_err;
kal_uint16 SW;
cmd[0]= 0xa0;
cmd[1]= 0xa4;
cmd[2]= 0x0;
cmd[3]= 0x0;
cmd[4]= 0x02;
cmd[5]= *inputdata;
cmd[6]= *(inputdata+1);
//SIM_Command(&sim_cmd);
rec = 0;
SW = L1sim_Cmd(cmd,7,NULL,&rec, &parity_err);
if (parity_err)
{
//////dbg_print("Parity Error\r\n");
}
*res = (kal_uint8)(SW >> 8);
*(res+1) = (kal_uint8)SW;
//////dbg_print("SelectFile SW=%x\r\n",SW);
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
//////dbg_print("Select File cmd is ok\r\n");
}
void GetResponse(kal_uint8 len, kal_uint16 *res)
{
kal_uint8 cmd[50];
kal_uint16 i;
kal_uint16 rec;
kal_uint8 resp[50];
kal_uint16 SW;
kal_uint8 parity_err;
cmd[0]= 0xa0;
cmd[1]= 0xc0;
cmd[2]= 0x0;
cmd[3]= 0x0;
cmd[4]= len;
//SIM_Command(&sim_cmd);
rec = len;
SW = L1sim_Cmd(cmd,5,(kal_uint8 *)resp,&rec, &parity_err);
for(i=0;i<rec;i++)
{
res[i] = (kal_uint16)resp[i];
}
*(res+rec) = (kal_uint8)(SW >> 8);
*(res+rec+1) = (kal_uint8)SW;
if (parity_err)
{
//////dbg_print("Parity Error\r\n");
}
//////dbg_print("GetResponse SW=%x\r\n",SW);
//////dbg_print("the voltage value = %x\r\n",res[13]);
}
void ReadBinary(kal_uint8 len, kal_uint16 *res)
{
kal_uint8 cmd[50];
kal_uint16 i;
kal_uint16 rec;
kal_uint8 resp[50];
kal_uint16 SW;
kal_uint8 parity_err;
cmd[0]= 0xa0;
cmd[1]= 0xb0;
cmd[2]= 0x0;
cmd[3]= 0x0;
cmd[4]= len;
//SIM_Command(&sim_cmd);
rec = len;
SW = L1sim_Cmd(cmd,5,(kal_uint8 *)resp,&rec, &parity_err);
for(i=0;i<rec;i++)
{
res[i] = (kal_uint16)resp[i];
}
*(res+rec) = (kal_uint8)(SW >> 8);
*(res+rec+1) = (kal_uint8)SW;
if (parity_err)
{
//////dbg_print("Parity Error\r\n");
}
//////dbg_print("ReadBinary SW=%x\r\n",SW);
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
//////dbg_print("Read Binary cmd is ok\r\n");
//////dbg_print("the read data [14] = %x\r\n",res[13]);
}
kal_bool vcc_check(void)
{
kal_uint8 cmd[50];
kal_uint16 resp[300];
kal_uint16 temp;
#if 1
// GetResponse(20,resp);
// GetResponse(20,resp);
// cmd[0]= 0x7f;
// cmd[1]= 0x20;
// SelectFile(cmd,resp);
cmd[0]= 0x7f;
cmd[1]= 0x20;
SelectFile(cmd,resp);
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
//////dbg_print("rec length = %d\r\n",*(resp+1));
GetResponse(*(resp+1),resp);
temp = resp[13] & 0x000d;
SimCard.clkStop = KAL_TRUE;
if (temp & 0x0001)
{
if ((temp & 0x0004)!=0)
{
SimCard.clkStopLevel = KAL_TRUE; //bit 3
}
if ((temp & 0x0008)!=0) //bit 4
{
SimCard.clkStopLevel = KAL_FALSE;
}
if ((temp & 0x000c) == 0) //default
{
SimCard.clkStopLevel = KAL_FALSE;
}
}
else
{
if ((temp & 0x0004)!=0)
{
SimCard.clkStopLevel = KAL_TRUE; //bit 3
}
if ((temp & 0x0008)!=0) //bit 4
{
SimCard.clkStopLevel = KAL_FALSE;
}
if ((temp & 0x000c) == 0) //default
{
SimCard.clkStopLevel = KAL_FALSE;
}
}
temp = resp[13] & 0x000d;
if (temp == 0)
{
SimCard.clkStop = KAL_FALSE;
////////dbg_print("fasfda&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\r\n");
}
temp = resp[13] & 0x0070;
temp >>= 4;
//////dbg_print("the volt = %d\r\n",temp);
if ( temp == 1) //3V card
{
if (SimCard.Power == SIM_18V)
{
//////dbg_print("3V reset\r\n");
L1sim_Reset(SIM_30V,NULL,NULL);
//return SimCard.result;
}
}
if (temp == 0) //5V card
{
if (SimCard.Power == SIM_30V)
{
//////dbg_print("5V reset\r\n");
L1sim_Reset(SIM_18V,NULL,NULL);
//return SimCard.result;
}
}
#endif
#if ( (defined(MT6205)) || (defined(MT6205B)) || (defined(MT6218)) )
if (SimCard.clkStop == KAL_TRUE)
{
DRV_Reg(SIM_CONF) |= SIM_CONF_HALTEN;
}
#endif /*MT6205,MT6205B,MT6218*/
return KAL_TRUE;
}
void CheckPinCMD(void)
{
kal_uint8 cmd[50];
kal_uint16 resp[300];
//1
cmd[0]= 0x7f;
cmd[1]= 0x20;
SelectFile(cmd,resp);
//2
GetResponse(*(resp+1),resp);
//3
cmd[0]= 0x6f;
cmd[1]= 0xae;
SelectFile(cmd,resp);
GetResponse(*(resp+1),resp); //GD
//4
ReadBinary(1,resp);
//5
cmd[0]= 0x3f;
cmd[1]= 0x00;
SelectFile(cmd,resp);
//6
cmd[0]= 0x2f;
cmd[1]= 0xe2;
SelectFile(cmd,resp);
//7
ReadBinary(10,resp);
//8
cmd[0]= 0x7f;
cmd[1]= 0x20;
SelectFile(cmd,resp);
//9
cmd[0]= 0x6f;
cmd[1]= 0x05;
SelectFile(cmd,resp);
//10
GetResponse(*(resp+1),resp);
#if 1
//11
ReadBinary(5,resp);
#endif
//12
cmd[0]= 0x6f;
cmd[1]= 0x39;
SelectFile(cmd,resp);
//13
GetResponse(*(resp+1),resp);
//14
cmd[0]= 0x6f;
cmd[1]= 0x37;
SelectFile(cmd,resp);
//15
GetResponse(*(resp+1),resp);
//16
cmd[0]= 0x6f;
cmd[1]= 0x41;
SelectFile(cmd,resp);
//17
GetResponse(*(resp+1),resp);
//18
cmd[0]= 0x32;
cmd[1]= 0x34;
cmd[2]= 0x36;
cmd[3]= 0x38;
cmd[4]= 0xff;
cmd[5]= 0xff;
cmd[6]= 0xff;
cmd[7]= 0xff;
PinCheck(cmd,resp);
//////dbg_print("Check PIN END..\r\n");
}
void closeSIMcmd(void)
{
kal_uint8 cmd[50];
kal_uint16 resp[300];
cmd[0]= 0x6f;
cmd[1]= 0x37;
SelectFile(cmd,resp);
GetResponse(*(resp+1),resp);
cmd[0]= 0x6f;
cmd[1]= 0x41;
SelectFile(cmd,resp);
GetResponse(*(resp+1),resp);
SIM_Reject();
}
#endif
void Sim_test(void)
{
kal_uint8 result;
result = L1sim_Reset(SIM_30V,&resVolt,&ATRInfo);
if (result == SIM_NO_ERROR)
{
//dbg_print("SIM has no Error!\r\n");
}
if (result == SIM_CARD_ERROR)
{
//dbg_print("SIM CARD has something error!\r\n");
return;
}
if (result == SIM_NO_INSERT)
{
//dbg_print("SIM CARD no insert!\r\n");
return;
}
//dbg_print("the resVolt = %x\r\n",resVolt);
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
#if 1
if (vcc_check())
{
//dbg_print("VCC check is ok\r\n");
// break;
}
else
{
//dbg_print("VCC check is Failed\r\n");
}
#endif
//return;
CheckPinCMD();
//////dbg_print("=========================================\r\n");
#if 1
//////dbg_print("Will be close the sim!!\r\n");
//delay1s(50);
closeSIMcmd();
//SIM_Reject();
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -