📄 mainjb.lst
字号:
328 2 while(1) //等待ICC回复起始位
329 2 {
330 3 if(SAM_DATA==0) //是否是起始位
331 3 {
332 4 delay_50us(); //延时去噪
333 4 if(SAM_DATA==0)
334 4 break; //是起始位则准备接收
335 4 }
336 3 if(TF1)
337 3 {
338 4 TF1=0;
339 4 EtuCount++;
340 4 if(EtuCount>WaitTime)
341 4 {
342 5 if(RICCLen!=0)
343 5 return OK;
344 5 else if(!SAM_DET)
345 5 return NoCard;
346 5 else
347 5 return HaveTimeOut;
348 5 }
349 4 }
350 3 }
351 2 EtuCount=0;
352 2 WaitTime=900;//Modi by lbz
353 2 initT1();
354 2 rbyte=0x00;
355 2 RBitCount=0x08; //置接收数据位数
356 2 while(RBitCount); //等待接收结束
357 2 delay_104SAM();
358 2 check=SAM_DATA; //接收校验位
359 2 if(check==P) //接收正确则保存
360 2 {
361 3 RICCBuf[RICCLen]=rbyte;
362 3 SAM_DATA=1; //接收正确
363 3 }
364 2 else
365 2 {
C51 COMPILER V6.12 MAINJB 12/09/2002 13:03:09 PAGE 7
366 3 SAM_DATA=0; //接收错误,请求重发
367 3 delay_50us();
368 3 delay_104SAM();
369 3 SAM_DATA=1;
370 3 RICCLen--;
371 3 continue; //重新接收数据
372 3 }
373 2 delay_104SAM(); //延时,准备接收下一位数据
374 2 }
375 1 }
376
377 /****************** 定义函数SendToICC,该函数实现将以SICCBuf为首址的数据发送到ICC **********/
378 /********************* 发送正确则返回OK,无卡则返回Nocard,其他返回invalid ****************/
379
380 uchar SendToSAM()
381 {
382 1 uchar data ErrorCount; //错误次数计数
383 1 bit check; //奇偶校验位
384 1 uchar data i;
385 1 IfSend=1; // 置接收标志
386 1 SAM_DATA=1;
387 1 delay_104SAM();
388 1 for(i=0;i<SICCLen;i++) //准备发送
389 1 {
390 2 sbyte=SICCBuf[i];
391 2 check=P;
392 2 SBitCount=8; //发送数据
393 2 // initT0();
394 2 TL1=0x74;
395 2 TR1=1;
396 2 ET1=1;
397 2 SAM_DATA=0; //发送起始位
398 2 while(SBitCount);
399 2 TL1=0x88;
400 2 ET1=0;
401 2 while(!TF1); //延时1etu
402 2 SAM_DATA=check; //发送校验位
403 2 TF1=0;
404 2 while(!TF1);
405 2 // delay_104us();
406 2 _nop_();
407 2 _nop_();
408 2 SAM_DATA=1;
409 2 TF1=0;
410 2 delay_104SAM(); //保护时间
411 2 //delay_50us();
412 2 if(SAM_DATA==1) //判断ICC是否接收正确
413 2 {
414 3 delay_104SAM();
415 3 ErrorCount=0;
416 3 continue; //正确则发送下字节数据
417 3 }
418 2 else if (ErrorCount<3) //判断错误次数是否超出
419 2 {
420 3 i--;
421 3 ErrorCount++;
422 3 delay_104SAM();
423 3 delay_104SAM();
424 3 continue;
425 3 }
426 2 else
427 2 {
C51 COMPILER V6.12 MAINJB 12/09/2002 13:03:09 PAGE 8
428 3 if(!SAM_DET) //判断是否有卡
429 3 return NoCard;
430 3 else
431 3 return SendError;
432 3 }
433 2 }
434 1 return OK;
435 1 }
436
437
438 /***** 定义ReceiveFromICC函数,该函数接收来自ICC的数据,并将其保存到以RICCBuf为首址的存储空间 *****/
439 /******************* 正确接收完则返回OK,无卡则返回NoCard,超时则返回HaveTimeOut *******************/
440
441 uchar ReceiveFromSAM()
442 {
443 1 uchar data i;
444 1 uint WaitTime;
445 1 WaitTime=9600;
446 1 SAM_DATA=1;
447 1 for(RICCLen=0,i=0;;RICCLen++)
448 1 {
449 2 IfSend=0;
450 2 EtuCount=0;
451 2 ET1=0; //关T0中断允许
452 2 TR1=1;
453 2 while(1) //等待ICC回复起始位
454 2 {
455 3 if(SAM_DATA==0) //是否是起始位
456 3 {
457 4 delay_50us(); //延时去噪
458 4 if(SAM_DATA==0)
459 4 break; //是起始位则准备接收
460 4 }
461 3 if(TF1)
462 3 {
463 4 TF1=0;
464 4 EtuCount++;
465 4 if(EtuCount>WaitTime)
466 4 {
467 5 if(RICCLen!=0)
468 5 return OK;
469 5 else if(!SAM_DET)
470 5 return NoCard;
471 5 else
472 5 return HaveTimeOut;
473 5 }
474 4 }
475 3 }
476 2 EtuCount=0;
477 2 WaitTime=50;
478 2 initT1();
479 2 rbyte=0x00;
480 2 RBitCount=0x08; //置接收数据位数
481 2 while(RBitCount); //等待接收结束
482 2 delay_104SAM();
483 2 check=SAM_DATA; //接收校验位
484 2 if(check==P) //接收正确则保存
485 2 {
486 3 RICCBuf[RICCLen]=rbyte;
487 3 SAM_DATA=1; //接收正确
488 3 ErrorCount=0;
489 3 }
C51 COMPILER V6.12 MAINJB 12/09/2002 13:03:09 PAGE 9
490 2 else if(ErrorCount<3)
491 2 {
492 3 SAM_DATA=0; //接收错误,请求重发
493 3 delay_50us();
494 3 delay_104SAM();
495 3 SAM_DATA=1;
496 3 RICCLen--;
497 3 ErrorCount++;
498 3 continue; //重新接收数据
499 3 }
500 2 else
501 2 {
502 3 if(!SAM_DET)
503 3 return NoCard;
504 3 else
505 3 return ReceiveError;
506 3 }
507 2 delay_104SAM(); //延时,准备接收下一位数据
508 2 }
509 1 }
510 /*************定义T0的中断服务程序*************/
511 /**************接收来自ICC的数据***************/
512
513 RSAM()interrupt 3 using 3
514 {
515 1 if(!IfSend)
516 1 {
517 2 SAM_DATA=1;//
518 2 if (SAM_DATA==1)
519 2 {
520 3 _nop_();
521 3 if(SAM_DATA==1)
522 3 rbyte|=0x80;
523 3 else
524 3 {
525 4 //ICC_OUTPUT=1;//
526 4 _nop_();
527 4 if(SAM_DATA==1)
528 4 rbyte|=0x80;
529 4 }
530 3 }
531 2 if(RBitCount>1)
532 2 rbyte=rbyte>>1;
533 2 RBitCount--;
534 2 }
535 1 else
536 1 {
537 2 if(sbyte%2) //发送一位数据
538 2 SAM_DATA=1;
539 2 else
540 2 SAM_DATA=0;
541 2 sbyte=sbyte>>1; //右移一位
542 2 SBitCount--;
543 2 }
544 1 }
545
546
547 /****************************************************************/
548 /*作者:刘丙周
549 /*日期:2001年9月
550 /*版本:1.0
551 /*描述:主要实现t=0协议中的
C51 COMPILER V6.12 MAINJB 12/09/2002 13:03:09 PAGE 10
552 /* acpdu 到tcpdu的转换
553 /* rcpdu到rapdu的转换
554 /****************************************************************/
555 void mmemcpy(uchar *mDest,uchar *mSrc,uchar len)
556 {
557 1 uchar i,ch;
558 1 for(i=0;i<len;i++)
559 1 {
560 2 ch=mSrc[i];
561 2 *(mDest+i)=ch;
562 2 }
563 1 }
564 void mmemcpy0(uchar *mDest,uchar *mSrc,uchar len)
565 {
566 1 uchar i,ch;
567 1 for(i=0;i<len;i++)
568 1 {
569 2 ch=*(mSrc+len-i-1);
570 2 *(mDest+len-i-1)=ch;
571 2 }
572 1 }
573 /*********************构造CTPDU**********************************/
574 /*作者:刘丙周 日期:2001年9月 版本:1.0
575 /*函数功能:从ACPDU构造 CTPDU
576 /*参数:使用全局变量:APDUBUf
577 /*返回值:使用全局变量:CTPDUBUF
578 /****************************************************************/
579
580 uchar iPrepare_Ctpdu()
581 {
582 1 uchar data iReturnCode = ERROR; /*定义并初始化返回码*/
583 1 /* --------------------------------------------------------------*/
584 1 if( SIFDLen == 4 ) /* CAPDU 情况1 无Lc字节: [CLA|INS|P1|P2]P3=0*/
585 1 {
586 2 ptCtpdu->uiCase = APDU_CASE_1;
587 2 SICCBuf[P3_IDX] = 0x00;
588 2 iReturnCode = OK;
589 2 }
590 1 /* --------------------------------------------------------------
591 1 * CAPDU情况2 short: [CLA|INS|P1|P2|Le]
592 1 * 无任何变化--------------------------------------------------*/
593 1 if( SIFDLen == 5 )
594 1 {
595 2 ptCtpdu->uiCase = APDU_CASE_2_SHORT;
596 2 ptCtpdu->uiLe = SICCBuf[LE_IDX];
597 2 ptCtpdu->uiLa = SICCBuf[LE_IDX];
598 2 if ( ptCtpdu->uiLe == 0x00 ) /* Le的值:1--256 */
599 2 {
600 3 ptCtpdu->uiLe = MAX_LE_SHORT; /* 要求的数据长度 */
601 3 ptCtpdu->uiLa = MAX_LE_SHORT; /* 可用的数据长度 */
602 3 }
603 2 iReturnCode = OK;
604 2 }
605 1
606 1 /* --------------------------------------------------------------
607 1 * CAPDU 情况3 short: [CLA|INS|P1|P2|Lc data[]] */
608 1 if( SIFDLen==(5+SICCBuf[LC_IDX]))
609 1 {
610 2 if( SICCBuf[LC_IDX] != 0x00 )
611 2 {
612 3 ptCtpdu->uiCase = APDU_CASE_3_SHORT;
613 3 ptCtpdu->uiLc = SICCBuf[LC_IDX]; /* 置Lc */
C51 COMPILER V6.12 MAINJB 12/09/2002 13:03:09 PAGE 11
614 3 }
615 2 iReturnCode = OK;
616 2 }
617 1 /* --------------------------------------------------------------
618 1 * CAPDU 情况 4 short: [CLA|INS|P1|P2|Lc data[]|Le]
619 1 最后一个字节LE将被去掉 */
620 1 if(SIFDLen==(6+SICCBuf[LC_IDX]))
621 1 {
622 2 ptCtpdu->uiCase = APDU_CASE_4_SHORT;
623 2 ptCtpdu->uiLc = SICCBuf[LC_IDX];
624 2 ptCtpdu->uiLe = SICCBuf[SIFDLen-LE_SHORT]; /* Le 的值: 1..256 */
625 2 if(ptCtpdu->uiLe==0x00)
626 2 {
627 3 ptCtpdu->uiLe=MAX_LE_SHORT; /* 要求数据长度 */
628 3 ptCtpdu->uiLa=MAX_LE_SHORT; /* 可用数据长度 */
629 3 }
630 2 iReturnCode = OK;
631 2 }
632 1 SICCLen=5;
633 1 return( iReturnCode );
634 1 }
635 /*******************************************************************/
636 /*作者:刘丙周 日期:2001年9月 版本:1.0
637 /*功能:将ic卡返回的RTPDU变换为RAPDU
638 /*参数:全局变量:RICCBUF
639 /*返回:全局变量:RAPDUBUF
640 /*
641 /*****************构造RAPDU*****************************************/
642 void vBuild_RAPDU()
643 {
644 1 uchar data uiBuild_Idx;
645 1 uchar data uiData_Idx;
646 1 uchar data uiRspBufLenSav;
647 1 uchar data uiBuild_Len;
648 1 uchar data uiData_Len = 0;
649 1 uchar data ucCurRspBufLen = 0;
650 1 uchar data ucRxBufOffset = 0;
651 1 uchar data uiLen=0;
652 1 // uchar data i;
653 1
654 1 uiRspBufLenSav = RICCLen;
655 1 uiBuild_Len = RICCLen;
656 1 if(ptRtpdu->uiCompProcuchars==0) /* 响应缓冲区没有包括INS字的补码*/
657 1 {
658 2 if(ptRtpdu->ucPartRspBuf == TRUE ) /* 如果返回数据是ICC信息的一部分,则付加数据在返回信息的尾部*/
659 2 {
660 3 ucRxBufOffset = ptRtpdu->ucLastRspBufPos; /* 取在缓冲区的偏移值 */
661 3 mmemcpy(SPCBuf+ucRxBufOffset+1,RICCBuf+PROC_uchar_LEN,
662 3 ptRtpdu->uiRspBufLen- PROC_uchar_LEN-STATUS_LEN );/* 付加数据在返回信息的尾部 */
663 3 ptRtpdu->uiLastRspBufLen += ( ptRtpdu->uiRspBufLen - PROC_uchar_LEN - STATUS_LEN );/* 计算返回信息的数
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -