|
|
View previous topic :: View next topic |
Author |
Message |
DiegoGarcia
Joined: 01 Mar 2008 Posts: 48
|
Need help with magnetic card reader |
Posted: Tue May 06, 2008 5:29 pm |
|
|
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
|
Ok the problem is solved now ;) |
Posted: Wed May 07, 2008 9:13 am |
|
|
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
|
mcr.c for both directions |
Posted: Fri Jun 18, 2010 8:34 am |
|
|
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
|
Reading Track1 in both directions. |
Posted: Mon Jun 21, 2010 12:03 pm |
|
|
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
|
|
Posted: Mon Jun 21, 2010 3:03 pm |
|
|
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
|
I tested the same code for Track1, only changed 0x30 to 0x20 |
Posted: Wed Jun 30, 2010 8:20 am |
|
|
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
|
|
Posted: Tue Mar 29, 2011 5:09 am |
|
|
Have you been able to read backwards the Track 1 data? If so, please let me know. Thanks |
|
|
|
|
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
|