/* Flashing Laser Barcode Emulator ver 0.2 by Adrian Crenshaw http://irongeek.com Inspired by Nathan Pegram's Shmoocon Barcode Contest Entry Thanks to Nathan for some tips on timing. Thanks to Bruce Potter and C-P for pointing me towards Nathan This code will not work if your barcode scanner is optical, only pens and laser barcode readers should work. If DIP 9 is set you can send strings via the serial interface. Hit return when finished typing the string. You may have to play with the timing (delaybase). */ const int ledPin = 21; // the number of the LED pin const int diagledPin = 11; int diagledPinstate=0; // Variables will change: int delaybase = 50; //100 best for pen reader? //50 was good for code 39 and laser //Items for serial read int incomingByte = 0; // for incoming serial data const int CommandStringSize=21; //Holds one less char than this int CommandStringTmpIndex=0; char CommandStringTmp[CommandStringSize]; char CommandString[CommandStringSize]; // #define STR_LENGTH 500 //500 should give us 100 Code 128 characters and 50 Code 39 char BarcodeBuf[STR_LENGTH]=""; //char RevBarcodeBuf[STR_LENGTH]=""; //All Code 39 symbols buffered by 1 so we end on a white space. char* code39bars[]={ "1113313111", "3113111131", "1133111131", "3133111111", "1113311131", "3113311111", "1133311111", "1113113131", "3113113111", "1133113111", "3111131131", "1131131131", "3131131111", "1111331131", "3111331111", "1131331111", "1111133131", "3111133111", "1131133111", "1111333111", "3111111331", "1131111331", "3131111311", "1111311331", "3111311311", "1131311311", "1111113331", "3111113311", "1131113311", "1111313311", "3311111131", "1331111131", "3331111111", "1311311131", "3311311111", "1331311111", "1311113131", "3311113111", "1331113111", "1313131111", "1313111311", "1311131311", "1113131311", "1311313111" }; char* code128bars[]={ "212222", "222122", "222221", "121223", "121322", "131222", "122213", "122312", "132212", "221213", "221312", "231212", "112232", "122132", "122231", "113222", "123122", "123221", "223211", "221132", "221231", "213212", "223112", "312131", "311222", "321122", "321221", "312212", "322112", "322211", "212123", "212321", "232121", "111323", "131123", "131321", "112313", "132113", "132311", "211313", "231113", "231311", "112133", "112331", "132131", "113123", "113321", "133121", "313121", "211331", "231131", "213113", "213311", "213131", "311123", "311321", "331121", "312113", "312311", "332111", "314111", "221411", "431111", "111224", "111422", "121124", "121421", "141122", "141221", "112214", "112412", "122114", "122411", "142112", "142211", "241211", "221114", "413111", "241112", "134111", "111242", "121142", "121241", "114212", "124112", "124211", "411212", "421112", "421211", "212141", "214121", "412121", "111143", "111341", "131141", "114113", "114311", "411113", "411311", "113141", "114131", "311141", "411131", "211412", "211214", "211232", "2331112"}; void setup() { pinMode(ledPin, OUTPUT); pinMode(diagledPin, OUTPUT); digitalWrite(diagledPin, diagledPinstate); for (int thispin=1; thispin <=10;thispin++){ pinMode(thispin, INPUT_PULLUP); // Se them high by default } pinMode(12, INPUT_PULLUP); Serial.begin(9600); Serial.println("Serial interface up..."); } void loop() { if (!digitalRead(12)){ //Set delay sweep diagledPinstate= !diagledPinstate; digitalWrite(diagledPin, diagledPinstate); delaybase = 50; Serial.println("12 pressed"); delay(500); } if (!digitalRead(1)){ //Uber simple test sting SendUSingDIPChoice("abc123"); } if (!digitalRead(2)){ //My old Shmoocon 2010 barcode SendUSingDIPChoice("e7e7f559-ce13-fd7f-baf0-9b4908dd1c73"); } if (!digitalRead(3)){ //Simple XSS attack, who sanitizes barcode input? SendUSingDIPChoice(""); } if (!digitalRead(4)){ //Simle SQL Injection attack via barcode SendUSingDIPChoice("' or 1=1 -- "); } if (!digitalRead(5)){//The EICAR test string, to see if AV freaks out SendUSingDIPChoice("X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*"); } if (!digitalRead(6)){ Code128StringSend("TRY TO PASTE v",103); //v in 128a should be a Ctrl+V } if (!digitalRead(7)){//Send some odd stuff, see what key press it is interpreted as SendUSingDIPChoice("Irongeek Was Here"); } if (!digitalRead(8)){//Send some odd stuff, see what key press it is interpreted as int points[]={ 64,65,66,67,68,69,70,71,72,73,74,75,75,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95 }; Code128IntArrSend(points, 103, 31); } if (!digitalRead(9)){//Listen to serial for things to send if (Serial.available() > 0) { // read the incoming byte: incomingByte = Serial.read(); if(incomingByte==13 || CommandStringTmpIndex==CommandStringSize-1){ CommandStringTmp[CommandStringTmpIndex]='\0'; strcpy(CommandString,CommandStringTmp); CommandStringTmpIndex=0; Serial.print("Will send \""); Serial.print(CommandString); Serial.println("\""); //delay(500); } else{ CommandStringTmp[CommandStringTmpIndex]=incomingByte; CommandStringTmpIndex++; } } SendUSingDIPChoice(CommandString); } //Try alternating timings if (diagledPinstate){ delaybase++; if (delaybase>100){ delaybase=1; } //Serial.println(delaybase); } } void SendUSingDIPChoice(char *SomeString) { if (!digitalRead(10)) { Code39StringSend(SomeString); } else { //Default to sending in Code 128b Code128StringSend(SomeString, 104); //104 means 128b, 103 is a, 105 is c } } //Based on stuff from http://www.codeguru.com/forum/showthread.php?t=303185 //not used yet char* rev(char* str) { int end= strlen(str)-1; int start = 0; while( start= 33 && Ivalue <= 126){ return Ivalue-32; } if (Ivalue >= 145){ return Ivalue-50; } if (Ivalue <= 31){ //Not used yet, but will be needed for Code 128a return Ivalue+64; } } int ASCIItoCode39Point(char Cvalue)// Converts the ASCII value to it's place in the Code 39 chart { int Ivalue=(int)Cvalue; if (Ivalue >= 48 && Ivalue <= 57){ return Ivalue-48; } if (Ivalue >= 65 && Ivalue <= 90){ return Ivalue-55; } if (Ivalue >= 97 && Ivalue <= 122){ return Ivalue-87; } switch (Cvalue) { case '-': return 36; break; case '.': return 37; break; case ' ': return 38; break; case '$': return 39; break; case '/': return 40; break; case '+': return 41; break; case '%': return 42; break; case '*': return 43; break; } } void UpperCase(char *SomeString) //Not used since I changed the wat I do code 39 { int i; for (i = 0; SomeString[i]!='\0'; i++) { if (SomeString[i] >= 97 && SomeString[i] <= 122){ SomeString[i]=SomeString[i]-32; } } } void Code128StringSend(char *SomeString, int ver) //Send the string. Ver should be 103 for 128a, 104 for 128b and 105 for 128c //Current code does not let you mix Code 128 versions { int i; int CheckSum = Code128CheckSum(SomeString, ver); //104 means Code 128B BarcodeBuf[0] = '\0'; //Turn on LED to read as white space digitalWrite(ledPin, LOW); delayMicroseconds(delaybase*100); strcat(BarcodeBuf, code128bars[ver]);//Code 128B start for (i = 0; SomeString[i]!='\0'; i++) { strcat(BarcodeBuf, code128bars[ASCIItoCode128Point(SomeString[i])]); } strcat(BarcodeBuf, code128bars[CheckSum]); //Checksum strcat(BarcodeBuf, "2331112"); //Code 128 end FlashSeq(BarcodeBuf); //Serial.println(BarcodeBuf); //Turn on LED to read as white space digitalWrite(ledPin, LOW); delayMicroseconds(delaybase*25); FlashSeq(rev(BarcodeBuf)); //Playing it backard helps reliability //Turn on LED to read as white space digitalWrite(ledPin, LOW); delayMicroseconds(delaybase*100); //Serial.println(BarcodeBuf); } void Code128IntArrSend(int *SomeIntArr, int ver, int arsize) //Using this for some odd characters //Send the string. Ver should be 103 for 128a, 104 for 128b and 105 for 128c //Current code does not let you mix Code 128 versions { int i; int CheckSum = Code128CheckSumInt(SomeIntArr, ver, arsize); //104 means Code 128B BarcodeBuf[0] = '\0'; //Turn on LED to read as white space digitalWrite(ledPin, LOW); delayMicroseconds(delaybase*100); strcat(BarcodeBuf, code128bars[ver]);//Code 128B start for (i = 0; i