CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Need help with magnetic card reader

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
DiegoGarcia



Joined: 01 Mar 2008
Posts: 48

View user's profile Send private message

Need help with magnetic card reader
PostPosted: Tue May 06, 2008 5:29 pm     Reply with quote

Hi guys I've changed the mcr.c file to read in both directions, but its very strange the data seens different when passed in the other direction ...
Here is my code
Code:

int mcr_read(char* track1=0x00, char* track2=0x00)
{
   int   error        = 0;

   int1  dataBit      = 0;

   char  i=0;
   int1  RtoL2         = 0;
   

   int1  set_one_time2= 0;

   int1  ST2          = 1;
   int1  ST2_old      = 1;
   int1  firstOne2    = 0;
   int1  parity2      = 0;
   int   count2       = 0;
   int   index2       = 0;
   int   LRC2         = 0;
   int   StCount2     = 0;

   int currentBit2 = 0;

   char  tmpEndSentinel2=0;
   
   char tmpTrack2[40];

   for(i=0;i<40;i++)   
   {     
     Track2[i]=0x00;
   }
   
   while(input(MCR_CARD_PRESENT))
   {
   }

   while(!input(MCR_CARD_PRESENT))
   {
      // Check for NULL pointer and an index less than 40
      if(tmpTrack2 != 0 && index2 < 40)
      {
         // Get strobe number 2
         ST2 = input(MCR_STROBE2);

         // If the strobe was high and is now low (falling edge),
         // then data is present
         if(ST2 == 0 && ST2_old == 1)
         {
            ST2_old = 0;
           
            // Check if the first 1 was received
            if(firstOne2 == 1)
            {             
               // Check if 4 bits of data were received
               if(count2 == 4)
               {
                  // Reset the bit counter back to 0
                  count2 = 0;

                  // Get a bit of data from the card
                  dataBit = !input(MCR_DATA2);

                  // XOR the data with the parity bit
                  parity2 ^= dataBit;

                  // Store the new bit of data
                  shift_right(tmpTrack2+index2, 1, dataBit);

                  index2++;
               }
               else
               {
                  // Get a bit of data from the card
                  dataBit = !input(MCR_DATA2);

                  // XOR the data with the parity bit
                  parity2 ^= dataBit;

                  // Store the new bit of data
                  shift_right(tmpTrack2+index2, 1, dataBit);

                  // Increment the bit counter
                  ++count2;
               }

            }// End FirstOne2 == 1
            else
            {
               // Check if the first 1 has appeard on the data line
               if(!input(MCR_DATA2))
               {
                    // Set the first 1 received flag
                    firstOne2 = 1;

                    // Store the first 1
                    shift_right(tmpTrack2+index2, 1, 1);

                    // Increment the bit counter
                    ++count2;

               } // End if (!input(MCR_DATA2))
            }// End FirstOne2 != 1

         }//End St2 == 0 & St2_old == 1
         else
           if(ST2 == 1)
            {
              ST2_old = 1;
            }
      }//End if (track 2 != 0 ...
   }//End while (!imput(MCR_CARD_PRESENT)

 set_one_time2 = 0;
 firstOne2 = 0;
 index2 = 0;
 count2 = 0;
 i=0;

 //Perform the Conversion of the in memory data.
 while (i<40)
  {
   if (!set_one_time2)
    {
      set_one_time2 = 1;

      tmpEndSentinel2=*(tmpTrack2+i);

      *(Track1 + 0) = tmpEndSentinel2;

      tmpEndSentinel2 >>= 3;

      *(Track1 + 1) = tmpEndSentinel2;     

      bit_clear(*(tmpEndSentinel2),4);

      *(Track1 + 2) = tmpEndSentinel2;
     
      if(tmpEndSentinel2 != 0x0B)                       
       {         
         RtoL2=1;
         index2=39;
       } else
          {
            tmpEndSentinel2=0x00;

            *(Track1 + 3) = tmpEndSentinel2;

            tmpEndSentinel2=*(tmpTrack2+1);

            *(Track1 + 4) = tmpEndSentinel2;

            tmpEndSentinel2 >>= 3;

            *(Track1 + 5) = tmpEndSentinel2;

            bit_clear(tmpEndSentinel2,4);

            *(Track1 + 6) = tmpEndSentinel2;

            if(tmpEndSentinel2==0x0F)
             {
              RtoL2=1;
              index2=39;
             }
          }
    }

    if (!RtoL2)
     {
      *(Track2+i) = *(tmpTrack2+i);
      *(Track2+i) >>= 3;
      bit_clear(*(Track2+i),4);
      //Convert to ASCII
      *(Track2+i) += 0x30;
      i++;
     }
      else
        {
            // Check if the first 1 was received
            if(firstOne2 == 1)
            {         
               // Check if 4 bits of data were received
               if(count2 == 4)
               {
                  // Reset the bit counter back to 0
                  count2 = 0;

                  // Get a bit of data from the vetor
                  dataBit = bit_test(*(tmpTrack2+index2),currentBit2);

                  // XOR the data with the parity bit
                  parity2 ^= dataBit;

                  // Store the new bit of data
                  shift_right(Track2+i, 1, dataBit);
                       
                  //*(Track2+i) = reverse(*Track2+i);

                  *(Track2+i) >>= 3;

                  bit_clear(*(Track2+i),4);

                  //Convert to ASCII
                  //*(Track2+i) += 0x30;

                  i++;
               }
               else
               {
                  // Get a bit of data tmpTrack2
                  dataBit = bit_test(*(tmpTrack2+index2),currentBit2);

                  // XOR the data with the parity bit
                  parity2 ^= dataBit;

                  // Store the new bit of data
                  shift_right(Track2+i, 1, dataBit);

                  // Increment the bit counter
                  ++count2;
               }
            }// End FirstOne2 == 1
            else
            {
               // Check if the first 1 has appeard on the tmpTrack2 Vector
               if(bit_test(*(tmpTrack2+index2),currentBit2) == 1)
               {
                    // Set the first 1 received flag
                    firstOne2 = 1;

                    // Store the first 1
                    shift_right(Track2+i, 1, 1);

                    // Increment the bit counter
                    ++count2;
               } // End if bit_test()
            }// End FirstOne2 != 1
           
            if (currentBit2 == 7)
             {
              if (firstOne2)
               currentBit2 = 4; else
               currentBit2 = 0;
              index2--;               
             } else
                currentBit2++;             
        }//end else !RtoL2         
  } //End while


 return error;
}//End function



The results are, passing the card in normal direction 0b, 05, 01 etc. its ok because when add 0x30 to it, it became 3b, 35 and 31 thats the right!

But the inverse response is 03, 05, 0d that if i add the 0x30 to it, it became 33, 35, 3d... wrong way ... I've rewrited this code almost ten times now, so I dont know more what to do ... can you guys help me with that ?

Thanks a lot guys
Regards
Diego Garcia
DiegoGarcia



Joined: 01 Mar 2008
Posts: 48

View user's profile Send private message

Ok the problem is solved now ;)
PostPosted: Wed May 07, 2008 9:13 am     Reply with quote

Ok I've done the full reading operation and it works amazing
now can some of you help me doing the lrc check ?

Here is the code, just the lrc and parity check is not working, but all the data is coming nice.

Code:
int mcr_read(char* track1=0x00, char* track2=0x00)
{
   int   error        = 0;

   int1  dataBit      = 0;

   char  i=0;
   int1  RtoL2         = 0;
   

   int1  set_one_time2= 0;

   int1  ST2          = 1;
   int1  ST2_old      = 1;
   int1  firstOne2    = 0;
   int1  parity2      = 0;
   int   count2       = 0;
   int   index2       = 0;
   int   LRC2         = 0;
   int   StCount2     = 0;

   int currentBit2 = 0;

   char  tmpEndSentinel2=0;
   
   char tmpTrack2[40];

   for(i=0;i<40;i++)   
   {     
     Track2[i]=0x00;
   }
   
   while(input(MCR_CARD_PRESENT))
   {
   }

   while(!input(MCR_CARD_PRESENT))
   {
      // Check for NULL pointer and an index less than 40
      if(tmpTrack2 != 0 && index2 < 40)
      {
         // Get strobe number 2
         ST2 = input(MCR_STROBE2);

         // If the strobe was high and is now low (falling edge),
         // then data is present
         if(ST2 == 0 && ST2_old == 1)
         {
            ST2_old = 0;
           
            // Check if the first 1 was received
            if(firstOne2 == 1)
            {             
               // Check if 4 bits of data were received
               if(count2 == 4)
               {
                  // Reset the bit counter back to 0
                  count2 = 0;

                  // Get a bit of data from the card
                  dataBit = !input(MCR_DATA2);

                  // Verify the LRC
                  if(*(tmpTrack2+index2-1) == '?' && LRC2 != *(tmpTrack2+index2))
                  {
                     error |= MCR_ERR_LRC2;
                  }
                  else
                  {
                     LRC2 ^= *(tmpTrack2+index2);
                  }

                  // Check the parity bit. The parity on a space is not checked
                  // because of the trailing zeros after the LRC character
                  if(databit != parity2 && *(tmpTrack2+index2) != '0')
                  {
                     error |= MCR_ERR_PARITY2;
                  }

                  // Reset the parity check
                  parity2 = 1;

                  // Store the new bit of data
                  shift_right(tmpTrack2+index2, 1, dataBit);

                  index2++;
               }
               else
               {
                  // Get a bit of data from the card
                  dataBit = !input(MCR_DATA2);

                  // XOR the data with the parity bit
                  parity2 ^= dataBit;

                  // Store the new bit of data
                  shift_right(tmpTrack2+index2, 1, dataBit);

                  // Increment the bit counter
                  ++count2;
               }

            }// End FirstOne2 == 1
            else
            {
               // Check if the first 1 has appeard on the data line
               if(!input(MCR_DATA2))
               {
                    // Set the first 1 received flag
                    firstOne2 = 1;

                    // Store the first 1
                    shift_right(tmpTrack2+index2, 1, 1);

                    // Increment the bit counter
                    ++count2;

               } // End if (!input(MCR_DATA2))
            }// End FirstOne2 != 1

         }//End St2 == 0 & St2_old == 1
         else
           if(ST2 == 1)
            {
              ST2_old = 1;
            }
      }//End if (track 2 != 0 ...
   }//End while (!imput(MCR_CARD_PRESENT)

 parity2 = 1;
 set_one_time2 = 0;
 firstOne2 = 0;
 index2 = 0;
 count2 = 0;
 i=0;

 //Perform the Conversion of the in memory data.
 while (i<40)
  {
   //If first time entering here
   if (!set_one_time2)
    {
      set_one_time2 = 1;

      tmpEndSentinel2 = *(tmpTrack2+i);

      tmpEndSentinel2 >>= 3;

      bit_clear(*(tmpEndSentinel2),4);

      //Check if the first char is not 0x0B (Start Sentinel), if true set the flag RtoL2 to 1
      if(tmpEndSentinel2 != 0x0B)                       
       { 
         error = 0;
         RtoL2=1;
         index2=39;
       } else //if first char is 0x0B then check the second char is 0x0F
              //(End Sentinel)
          {

            tmpEndSentinel2=0x00;

            tmpEndSentinel2=*(tmpTrack2+1);

            tmpEndSentinel2 >>= 3;

            bit_clear(tmpEndSentinel2,4);
            //If next char is an end sentinel then set the flag RtoL2 to 1
            if(tmpEndSentinel2==0x0F)
             {
              error = 0;
              RtoL2=1;
              index2=39;
             }
          }
    }
    //if not set to 1 the RtoL2 flag then just rotate the bits, clear
    //the bit 4 (parity bit) and add 0x30 to transform it to ASCII   
    if (!RtoL2)
     {
      *(Track2+i) = *(tmpTrack2+i);
      *(Track2+i) >>= 3;
      bit_clear(*(Track2+i),4);
      //Convert to ASCII
      *(Track2+i) += 0x30;
      i++;
     }
      else
        {
            // Check if the first 1 was founded in the vetor
            if(firstOne2 == 1)
            {         
               // Check if 4 bits of data were cached to Track2 var
               if(count2 == 4)
               {
                  // Reset the bit counter back to 0
                  count2 = 0;

                  databit = bit_test(*(tmpTrack2+index2),currentBit2);

                  // Shift the bits right by 4   
                  *(Track2+i) >>= 4;

                  // Verify the LRC
                  if(*(Track2+i-1) == '?' && LRC2 != *(Track2+i))
                  {
                     //error |= MCR_ERR_LRC2;
                  }
                  else
                  {
                     //LRC2 ^= *(Track2+i);
                  }

                  //Convert to ASCII
                  *(Track2+i) += 0x30;

                  // Check the parity bit. The parity on a space is not checked
                  // because of the trailing zeros after the LRC character
                  if(databit != parity2 && *(Track2+i) != '0')
                  {
                   //  error |= MCR_ERR_PARITY2;
                  }

                  // Reset the parity check
                  parity2 = 1;

                  i++;
               }
               else
               {
                  // Get a bit of data tmpTrack2
                  dataBit = bit_test(*(tmpTrack2+index2),currentBit2);

                  // XOR the data with the parity bit
                  parity2 ^= dataBit;

                  // Store the new bit of data
                  shift_right(Track2+i, 1, dataBit);

                  // Increment the bit counter
                  ++count2;
               }
            }// End FirstOne2 == 1
            else
            {
               // Check if the first 1 has appeard on the tmpTrack2 Vector
               if(bit_test(*(tmpTrack2+index2),currentBit2) == 1)
               {
                    // Set the first 1 received flag
                    firstOne2 = 1;

                    // Store the first 1
                    shift_right(Track2+i, 1, 1);

                    // Increment the bit counter
                    ++count2;
               } // End if bit_test()
            }// End FirstOne2 != 1

            if (currentBit2 == 3)
             {
               currentBit2 = 7;
               index2--;               
             } else
                currentBit2--;
        }//end else !RtoL2         
  } //End while


 return error;
}//End function


Thanks a lote guys,
Regards,
Diego Garcia
RodrigoPatto



Joined: 18 Jun 2010
Posts: 3

View user's profile Send private message

mcr.c for both directions
PostPosted: Fri Jun 18, 2010 8:34 am     Reply with quote

I'm an engineer from Brazil and I'm new in CCS forum.
I'm developing a project of a Magnetic Card Reader. I want to change the original mcr.c file to work in both directions.
I tried the code above but it worked fine in only one direction. When I tried in the other direction I can only see this in track 2 "1000000000000000000000000000000000000000".
Can you help me please?
Thanks.
RodrigoPatto



Joined: 18 Jun 2010
Posts: 3

View user's profile Send private message

Reading Track1 in both directions.
PostPosted: Mon Jun 21, 2010 12:03 pm     Reply with quote

Hello.
I tested the code above for Track2 more times and now it is working.
I can read Track2 in both directions fine.
I want to read the Track1 in both directions too. Can someone help me?
I tested the same code for Track1, only changed 0x30 to 0x20 in the conversion for ascii, but it did not work.
Thanks.
Code:

int mcr_read(char* track1=0x00, char* track2=0x00)
{
   int   error        = 0;

   int1  dataBit      = 0;

   int  i=0;
   
   int1  RtoL1         = 0;
   int1  set_one_time1= 0;
   
   int1  ST1      = 1;
   int1  ST1_old  = 1;
   int1  firstOne1= 0;
   int1  parity1  = 0;
   int   count1   = 0;
   int   index1   = 0;
   int   LRC1     = 0;
   
   int currentBit1 = 0;
   char  tmpEndSentinel1=0;   
   char tmpTrack1[79];
   
   for(i=0;i<79;i++)   
   {     
     Track1[i]=0x00;
     tmpTrack1[i]=0x00;
   }

   while(input(MCR_CARD_PRESENT))
   {
   }

   while(!input(MCR_CARD_PRESENT))
   {     

      if(tmpTrack1 != 0 && index1 < 79)
      {

         ST1 = input(MCR_STROBE1);

         if(ST1 == 0 && ST1_old == 1)
         {
            ST1_old = 0;
           
            if(firstOne1 == 1)
            {             
               if(count1 == 6)
               {
                  count1 = 0;

                  dataBit = !input(MCR_DATA1);

                  if(*(tmpTrack1+index1-1) == '?' && LRC1 != *(tmpTrack1+index1))
                  {
                     error |= MCR_ERR_LRC1;
                  }
                  else
                  {
                     LRC1 ^= *(tmpTrack1+index1);
                  }

                  if(databit != parity1 && *(tmpTrack1+index1) != '0')
                  {
                     error |= MCR_ERR_PARITY1;
                  }

                  parity1 = 1;

                  shift_right(tmpTrack1+index1, 1, dataBit);

                  index1++;
               }
               else
               {
                  dataBit = !input(MCR_DATA1);

                  parity1 ^= dataBit;

                  shift_right(tmpTrack1+index1, 1, dataBit);

                  ++count1;
               }

            }// End FirstOne1 == 1
            else
            {
               if(!input(MCR_DATA1))
               {
                    firstOne1 = 1;


                    shift_right(tmpTrack1, 1, 1);

                    // Increment the bit counter
                    ++count1;

               }
            }

         }
         else
           if(ST1 == 1)
            {
              ST1_old = 1;
            }
      }
   }

 parity1 = 1;
 set_one_time1 = 0;
 firstOne1 = 0;
 index1 = 0;
 count1 = 0;
 i=0;
 
  while (i<79)
  {
   if (!set_one_time1)
    {
      set_one_time1 = 1;

      tmpEndSentinel1 = *(tmpTrack1+i);

      tmpEndSentinel1 >>= 3;

      bit_clear(*(tmpEndSentinel1),4);

      if(tmpEndSentinel1 != 0x05)                       
       {
         error = 0;
         RtoL1=1;
         index1=78;
       } else //if first char is 0x0B then check the second char is 0x0F
              //(End Sentinel)
          {

            tmpEndSentinel1=0x00;

            tmpEndSentinel1=*(tmpTrack1+1);

            tmpEndSentinel1 >>= 1;

            bit_clear(tmpEndSentinel1,2);
           
            if(tmpEndSentinel1==0x0F)
             {
              error = 0;
              RtoL1=1;
              index1=78;
             }
          }
    }
   
    if (!RtoL1)
     {
      *(Track1+i) = *(tmpTrack1+i);
      *(Track1+i) >>= 3;
      bit_clear(*(Track1+i),4);
      //Convert to ASCII
      *(Track1+i) += 0x20;
      i++;
     }
      else
        {

            if(firstOne1 == 1)
            {         

               if(count1 == 6)
               {

                  count1 = 0;

                  databit = bit_test(*(tmpTrack1+index1),currentBit1);

 
                  *(Track1+i) >>= 2;

                  if(*(Track1+i-1) == '?' && LRC1 != *(Track1+i))
                  {
                     error |= MCR_ERR_LRC1;
                  }
                  else
                  {
                     LRC1 ^= *(Track1+i);
                  }

                  //Convert to ASCII
                  *(Track1+i) += 0x20;


                  if(databit != parity1 && *(Track1+i) != '0')
                  {
                     error |= MCR_ERR_PARITY1;
                  }

                  parity1 = 1;

                  i++;
               }
               else
               {

                  dataBit = bit_test(*(tmpTrack1+index1),currentBit1);

                  parity1 ^= dataBit;

                  shift_right(Track1+i, 1, dataBit);

                  ++count1;
               }
            }// End FirstOne1 == 1
            else
            {
               if(bit_test(*(tmpTrack1+index1),currentBit1) == 1)
               {
                    firstOne1 = 1;

                    shift_right(Track1+i, 1, 1);

                    ++count1;
               } // End if bit_test()
            }// End FirstOne2 != 1

            if (currentBit1 == 3)
             {
               currentBit1 = 7;
               index1--;               
             } else
                currentBit1--;
        }//end else !RtoL2         
  } //End while

 return error;
}//End function
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Jun 21, 2010 3:03 pm     Reply with quote

Quote:
I tested the same code for Track1, only changed 0x30 to 0x20 in the conversion for ascii, but it did not work.
??????
This makes no sense to me.

The line you refer to is converting the decimal data to readable ASCII code. It has nothing to do with selecting the track number. Have a look at the ASCII table to understand what the line is doing.
For example: If you have read the decimal value 3 and add 0x30 you get 0x33, this is character '3' in the table.
With your change the decimal value 3 becomes 0x20 + 3 = 0x23, which is the character '#'. Not really a helpful conversion...

Code:
int mcr_read(char* track1=0x00, char* track2=0x00)
You can not initialize variables like this in C. Change to:
Code:
int mcr_read(char* track1, char* track2)


Instead of modifying the code from the forum I suggest you use the mcr.c driver file, see your CCS program directory. This is the same driver but with several bugs fixed.
See ex_mcr.c for how to use it.

To read Track1 your card reader must have physical support this. For example the Omron V3A-6 that the driver was written for uses a separate clock and data output for each track.
RodrigoPatto



Joined: 18 Jun 2010
Posts: 3

View user's profile Send private message

I tested the same code for Track1, only changed 0x30 to 0x20
PostPosted: Wed Jun 30, 2010 8:20 am     Reply with quote

Take a look at the code of mcr.c
As you see, in the decoding process of Track 1 the conversion to ASCII is different.

Code:

/////////////////////////////////////////////////////////////////////////
////                           MCR.C                                 ////



+++++++++++++++++++++++++++++
Code deleted.

Reason: Forum Rule #10

10. Don't post the CCS example code or drivers.
http://www.ccsinfo.com/forum/viewtopic.php?t=26245

-- Forum Moderator
+++++++++++++++++++++++++++++
dsolorzano



Joined: 29 Mar 2011
Posts: 3

View user's profile Send private message

PostPosted: Tue Mar 29, 2011 5:09 am     Reply with quote

Have you been able to read backwards the Track 1 data? If so, please let me know. Thanks
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group