]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge pull request #910 from pwpiwi/small_USB_response
authorpwpiwi <pwpiwi@users.noreply.github.com>
Thu, 6 Feb 2020 20:49:15 +0000 (21:49 +0100)
committerGitHub <noreply@github.com>
Thu, 6 Feb 2020 20:49:15 +0000 (21:49 +0100)
Improve USB communications

43 files changed:
armsrc/Makefile
armsrc/appmain.c
armsrc/apps.h
armsrc/epa.c
armsrc/hfsnoop.c
armsrc/hitag2.c
armsrc/hitagS.c
armsrc/i2c.c
armsrc/iclass.c
armsrc/iso14443a.c
armsrc/iso14443a.h
armsrc/iso14443b.c
armsrc/iso15693.c
armsrc/legicrf.c
armsrc/lfops.c
armsrc/mifarecmd.c
armsrc/mifaresim.c
armsrc/mifaresniff.c
armsrc/pcf7931.c
armsrc/util.h
bootrom/Makefile
bootrom/bootrom.c
client/cmdhf14a.c
client/cmdhficlass.c
client/cmdhfmf.c
client/cmdhfmfu.c
client/cmdsmartcard.c
client/comms.c
client/comms.h
client/flash.c
client/flasher.c
client/mifare/mifarehost.c
client/proxmark3.c
client/scripting.c
common/cmd.c [deleted file]
common/cmd.h [deleted file]
common/usb_cdc.c
common/usb_cdc.h
include/common.h
include/usb_cmd.h
uart/uart.h
uart/uart_posix.c [changed mode: 0644->0755]
uart/uart_win32.c

index 3d1ba79ea62fc758a50eb742ea51618eb2eda0d0..7b9e13566dc7e55e2d0d68bcefe330fcc390b1ba 100644 (file)
@@ -50,8 +50,7 @@ THUMBSRC = start.c \
        printf.c \
        util.c \
        string.c \
-       usb_cdc.c \
-       cmd.c
+       usb_cdc.c
 
 # Compile these in thumb mode optimized for speed (still smaller than ARM mode)
 THUMBOPTSRC = $(SRC_ISO15693)
index 70cabd2e20bfc00d8106a8c6443984db7135fb9a..4f0a19b9282da939760e155eff77bfea880d0487 100644 (file)
@@ -13,7 +13,6 @@
 #include <stdarg.h>
 
 #include "usb_cdc.h"
-#include "cmd.h"
 #include "proxmark3.h"
 #include "apps.h"
 #include "fpga.h"
@@ -312,6 +311,7 @@ void set_hw_capabilities(void) {
 
 
 void SendVersion(void) {
+       LED_A_ON();
        set_hw_capabilities();
 
        char temp[USB_CMD_DATA_SIZE]; /* Limited data payload in USB packets */
@@ -347,7 +347,8 @@ void SendVersion(void) {
        // Send Chip ID and used flash memory
        uint32_t text_and_rodata_section_size = (uint32_t)&__data_src_start__ - (uint32_t)&_flash_start;
        uint32_t compressed_data_section_size = common_area.arg1;
-       cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, hw_capabilities, VersionString, strlen(VersionString));
+       cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, hw_capabilities, VersionString, strlen(VersionString) + 1);
+       LED_A_OFF();
 }
 
 // measure the USB Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
@@ -363,13 +364,11 @@ void printUSBSpeed(void) {
        uint32_t start_time = end_time = GetTickCount();
        uint32_t bytes_transferred = 0;
 
-       LED_B_ON();
-       while(end_time < start_time + USB_SPEED_TEST_MIN_TIME) {
+       while (end_time < start_time + USB_SPEED_TEST_MIN_TIME) {
                cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, 0, USB_CMD_DATA_SIZE, 0, test_data, USB_CMD_DATA_SIZE);
                end_time = GetTickCount();
                bytes_transferred += USB_CMD_DATA_SIZE;
        }
-       LED_B_OFF();
 
        Dbprintf("  Time elapsed:      %dms", end_time - start_time);
        Dbprintf("  Bytes transferred: %d", bytes_transferred);
@@ -382,6 +381,7 @@ void printUSBSpeed(void) {
   * Prints runtime information about the PM3.
 **/
 void SendStatus(void) {
+       LED_A_ON();
        BigBuf_print_status();
        Fpga_print_status();
 #ifdef WITH_SMARTCARD
@@ -394,7 +394,8 @@ void SendStatus(void) {
        Dbprintf("  ToSendMax..........%d", ToSendMax);
        Dbprintf("  ToSendBit..........%d", ToSendBit);
 
-       cmd_send(CMD_ACK,1,0,0,0,0);
+       cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
+       LED_A_OFF();
 }
 
 #if defined(WITH_ISO14443a_StandAlone) || defined(WITH_LF_StandAlone)
@@ -936,9 +937,7 @@ void ListenReaderField(int limit) {
 }
 
 
-void UsbPacketReceived(uint8_t *packet, int len) {
-
-       UsbCommand *c = (UsbCommand *)packet;
+void UsbPacketReceived(UsbCommand *c) {
 
 //  Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d",len,c->cmd,c->arg[0],c->arg[1],c->arg[2]);
 
@@ -1337,9 +1336,11 @@ void UsbPacketReceived(uint8_t *packet, int len) {
                        break;
 
                case CMD_FPGA_MAJOR_MODE_OFF:       // ## FPGA Control
+                       LED_A_ON();
                        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
                        SpinDelay(200);
                        LED_D_OFF(); // LED D indicates field ON or OFF
+                       LED_A_OFF();
                        break;
 
                case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
@@ -1428,7 +1429,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
                case CMD_DEVICE_INFO: {
                        uint32_t dev_info = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS;
                        if(common_area.flags.bootrom_present) dev_info |= DEVICE_INFO_FLAG_BOOTROM_PRESENT;
-                       cmd_send(CMD_DEVICE_INFO,dev_info,0,0,0,0);
+                       cmd_send_old(CMD_DEVICE_INFO,dev_info,0,0,0,0);
                        break;
                }
                default:
@@ -1479,13 +1480,12 @@ void  __attribute__((noreturn)) AppMain(void) {
        LCDInit();
 #endif
 
-       uint8_t rx[sizeof(UsbCommand)];
-       size_t rx_len;
-
+       UsbCommand rx;
+  
        for(;;) {
                WDT_HIT();
-               if (usb_poll() && (rx_len = usb_read(rx, sizeof(rx)))) {
-                       UsbPacketReceived(rx, rx_len);
+               if (cmd_receive(&rx)) {
+                       UsbPacketReceived(&rx);
                } else {
 #if defined(WITH_LF_StandAlone) && !defined(WITH_ISO14443a_StandAlone)
                        if (BUTTON_HELD(1000) > 0)
index 5d3e3e59974e1078c90b8e37e35131741c4ff34b..0431d2ee648bf3a461f6d5d29f53ae1837f72018 100644 (file)
@@ -112,8 +112,4 @@ void    ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t * datain);
 int     DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout);
 size_t  CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout);
 
-// cmd.h
-bool cmd_receive(UsbCommand* cmd);
-bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len);
-
 #endif
index 0e999e1ed34b0650559359e83c83d40203879c66..fe32e4971b25eb5ad55526ce4e4a49860631391e 100644 (file)
@@ -15,7 +15,7 @@
 #include "iso14443a.h"
 #include "iso14443b.h"
 #include "epa.h"
-#include "cmd.h"
+#include "usb_cdc.h"
 #include "fpgaloader.h"
 #include "string.h"
 #include "util.h"
@@ -453,20 +453,17 @@ int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password)
 //-----------------------------------------------------------------------------
 // Perform the PACE protocol by replaying given APDUs
 //-----------------------------------------------------------------------------
-void EPA_PACE_Replay(UsbCommand *c)
-{
+void EPA_PACE_Replay(UsbCommand *c) {
        uint32_t timings[sizeof(apdu_lengths_replay) / sizeof(apdu_lengths_replay[0])] = {0};
 
-       // if an APDU has been passed, save it
+       // if an APDU has been passed, just save it
        if (c->arg[0] != 0) {
                // make sure it's not too big
-               if(c->arg[2] > apdus_replay[c->arg[0] - 1].len)
-               {
+               if(c->arg[2] > apdus_replay[c->arg[0] - 1].len) {
                        cmd_send(CMD_ACK, 1, 0, 0, NULL, 0);
+                       return;
                }
-               memcpy(apdus_replay[c->arg[0] - 1].data + c->arg[1],
-                  c->d.asBytes,
-                  c->arg[2]);
+               memcpy(apdus_replay[c->arg[0] - 1].data + c->arg[1], c->d.asBytes, c->arg[2]);
                // save/update APDU length
                if (c->arg[1] == 0) {
                        apdu_lengths_replay[c->arg[0] - 1] = c->arg[2];
index 755ac0ccc79c3bb0ba27401873d40ab6caf9f149..3a0ac65f504a1bcc2020115777485671a465e27e 100644 (file)
@@ -14,7 +14,7 @@
 #include "BigBuf.h"
 #include "util.h"
 #include "apps.h"
-#include "usb_cdc.h"   // for usb_poll_validate_length
+#include "usb_cdc.h"
 #include "fpga.h"
 #include "fpgaloader.h"
 
index 7cdabefaaa4dada3502c516c083c9b391c491af0..688805bea19aa5fbc5592f3c10b9e078e7c8ae66 100644 (file)
@@ -19,7 +19,7 @@
 #include "hitag2.h"
 
 #include "proxmark3.h"
-#include "cmd.h"
+#include "usb_cdc.h"
 #include "apps.h"
 #include "util.h"
 #include "hitag.h"
index 5da170bbcc5e8b125bff365f856d2eb7fae2e4e5..8f40146a6591dcb0c0e3342137d07de60df935d9 100644 (file)
@@ -17,6 +17,7 @@
 #include <stdlib.h>
 #include "proxmark3.h"
 #include "apps.h"
+#include "usb_cdc.h"
 #include "util.h"
 #include "hitag.h"
 #include "string.h"
index 51513114d3e81494e626714a24ca0388b37e32d0..3d16b42cea10783cfc27fb7b9b646ffdf58f0a70 100644 (file)
@@ -18,6 +18,7 @@
 #include "mifareutil.h" // for MF_DBGLEVEL
 #include "BigBuf.h"
 #include "apps.h"
+#include "usb_cdc.h"
 
 #ifdef WITH_SMARTCARD
 #include "smartcard.h"
index 28cfcaa66c407bf5a54d3c47afe817be5ad1cd71..afe1a607e9e1e823372bfdc285761409327915b4 100644 (file)
@@ -24,7 +24,7 @@
 #include "string.h"
 #include "printf.h"
 #include "common.h"
-#include "cmd.h"
+#include "usb_cdc.h"
 #include "iso14443a.h"
 #include "iso15693.h"
 // Needed for CRC in emulation mode;
@@ -34,7 +34,6 @@
 #include "iso15693tools.h"
 #include "protocols.h"
 #include "optimized_cipher.h"
-#include "usb_cdc.h" // for usb_poll_validate_length
 #include "fpgaloader.h"
 
 // iCLASS has a slightly different timing compared to ISO15693. According to the picopass data sheet the tag response is expected 330us after
@@ -675,14 +674,14 @@ static bool selectIclassTag(uint8_t *card_data, uint32_t *eof_time) {
        // Send act_all
        ReaderTransmitIClass(act_all, 1, &start_time);
        // Card present?
-       if (GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_ACTALL, eof_time) < 0) return false;//Fail
+       if (GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_ACTALL, eof_time) < 0) return false; //Fail
 
        //Send Identify
        start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
        ReaderTransmitIClass(identify, 1, &start_time);
        //We expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC
        uint8_t len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time);
-       if (len != 10) return false;//Fail
+       if (len != 10) return false; //Fail
 
        //Copy the Anti-collision CSN to our select-packet
        memcpy(&select[1], resp, 8);
@@ -691,7 +690,7 @@ static bool selectIclassTag(uint8_t *card_data, uint32_t *eof_time) {
        ReaderTransmitIClass(select, sizeof(select), &start_time);
        //We expect a 10-byte response here, 8 byte CSN and 2 byte CRC
        len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time);
-       if (len != 10) return false;//Fail
+       if (len != 10) return false; //Fail
 
        //Success - we got CSN
        //Save CSN in response data
@@ -734,42 +733,42 @@ void ReaderIClass(uint8_t flags) {
        if (selectIclassTag(resp, &eof_time)) {
                result_status = FLAG_ICLASS_READER_CSN;
                memcpy(card_data, resp, 8);
-       }
 
-       start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
+               start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
 
-       //Read block 1, config
-       if (flags & FLAG_ICLASS_READER_CONF) {
-               if (sendCmdGetResponseWithRetries(readConf, sizeof(readConf), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
-                       result_status |= FLAG_ICLASS_READER_CONF;
-                       memcpy(card_data+8, resp, 8);
-               } else {
-                       Dbprintf("Failed to read config block");
+               //Read block 1, config
+               if (flags & FLAG_ICLASS_READER_CONF) {
+                       if (sendCmdGetResponseWithRetries(readConf, sizeof(readConf), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
+                               result_status |= FLAG_ICLASS_READER_CONF;
+                               memcpy(card_data+8, resp, 8);
+                       } else {
+                               Dbprintf("Failed to read config block");
+                       }
+                       start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
                }
-               start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
-       }
 
-       //Read block 2, e-purse
-       if (flags & FLAG_ICLASS_READER_CC) {
-               if (sendCmdGetResponseWithRetries(readEpurse, sizeof(readEpurse), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
-                       result_status |= FLAG_ICLASS_READER_CC;
-                       memcpy(card_data + (8*2), resp, 8);
-               } else {
-                       Dbprintf("Failed to read e-purse");
+               //Read block 2, e-purse
+               if (flags & FLAG_ICLASS_READER_CC) {
+                       if (sendCmdGetResponseWithRetries(readEpurse, sizeof(readEpurse), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
+                               result_status |= FLAG_ICLASS_READER_CC;
+                               memcpy(card_data + (8*2), resp, 8);
+                       } else {
+                               Dbprintf("Failed to read e-purse");
+                       }
+                       start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
                }
-               start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
-       }
 
-       //Read block 5, AA
-       if (flags & FLAG_ICLASS_READER_AA) {
-               if (sendCmdGetResponseWithRetries(readAA, sizeof(readAA), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
-                       result_status |= FLAG_ICLASS_READER_AA;
-                       memcpy(card_data + (8*5), resp, 8);
-               } else {
-                       Dbprintf("Failed to read AA block");
+               //Read block 5, AA
+               if (flags & FLAG_ICLASS_READER_AA) {
+                       if (sendCmdGetResponseWithRetries(readAA, sizeof(readAA), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
+                               result_status |= FLAG_ICLASS_READER_AA;
+                               memcpy(card_data + (8*5), resp, 8);
+                       } else {
+                               Dbprintf("Failed to read AA block");
+                       }
                }
        }
-
+       
        cmd_send(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data));
 
        LED_A_OFF();
@@ -820,9 +819,9 @@ void iClass_ReadBlk(uint8_t blockno) {
 
        uint8_t readblockdata[10];
        bool isOK = iClass_ReadBlock(blockno, readblockdata);
-       cmd_send(CMD_ACK, isOK, 0, 0, readblockdata, 8);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        LED_D_OFF();
+       cmd_send(CMD_ACK, isOK, 0, 0, readblockdata, 8);
 
        LED_A_OFF();
 }
@@ -900,11 +899,10 @@ void iClass_WriteBlock(uint8_t blockNo, uint8_t *data) {
        } else {
                Dbprintf("Write block [%02x] failed", blockNo);
        }
-       cmd_send(CMD_ACK, isOK, 0, 0, 0, 0);
-
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        LED_D_OFF();
 
+       cmd_send(CMD_ACK, isOK, 0, 0, 0, 0);
        LED_A_OFF();
 }
 
@@ -935,6 +933,5 @@ void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data) {
        LED_D_OFF();
 
        cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
-
        LED_A_OFF();
 }
index 31a3e4ccc1e2bc48415d22a04501ad927a8b0cdb..0de5ea6f67789ebdf40981cbf8892c085e1603f1 100644 (file)
@@ -17,7 +17,7 @@
 #include "proxmark3.h"
 #include "apps.h"
 #include "util.h"
-#include "cmd.h"
+#include "usb_cdc.h"
 #include "iso14443crc.h"
 #include "crapto1/crapto1.h"
 #include "mifareutil.h"
@@ -942,7 +942,7 @@ bool prepare_allocated_tag_modulation(tag_response_info_t* response_info, uint8_
 // Main loop of simulated tag: receive commands from reader, decide what
 // response to send, and send it.
 //-----------------------------------------------------------------------------
-void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) {
+void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, uint8_t* data) {
 
        uint8_t sak;
 
@@ -1701,13 +1701,13 @@ static int GetATQA(uint8_t *resp, uint8_t *resp_par) {
 // if anticollision is false, then the UID must be provided in uid_ptr[]
 // and num_cascades must be set (1: 4 Byte UID, 2: 7 Byte UID, 3: 10 Byte UID)
 // requests ATS unless no_rats is true
-int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats) {
+int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats) {
        uint8_t sel_all[]    = { 0x93,0x20 };
        uint8_t sel_uid[]    = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
        uint8_t rats[]       = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0
        uint8_t resp[MAX_FRAME_SIZE]; // theoretically. A usual RATS will be much smaller
        uint8_t resp_par[MAX_PARITY_SIZE];
-       byte_t uid_resp[4];
+       uint8_t uid_resp[4];
        size_t uid_resp_len;
 
        uint8_t sak = 0x04; // cascade uid
@@ -2020,21 +2020,21 @@ void ReaderIso14443a(UsbCommand *c) {
        size_t lenbits = c->arg[1] >> 16;
        uint32_t timeout = c->arg[2];
        uint32_t arg0 = 0;
-       byte_t buf[USB_CMD_DATA_SIZE] = {0};
+       uint8_t buf[USB_CMD_DATA_SIZE] = {0};
        uint8_t par[MAX_PARITY_SIZE];
        bool cantSELECT = false;
 
        set_tracing(true);
 
-       if(param & ISO14A_CLEAR_TRACE) {
+       if (param & ISO14A_CLEAR_TRACE) {
                clear_trace();
        }
 
-       if(param & ISO14A_REQUEST_TRIGGER) {
+       if (param & ISO14A_REQUEST_TRIGGER) {
                iso14a_set_trigger(true);
        }
 
-       if(param & ISO14A_CONNECT) {
+       if (param & ISO14A_CONNECT) {
                LED_A_ON();
                iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
                if(!(param & ISO14A_NO_SELECT)) {
@@ -2048,16 +2048,16 @@ void ReaderIso14443a(UsbCommand *c) {
                        }
                        FpgaDisableTracing();
                        LED_B_ON();
-                       cmd_send(CMD_ACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
+                       cmd_send(CMD_NACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
                        LED_B_OFF();
                }
        }
 
-       if(param & ISO14A_SET_TIMEOUT) {
+       if (param & ISO14A_SET_TIMEOUT) {
                iso14a_set_timeout(timeout);
        }
 
-       if(param & ISO14A_APDU && !cantSELECT) {
+       if (param & ISO14A_APDU && !cantSELECT) {
                uint8_t res;
                arg0 = iso14_apdu(cmd, len, (param & ISO14A_SEND_CHAINING), buf, &res);
                FpgaDisableTracing();
@@ -2066,8 +2066,8 @@ void ReaderIso14443a(UsbCommand *c) {
                LED_B_OFF();
        }
 
-       if(param & ISO14A_RAW && !cantSELECT) {
-               if(param & ISO14A_APPEND_CRC) {
+       if (param & ISO14A_RAW && !cantSELECT) {
+               if (param & ISO14A_APPEND_CRC) {
                        if(param & ISO14A_TOPAZMODE) {
                                AppendCrc14443b(cmd,len);
                        } else {
@@ -2076,8 +2076,8 @@ void ReaderIso14443a(UsbCommand *c) {
                        len += 2;
                        if (lenbits) lenbits += 16;
                }
-               if(lenbits>0) {             // want to send a specific number of bits (e.g. short commands)
-                       if(param & ISO14A_TOPAZMODE) {
+               if (lenbits > 0) {             // want to send a specific number of bits (e.g. short commands)
+                       if (param & ISO14A_TOPAZMODE) {
                                int bits_to_send = lenbits;
                                uint16_t i = 0;
                                ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 7), NULL, NULL);     // first byte is always short (7bits) and no parity
@@ -2091,7 +2091,7 @@ void ReaderIso14443a(UsbCommand *c) {
                                ReaderTransmitBitsPar(cmd, lenbits, par, NULL);                         // bytes are 8 bit with odd parity
                        }
                } else {                    // want to send complete bytes only
-                       if(param & ISO14A_TOPAZMODE) {
+                       if (param & ISO14A_TOPAZMODE) {
                                uint16_t i = 0;
                                ReaderTransmitBitsPar(&cmd[i++], 7, NULL, NULL);                        // first byte: 7 bits, no paritiy
                                while (i < len) {
@@ -2105,15 +2105,15 @@ void ReaderIso14443a(UsbCommand *c) {
                FpgaDisableTracing();
 
                LED_B_ON();
-               cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
+               cmd_send(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
                LED_B_OFF();
        }
 
-       if(param & ISO14A_REQUEST_TRIGGER) {
+       if (param & ISO14A_REQUEST_TRIGGER) {
                iso14a_set_trigger(false);
        }
 
-       if(param & ISO14A_NO_DISCONNECT) {
+       if (param & ISO14A_NO_DISCONNECT) {
                return;
        }
 
index d2a94a788395ba1b6946fa1b23ca3fd3c496e8d8..32bf3971381d5919650c3d0a82baed8caf30d5cb 100644 (file)
@@ -13,6 +13,7 @@
 #ifndef __ISO14443A_H
 #define __ISO14443A_H
 
+#include <stddef.h>
 #include <stdint.h>
 #include <stdbool.h>
 #include "usb_cmd.h"
@@ -31,7 +32,7 @@ extern void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par);
 extern void AppendCrc14443a(uint8_t *data, int len);
 
 extern void RAMFUNC SnoopIso14443a(uint8_t param);
-extern void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t *data);
+extern void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, uint8_t *data);
 extern void ReaderIso14443a(UsbCommand *c);
 extern void ReaderTransmit(uint8_t *frame, uint16_t len, uint32_t *timing);
 extern void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t *timing);
index 6434409d905312b945f85a139fc8a91d03cb7f18..0f36c7c7b33c6810371c6333db686d751337ce69 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "proxmark3.h"
 #include "apps.h"
+#include "usb_cdc.h"
 #include "util.h"
 #include "string.h"
 #include "iso14443crc.h"
index 351b01846bb20e63d22ac632674ec1d472d42311..9f6516aad3398c5df4524ee1b3c1d377c0b313e4 100644 (file)
@@ -58,7 +58,7 @@
 #include "string.h"
 #include "iso15693tools.h"
 #include "protocols.h"
-#include "cmd.h"
+#include "usb_cdc.h"
 #include "BigBuf.h"
 #include "fpgaloader.h"
 
index 97af88433e3afdce5f9c91b735636c954065bc73..71ff0321c546208fbda0928bfadaf3184f09c328 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "proxmark3.h"
 #include "apps.h"
+#include "usb_cdc.h"
 #include "util.h"
 #include "string.h"
 #include "legic_prng.h"
index 12f9de08741013c139f10c5d18a44e60af3fcc10..995a8810ad6f856772e87a56111c475de9c29473 100644 (file)
@@ -17,7 +17,7 @@
 #include "lfdemod.h"
 #include "lfsampling.h"
 #include "protocols.h"
-#include "usb_cdc.h" // for usb_poll_validate_length
+#include "usb_cdc.h"
 #include "fpgaloader.h"
 
 /**
index b9032c5fafc3dd9dff78f973a495648459a48abc..27b1cf1923456be7248e1065471bc0fdc5b96ad6 100644 (file)
@@ -18,7 +18,7 @@
 #include <stdint.h>\r
 \r
 #include "proxmark3.h"\r
-#include "cmd.h"\r
+#include "usb_cdc.h"\r
 #include "crapto1/crapto1.h"\r
 #include "iso14443a.h"\r
 #include "BigBuf.h"\r
@@ -111,11 +111,12 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 \r
        if (MF_DBGLEVEL >= 2)   DbpString("READ BLOCK FINISHED");\r
 \r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);\r
        LED_B_OFF();\r
 \r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 }\r
 \r
@@ -202,9 +203,10 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
                return;\r
        }\r
 \r
-       cmd_send(CMD_ACK,1,0,0,dataout,16);\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LED_D_OFF();\r
+\r
+       cmd_send(CMD_ACK,1,0,0,dataout,16);\r
        LED_A_OFF();\r
 }\r
 \r
@@ -266,12 +268,13 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 \r
        if (MF_DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED");\r
 \r
+       // Thats it...\r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16*NumBlocksPerSector(sectorNo));\r
        LED_B_OFF();\r
 \r
-       // Thats it...\r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 }\r
 \r
@@ -362,10 +365,11 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
 \r
        if (MF_DBGLEVEL >= MF_DBG_DEBUG) Dbprintf("Blocks read %d", countblocks);\r
 \r
-       cmd_send(CMD_ACK, 1, countblocks*4, BigBuf_max_traceLen(), 0, 0);\r
-\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LED_D_OFF();\r
+\r
+       cmd_send(CMD_ACK, 1, countblocks*4, BigBuf_max_traceLen(), 0, 0);\r
+\r
        BigBuf_free();\r
        LED_A_OFF();\r
 }\r
@@ -431,13 +435,14 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 \r
        if (MF_DBGLEVEL >= 2)   DbpString("WRITE BLOCK FINISHED");\r
 \r
+       // Thats it...\r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK,isOK,0,0,0,0);\r
        LED_B_OFF();\r
 \r
 \r
-       // Thats it...\r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 }\r
 \r
@@ -475,8 +480,9 @@ void MifareUWriteBlockCompat(uint8_t arg0, uint8_t *datain)
 \r
        if (MF_DBGLEVEL >= 2)   DbpString("WRITE BLOCK FINISHED");\r
 \r
-       cmd_send(CMD_ACK,1,0,0,0,0);\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
+       cmd_send(CMD_ACK,1,0,0,0,0);\r
        LEDsoff();\r
 }\r
 */\r
@@ -544,8 +550,9 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
 \r
        if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
 \r
-       cmd_send(CMD_ACK,1,0,0,0,0);\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
+       cmd_send(CMD_ACK,1,0,0,0,0);\r
        LEDsoff();\r
 }\r
 \r
@@ -613,8 +620,9 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
                return;\r
        };\r
 \r
-       cmd_send(CMD_ACK,1,0,0,0,0);\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
+       cmd_send(CMD_ACK,1,0,0,0,0);\r
        LEDsoff();\r
 }\r
 \r
@@ -743,16 +751,17 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
 \r
        crypto1_destroy(pcs);\r
 \r
+       if (field_off) {\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+               LEDsoff();\r
+       }\r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK, isOK, cuid, num_nonces, buf, sizeof(buf));\r
        LED_B_OFF();\r
 \r
        if (MF_DBGLEVEL >= 3)   DbpString("AcquireEncryptedNonces finished");\r
 \r
-       if (field_off) {\r
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
-               LEDsoff();\r
-       }\r
 }\r
 \r
 \r
@@ -978,13 +987,14 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
        memcpy(buf+16, &target_ks[1], 4);\r
        memcpy(buf+20, &authentication_timeout, 4);\r
 \r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
+       if (MF_DBGLEVEL >= 3)   DbpString("NESTED FINISHED");\r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK, isOK, 0, targetBlockNo + (targetKeyType * 0x100), buf, sizeof(buf));\r
        LED_B_OFF();\r
 \r
-       if (MF_DBGLEVEL >= 3)   DbpString("NESTED FINISHED");\r
-\r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 }\r
 \r
@@ -1352,13 +1362,14 @@ void MifareCWipe(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
                break;\r
        }\r
 \r
+       // reset fpga\r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
        // send USB response\r
        LED_B_ON();\r
        cmd_send(CMD_ACK,isOK,0,0,NULL,0);\r
        LED_B_OFF();\r
 \r
-       // reset fpga\r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 \r
        return;\r
@@ -1490,14 +1501,15 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                break;\r
        }\r
 \r
+       if ((workFlags & 0x10) || (!isOK)) {\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+       }\r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK,isOK,0,0,uid,4);\r
        LED_B_OFF();\r
 \r
-       if ((workFlags & 0x10) || (!isOK)) {\r
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
-               LEDsoff();\r
-       }\r
+       LEDsoff();\r
 }\r
 \r
 \r
@@ -1574,6 +1586,10 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                break;\r
        }\r
 \r
+       if ((workFlags & 0x10) || (!isOK)) {\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+       }\r
+\r
        LED_B_ON();\r
        if (workFlags & 0x20) {\r
                if (isOK)\r
@@ -1583,10 +1599,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                cmd_send(CMD_ACK,isOK,0,0,data,18);\r
        LED_B_OFF();\r
 \r
-       if ((workFlags & 0x10) || (!isOK)) {\r
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
-               LEDsoff();\r
-       }\r
+       LEDsoff();\r
 }\r
 \r
 void MifareCIdent(){\r
@@ -1622,11 +1635,12 @@ void MifareCIdent(){
        // From iceman1001: removed the if,  since some magic tags misbehavies and send an answer to it.\r
        mifare_classic_halt(NULL, 0);\r
 \r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK,isOK,0,0,0,0);\r
        LED_B_OFF();\r
 \r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 }\r
 \r
@@ -1657,7 +1671,8 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
        }\r
 \r
        if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED");\r
-       cmd_send(CMD_ACK,1,cuid,0,dataout, sizeof(dataout));\r
+\r
+       cmd_send(CMD_ACK, 1, cuid, 0, dataout, sizeof(dataout));\r
 }\r
 \r
 void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){\r
@@ -1671,16 +1686,17 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
 \r
        isOK = mifare_desfire_des_auth2(cuid, key, dataout);\r
 \r
-       ifisOK) {\r
+       if (isOK) {\r
                if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Authentication part2: Failed");\r
                OnError(4);\r
                return;\r
        }\r
 \r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
        if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 2 FINISHED");\r
 \r
        cmd_send(CMD_ACK, isOK, 0, 0, dataout, sizeof(dataout));\r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 }\r
 \r
index 891e0dafcdf5740c39411beb694ae4d0197cce95..b63160c945c3211265fcd7120e93753236894d5e 100644 (file)
@@ -20,7 +20,6 @@
 #include "fpgaloader.h"
 #include "proxmark3.h"
 #include "usb_cdc.h"
-#include "cmd.h"
 #include "protocols.h"
 #include "apps.h"
 
index 4dbcd90434cefabc8cbf579d2e21a9d62e09a6e2..f3ee4a3f79dde9566b23a92581be5fd7ee829278 100644 (file)
@@ -18,7 +18,7 @@
 #include "crapto1/crapto1.h"
 #include "mifareutil.h"
 #include "common.h"
-#include "cmd.h"
+#include "usb_cdc.h"
 #include "BigBuf.h"
 #include "fpgaloader.h"
 
@@ -152,7 +152,7 @@ bool intMfSniffSend() {
        while (pckLen > 0) {
                pckSize = MIN(USB_CMD_DATA_SIZE, pckLen);
                LED_B_ON();
-               cmd_send(CMD_ACK, 1, BigBuf_get_traceLen(), pckSize, trace + BigBuf_get_traceLen() - pckLen, pckSize);
+               cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, 1, BigBuf_get_traceLen(), pckSize, trace + BigBuf_get_traceLen() - pckLen, pckSize);
                LED_B_OFF();
 
                pckLen -= pckSize;
@@ -160,7 +160,7 @@ bool intMfSniffSend() {
        }
 
        LED_B_ON();
-       cmd_send(CMD_ACK,2,0,0,0,0);
+       cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,2,0,0,0,0);
        LED_B_OFF();
 
        clear_trace();
index 147f6fb8d215441b47c1447455c4317774b612c2..2fae74cc60f947ca944fac8494b31a07b9b7d5ce 100644 (file)
@@ -1,5 +1,6 @@
 #include "proxmark3.h"
 #include "apps.h"
+#include "usb_cdc.h"
 #include "lfsampling.h"
 #include "pcf7931.h"
 #include "util.h"
index 14ac5e100b94c753ce54bba91880d5760b59b61c..bdb7fafd1e885c87a3c851eb0dc0ca85edda95bd 100644 (file)
@@ -8,12 +8,13 @@
 // Utility functions used in many places, not specific to any piece of code.
 //-----------------------------------------------------------------------------
 
-#ifndef __UTIL_H
-#define __UTIL_H
+#ifndef UTIL_H__
+#define UTIL_H__
 
 #include <stddef.h>
 #include <stdint.h>
 #include "common.h"
+#include "at91sam7s512.h"
 
 #define BYTEx(x, n) (((x) >> (n * 8)) & 0xff )
 
 #define REV32(x) (REV16(x) | (REV16(x >> 16) << 16))
 #define REV64(x) (REV32(x) | (REV32(x >> 32) << 32))
 
-void print_result(char *name, uint8_t *buf, size_t len);
-size_t nbytes(size_t nbits);
-uint32_t SwapBits(uint32_t value, int nrbits);
-void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
-uint64_t bytes_to_num(uint8_t* src, size_t len);
-void rol(uint8_t *data, const size_t len);
-void lsl (uint8_t *data, size_t len);
-
-void LED(int led, int ms);
-void LEDsoff();
-void LEDson();
-void LEDsinvert();
-int BUTTON_CLICKED(int ms);
-int BUTTON_HELD(int ms);
-void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information);
+extern void print_result(char *name, uint8_t *buf, size_t len);
+extern size_t nbytes(size_t nbits);
+extern uint32_t SwapBits(uint32_t value, int nrbits);
+extern void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
+extern uint64_t bytes_to_num(uint8_t* src, size_t len);
+extern void rol(uint8_t *data, const size_t len);
+extern void lsl (uint8_t *data, size_t len);
+
+extern void LED(int led, int ms);
+extern void LEDsoff();
+extern void LEDson();
+extern void LEDsinvert();
+extern int BUTTON_CLICKED(int ms);
+extern int BUTTON_HELD(int ms);
+extern void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information);
 
 //iceman's ticks.h
 #ifndef GET_TICKS
 # define GET_TICKS GetTicks()
 #endif
 
-void SpinDelay(int ms);
-void SpinDelayUs(int us);
+extern void SpinDelay(int ms);
+extern void SpinDelayUs(int us);
 
-void StartTickCount();
-uint32_t RAMFUNC GetTickCount();
+extern void StartTickCount();
+extern uint32_t RAMFUNC GetTickCount();
 
-void StartCountUS();
-uint32_t RAMFUNC GetCountUS();
-uint32_t RAMFUNC GetDeltaCountUS();
+extern void StartCountUS();
+extern uint32_t RAMFUNC GetCountUS();
+extern uint32_t RAMFUNC GetDeltaCountUS();
 
-void StartCountSspClk();
-void ResetSspClk(void);
-uint32_t GetCountSspClk();
+extern void StartCountSspClk();
+extern void ResetSspClk(void);
+extern uint32_t GetCountSspClk();
 
 extern void StartTicks(void);
 extern uint32_t GetTicks(void);
@@ -78,6 +79,6 @@ extern void ResetTimer(AT91PS_TC timer);
 extern void StopTicks(void);
 // end iceman's ticks.h
 
-uint32_t prand();
+extern uint32_t prand();
 
 #endif
index dd1e7e0830877d14d1870549f0d4620b9b1c2c93..b1e2e6cd14a7b00125777156c4ec0deb59c514d4 100644 (file)
@@ -8,7 +8,7 @@
 
 # DO NOT use thumb mode in the phase 1 bootloader since that generates a section with glue code
 ARMSRC = 
-THUMBSRC = cmd.c usb_cdc.c bootrom.c
+THUMBSRC = usb_cdc.c bootrom.c
 ASMSRC = ram-reset.s flash-reset.s
 VERSIONSRC = version.c
 
index bbea07b53dedf72bd47501ff0639db4bcb80f02b..817421763182776e9669590c6ca7aa4fe56870c3 100644 (file)
@@ -6,17 +6,15 @@
 // Main code for the bootloader
 //-----------------------------------------------------------------------------
 
-#include <proxmark3.h>
+#include "proxmark3.h"
 #include "usb_cdc.h"
-#include "cmd.h"
-//#include "usb_hid.h"
 
 void DbpString(char *str) {
-  byte_t len = 0;
+  uint8_t len = 0;
   while (str[len] != 0x00) {
     len++;
   }
-  cmd_send(CMD_DEBUG_PRINT_STRING,len,0,0,(byte_t*)str,len);
+  cmd_send_old(CMD_DEBUG_PRINT_STRING,len,0,0,(uint8_t*)str,len);
 }
 
 struct common_area common_area __attribute__((section(".commonarea")));
@@ -89,26 +87,22 @@ static void Fatal(void)
   for(;;);
 }
 
-void UsbPacketReceived(uint8_t *packet, int len) {
+void UsbPacketReceived(UsbCommand *c) {
   int i, dont_ack=0;
-  UsbCommand* c = (UsbCommand *)packet;
   volatile uint32_t *p;
   
-  if(len != sizeof(UsbCommand)) {
-    Fatal();
-  }
-  
   uint32_t arg0 = (uint32_t)c->arg[0];
   
   switch(c->cmd) {
     case CMD_DEVICE_INFO: {
       dont_ack = 1;
-      arg0 = DEVICE_INFO_FLAG_BOOTROM_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM |
-      DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH;
+      arg0 = DEVICE_INFO_FLAG_BOOTROM_PRESENT 
+               | DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM
+               | DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH;
       if(common_area.flags.osimage_present) {
         arg0 |= DEVICE_INFO_FLAG_OSIMAGE_PRESENT;
       }
-      cmd_send(CMD_DEVICE_INFO,arg0,1,2,0,0);
+      cmd_send_old(CMD_DEVICE_INFO,arg0,1,2,0,0);
     } break;
       
     case CMD_SETUP_WRITE: {
@@ -134,7 +128,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
         if( ((flash_address+AT91C_IFLASH_PAGE_SIZE-1) >= end_addr) || (flash_address < start_addr) ) {
           /* Disallow write */
           dont_ack = 1;
-          cmd_send(CMD_NACK,0,0,0,0,0);
+          cmd_send_old(CMD_NACK,0,0,0,0,0);
         } else {
           uint32_t page_n = (flash_address - ((uint32_t)flash_mem)) / AT91C_IFLASH_PAGE_SIZE;
           /* Translate address to flash page and do flash, update here for the 512k part */
@@ -148,7 +142,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
         while(!((sr = AT91C_BASE_EFC0->EFC_FSR) & AT91C_MC_FRDY));
         if(sr & (AT91C_MC_LOCKE | AT91C_MC_PROGE)) {
           dont_ack = 1;
-          cmd_send(CMD_NACK,0,0,0,0,0);
+          cmd_send_old(CMD_NACK,0,0,0,0,0);
         }
       }
     } break;
@@ -179,7 +173,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
         } else {
           start_addr = end_addr = 0;
           dont_ack = 1;
-          cmd_send(CMD_NACK,0,0,0,0,0);
+          cmd_send_old(CMD_NACK,0,0,0,0,0);
         }
       }
     } break;
@@ -190,7 +184,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
   }
   
   if(!dont_ack) {
-    cmd_send(CMD_ACK,arg0,0,0,0,0);
+    cmd_send_old(CMD_ACK,arg0,0,0,0,0);
   }
 }
 
@@ -199,21 +193,17 @@ static void flash_mode(int externally_entered)
        start_addr = 0;
        end_addr = 0;
        bootrom_unlocked = 0;
-  byte_t rx[sizeof(UsbCommand)];
-       size_t rx_len;
+    UsbCommand rx;
 
-  usb_enable();
-  for (volatile size_t i=0; i<0x100000; i++) {};
+       usb_enable();
+       for (volatile size_t i=0; i<0x100000; i++) {};
 
        for(;;) {
                WDT_HIT();
 
-    if (usb_poll()) {
-      rx_len = usb_read(rx,sizeof(UsbCommand));
-      if (rx_len) {
-        UsbPacketReceived(rx,rx_len);
-      }
-    }
+               if (cmd_receive(&rx)) {
+                       UsbPacketReceived(&rx);
+               }
 
                if(!externally_entered && !BUTTON_PRESS()) {
                        /* Perform a reset to leave flash mode */
index eba33947fd33ac19efd693e7101ed3f0dd5aa0d8..58315582742ed8850c15e1277f7f9f065cfa0791 100644 (file)
@@ -46,28 +46,28 @@ int CmdHF14AList(const char *Cmd)
        return 0;
 }
 
-int Hf14443_4aGetCardData(iso14a_card_select_t * card) {
+int Hf14443_4aGetCardData(iso14a_card_select_t *card) {
        UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
        SendCommand(&c);
 
        UsbCommand resp;
-       WaitForResponse(CMD_ACK,&resp);
+       WaitForResponse(CMD_NACK, &resp);
 
        memcpy(card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
 
        uint64_t select_status = resp.arg[0];       // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
 
-       if(select_status == 0) {
+       if (select_status == 0) {
                PrintAndLog("E->iso14443a card select failed");
                return 1;
        }
 
-       if(select_status == 2) {
+       if (select_status == 2) {
                PrintAndLog("E->Card doesn't support iso14443-4 mode");
                return 1;
        }
 
-       if(select_status == 3) {
+       if (select_status == 3) {
                PrintAndLog("E->Card doesn't support standard iso14443-3 anticollision");
                PrintAndLog("\tATQA : %02x %02x", card->atqa[1], card->atqa[0]);
                return 1;
@@ -156,20 +156,24 @@ int CmdHF14AReader(const char *Cmd) {
        return 0;
 }
 
-int CmdHF14AInfo(const char *Cmd)
-{
+
+int CmdHF14AInfo(const char *Cmd) {
+
        UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
        SendCommand(&c);
 
        UsbCommand resp;
-       WaitForResponse(CMD_ACK,&resp);
-
+       if (!WaitForResponseTimeout(CMD_NACK, &resp, 500)) {
+               if (Cmd[0] != 's') PrintAndLog("Error: No response from Proxmark.\n");
+               return 0;
+       }
+       
        iso14a_card_select_t card;
        memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
 
        uint64_t select_status = resp.arg[0];       // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
 
-       if(select_status == 0) {
+       if (select_status == 0) {
                if (Cmd[0] != 's') PrintAndLog("iso14443a card select failed");
                // disconnect
                c.arg[0] = 0;
@@ -217,13 +221,13 @@ int CmdHF14AInfo(const char *Cmd)
                        SendCommand(&c);
 
                        UsbCommand resp;
-                       WaitForResponse(CMD_ACK,&resp);
+                       WaitForResponse(CMD_NACK,&resp);
 
                        memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
 
                        select_status = resp.arg[0];        // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS
 
-                       if(select_status == 0) {
+                       if (select_status == 0) {
                                //PrintAndLog("iso14443a card select failed");
                                // disconnect
                                c.arg[0] = 0;
@@ -272,7 +276,7 @@ int CmdHF14AInfo(const char *Cmd)
 
        // Double & triple sized UID, can be mapped to a manufacturer.
        // HACK: does this apply for Ultralight cards?
-       if ( card.uidlen > 4 ) {
+       if (card.uidlen > 4) {
                PrintAndLog("MANUFACTURER : %s", getManufacturerName(card.uid[0]));
        }
 
@@ -430,7 +434,7 @@ int CmdHF14AInfo(const char *Cmd)
        (void)mfCIdentify();
 
        if (isMifareClassic) {
-               switch(DetectClassicPrng()) {
+               switch (DetectClassicPrng()) {
                case 0:
                        PrintAndLog("Prng detection: HARDENED (hardnested)");
                        break;
@@ -462,7 +466,7 @@ int CmdHF14ACUIDs(const char *Cmd)
                SendCommand(&c);
 
                UsbCommand resp;
-               WaitForResponse(CMD_ACK,&resp);
+               WaitForResponse(CMD_NACK,&resp);
 
                iso14a_card_select_t *card = (iso14a_card_select_t *) resp.d.asBytes;
 
index 1400395aa8dbb97ca1b78d23ce54ddab3175de3f..93e46b679e7a43c007bdfcde7f6af95c46a4c2b6 100644 (file)
@@ -333,7 +333,7 @@ int HFiClassReader(bool loop, bool verbose) {
 
        while (!ukbhit()) {
                SendCommand(&c);
-               if (WaitForResponseTimeout(CMD_ACK,&resp, 4500)) {
+               if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
                        uint8_t readStatus = resp.arg[0] & 0xff;
                        uint8_t *data = resp.d.asBytes;
 
@@ -368,7 +368,8 @@ int HFiClassReader(bool loop, bool verbose) {
 
                        if (tagFound && !loop) return 1;
                } else {
-                       if (verbose) PrintAndLog("Command execute timeout");
+                       if (verbose) PrintAndLog("Error: No response from Proxmark.");
+                       break;
                }
                if (!loop) break;
        }
index 93c3ea65c37a00026b8b4d2b6012c6f23178d25d..33790230fa7324ccae4529f0400fd1f3d26154fa 100644 (file)
@@ -2672,7 +2672,7 @@ int CmdHF14AMfSniff(const char *Cmd){
                }\r
 \r
                UsbCommand resp;\r
-               if (WaitForResponseTimeoutW(CMD_ACK, &resp, 2000, false)) {\r
+               if (WaitForResponseTimeoutW(CMD_UNKNOWN, &resp, 2000, false)) {\r
                        res = resp.arg[0] & 0xff;\r
                        uint16_t traceLen = resp.arg[1];\r
                        len = resp.arg[2];\r
index 39a00d636f6b9aad530ac3e5a4c3cbf6874cb2e6..d53620addaec52fe93ae369e4b455f1e6e0cb63f 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <stdint.h>
 #include <stdio.h>
+#include <string.h>
 #include "comms.h"
 #include "usb_cmd.h"
 #include "cmdmain.h"
index b0d96f1320f422848b48c74c7d0ba5b55ef188f6..caf33db6a886f76103ae1318f333423d3114486e 100644 (file)
@@ -10,6 +10,7 @@
 #include "cmdsmartcard.h"
 
 #include <ctype.h>
+#include <string.h>
 
 #include "ui.h"
 #include "cmdparser.h"
index 5af53715e9fa27470ca934dae87e968553ae0a2a..b3b85fd2dad016ba1a7a518aecb1ca42d145109a 100644 (file)
 
 #include "comms.h"
 
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
 #include <pthread.h>
-#if defined(__linux__) && !defined(NO_UNLINK)
-#include <unistd.h>            // for unlink()
-#endif
+#include <inttypes.h>
+#include <time.h>
+
 #include "uart.h"
 #include "ui.h"
 #include "common.h"
@@ -31,7 +34,6 @@ static bool offline;
 
 typedef struct {
        bool run; // If TRUE, continue running the uart_communication thread
-       bool block_after_ACK; // if true, block after receiving an ACK package
 } communication_arg_t;
 
 static communication_arg_t conn;
@@ -45,6 +47,9 @@ static pthread_cond_t txBufferSig = PTHREAD_COND_INITIALIZER;
 
 // Used by UsbReceiveCommand as a ring buffer for messages that are yet to be
 // processed by a command handler (WaitForResponse{,Timeout})
+#define CMD_BUFFER_SIZE 50
+#define CMD_BUFFER_CHECK_TIME 10 // maximum time (in ms) to wait in getCommand()
+
 static UsbCommand rxBuffer[CMD_BUFFER_SIZE];
 
 // Points to the next empty position to write to
@@ -55,6 +60,7 @@ static int cmd_tail = 0;
 
 // to lock rxBuffer operations from different threads
 static pthread_mutex_t rxBufferMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t rxBufferSig = PTHREAD_COND_INITIALIZER;
 
 // These wrappers are required because it is not possible to access a static
 // global variable outside of the context of a single file.
@@ -69,17 +75,17 @@ bool IsOffline() {
 
 void SendCommand(UsbCommand *c) {
        #ifdef COMMS_DEBUG
-       printf("Sending %04x cmd\n", c->cmd);
+       printf("Sending %04" PRIx64 " cmd\n", c->cmd);
        #endif
 
        if (offline) {
                PrintAndLog("Sending bytes to proxmark failed - offline");
                return;
-    }
+       }
 
        pthread_mutex_lock(&txBufferMutex);
        /**
-       This causes hangups at times, when the pm3 unit is unresponsive or disconnected. The main console thread is alive, 
+       This causes hangups at times, when the pm3 unit is unresponsive or disconnected. The main console thread is alive,
        but comm thread just spins here. Not good.../holiman
        **/
        while (txBuffer_pending) {
@@ -101,8 +107,7 @@ void SendCommand(UsbCommand *c) {
  *  A better method could have been to have explicit command-ACKS, so we can know which ACK goes to which
  *  operation. Right now we'll just have to live with this.
  */
-void clearCommandBuffer()
-{
+void clearCommandBuffer() {
        //This is a very simple operation
        pthread_mutex_lock(&rxBufferMutex);
        cmd_tail = cmd_head;
@@ -113,11 +118,9 @@ void clearCommandBuffer()
  * @brief storeCommand stores a USB command in a circular buffer
  * @param UC
  */
-static void storeCommand(UsbCommand *command)
-{
+static void storeCommand(UsbCommand *command) {
        pthread_mutex_lock(&rxBufferMutex);
-       if( (cmd_head+1) % CMD_BUFFER_SIZE == cmd_tail)
-       {
+       if ((cmd_head + 1) % CMD_BUFFER_SIZE == cmd_tail) {
                // If these two are equal, we're about to overwrite in the
                // circular buffer.
                PrintAndLog("WARNING: Command buffer about to overwrite command! This needs to be fixed!");
@@ -127,7 +130,8 @@ static void storeCommand(UsbCommand *command)
        UsbCommand* destination = &rxBuffer[cmd_head];
        memcpy(destination, command, sizeof(UsbCommand));
 
-       cmd_head = (cmd_head +1) % CMD_BUFFER_SIZE; //increment head and wrap
+       cmd_head = (cmd_head + 1) % CMD_BUFFER_SIZE; //increment head and wrap
+       pthread_cond_signal(&rxBufferSig); // tell main thread that a new command can be retreived
        pthread_mutex_unlock(&rxBufferMutex);
 }
 
@@ -135,21 +139,32 @@ static void storeCommand(UsbCommand *command)
 /**
  * @brief getCommand gets a command from an internal circular buffer.
  * @param response location to write command
- * @return 1 if response was returned, 0 if nothing has been received
+ * @return 1 if response was returned, 0 if nothing has been received in time
  */
-static int getCommand(UsbCommand* response)
-{
+static int getCommand(UsbCommand* response, uint32_t ms_timeout) {
+
+       struct timespec end_time;
+       clock_gettime(CLOCK_REALTIME, &end_time);
+       end_time.tv_sec += ms_timeout / 1000;
+       end_time.tv_nsec += (ms_timeout % 1000) * 1000000;
+       if (end_time.tv_nsec > 1000000000) {
+               end_time.tv_nsec -= 1000000000;
+               end_time.tv_sec += 1;
+       }
        pthread_mutex_lock(&rxBufferMutex);
-       //If head == tail, there's nothing to read, or if we just got initialized
-       if (cmd_head == cmd_tail){
+       int res = 0;
+       while (cmd_head == cmd_tail && !res) {
+               res = pthread_cond_timedwait(&rxBufferSig, &rxBufferMutex, &end_time);
+       }
+       if (res) { // timeout
                pthread_mutex_unlock(&rxBufferMutex);
                return 0;
        }
 
-       //Pick out the next unread command
+       // Pick out the next unread command
        UsbCommand* last_unread = &rxBuffer[cmd_tail];
        memcpy(response, last_unread, sizeof(UsbCommand));
-       //Increment tail - this is a circular buffer, so modulo buffer size
+       // Increment tail - this is a circular buffer, so modulo buffer size
        cmd_tail = (cmd_tail + 1) % CMD_BUFFER_SIZE;
 
        pthread_mutex_unlock(&rxBufferMutex);
@@ -161,15 +176,14 @@ static int getCommand(UsbCommand* response)
 // Entry point into our code: called whenever we received a packet over USB.
 // Handle debug commands directly, store all other commands in circular buffer.
 //----------------------------------------------------------------------------------
-static void UsbCommandReceived(UsbCommand *UC)
-{
-       switch(UC->cmd) {
+static void UsbCommandReceived(UsbCommand *UC) {
+       switch (UC->cmd) {
                // First check if we are handling a debug message
                case CMD_DEBUG_PRINT_STRING: {
                        char s[USB_CMD_DATA_SIZE+1];
                        memset(s, 0x00, sizeof(s));
-                       size_t len = MIN(UC->arg[0],USB_CMD_DATA_SIZE);
-                       memcpy(s,UC->d.asBytes,len);
+                       size_t len = MIN(UC->arg[0], USB_CMD_DATA_SIZE);
+                       memcpy(s, UC->d.asBytes,len);
                        PrintAndLog("#db# %s", s);
                        return;
                } break;
@@ -180,64 +194,103 @@ static void UsbCommandReceived(UsbCommand *UC)
                } break;
 
                default:
-                       storeCommand(UC);
+                       storeCommand(UC);
                        break;
        }
 
 }
 
 
+static bool receive_from_serial(serial_port sp, uint8_t *rx_buf, size_t len, size_t *received_len) {
+       size_t bytes_read = 0;
+       *received_len = 0;
+       // we eventually need to call uart_receive several times because it may timeout in the middle of a transfer
+       while (uart_receive(sp, rx_buf + *received_len, len - *received_len, &bytes_read) && bytes_read && *received_len < len) {
+               #ifdef COMMS_DEBUG
+               if (bytes_read != len - *received_len) {
+                       printf("uart_receive() returned true but not enough bytes could be received. received: %zd, wanted to receive: %zd, already received before: %zd\n",
+                               bytes_read, len - *received_len, *received_len);
+               }
+               #endif
+               *received_len += bytes_read;
+               bytes_read = 0;
+       }
+       return (*received_len == len);
+}
+
+
 static void
 #ifdef __has_attribute
 #if __has_attribute(force_align_arg_pointer)
-__attribute__((force_align_arg_pointer)) 
+__attribute__((force_align_arg_pointer))
 #endif
 #endif
 *uart_communication(void *targ) {
        communication_arg_t *conn = (communication_arg_t*)targ;
-       size_t rxlen;
-       UsbCommand rx;
-       UsbCommand *prx = &rx;
+       uint8_t rx[sizeof(UsbCommand)];
+       size_t rxlen = 0;
+       uint8_t *prx = rx;
+       UsbCommand *command = (UsbCommand*)rx;
+       UsbResponse *response = (UsbResponse*)rx;
 
 #if defined(__MACH__) && defined(__APPLE__)
        disableAppNap("Proxmark3 polling UART");
 #endif
 
        while (conn->run) {
-               rxlen = 0;
                bool ACK_received = false;
-               if (uart_receive(sp, (uint8_t *)prx, sizeof(UsbCommand) - (prx-&rx), &rxlen) && rxlen) {
+               prx = rx;
+               size_t bytes_to_read = offsetof(UsbResponse, d);  // the fixed part of a new style UsbResponse. Otherwise this will be cmd and arg[0] (64 bit each)
+               if (receive_from_serial(sp, prx, bytes_to_read, &rxlen)) {
                        prx += rxlen;
-                       if (prx-&rx < sizeof(UsbCommand)) {
-                               continue;
-                       }
-                       UsbCommandReceived(&rx);
-                       if (rx.cmd == CMD_ACK) {
-                               ACK_received = true;
+                       if (response->cmd & CMD_VARIABLE_SIZE_FLAG) { // new style response with variable size
+#ifdef COMMS_DEBUG
+                               PrintAndLog("received new style response %04" PRIx16 ", datalen = %zd, arg[0] = %08" PRIx32 ", arg[1] = %08" PRIx32 ", arg[2] = %08" PRIx32,
+                                       response->cmd, response->datalen, response->arg[0], response->arg[1], response->arg[2]);
+#endif
+                               bytes_to_read = response->datalen;
+                               if (receive_from_serial(sp, prx, bytes_to_read, &rxlen)) {
+                                       UsbCommand resp;
+                                       resp.cmd = response->cmd & ~CMD_VARIABLE_SIZE_FLAG;  // remove the flag
+                                       resp.arg[0] = response->arg[0];
+                                       resp.arg[1] = response->arg[1];
+                                       resp.arg[2] = response->arg[2];
+                                       memcpy(&resp.d.asBytes, &response->d.asBytes, response->datalen);
+                                       UsbCommandReceived(&resp);
+                                       if (resp.cmd == CMD_ACK) {
+                                               ACK_received = true;
+                                       }
+                               }
+                       } else { // old style response uses same data structure as commands. Fixed size.
+#ifdef COMMS_DEBUG
+                               PrintAndLog("received old style response %016" PRIx64 ", arg[0] = %016" PRIx64, command->cmd, command->arg[0]);
+#endif
+                               bytes_to_read = sizeof(UsbCommand) - bytes_to_read;
+                               if (receive_from_serial(sp, prx, bytes_to_read, &rxlen)) {
+                                       UsbCommandReceived(command);
+                                       if (command->cmd == CMD_ACK) {
+                                               ACK_received = true;
+                                       }
+                               }
                        }
                }
-               prx = &rx;
 
-               
                pthread_mutex_lock(&txBufferMutex);
-
-               if (conn->block_after_ACK) {
-                       // if we just received an ACK, wait here until a new command is to be transmitted
-                       if (ACK_received) {
-                               while (!txBuffer_pending) {
-                                       pthread_cond_wait(&txBufferSig, &txBufferMutex);
-                               }
+               // if we received an ACK the PM has done its job and waits for another command.
+               // We therefore can wait here as well until a new command is to be transmitted.
+               // The advantage is that the next command will be transmitted immediately without the need to wait for a receive timeout
+               if (ACK_received) {
+                       while (!txBuffer_pending) {
+                               pthread_cond_wait(&txBufferSig, &txBufferMutex);
                        }
                }
-                               
-               if(txBuffer_pending) {
+               if (txBuffer_pending) {
                        if (!uart_send(sp, (uint8_t*) &txBuffer, sizeof(UsbCommand))) {
                                PrintAndLog("Sending bytes to proxmark failed");
                        }
                        txBuffer_pending = false;
-                       pthread_cond_signal(&txBufferSig); // tell main thread that txBuffer is empty
                }
-
+               pthread_cond_signal(&txBufferSig); // tell main thread that txBuffer is empty
                pthread_mutex_unlock(&txBufferMutex);
        }
 
@@ -262,21 +315,30 @@ __attribute__((force_align_arg_pointer))
  * @param show_warning display message after 2 seconds
  * @return true if command was returned, otherwise false
  */
-bool GetFromBigBuf(uint8_t *dest, int bytes, int start_index, UsbCommand *response, size_t ms_timeout, bool show_warning)
-{
-       UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
-       SendCommand(&c);
+bool GetFromBigBuf(uint8_t *dest, int bytes, int start_index, UsbCommand *response, size_t ms_timeout, bool show_warning) {
 
        uint64_t start_time = msclock();
 
+       UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
+       SendCommand(&c);
+
        UsbCommand resp;
-       if (response == NULL) {
+       if (response == NULL) {
                response = &resp;
        }
 
        int bytes_completed = 0;
-       while(true) {
-               if (getCommand(response)) {
+       while (true) {
+               if (msclock() - start_time > ms_timeout) {
+                       break; // timeout
+               }
+               if (msclock() - start_time > 2000 && show_warning) {
+                       // 2 seconds elapsed (but this doesn't mean the timeout was exceeded)
+                       PrintAndLog("Waiting for a response from the proxmark...");
+                       PrintAndLog("You can cancel this operation by pressing the pm3 button");
+                       show_warning = false;
+               }
+               if (getCommand(response, CMD_BUFFER_CHECK_TIME)) {
                        if (response->cmd == CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) {
                                int copy_bytes = MIN(bytes - bytes_completed, response->arg[1]);
                                memcpy(dest + response->arg[0], response->d.asBytes, copy_bytes);
@@ -285,35 +347,30 @@ bool GetFromBigBuf(uint8_t *dest, int bytes, int start_index, UsbCommand *respon
                                return true;
                        }
                }
-
-               if (msclock() - start_time > ms_timeout) {
-                       break;
-               }
-
-               if (msclock() - start_time > 2000 && show_warning) {
-                       PrintAndLog("Waiting for a response from the proxmark...");
-                       PrintAndLog("You can cancel this operation by pressing the pm3 button");
-                       show_warning = false;
-               }
        }
 
        return false;
 }
 
-       
-bool GetFromFpgaRAM(uint8_t *dest, int bytes)
-{
-       UsbCommand c = {CMD_HF_PLOT, {0, 0, 0}};
-       SendCommand(&c);
+
+bool GetFromFpgaRAM(uint8_t *dest, int bytes) {
 
        uint64_t start_time = msclock();
 
+       UsbCommand c = {CMD_HF_PLOT, {0, 0, 0}};
+       SendCommand(&c);
+
        UsbCommand response;
-       
+
        int bytes_completed = 0;
        bool show_warning = true;
-       while(true) {
-               if (getCommand(&response)) {
+       while (true) {
+               if (msclock() - start_time > 2000 && show_warning) {
+                       PrintAndLog("Waiting for a response from the proxmark...");
+                       PrintAndLog("You can cancel this operation by pressing the pm3 button");
+                       show_warning = false;
+               }
+               if (getCommand(&response, CMD_BUFFER_CHECK_TIME)) {
                        if (response.cmd == CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) {
                                int copy_bytes = MIN(bytes - bytes_completed, response.arg[1]);
                                memcpy(dest + response.arg[0], response.d.asBytes, copy_bytes);
@@ -322,19 +379,13 @@ bool GetFromFpgaRAM(uint8_t *dest, int bytes)
                                return true;
                        }
                }
-
-               if (msclock() - start_time > 2000 && show_warning) {
-                       PrintAndLog("Waiting for a response from the proxmark...");
-                       PrintAndLog("You can cancel this operation by pressing the pm3 button");
-                       show_warning = false;
-               }
        }
 
        return false;
 }
 
 
-bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode) {
+bool OpenProxmark(void *port, bool wait_for_port, int timeout) {
        char *portname = (char *)port;
        if (!wait_for_port) {
                sp = uart_open(portname);
@@ -347,7 +398,7 @@ bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode)
                        msleep(1000);
                        printf(".");
                        fflush(stdout);
-               } while(++openCount < timeout && (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT));
+               } while (++openCount < timeout && (sp == INVALID_SERIAL_PORT || sp == CLAIMED_SERIAL_PORT));
                printf("\n");
        }
 
@@ -366,7 +417,6 @@ bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode)
                // start the USB communication thread
                serial_port_name = portname;
                conn.run = true;
-               conn.block_after_ACK = flash_mode;
                pthread_create(&USB_communication_thread, NULL, &uart_communication, &conn);
                return true;
        }
@@ -394,15 +444,6 @@ void CloseProxmark(void) {
                uart_close(sp);
        }
 
-#if defined(__linux__) && !defined(NO_UNLINK)
-       // Fix for linux, it seems that it is extremely slow to release the serial port file descriptor /dev/*
-       //
-       // This may be disabled at compile-time with -DNO_UNLINK (used for a JNI-based serial port on Android).
-       if (serial_port_name) {
-               unlink(serial_port_name);
-       }
-#endif
-
        // Clean up our state
        sp = NULL;
        serial_port_name = NULL;
@@ -430,30 +471,28 @@ bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeo
        printf("Waiting for %04x cmd\n", cmd);
        #endif
 
+       uint64_t start_time = msclock();
+
        if (response == NULL) {
                response = &resp;
        }
 
-       uint64_t start_time = msclock();
-
        // Wait until the command is received
        while (true) {
-               while(getCommand(response)) {
-                       if (cmd == CMD_UNKNOWN || response->cmd == cmd) {
-                               return true;
-                       }
-               }
-
-               if (msclock() - start_time > ms_timeout) {
-                       break;
+               if (ms_timeout != -1 && msclock() > start_time + ms_timeout) {
+                       break; // timeout
                }
-
                if (msclock() - start_time > 2000 && show_warning) {
                        // 2 seconds elapsed (but this doesn't mean the timeout was exceeded)
                        PrintAndLog("Waiting for a response from the proxmark...");
                        PrintAndLog("You can cancel this operation by pressing the pm3 button");
                        show_warning = false;
                }
+               if (getCommand(response, CMD_BUFFER_CHECK_TIME)) {
+                       if (cmd == CMD_UNKNOWN || response->cmd == cmd) {
+                               return true;
+                       }
+               }
        }
        return false;
 }
index 65294695bf500a95a2ec2602ccb1b6585adf472e..649576041921d9091b02962275e3fc2338186f69 100644 (file)
@@ -9,32 +9,24 @@
 // Code for communicating with the proxmark3 hardware.
 //-----------------------------------------------------------------------------
 
-#ifndef COMMS_H_
-#define COMMS_H_
+#ifndef COMMS_H__
+#define COMMS_H__
 
+#include <stddef.h>
+#include <stdint.h>
 #include <stdbool.h>
-#include <pthread.h>
-
 #include "usb_cmd.h"
-#include "uart.h"
-
-#ifndef CMD_BUFFER_SIZE
-#define CMD_BUFFER_SIZE 50
-#endif
-
-void SetOffline(bool new_offline);
-bool IsOffline();
-
-bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode);
-void CloseProxmark(void);
-
-void SendCommand(UsbCommand *c);
-
-void clearCommandBuffer();
-bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning);
-bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout);
-bool WaitForResponse(uint32_t cmd, UsbCommand* response);
-bool GetFromBigBuf(uint8_t *dest, int bytes, int start_index, UsbCommand *response, size_t ms_timeout, bool show_warning);
-bool GetFromFpgaRAM(uint8_t *dest, int bytes);
 
-#endif // COMMS_H_
+extern void SetOffline(bool new_offline);
+extern bool IsOffline();
+extern bool OpenProxmark(void *port, bool wait_for_port, int timeout);
+extern void CloseProxmark(void);
+extern void SendCommand(UsbCommand *c);
+extern void clearCommandBuffer();
+extern bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeout, bool show_warning);
+extern bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout);
+extern bool WaitForResponse(uint32_t cmd, UsbCommand* response);
+extern bool GetFromBigBuf(uint8_t *dest, int bytes, int start_index, UsbCommand *response, size_t ms_timeout, bool show_warning);
+extern bool GetFromFpgaRAM(uint8_t *dest, int bytes);
+
+#endif // COMMS_H__
index 9a443cb84fce8df45ee0ec70ca3d6e9b26753b36..f3d2f420934a87c0282571502ebbcc63a536e430 100644 (file)
@@ -185,9 +185,9 @@ static int check_segs(flash_file_t *ctx, int can_write_bl) {
        return 0;
 }
 
+
 // Load an ELF file and prepare it for flashing
-int flash_load(flash_file_t *ctx, const char *name, bool can_write_bl)
-{
+int flash_load(flash_file_t *ctx, const char *name, bool can_write_bl) {
        FILE *fd = NULL;
        Elf32_Ehdr ehdr;
        Elf32_Phdr *phdrs = NULL;
@@ -267,9 +267,9 @@ fail:
        return -1;
 }
 
+
 // Get the state of the proxmark, backwards compatible
-static int get_proxmark_state(uint32_t *state)
-{
+static int get_proxmark_state(uint32_t *state) {
        UsbCommand c = {0};
        c.cmd = CMD_DEVICE_INFO;
        SendCommand(&c);
@@ -300,9 +300,9 @@ static int get_proxmark_state(uint32_t *state)
        return 0;
 }
 
+
 // Enter the bootloader to be able to start flashing
-static int enter_bootloader(char *serial_port_name)
-{
+static int enter_bootloader(char *serial_port_name) {
        uint32_t state;
 
        if (get_proxmark_state(&state) < 0)
@@ -314,7 +314,7 @@ static int enter_bootloader(char *serial_port_name)
        }
 
        if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
-               fprintf(stderr,"Entering bootloader...\n");
+               fprintf(stderr, "Entering bootloader...\n");
                UsbCommand c;
                memset(&c, 0, sizeof (c));
 
@@ -336,7 +336,9 @@ static int enter_bootloader(char *serial_port_name)
                msleep(100);
                CloseProxmark();
 
-               bool opened = OpenProxmark(serial_port_name, true, 120, true);   // wait for 2 minutes
+               msleep(1000); // wait for OS to detect device disconnect.
+
+               bool opened = OpenProxmark(serial_port_name, true, 120);   // wait for 2 minutes
                if (opened) {
                        fprintf(stderr," Found.\n");
                        return 0;
@@ -350,6 +352,7 @@ static int enter_bootloader(char *serial_port_name)
        return -1;
 }
 
+
 static int wait_for_ack(void)
 {
        UsbCommand ack;
@@ -361,11 +364,11 @@ static int wait_for_ack(void)
        return 0;
 }
 
+
 // Go into flashing mode
 int flash_start_flashing(int enable_bl_writes,char *serial_port_name)
 {
        uint32_t state;
-
        if (enter_bootloader(serial_port_name) < 0)
                return -1;
 
index a008f7bc9d85c82cb3dac55a723e6dbac83e2a04..d7fa0b5e866ee098ed0dbb79fc86d69b8f19f281 100644 (file)
@@ -17,7 +17,7 @@
 #include "flash.h"
 #include "comms.h"
 #include "usb_cmd.h"
-
+#include "uart.h"
 
 void cmd_debug(UsbCommand* UC) {
   //  Debug
@@ -83,7 +83,7 @@ int main(int argc, char **argv)
 
        char* serial_port_name = argv[1];
 
-       if (!OpenProxmark(serial_port_name, true, 120, true)) {   // wait for 2 minutes
+       if (!OpenProxmark(serial_port_name, true, 120)) {   // wait for 2 minutes
                fprintf(stderr, "Could not find Proxmark on %s.\n\n", serial_port_name);
                return -1;
        } else {
index 7b7107105aa92b9ff000b1221b6cabc4d578ba1a..bc53e1fe8731f88ba6363f564c53af1d12f57574 100644 (file)
@@ -1164,7 +1164,7 @@ int DetectClassicPrng(void){
 
        clearCommandBuffer();
        SendCommand(&c);
-       if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
+       if (!WaitForResponseTimeout(CMD_NACK, &resp, 2000)) {
         PrintAndLog("PRNG UID: Reply timeout.");
                return -1;
        }
index fda9f313b3f6876f5c2fe19a8ccbbcf73af651ce..fb17d13d13ce94501a35cb3f14145504ce6b5868 100644 (file)
@@ -28,7 +28,7 @@
 #include "cmdhw.h"
 #include "whereami.h"
 #include "comms.h"
-
+#include "uart.h"
 
 void
 #ifdef __has_attribute
@@ -286,7 +286,7 @@ int main(int argc, char* argv[]) {
        set_my_executable_path();
 
        // try to open USB connection to Proxmark
-       usb_present = OpenProxmark(argv[1], waitCOMPort, 20, false);
+       usb_present = OpenProxmark(argv[1], waitCOMPort, 20);
 
 #ifdef HAVE_GUI
 #ifdef _WIN32
@@ -309,8 +309,10 @@ int main(int argc, char* argv[]) {
        main_loop(script_cmds_file, script_cmd, usb_present);
 #endif 
 
-       // Clean up the port
+       // Switch off field and clean up the port
        if (usb_present) {
+               UsbCommand c = {CMD_FPGA_MAJOR_MODE_OFF};
+               SendCommand(&c);
                CloseProxmark();
        }
 
index 85a788e97a964233382c193e3f5948113e6e6d0f..1ad5d214dace12714c2108ebfb7aebd7ce0a87d8 100644 (file)
@@ -14,6 +14,7 @@
 #include <lua.h>
 #include <lualib.h>
 #include <lauxlib.h>
+#include <string.h>
 #include "proxmark3.h"
 #include "comms.h"
 #include "usb_cmd.h"
diff --git a/common/cmd.c b/common/cmd.c
deleted file mode 100644 (file)
index 0c3ecc1..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*\r
- * Proxmark send and receive commands\r
- *\r
- * Copyright (c) 2012, Roel Verdult\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- * 1. Redistributions of source code must retain the above copyright\r
- * notice, this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the\r
- * documentation and/or other materials provided with the distribution.\r
- * 3. Neither the name of the copyright holders nor the\r
- * names of its contributors may be used to endorse or promote products\r
- * derived from this software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY\r
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY\r
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- *\r
- * @file cmd.c\r
- * @brief\r
- */\r
-\r
-#include "cmd.h"\r
-#include "string.h"\r
-#include "proxmark3.h"\r
-\r
-bool cmd_receive(UsbCommand* cmd) {\r
\r
-  // Check if there is a usb packet available\r
-  if (!usb_poll()) return false;\r
-  \r
-  // Try to retrieve the available command frame\r
-  size_t rxlen = usb_read((byte_t*)cmd,sizeof(UsbCommand));\r
-\r
-  // Check if the transfer was complete\r
-  if (rxlen != sizeof(UsbCommand)) return false;\r
-  \r
-  // Received command successfully\r
-  return true;\r
-}\r
-\r
-bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len) {\r
-  UsbCommand txcmd;\r
-\r
-  for (size_t i=0; i<sizeof(UsbCommand); i++) {\r
-    ((byte_t*)&txcmd)[i] = 0x00;\r
-  }\r
-  \r
-  // Compose the outgoing command frame\r
-  txcmd.cmd = cmd;\r
-  txcmd.arg[0] = arg0;\r
-  txcmd.arg[1] = arg1; \r
-  txcmd.arg[2] = arg2;\r
-\r
-  // Add the (optional) content to the frame, with a maximum size of USB_CMD_DATA_SIZE\r
-  if (data && len) {\r
-    len = MIN(len,USB_CMD_DATA_SIZE);\r
-    for (size_t i=0; i<len; i++) {\r
-      txcmd.d.asBytes[i] = ((byte_t*)data)[i];\r
-    }\r
-  }\r
-  \r
-  // Send frame and make sure all bytes are transmitted\r
-  if (usb_write((byte_t*)&txcmd,sizeof(UsbCommand)) != 0) return false;\r
-  \r
-  return true;\r
-}\r
-\r
-\r
diff --git a/common/cmd.h b/common/cmd.h
deleted file mode 100644 (file)
index bc69ff6..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*\r
- * Proxmark send and receive commands\r
- *\r
- * Copyright (c) 2010, Roel Verdult\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- * 1. Redistributions of source code must retain the above copyright\r
- * notice, this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- * notice, this list of conditions and the following disclaimer in the\r
- * documentation and/or other materials provided with the distribution.\r
- * 3. Neither the name of the copyright holders nor the\r
- * names of its contributors may be used to endorse or promote products\r
- * derived from this software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY\r
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY\r
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- *\r
- * @file cmd.h\r
- * @brief\r
- */\r
-\r
-#ifndef _PROXMARK_CMD_H_\r
-#define _PROXMARK_CMD_H_\r
-\r
-#include "common.h"\r
-#include "usb_cmd.h"\r
-#include "usb_cdc.h"\r
-\r
-bool cmd_receive(UsbCommand* cmd);\r
-bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len);\r
-\r
-#endif // _PROXMARK_CMD_H_\r
-\r
index d33bca7bcbd5dd0e0975c2742470bc47e358b364..acd16b4e704b689b8d7156d194144c6580b810ee 100644 (file)
  */\r
 \r
 #include "usb_cdc.h"\r
+\r
+#include <stddef.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+\r
+#include "common.h"\r
 #include "at91sam7s512.h"\r
 #include "config_gpio.h"\r
 \r
-\r
 #define AT91C_EP_CONTROL     0\r
 #define AT91C_EP_OUT         1\r
 #define AT91C_EP_IN          2\r
@@ -49,6 +54,7 @@
 #define STR_MANUFACTURER   0x01\r
 #define STR_PRODUCT        0x02\r
 \r
+\r
 static const char devDescriptor[] = {\r
        /* Device descriptor */\r
        0x12,      // bLength\r
@@ -67,6 +73,7 @@ static const char devDescriptor[] = {
        0x01       // bNumConfigs\r
 };\r
 \r
+\r
 static const char cfgDescriptor[] = {\r
        /* ============== CONFIGURATION 1 =========== */\r
        /* Configuration 1 descriptor */\r
@@ -157,47 +164,50 @@ static const char cfgDescriptor[] = {
        0x00    // bInterval\r
 };\r
 \r
+\r
 static const char StrDescLanguageCodes[] = {\r
-  4,                   // Length\r
-  0x03,                        // Type is string\r
-  0x09, 0x04   // supported language Code 0 = 0x0409 (English)\r
+       4,          // Length\r
+       0x03,       // Type is string\r
+       0x09, 0x04  // supported language Code 0 = 0x0409 (English)\r
 };\r
 \r
+\r
 // Note: ModemManager (Linux) ignores Proxmark3 devices by matching the\r
 // manufacturer string "proxmark.org". Don't change this.\r
 static const char StrDescManufacturer[] = {\r
-  26,                  // Length\r
-  0x03,                        // Type is string\r
-  'p', 0x00,\r
-  'r', 0x00,\r
-  'o', 0x00,\r
-  'x', 0x00,\r
-  'm', 0x00,\r
-  'a', 0x00,\r
-  'r', 0x00,\r
-  'k', 0x00,\r
-  '.', 0x00,\r
-  'o', 0x00,\r
-  'r', 0x00,\r
-  'g', 0x00\r
+       26,         // Length\r
+       0x03,       // Type is string\r
+       'p', 0x00,\r
+       'r', 0x00,\r
+       'o', 0x00,\r
+       'x', 0x00,\r
+       'm', 0x00,\r
+       'a', 0x00,\r
+       'r', 0x00,\r
+       'k', 0x00,\r
+       '.', 0x00,\r
+       'o', 0x00,\r
+       'r', 0x00,\r
+       'g', 0x00\r
 };\r
 \r
+\r
 static const char StrDescProduct[] = {\r
-  20,                  // Length\r
-  0x03,                        // Type is string\r
-  'p', 0x00,\r
-  'r', 0x00,\r
-  'o', 0x00,\r
-  'x', 0x00,\r
-  'm', 0x00,\r
-  'a', 0x00,\r
-  'r', 0x00,\r
-  'k', 0x00,\r
-  '3', 0x00\r
+       20,         // Length\r
+       0x03,       // Type is string\r
+       'p', 0x00,\r
+       'r', 0x00,\r
+       'o', 0x00,\r
+       'x', 0x00,\r
+       'm', 0x00,\r
+       'a', 0x00,\r
+       'r', 0x00,\r
+       'k', 0x00,\r
+       '3', 0x00\r
 };\r
 \r
-const char* getStringDescriptor(uint8_t idx)\r
-{\r
+\r
+static const char* getStringDescriptor(uint8_t idx) {\r
        switch (idx) {\r
                case STR_LANGUAGE_CODES:\r
                        return StrDescLanguageCodes;\r
@@ -210,29 +220,31 @@ const char* getStringDescriptor(uint8_t idx)
        }\r
 }\r
 \r
+\r
 // Bitmap for all status bits in CSR which must be written as 1 to cause no effect\r
-#define REG_NO_EFFECT_1_ALL      AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1 \\r
-                                |AT91C_UDP_STALLSENT   | AT91C_UDP_RXSETUP \\r
-                                |AT91C_UDP_TXCOMP\r
+#define REG_NO_EFFECT_1_ALL     (AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1 | AT91C_UDP_STALLSENT | AT91C_UDP_RXSETUP | AT91C_UDP_TXCOMP)\r
+\r
 \r
 // Clear flags in the UDP_CSR register\r
 #define UDP_CLEAR_EP_FLAGS(endpoint, flags) { \\r
        volatile unsigned int reg; \\r
-       reg = pUdp->UDP_CSR[(endpoint)]; \\r
+       reg = AT91C_BASE_UDP->UDP_CSR[(endpoint)]; \\r
        reg |= REG_NO_EFFECT_1_ALL; \\r
        reg &= ~(flags); \\r
-       pUdp->UDP_CSR[(endpoint)] = reg; \\r
-} \r
+       AT91C_BASE_UDP->UDP_CSR[(endpoint)] = reg; \\r
+}\r
+\r
 \r
 // Set flags in the UDP_CSR register\r
 #define UDP_SET_EP_FLAGS(endpoint, flags) { \\r
        volatile unsigned int reg; \\r
-       reg = pUdp->UDP_CSR[(endpoint)]; \\r
+       reg = AT91C_BASE_UDP->UDP_CSR[(endpoint)]; \\r
        reg |= REG_NO_EFFECT_1_ALL; \\r
        reg |= (flags); \\r
-       pUdp->UDP_CSR[(endpoint)] = reg; \\r
+       AT91C_BASE_UDP->UDP_CSR[(endpoint)] = reg; \\r
 }\r
 \r
+\r
 /* USB standard request codes */\r
 #define STD_GET_STATUS_ZERO           0x0080\r
 #define STD_GET_STATUS_INTERFACE      0x0081\r
@@ -260,6 +272,7 @@ const char* getStringDescriptor(uint8_t idx)
 #define SET_LINE_CODING               0x2021\r
 #define SET_CONTROL_LINE_STATE        0x2221\r
 \r
+\r
 typedef struct {\r
        unsigned int dwDTERRate;\r
        char bCharFormat;\r
@@ -267,19 +280,17 @@ typedef struct {
        char bDataBits;\r
 } AT91S_CDC_LINE_CODING, *AT91PS_CDC_LINE_CODING;\r
 \r
-AT91S_CDC_LINE_CODING line = {\r
+\r
+static AT91S_CDC_LINE_CODING line = {\r
        115200, // baudrate\r
        0,      // 1 Stop Bit\r
        0,      // None Parity\r
        8};     // 8 Data bits\r
 \r
 \r
-void AT91F_CDC_Enumerate();\r
-\r
-AT91PS_UDP pUdp = AT91C_BASE_UDP;\r
-byte_t btConfiguration = 0;\r
-byte_t btConnection    = 0;\r
-byte_t btReceiveBank   = AT91C_UDP_RX_DATA_BK0;\r
+static uint8_t btConfiguration = 0;\r
+static uint8_t btConnection    = 0;\r
+static uint8_t btReceiveBank   = AT91C_UDP_RX_DATA_BK0;\r
 \r
 \r
 //*----------------------------------------------------------------------------\r
@@ -291,8 +302,8 @@ void usb_disable() {
        AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU;\r
 \r
        // Clear all lingering interrupts\r
-       if(pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES) {\r
-               pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;\r
+       if (AT91C_BASE_UDP->UDP_ISR & AT91C_UDP_ENDBUSRES) {\r
+               AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES;\r
        }\r
 }\r
 \r
@@ -322,7 +333,7 @@ void usb_enable() {
        usb_disable();\r
 \r
        // Wait for a short while\r
-       for (volatile size_t i=0; i<0x100000; i++);\r
+       for (volatile size_t i = 0; i < 0x100000; i++);\r
 \r
        // Reconnect USB reconnect\r
        AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU;\r
@@ -331,127 +342,16 @@ void usb_enable() {
 \r
 \r
 //*----------------------------------------------------------------------------\r
-//* \fn    usb_check\r
-//* \brief Test if the device is configured and handle enumeration\r
-//*----------------------------------------------------------------------------\r
-bool usb_check() {\r
-       AT91_REG isr = pUdp->UDP_ISR;\r
-\r
-       if (isr & AT91C_UDP_ENDBUSRES) {\r
-               pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;\r
-               // reset all endpoints\r
-               pUdp->UDP_RSTEP  = (unsigned int)-1;\r
-               pUdp->UDP_RSTEP  = 0;\r
-               // Enable the function\r
-               pUdp->UDP_FADDR = AT91C_UDP_FEN;\r
-               // Configure endpoint 0\r
-               pUdp->UDP_CSR[AT91C_EP_CONTROL] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);\r
-       } else if (isr & AT91C_UDP_EPINT0) {\r
-               pUdp->UDP_ICR = AT91C_UDP_EPINT0;\r
-               AT91F_CDC_Enumerate();\r
-       }\r
-       return (btConfiguration) ? true : false;\r
-}\r
-\r
-\r
-bool usb_poll()\r
-{\r
-       if (!usb_check()) return false;\r
-       return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank);\r
-}\r
-\r
-\r
-/**\r
-       In github PR #129, some users appears to get a false positive from\r
-       usb_poll, which returns true, but the usb_read operation\r
-       still returns 0.\r
-       This check is basically the same as above, but also checks\r
-       that the length available to read is non-zero, thus hopefully fixes the\r
-       bug.\r
-**/\r
-bool usb_poll_validate_length()\r
-{\r
-       if (!usb_check()) return false;\r
-       if (!(pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank)) return false;\r
-       return (pUdp->UDP_CSR[AT91C_EP_OUT] >> 16) >  0;\r
-}\r
-\r
-//*----------------------------------------------------------------------------\r
-//* \fn    usb_read\r
-//* \brief Read available data from Endpoint OUT\r
-//*----------------------------------------------------------------------------\r
-uint32_t usb_read(byte_t* data, size_t len) {\r
-       byte_t bank = btReceiveBank;\r
-       uint32_t packetSize, nbBytesRcv = 0;\r
-       uint32_t time_out = 0;\r
-  \r
-       while (len)  {\r
-               if (!usb_check()) break;\r
-\r
-               if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) {\r
-                       packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len);\r
-                       len -= packetSize;\r
-                       while(packetSize--)\r
-                               data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT];\r
-                       UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT, bank);\r
-                       if (bank == AT91C_UDP_RX_DATA_BK0) {\r
-                               bank = AT91C_UDP_RX_DATA_BK1;\r
-                       } else {\r
-                               bank = AT91C_UDP_RX_DATA_BK0;\r
-                       }\r
-               }\r
-               if (time_out++ == 0x1fff) break;\r
-       }\r
-\r
-       btReceiveBank = bank;\r
-       return nbBytesRcv;\r
-}\r
-\r
-\r
-//*----------------------------------------------------------------------------\r
-//* \fn    usb_write\r
-//* \brief Send through endpoint 2\r
+//* \fn    AT91F_USB_SendZlp\r
+//* \brief Send zero length packet through an endpoint\r
 //*----------------------------------------------------------------------------\r
-uint32_t usb_write(const byte_t* data, const size_t len) {\r
-       size_t length = len;\r
-       uint32_t cpt = 0;\r
-\r
-       if (!length) return 0;\r
-       if (!usb_check()) return 0;\r
-\r
-       // Send the first packet\r
-       cpt = MIN(length, AT91C_EP_IN_SIZE);\r
-       length -= cpt;\r
-       while (cpt--) {\r
-               pUdp->UDP_FDR[AT91C_EP_IN] = *data++;\r
-       }\r
-       UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);\r
-\r
-       while (length) {\r
-               // Fill the next bank\r
-               cpt = MIN(length, AT91C_EP_IN_SIZE);\r
-               length -= cpt;\r
-               while (cpt--) {\r
-                       pUdp->UDP_FDR[AT91C_EP_IN] = *data++;\r
-               }\r
-               // Wait for the previous bank to be sent\r
-               while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {\r
-                       if (!usb_check()) return length;\r
-               }\r
-               UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);\r
-               while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);\r
-               UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);\r
-       }\r
-\r
-       // Wait for the end of transfer\r
-       while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {\r
-               if (!usb_check()) return length;\r
-       }\r
-\r
-       UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);\r
-       while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);\r
-\r
-       return length;\r
+static void AT91F_USB_SendZlp(uint8_t endpoint) {\r
+       UDP_SET_EP_FLAGS(endpoint, AT91C_UDP_TXPKTRDY);\r
+       while (!(AT91C_BASE_UDP->UDP_CSR[endpoint] & AT91C_UDP_TXCOMP))\r
+               /* wait */;\r
+       UDP_CLEAR_EP_FLAGS(endpoint, AT91C_UDP_TXCOMP);\r
+       while (AT91C_BASE_UDP->UDP_CSR[endpoint] & AT91C_UDP_TXCOMP)\r
+               /* wait */;\r
 }\r
 \r
 \r
@@ -459,10 +359,7 @@ uint32_t usb_write(const byte_t* data, const size_t len) {
 //* \fn    AT91F_USB_SendData\r
 //* \brief Send Data through the control endpoint\r
 //*----------------------------------------------------------------------------\r
-unsigned int csrTab[100] = {0x00};\r
-unsigned char csrIdx = 0;\r
-\r
-static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {\r
+static void AT91F_USB_SendData(const char *pData, uint32_t length) {\r
        uint32_t cpt = 0;\r
        AT91_REG csr;\r
 \r
@@ -471,54 +368,46 @@ static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t leng
                length -= cpt;\r
 \r
                while (cpt--)\r
-                       pUdp->UDP_FDR[0] = *pData++;\r
+                       AT91C_BASE_UDP->UDP_FDR[0] = *pData++;\r
 \r
-               if (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {\r
+               if (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {\r
                        UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);\r
-                       while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP);\r
+                       while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)\r
+                               /* wait */;\r
                }\r
 \r
                UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY);\r
                do {\r
-                       csr = pUdp->UDP_CSR[AT91C_EP_CONTROL];\r
+                       csr = AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL];\r
 \r
                        // Data IN stage has been stopped by a status OUT\r
                        if (csr & AT91C_UDP_RX_DATA_BK0) {\r
                                UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0);\r
                                return;\r
                        }\r
-               } while ( !(csr & AT91C_UDP_TXCOMP) );\r
+               } while (!(csr & AT91C_UDP_TXCOMP));\r
 \r
        } while (length);\r
 \r
-       if (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {\r
+       if (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {\r
                UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);\r
-               while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP);\r
+               while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)\r
+                       /* wait */;\r
        }\r
 }\r
 \r
 \r
-//*----------------------------------------------------------------------------\r
-//* \fn    AT91F_USB_SendZlp\r
-//* \brief Send zero length packet through the control endpoint\r
-//*----------------------------------------------------------------------------\r
-void AT91F_USB_SendZlp(AT91PS_UDP pUdp) {\r
-       UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY);\r
-       while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) );\r
-       UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);\r
-       while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP);\r
-}\r
-\r
-\r
 //*----------------------------------------------------------------------------\r
 //* \fn    AT91F_USB_SendStall\r
 //* \brief Stall the control endpoint\r
 //*----------------------------------------------------------------------------\r
-void AT91F_USB_SendStall(AT91PS_UDP pUdp) {\r
+static void AT91F_USB_SendStall(void) {\r
        UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL);\r
-       while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_ISOERROR) );\r
+       while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_ISOERROR))\r
+               /* wait */;\r
        UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);\r
-       while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR));\r
+       while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR))\r
+               /* wait */;\r
 }\r
 \r
 \r
@@ -526,136 +415,349 @@ void AT91F_USB_SendStall(AT91PS_UDP pUdp) {
 //* \fn    AT91F_CDC_Enumerate\r
 //* \brief This function is a callback invoked when a SETUP packet is received\r
 //*----------------------------------------------------------------------------\r
-void AT91F_CDC_Enumerate() {\r
-       byte_t bmRequestType, bRequest;\r
+static void AT91F_CDC_Enumerate() {\r
+       uint8_t bmRequestType, bRequest;\r
        uint16_t wValue, wIndex, wLength, wStatus;\r
 \r
-       if ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP) )\r
+       if (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP))\r
                return;\r
 \r
-       bmRequestType = pUdp->UDP_FDR[AT91C_EP_CONTROL];\r
-       bRequest      = pUdp->UDP_FDR[AT91C_EP_CONTROL];\r
-       wValue        = (pUdp->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
-       wValue       |= (pUdp->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
-       wIndex        = (pUdp->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
-       wIndex       |= (pUdp->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
-       wLength       = (pUdp->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
-       wLength      |= (pUdp->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
+       bmRequestType = AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL];\r
+       bRequest      = AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL];\r
+       wValue        = (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
+       wValue       |= (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
+       wIndex        = (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
+       wIndex       |= (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
+       wLength       = (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
+       wLength      |= (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
 \r
-       if (bmRequestType & 0x80) {     // Data Phase Transfer Direction Device to Host\r
+       if (bmRequestType & 0x80) { // Data Phase Transfer Direction Device to Host\r
                UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_DIR);\r
-               while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_DIR) );\r
+               while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_DIR))\r
+                       /* wait */;\r
        }\r
        UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RXSETUP);\r
-       while ( (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP)  );\r
+       while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP)\r
+               /* wait */;\r
 \r
        // Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1\r
        switch ((bRequest << 8) | bmRequestType) {\r
        case STD_GET_DESCRIPTOR:\r
                if (wValue == 0x100)       // Return Device Descriptor\r
-                       AT91F_USB_SendData(pUdp, devDescriptor, MIN(sizeof(devDescriptor), wLength));\r
+                       AT91F_USB_SendData(devDescriptor, MIN(sizeof(devDescriptor), wLength));\r
                else if (wValue == 0x200)  // Return Configuration Descriptor\r
-                       AT91F_USB_SendData(pUdp, cfgDescriptor, MIN(sizeof(cfgDescriptor), wLength));\r
+                       AT91F_USB_SendData(cfgDescriptor, MIN(sizeof(cfgDescriptor), wLength));\r
                else if ((wValue & 0xF00) == 0x300) { // Return String Descriptor\r
                        const char *strDescriptor = getStringDescriptor(wValue & 0xff);\r
                        if (strDescriptor != NULL) {\r
-                               AT91F_USB_SendData(pUdp, strDescriptor, MIN(strDescriptor[0], wLength));\r
+                               AT91F_USB_SendData(strDescriptor, MIN(strDescriptor[0], wLength));\r
                        } else {\r
-                               AT91F_USB_SendStall(pUdp);\r
+                               AT91F_USB_SendStall();\r
                        }\r
                }\r
                else\r
-                       AT91F_USB_SendStall(pUdp);\r
+                       AT91F_USB_SendStall();\r
                break;\r
        case STD_SET_ADDRESS:\r
-               AT91F_USB_SendZlp(pUdp);\r
-               pUdp->UDP_FADDR = (AT91C_UDP_FEN | wValue);\r
-               pUdp->UDP_GLBSTATE  = (wValue) ? AT91C_UDP_FADDEN : 0;\r
+               AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
+               AT91C_BASE_UDP->UDP_FADDR = (AT91C_UDP_FEN | wValue);\r
+               AT91C_BASE_UDP->UDP_GLBSTATE  = (wValue) ? AT91C_UDP_FADDEN : 0;\r
                break;\r
        case STD_SET_CONFIGURATION:\r
                btConfiguration = wValue;\r
-               AT91F_USB_SendZlp(pUdp);\r
-               pUdp->UDP_GLBSTATE  = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;\r
-               pUdp->UDP_CSR[AT91C_EP_OUT]    = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0;\r
-               pUdp->UDP_CSR[AT91C_EP_IN]     = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN)  : 0;\r
-               pUdp->UDP_CSR[AT91C_EP_NOTIFY] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN)   : 0;\r
+               AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
+               AT91C_BASE_UDP->UDP_GLBSTATE  = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;\r
+               AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT]    = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0;\r
+               AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN]     = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN)  : 0;\r
+               AT91C_BASE_UDP->UDP_CSR[AT91C_EP_NOTIFY] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN)   : 0;\r
                break;\r
        case STD_GET_CONFIGURATION:\r
-               AT91F_USB_SendData(pUdp, (char *) &(btConfiguration), sizeof(btConfiguration));\r
+               AT91F_USB_SendData((char *) &(btConfiguration), sizeof(btConfiguration));\r
                break;\r
        case STD_GET_STATUS_ZERO:\r
-               wStatus = 0;    // Device is Bus powered, remote wakeup disabled\r
-               AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
+               wStatus = 0;    // Device is Bus powered, remote wakeup disabled\r
+               AT91F_USB_SendData((char *) &wStatus, sizeof(wStatus));\r
                break;\r
        case STD_GET_STATUS_INTERFACE:\r
-               wStatus = 0;    // reserved for future use\r
-               AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
+               wStatus = 0;    // reserved for future use\r
+               AT91F_USB_SendData((char *) &wStatus, sizeof(wStatus));\r
                break;\r
        case STD_GET_STATUS_ENDPOINT:\r
                wStatus = 0;\r
                wIndex &= 0x0F;\r
-               if ((pUdp->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= AT91C_EP_NOTIFY)) {\r
-                       wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;\r
-                       AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
-               }\r
-               else if ((pUdp->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == AT91C_EP_CONTROL)) {\r
-                       wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;\r
-                       AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
-               }\r
-               else\r
-                       AT91F_USB_SendStall(pUdp);\r
+               if ((AT91C_BASE_UDP->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= AT91C_EP_NOTIFY)) {\r
+                       wStatus = (AT91C_BASE_UDP->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;\r
+                       AT91F_USB_SendData((char *) &wStatus, sizeof(wStatus));\r
+               } else if ((AT91C_BASE_UDP->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == AT91C_EP_CONTROL)) {\r
+                       wStatus = (AT91C_BASE_UDP->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;\r
+                       AT91F_USB_SendData((char *) &wStatus, sizeof(wStatus));\r
+               } else\r
+                       AT91F_USB_SendStall();\r
                break;\r
        case STD_SET_FEATURE_ZERO:\r
-               AT91F_USB_SendStall(pUdp);\r
-           break;\r
+               AT91F_USB_SendStall();\r
+               break;\r
        case STD_SET_FEATURE_INTERFACE:\r
-               AT91F_USB_SendZlp(pUdp);\r
+               AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
                break;\r
        case STD_SET_FEATURE_ENDPOINT:\r
                wIndex &= 0x0F;\r
                if ((wValue == 0) && (wIndex >= AT91C_EP_OUT) && (wIndex <= AT91C_EP_NOTIFY)) {\r
-                       pUdp->UDP_CSR[wIndex] = 0;\r
-                       AT91F_USB_SendZlp(pUdp);\r
-               }\r
-               else\r
-                       AT91F_USB_SendStall(pUdp);\r
+                       AT91C_BASE_UDP->UDP_CSR[wIndex] = 0;\r
+                       AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
+               } else\r
+                       AT91F_USB_SendStall();\r
                break;\r
        case STD_CLEAR_FEATURE_ZERO:\r
-               AT91F_USB_SendStall(pUdp);\r
-           break;\r
+               AT91F_USB_SendStall();\r
+               break;\r
        case STD_CLEAR_FEATURE_INTERFACE:\r
-               AT91F_USB_SendZlp(pUdp);\r
+               AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
                break;\r
        case STD_CLEAR_FEATURE_ENDPOINT:\r
                wIndex &= 0x0F;\r
                if ((wValue == 0) && (wIndex >= AT91C_EP_OUT) && (wIndex <= AT91C_EP_NOTIFY)) {\r
                        if (wIndex == AT91C_EP_OUT)\r
-                               pUdp->UDP_CSR[AT91C_EP_OUT] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);\r
+                               AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);\r
                        else if (wIndex == AT91C_EP_IN)\r
-                               pUdp->UDP_CSR[AT91C_EP_IN] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);\r
+                               AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);\r
                        else if (wIndex == AT91C_EP_NOTIFY)\r
-                               pUdp->UDP_CSR[AT91C_EP_NOTIFY] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN);\r
-                       AT91F_USB_SendZlp(pUdp);\r
+                               AT91C_BASE_UDP->UDP_CSR[AT91C_EP_NOTIFY] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN);\r
+                       AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
                }\r
                else\r
-                       AT91F_USB_SendStall(pUdp);\r
+                       AT91F_USB_SendStall();\r
                break;\r
 \r
        // handle CDC class requests\r
        case SET_LINE_CODING:\r
-               while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RX_DATA_BK0) );\r
+               while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RX_DATA_BK0))\r
+                       /* wait */;\r
                UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0);\r
-               AT91F_USB_SendZlp(pUdp);\r
+               AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
                break;\r
        case GET_LINE_CODING:\r
-               AT91F_USB_SendData(pUdp, (char *) &line, MIN(sizeof(line), wLength));\r
+               AT91F_USB_SendData((char *) &line, MIN(sizeof(line), wLength));\r
                break;\r
        case SET_CONTROL_LINE_STATE:\r
                btConnection = wValue;\r
-               AT91F_USB_SendZlp(pUdp);\r
+               AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
                break;\r
        default:\r
-               AT91F_USB_SendStall(pUdp);\r
-           break;\r
+               AT91F_USB_SendStall();\r
+               break;\r
+       }\r
+}\r
+\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn    usb_check\r
+//* \brief Test if the device is configured and handle enumeration\r
+//*----------------------------------------------------------------------------\r
+static bool usb_check() {\r
+       AT91_REG isr = AT91C_BASE_UDP->UDP_ISR;\r
+\r
+       if (isr & AT91C_UDP_ENDBUSRES) {\r
+               AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES;\r
+               // reset all endpoints\r
+               AT91C_BASE_UDP->UDP_RSTEP  = (unsigned int)-1;\r
+               AT91C_BASE_UDP->UDP_RSTEP  = 0;\r
+               // Enable the function\r
+               AT91C_BASE_UDP->UDP_FADDR = AT91C_UDP_FEN;\r
+               // Configure endpoint 0\r
+               AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);\r
+       } else if (isr & AT91C_UDP_EPINT0) {\r
+               AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_EPINT0;\r
+               AT91F_CDC_Enumerate();\r
+       }\r
+       return (btConfiguration) ? true : false;\r
+}\r
+\r
+\r
+bool usb_poll() {\r
+       if (!usb_check()) return false;\r
+       return (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] & btReceiveBank);\r
+}\r
+\r
+\r
+/**\r
+       In github PR #129, some users appears to get a false positive from\r
+       usb_poll, which returns true, but the usb_read operation\r
+       still returns 0.\r
+       This check is basically the same as above, but also checks\r
+       that the length available to read is non-zero, thus hopefully fixes the\r
+       bug.\r
+**/\r
+bool usb_poll_validate_length() {\r
+       if (!usb_check()) return false;\r
+       if (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] & btReceiveBank)) return false;\r
+       return (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] >> 16) >  0;\r
+}\r
+\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn    usb_read\r
+//* \brief Read available data from Endpoint OUT\r
+//*----------------------------------------------------------------------------\r
+static uint32_t usb_read(uint8_t* data, size_t len) {\r
+       uint8_t bank = btReceiveBank;\r
+       uint32_t packetSize, nbBytesRcv = 0;\r
+       uint32_t time_out = 0;\r
+\r
+       while (len)  {\r
+               if (!usb_check()) break;\r
+\r
+               if ( AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] & bank ) {\r
+                       packetSize = MIN(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] >> 16, len);\r
+                       len -= packetSize;\r
+                       while (packetSize--)\r
+                               data[nbBytesRcv++] = AT91C_BASE_UDP->UDP_FDR[AT91C_EP_OUT];\r
+                       UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT, bank);\r
+                       if (bank == AT91C_UDP_RX_DATA_BK0) {\r
+                               bank = AT91C_UDP_RX_DATA_BK1;\r
+                       } else {\r
+                               bank = AT91C_UDP_RX_DATA_BK0;\r
+                       }\r
+               }\r
+               if (time_out++ == 0x1fff) break;\r
+       }\r
+\r
+       btReceiveBank = bank;\r
+       return nbBytesRcv;\r
+}\r
+\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn    usb_write\r
+//* \brief Send through endpoint 2\r
+//*----------------------------------------------------------------------------\r
+static uint32_t usb_write(const uint8_t* data, const size_t len) {\r
+       size_t length = len;\r
+       uint32_t cpt = 0;\r
+\r
+       if (!length) return 0;\r
+       if (!usb_check()) return 0;\r
+\r
+       // Send the first packet\r
+       cpt = MIN(length, AT91C_EP_IN_SIZE);\r
+       length -= cpt;\r
+       while (cpt--) {\r
+               AT91C_BASE_UDP->UDP_FDR[AT91C_EP_IN] = *data++;\r
+       }\r
+       UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);\r
+       while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY))\r
+               /* wait */;\r
+\r
+       while (length) {\r
+               // Fill the next bank\r
+               cpt = MIN(length, AT91C_EP_IN_SIZE);\r
+               length -= cpt;\r
+               while (cpt--) {\r
+                       AT91C_BASE_UDP->UDP_FDR[AT91C_EP_IN] = *data++;\r
+               }\r
+               // Wait for the previous bank to be sent\r
+               while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {\r
+                       if (!usb_check()) return length;\r
+               }\r
+               UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);\r
+               while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY))\r
+                       /* wait */;\r
+               UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);\r
+               while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)\r
+                       /* wait */;\r
+       }\r
+\r
+       // Wait for the end of transfer\r
+       while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {\r
+               if (!usb_check()) return length;\r
+       }\r
+       UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);\r
+       while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)\r
+               /* wait */;\r
+\r
+       if (len % AT91C_EP_IN_SIZE == 0) { // need to send a zero length packet to complete the transfer\r
+               AT91F_USB_SendZlp(AT91C_EP_IN);\r
        }\r
+\r
+       return length;\r
+}\r
+\r
+\r
+//***************************************************************************\r
+// Interface to the main program\r
+//***************************************************************************\r
+\r
+// The function to receive a command from the client via USB\r
+bool cmd_receive(UsbCommand* cmd) {\r
+\r
+       // Check if there is a usb packet available\r
+       if (!usb_poll())\r
+               return false;\r
+\r
+       // Try to retrieve the available command frame\r
+       size_t rxlen = usb_read((uint8_t*)cmd, sizeof(UsbCommand));\r
+\r
+       // Check if the transfer was complete\r
+       if (rxlen != sizeof(UsbCommand))\r
+               return false;\r
+\r
+       // Received command successfully\r
+       return true;\r
 }\r
+\r
+\r
+// The function to send a response to the client via USB\r
+bool cmd_send(uint16_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, uint16_t datalen) {\r
+\r
+       UsbResponse txcmd;\r
+\r
+       // Compose the outgoing response frame\r
+       txcmd.cmd = cmd | CMD_VARIABLE_SIZE_FLAG;\r
+       txcmd.arg[0] = arg0;\r
+       txcmd.arg[1] = arg1;\r
+       txcmd.arg[2] = arg2;\r
+\r
+       // Add the (optional) content to the frame, with a maximum size of USB_CMD_DATA_SIZE\r
+       if (data) {\r
+               datalen = MIN(datalen, USB_CMD_DATA_SIZE);\r
+               for (uint16_t i = 0; i < datalen; i++) {\r
+                       txcmd.d.asBytes[i] = ((uint8_t*)data)[i];\r
+               }\r
+               txcmd.datalen = datalen;\r
+       } else {\r
+               txcmd.datalen = 0;\r
+       }\r
+\r
+       // Send frame and make sure all bytes are transmitted\r
+       size_t tx_size = offsetof(UsbResponse, d) + datalen;\r
+       if (usb_write((uint8_t*)&txcmd, tx_size) != 0) return false;\r
+\r
+       return true;\r
+}\r
+\r
+\r
+// For compatibility only: legacy function to send a response with fixed size to the client via USB\r
+bool cmd_send_old(uint16_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, uint16_t datalen) {\r
+\r
+       UsbCommand txcmd;\r
+\r
+       // Compose the outgoing response frame\r
+       txcmd.cmd = cmd;\r
+       txcmd.arg[0] = arg0;\r
+       txcmd.arg[1] = arg1;\r
+       txcmd.arg[2] = arg2;\r
+\r
+       // Add the (optional) content to the frame, with a maximum size of USB_CMD_DATA_SIZE\r
+       if (data) {\r
+               datalen = MIN(datalen, USB_CMD_DATA_SIZE);\r
+               for (uint16_t i = 0; i < datalen; i++) {\r
+                       txcmd.d.asBytes[i] = ((uint8_t*)data)[i];\r
+               }\r
+       }\r
+\r
+       // Send frame and make sure all bytes are transmitted\r
+       if (usb_write((uint8_t*)&txcmd, sizeof(UsbCommand)) != 0) return false;\r
+\r
+       return true;\r
+}\r
+\r
index c42da8db90d1717c7c0188c84c29cb652c753d66..3fff154dbad54bf2528663a2b03787f8ee8c0bd7 100644 (file)
  * @brief\r
  */\r
 \r
-#ifndef _USB_CDC_H_\r
-#define _USB_CDC_H_\r
+#ifndef USB_CDC_H__\r
+#define USB_CDC_H__\r
 \r
-#include "common.h"\r
+#include <stddef.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include "usb_cmd.h"\r
 \r
-void usb_disable();\r
-void usb_enable();\r
-bool usb_check();\r
-bool usb_poll();\r
-bool usb_poll_validate_length();\r
-uint32_t usb_read(byte_t* data, size_t len);\r
-uint32_t usb_write(const byte_t* data, const size_t len);\r
-\r
-#endif // _USB_CDC_H_\r
+extern void usb_disable();\r
+extern void usb_enable();\r
+extern bool usb_poll();\r
+extern bool usb_poll_validate_length();\r
+extern bool cmd_receive(UsbCommand* cmd);\r
+extern bool cmd_send(uint16_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, uint16_t datalen); // new variable sized response\r
+extern bool cmd_send_old(uint16_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, uint16_t datalen); // old fixed size response\r
 \r
+#endif // USB_CDC_H__\r
index 998db64dccc7820493dbb3df1042562e7b613ef1..89a6cd7eaaabe218b038d004e2bb8de665f96440 100644 (file)
@@ -9,13 +9,9 @@
 // Interlib Definitions
 //-----------------------------------------------------------------------------
 
-#ifndef __COMMON_H
-#define __COMMON_H
+#ifndef COMMON_H__
+#define COMMON_H__
 
-#include <stddef.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <at91sam7s512.h>
 typedef unsigned char byte_t;
 
 #ifndef MIN
@@ -25,10 +21,9 @@ typedef unsigned char byte_t;
 # define MAX(a, b) (((a) > (b)) ? (a) : (b))
 #endif
 #ifndef ABS
-# define ABS(a) ( ((a)<0) ? -(a) : (a) )
+# define ABS(a) (((a) < 0) ? -(a) : (a))
 #endif
 
-
 #define RAMFUNC __attribute((long_call, section(".ramfunc")))
 
 #endif
index c588328c445b65810c1744f8b612068662783f0f..a4d164f039ce6c3f0a1b725f472f51b69f1269b6 100644 (file)
 // own protocol.
 //-----------------------------------------------------------------------------
 
-#ifndef __USB_CMD_H
-#define __USB_CMD_H
+#ifndef USB_CMD_H__
+#define USB_CMD_H__
+
 #ifdef _MSC_VER
 typedef DWORD uint32_t;
 typedef BYTE uint8_t;
 #define PACKED
-// stuff
 #else
 #include <stdint.h>
 #include <stdbool.h>
@@ -25,17 +25,29 @@ typedef BYTE uint8_t;
 
 #define USB_CMD_DATA_SIZE 512
 
+// the packets sent from client to PM3
 typedef struct {
-  uint64_t cmd;
-  uint64_t arg[3];
-  union {
-    uint8_t  asBytes[USB_CMD_DATA_SIZE];
-    uint32_t asDwords[USB_CMD_DATA_SIZE/4];
-  } d;
+       uint64_t cmd;
+       uint64_t arg[3];
+       union {
+               uint8_t  asBytes[USB_CMD_DATA_SIZE];
+               uint32_t asDwords[USB_CMD_DATA_SIZE/4];
+       } d;
 } PACKED UsbCommand;
 
+// the packets sent from PM3 to client (a smaller version of UsbCommand)
+typedef struct {
+       uint16_t cmd;
+       uint16_t datalen;
+       uint32_t arg[3];
+       union {
+               uint8_t  asBytes[USB_CMD_DATA_SIZE];
+               uint32_t asDwords[USB_CMD_DATA_SIZE/4];
+       } d;
+} PACKED UsbResponse;
+
 // A struct used to send sample-configs over USB
-typedef struct{
+typedef struct {
        uint8_t decimation;
        uint8_t bits_per_sample;
        bool averaging;
@@ -44,6 +56,7 @@ typedef struct{
        int samples_to_skip;
 } sample_config;
 
+
 // For the bootloader
 #define CMD_DEVICE_INFO                                                   0x0000
 #define CMD_SETUP_WRITE                                                   0x0001
@@ -165,7 +178,7 @@ typedef struct{
 #define CMD_ICLASS_WRITEBLOCK                                             0x0397
 #define CMD_ICLASS_EML_MEMSET                                             0x0398
 #define CMD_ICLASS_CHECK                                                  0x0399
-#define CMD_ICLASS_READCHECK                                              0x039A                                         
+#define CMD_ICLASS_READCHECK                                              0x039A
 
 // For measurements of the antenna tuning
 #define CMD_MEASURE_ANTENNA_TUNING                                        0x0400
@@ -208,7 +221,7 @@ typedef struct{
 #define CMD_MIFAREU_WRITEBL                                               0x0722
 #define CMD_MIFAREU_WRITEBL_COMPAT                                        0x0723
 #define CMD_MIFAREUC_AUTH                                                 0x0724
-//0x0725 and 0x0726 no longer used 
+//0x0725 and 0x0726 no longer used
 #define CMD_MIFAREUC_SETPWD                                               0x0727
 
 
@@ -224,15 +237,16 @@ typedef struct{
 #define CMD_HF_SNIFFER                                                    0x0800
 #define CMD_HF_PLOT                                                       0x0801
 
+#define CMD_VARIABLE_SIZE_FLAG                                            0x8000
 #define CMD_UNKNOWN                                                       0xFFFF
 
 
 // Mifare simulation flags
-#define FLAG_INTERACTIVE                (1<<0)
-#define FLAG_4B_UID_IN_DATA             (1<<1)
-#define FLAG_7B_UID_IN_DATA             (1<<2)
-#define FLAG_NR_AR_ATTACK               (1<<4)
-#define FLAG_RANDOM_NONCE               (1<<5)
+#define FLAG_INTERACTIVE                 (1<<0)
+#define FLAG_4B_UID_IN_DATA              (1<<1)
+#define FLAG_7B_UID_IN_DATA              (1<<2)
+#define FLAG_NR_AR_ATTACK                (1<<4)
+#define FLAG_RANDOM_NONCE                (1<<5)
 
 
 // iCLASS reader flags
@@ -266,19 +280,19 @@ typedef struct{
 
 // CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions:
 /* Whether a bootloader that understands the common_area is present */
-#define DEVICE_INFO_FLAG_BOOTROM_PRESENT               (1<<0)
+#define DEVICE_INFO_FLAG_BOOTROM_PRESENT            (1<<0)
 
 /* Whether a osimage that understands the common_area is present */
-#define DEVICE_INFO_FLAG_OSIMAGE_PRESENT               (1<<1)
+#define DEVICE_INFO_FLAG_OSIMAGE_PRESENT            (1<<1)
 
 /* Set if the bootloader is currently executing */
-#define DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM          (1<<2)
+#define DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM       (1<<2)
 
 /* Set if the OS is currently executing */
-#define DEVICE_INFO_FLAG_CURRENT_MODE_OS               (1<<3)
+#define DEVICE_INFO_FLAG_CURRENT_MODE_OS            (1<<3)
 
 /* Set if this device understands the extend start flash command */
-#define DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH       (1<<4)
+#define DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH    (1<<4)
 
 /* CMD_START_FLASH may have three arguments: start of area to flash,
    end of area to flash, optional magic.
index 3b563be2120c803848df7cbad01cbf5f1258cee3..c0a709cf05ee2bc0cf97b1900ca25f63fdc55e88 100644 (file)
  * @file uart.h
  */
 
-#ifndef _PM3_UART_H_
-#define _PM3_UART_H_
+#ifndef PM3_UART_H__
+#define PM3_UART_H__
 
-#include <stdio.h>
-#include <string.h>
 #include <stdlib.h>
-
 #include <stdint.h>
 #include <stdbool.h>
 
 /* Used to substitute for an example serial port path on each platform.
  */
 #ifdef _WIN32
-#define SERIAL_PORT_H  "com3"
+#define SERIAL_PORT_H   "com3"
 #elif __APPLE__
-#define SERIAL_PORT_H  "/dev/tty.usbmodem*"
+#define SERIAL_PORT_H   "/dev/tty.usbmodem*"
 #else
-#define SERIAL_PORT_H  "/dev/ttyACM0"
+#define SERIAL_PORT_H   "/dev/ttyACM0"
 #endif
 
 /* serial_port is declared as a void*, which you should cast to whatever type
@@ -69,11 +66,11 @@ typedef void* serial_port;
  *
  * On errors, this method returns INVALID_SERIAL_PORT or CLAIMED_SERIAL_PORT.
  */
-serial_port uart_open(const char* pcPortName);
+extern serial_port uart_open(const char* pcPortName);
 
 /* Closes the given port.
  */
-void uart_close(const serial_port sp);
+extern void uart_close(const serial_port sp);
 
 /* Reads from the given serial port for up to 30ms.
  *   pbtRx: A pointer to a buffer for the returned data to be written to.
@@ -84,15 +81,17 @@ void uart_close(const serial_port sp);
  *
  * Returns FALSE if there was an error reading from the device. Note that a
  * partial read may have completed into the buffer by the corresponding
- * implementation, so pszRxLen should be checked to see if any data was written. 
+ * implementation, so pszRxLen should be checked to see if any data was written.
  */
-bool uart_receive(const serial_port sp, uint8_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen);
+extern bool uart_receive(const serial_port sp, uint8_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen);
 
 /* Sends a buffer to a given serial port.
  *   pbtTx: A pointer to a buffer containing the data to send.
  *   szTxLen: The amount of data to be sent.
+ *
+ * Returns TRUE if all data could be sent within 30ms.
  */
-bool uart_send(const serial_port sp, const uint8_t* pbtTx, const size_t szTxLen);
+extern bool uart_send(const serial_port sp, const uint8_t* pbtTx, const size_t szTxLen);
 
 /* Sets the current speed of the serial port, in baud.
  */
@@ -100,7 +99,7 @@ bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed);
 
 /* Gets the current speed of the serial port, in baud.
  */
-uint32_t uart_get_speed(const serial_port sp);
+extern uint32_t uart_get_speed(const serial_port sp);
 
-#endif // _PM3_UART_H_
+#endif // PM3_UART_H__
 
old mode 100644 (file)
new mode 100755 (executable)
index 29a02cf..f6e6519
-/*
- * Generic uart / rs232/ serial port library
- *
- * Copyright (c) 2013, Roel Verdult
- * Copyright (c) 2018 Google
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holders nor the
- * names of its contributors may be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @file uart_posix.c
- *
- * This version of the library has functionality removed which was not used by
- * proxmark3 project.
- */
-
-// Test if we are dealing with posix operating systems
-#ifndef _WIN32
-#define _DEFAULT_SOURCE
-
-#include "uart.h"
-
-#include <termios.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <limits.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-
-// Fix missing definition on OS X.
-// Taken from https://github.com/unbit/uwsgi/commit/b608eb1772641d525bfde268fe9d6d8d0d5efde7
-#ifndef SOL_TCP
-#define SOL_TCP IPPROTO_TCP
-#endif
-
-typedef struct termios term_info;
-typedef struct {
-  int fd;           // Serial port file descriptor
-  term_info tiOld;  // Terminal info before using the port
-  term_info tiNew;  // Terminal info during the transaction
-} serial_port_unix;
-
-// Set time-out on 30 miliseconds
-struct timeval timeout = {
-  .tv_sec  =     0, // 0 second
-  .tv_usec = 30000  // 30000 micro seconds
-};
-
-serial_port uart_open(const char* pcPortName)
-{
-  serial_port_unix* sp = malloc(sizeof(serial_port_unix));
-  if (sp == 0) return INVALID_SERIAL_PORT;
-  
-  if (memcmp(pcPortName, "tcp:", 4) == 0) {
-    struct addrinfo *addr = NULL, *rp;
-    char *addrstr = strdup(pcPortName + 4);
-    if (addrstr == NULL) {
-      printf("Error: strdup\n");
-      return INVALID_SERIAL_PORT;
-    }
-    char *colon = strrchr(addrstr, ':');
-    char *portstr;
-
-    // Set time-out to 300 miliseconds only for TCP port
-    timeout.tv_usec = 300000;
-
-    if (colon) {
-      portstr = colon + 1;
-      *colon = '\0';
-    } else
-      portstr = "7901";
-
-    struct addrinfo info;
-
-    memset (&info, 0, sizeof(info));
-
-    info.ai_socktype = SOCK_STREAM;
-
-    int s = getaddrinfo(addrstr, portstr, &info, &addr);
-    if (s != 0) {
-      printf("Error: getaddrinfo: %s\n", gai_strerror(s));
-      return INVALID_SERIAL_PORT;
-    }
-
-    int sfd;
-    for (rp = addr; rp != NULL; rp = rp->ai_next) {
-      sfd = socket(rp->ai_family, rp->ai_socktype,
-                  rp->ai_protocol);
-      if (sfd == -1)
-       continue;
-
-      if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
-       break;
-
-      close(sfd);
-    }
-
-    if (rp == NULL) {               /* No address succeeded */
-      printf("Error: Could not connect\n");
-      return INVALID_SERIAL_PORT;
-    }
-
-    freeaddrinfo(addr);
-    free(addrstr);
-
-    sp->fd = sfd;
-
-    int one = 1;
-    setsockopt(sp->fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one));
-    return sp;
-  }
-
-  sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
-  if(sp->fd == -1) {
-    uart_close(sp);
-    return INVALID_SERIAL_PORT;
-  }
-
-  // Finally figured out a way to claim a serial port interface under unix
-  // We just try to set a (advisory) lock on the file descriptor
-  struct flock fl;
-  fl.l_type   = F_WRLCK;
-  fl.l_whence = SEEK_SET;
-  fl.l_start  = 0;
-  fl.l_len    = 0;
-  fl.l_pid    = getpid();
-  
-  // Does the system allows us to place a lock on this file descriptor
-  if (fcntl(sp->fd, F_SETLK, &fl) == -1) {
-    // A conflicting lock is held by another process
-    free(sp);
-    return CLAIMED_SERIAL_PORT;
-  }
-
-  // Try to retrieve the old (current) terminal info struct
-  if(tcgetattr(sp->fd,&sp->tiOld) == -1) {
-    uart_close(sp);
-    return INVALID_SERIAL_PORT;
-  }
-  
-  // Duplicate the (old) terminal info struct
-  sp->tiNew = sp->tiOld;
-  
-  // Configure the serial port
-  sp->tiNew.c_cflag = CS8 | CLOCAL | CREAD;
-  sp->tiNew.c_iflag = IGNPAR;
-  sp->tiNew.c_oflag = 0;
-  sp->tiNew.c_lflag = 0;
-    
-  // Block until n bytes are received
-  sp->tiNew.c_cc[VMIN] = 0;
-  // Block until a timer expires (n * 100 mSec.)
-  sp->tiNew.c_cc[VTIME] = 0;
-  
-  // Try to set the new terminal info struct
-  if(tcsetattr(sp->fd,TCSANOW,&sp->tiNew) == -1) {
-    uart_close(sp);
-    return INVALID_SERIAL_PORT;
-  }
-  
-  // Flush all lingering data that may exist
-  tcflush(sp->fd, TCIOFLUSH);
-
-  return sp;
-}
-
-void uart_close(const serial_port sp) {
-  serial_port_unix* spu = (serial_port_unix*)sp;
-  tcflush(spu->fd,TCIOFLUSH);
-  tcsetattr(spu->fd,TCSANOW,&(spu->tiOld));
-  struct flock fl;
-  fl.l_type   = F_UNLCK;
-  fl.l_whence = SEEK_SET;
-  fl.l_start  = 0;
-  fl.l_len    = 0;
-  fl.l_pid    = getpid();
-  fcntl(spu->fd, F_SETLK, &fl);
-  close(spu->fd);
-  free(sp);
-}
-
-bool uart_receive(const serial_port sp, uint8_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen) {
-  int res;
-  int byteCount;
-  fd_set rfds;
-  struct timeval tv;
-  
-  // Reset the output count
-  *pszRxLen = 0;
-  
-  do {
-    // Reset file descriptor
-    FD_ZERO(&rfds);
-    FD_SET(((serial_port_unix*)sp)->fd,&rfds);
-    tv = timeout;
-    res = select(((serial_port_unix*)sp)->fd+1, &rfds, NULL, NULL, &tv);
-    
-    // Read error
-    if (res < 0) {
-      return false;
-    }
-    // Read time-out
-    if (res == 0) {
-      if (*pszRxLen == 0) {
-        // Error, we received no data
-        return false;
-      } else {
-        // We received some data, but nothing more is available
-        return true;
-      }
-    }
-    // Retrieve the count of the incoming bytes
-    res = ioctl(((serial_port_unix*)sp)->fd, FIONREAD, &byteCount);
-    if (res < 0) return false;
-    
-    // Cap the number of bytes, so we don't overrun the buffer
-    if (pszMaxRxLen - (*pszRxLen) < byteCount) {
-       byteCount = pszMaxRxLen - (*pszRxLen);
-    }
-
-    // There is something available, read the data
-    res = read(((serial_port_unix*)sp)->fd, pbtRx+(*pszRxLen), byteCount);
-
-    // Stop if the OS has some troubles reading the data
-    if (res <= 0) return false;
-    *pszRxLen += res;
-
-    if (*pszRxLen == pszMaxRxLen) {
-       // We have all the data we wanted.
-      return true;
-    }
-    
-  } while (byteCount);
-
-  return true;
-}
-
-bool uart_send(const serial_port sp, const uint8_t* pbtTx, const size_t szTxLen) {
-  int32_t res;
-  size_t szPos = 0;
-  fd_set rfds;
-  struct timeval tv;
-  
-  while (szPos < szTxLen) {
-    // Reset file descriptor
-    FD_ZERO(&rfds);
-    FD_SET(((serial_port_unix*)sp)->fd,&rfds);
-    tv = timeout;
-    res = select(((serial_port_unix*)sp)->fd+1, NULL, &rfds, NULL, &tv);
-    
-    // Write error
-    if (res < 0) {
-      return false;
-    }
-    
-    // Write time-out
-    if (res == 0) {
-      return false;
-    }
-    
-    // Send away the bytes
-    res = write(((serial_port_unix*)sp)->fd,pbtTx+szPos,szTxLen-szPos);
-    
-    // Stop if the OS has some troubles sending the data
-    if (res <= 0) return false;
-    
-    szPos += res;
-  }
-  return true;
-}
-
-bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {
-  const serial_port_unix* spu = (serial_port_unix*)sp;
-  speed_t stPortSpeed;
-  switch (uiPortSpeed) {
-    case 0: stPortSpeed = B0; break;
-    case 50: stPortSpeed = B50; break;
-    case 75: stPortSpeed = B75; break;
-    case 110: stPortSpeed = B110; break;
-    case 134: stPortSpeed = B134; break;
-    case 150: stPortSpeed = B150; break;
-    case 300: stPortSpeed = B300; break;
-    case 600: stPortSpeed = B600; break;
-    case 1200: stPortSpeed = B1200; break;
-    case 1800: stPortSpeed = B1800; break;
-    case 2400: stPortSpeed = B2400; break;
-    case 4800: stPortSpeed = B4800; break;
-    case 9600: stPortSpeed = B9600; break;
-    case 19200: stPortSpeed = B19200; break;
-    case 38400: stPortSpeed = B38400; break;
-#  ifdef B57600
-    case 57600: stPortSpeed = B57600; break;
-#  endif
-#  ifdef B115200
-    case 115200: stPortSpeed = B115200; break;
-#  endif
-#  ifdef B230400
-    case 230400: stPortSpeed = B230400; break;
-#  endif
-#  ifdef B460800
-    case 460800: stPortSpeed = B460800; break;
-#  endif
-#  ifdef B921600
-    case 921600: stPortSpeed = B921600; break;
-#  endif
-    default: return false;
-  };
-  struct termios ti;
-  if (tcgetattr(spu->fd,&ti) == -1) return false;
-  // Set port speed (Input and Output)
-  cfsetispeed(&ti,stPortSpeed);
-  cfsetospeed(&ti,stPortSpeed);
-  return (tcsetattr(spu->fd,TCSANOW,&ti) != -1);
-}
-
-uint32_t uart_get_speed(const serial_port sp) {
-  struct termios ti;
-  uint32_t uiPortSpeed;
-  const serial_port_unix* spu = (serial_port_unix*)sp;
-  if (tcgetattr(spu->fd,&ti) == -1) return 0;
-  // Set port speed (Input)
-  speed_t stPortSpeed = cfgetispeed(&ti);
-  switch (stPortSpeed) {
-    case B0: uiPortSpeed = 0; break;
-    case B50: uiPortSpeed = 50; break;
-    case B75: uiPortSpeed = 75; break;
-    case B110: uiPortSpeed = 110; break;
-    case B134: uiPortSpeed = 134; break;
-    case B150: uiPortSpeed = 150; break;
-    case B300: uiPortSpeed = 300; break;
-    case B600: uiPortSpeed = 600; break;
-    case B1200: uiPortSpeed = 1200; break;
-    case B1800: uiPortSpeed = 1800; break;
-    case B2400: uiPortSpeed = 2400; break;
-    case B4800: uiPortSpeed = 4800; break;
-    case B9600: uiPortSpeed = 9600; break;
-    case B19200: uiPortSpeed = 19200; break;
-    case B38400: uiPortSpeed = 38400; break;
-#  ifdef B57600
-    case B57600: uiPortSpeed = 57600; break;
-#  endif
-#  ifdef B115200
-    case B115200: uiPortSpeed = 115200; break;
-#  endif
-#  ifdef B230400
-    case B230400: uiPortSpeed = 230400; break;
-#  endif
-#  ifdef B460800
-    case B460800: uiPortSpeed = 460800; break;
-#  endif
-#  ifdef B921600
-    case B921600: uiPortSpeed = 921600; break;
-#  endif
-    default: return 0;
-  };
-  return uiPortSpeed;
-}
-
-#endif
-
+/*\r
+ * Generic uart / rs232/ serial port library\r
+ *\r
+ * Copyright (c) 2013, Roel Verdult\r
+ * Copyright (c) 2018 Google\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ * 3. Neither the name of the copyright holders nor the\r
+ * names of its contributors may be used to endorse or promote products\r
+ * derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY\r
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY\r
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * @file uart_posix.c\r
+ *\r
+ * This version of the library has functionality removed which was not used by\r
+ * proxmark3 project.\r
+ */\r
+\r
+// Test if we are dealing with posix operating systems\r
+#ifndef _WIN32\r
+#define _DEFAULT_SOURCE\r
+\r
+#include "uart.h"\r
+\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdbool.h>\r
+#include <termios.h>\r
+#include <sys/ioctl.h>\r
+#include <unistd.h>\r
+#include <fcntl.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#include <sys/socket.h>\r
+#include <netinet/tcp.h>\r
+#include <netdb.h>\r
+#include <sys/time.h>\r
+#include <errno.h>\r
+\r
+// Fix missing definition on OS X.\r
+// Taken from https://github.com/unbit/uwsgi/commit/b608eb1772641d525bfde268fe9d6d8d0d5efde7\r
+#ifndef SOL_TCP\r
+#define SOL_TCP IPPROTO_TCP\r
+#endif\r
+\r
+typedef struct termios term_info;\r
+typedef struct {\r
+       int fd;           // Serial port file descriptor\r
+       term_info tiOld;  // Terminal info before using the port\r
+       term_info tiNew;  // Terminal info during the transaction\r
+} serial_port_unix;\r
+\r
+// Set time-out on 30 miliseconds\r
+static struct timeval timeout = {\r
+       .tv_sec  =     0, // 0 second\r
+       .tv_usec = 30000  // 30000 micro seconds\r
+};\r
+\r
+\r
+void uart_close(const serial_port sp) {\r
+       serial_port_unix* spu = (serial_port_unix*)sp;\r
+       tcflush(spu->fd, TCIOFLUSH);\r
+       tcsetattr(spu->fd, TCSANOW, &(spu->tiOld));\r
+       struct flock fl;\r
+       fl.l_type   = F_UNLCK;\r
+       fl.l_whence = SEEK_SET;\r
+       fl.l_start  = 0;\r
+       fl.l_len    = 0;\r
+       fl.l_pid    = getpid();\r
+       fcntl(spu->fd, F_SETLK, &fl);\r
+       close(spu->fd);\r
+       free(sp);\r
+}\r
+\r
+\r
+serial_port uart_open(const char* pcPortName) {\r
+\r
+       serial_port_unix* sp = malloc(sizeof(serial_port_unix));\r
+       if (sp == 0) return INVALID_SERIAL_PORT;\r
+\r
+       if (memcmp(pcPortName, "tcp:", 4) == 0) {\r
+               struct addrinfo *addr = NULL, *rp;\r
+               char *addrstr = strdup(pcPortName + 4);\r
+               if (addrstr == NULL) {\r
+                       printf("Error: strdup\n");\r
+                       return INVALID_SERIAL_PORT;\r
+               }\r
+               char *colon = strrchr(addrstr, ':');\r
+               char *portstr;\r
+\r
+               // Set time-out to 300 milliseconds only for TCP port\r
+               timeout.tv_usec = 300000;\r
+\r
+               if (colon) {\r
+                       portstr = colon + 1;\r
+                       *colon = '\0';\r
+               } else {\r
+                       portstr = "7901";\r
+               }\r
+\r
+               struct addrinfo info;\r
+\r
+               memset(&info, 0, sizeof(info));\r
+\r
+               info.ai_socktype = SOCK_STREAM;\r
+\r
+               int s = getaddrinfo(addrstr, portstr, &info, &addr);\r
+               if (s != 0) {\r
+                       printf("Error: getaddrinfo: %s\n", gai_strerror(s));\r
+                       return INVALID_SERIAL_PORT;\r
+               }\r
+\r
+               int sfd;\r
+               for (rp = addr; rp != NULL; rp = rp->ai_next) {\r
+                       sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);\r
+                       if (sfd == -1)\r
+                               continue;\r
+                       if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)\r
+                               break;\r
+                       close(sfd);\r
+               }\r
+\r
+               if (rp == NULL) {               /* No address succeeded */\r
+                       printf("Error: Could not connect\n");\r
+                       return INVALID_SERIAL_PORT;\r
+               }\r
+\r
+               freeaddrinfo(addr);\r
+               free(addrstr);\r
+\r
+               sp->fd = sfd;\r
+\r
+               int one = 1;\r
+               setsockopt(sp->fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one));\r
+               return sp;\r
+       }\r
+\r
+       sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);\r
+       if (sp->fd == -1) {\r
+               uart_close(sp);\r
+               return INVALID_SERIAL_PORT;\r
+       }\r
+\r
+       // Finally figured out a way to claim a serial port interface under unix\r
+       // We just try to set a (advisory) lock on the file descriptor\r
+       struct flock fl;\r
+       fl.l_type   = F_WRLCK;\r
+       fl.l_whence = SEEK_SET;\r
+       fl.l_start  = 0;\r
+       fl.l_len    = 0;\r
+       fl.l_pid    = getpid();\r
+\r
+       // Does the system allows us to place a lock on this file descriptor\r
+       if (fcntl(sp->fd, F_SETLK, &fl) == -1) {\r
+               // A conflicting lock is held by another process\r
+               free(sp);\r
+               return CLAIMED_SERIAL_PORT;\r
+       }\r
+\r
+       // Try to retrieve the old (current) terminal info struct\r
+       if (tcgetattr(sp->fd,&sp->tiOld) == -1) {\r
+               uart_close(sp);\r
+               return INVALID_SERIAL_PORT;\r
+       }\r
+\r
+       // Duplicate the (old) terminal info struct\r
+       sp->tiNew = sp->tiOld;\r
+\r
+       // Configure the serial port\r
+       sp->tiNew.c_cflag &= ~(CSIZE | PARENB);\r
+       sp->tiNew.c_cflag |= (CS8 | CLOCAL | CREAD);\r
+       sp->tiNew.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);\r
+       sp->tiNew.c_iflag |= IGNPAR;\r
+       sp->tiNew.c_oflag &= ~OPOST;\r
+       sp->tiNew.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);\r
+\r
+\r
+       // Try to set the new terminal info struct\r
+       if (tcsetattr(sp->fd, TCSANOW, &sp->tiNew) == -1) {\r
+               uart_close(sp);\r
+               return INVALID_SERIAL_PORT;\r
+       }\r
+\r
+       // Flush all lingering data that may exist\r
+       tcflush(sp->fd, TCIOFLUSH);\r
+\r
+       return sp;\r
+}\r
+\r
+\r
+bool uart_receive(const serial_port sp, uint8_t* pbtRx, size_t szMaxRxLen, size_t* pszRxLen) {\r
+\r
+       *pszRxLen = 0;\r
+\r
+       if (szMaxRxLen == 0) return true;\r
+\r
+       struct timeval t_current;\r
+       gettimeofday(&t_current, NULL);\r
+       struct timeval t_end;\r
+       timeradd(&t_current, &timeout, &t_end);\r
+\r
+       while (true) {\r
+               int res = read(((serial_port_unix*)sp)->fd, pbtRx, szMaxRxLen - *pszRxLen);\r
+               if (res < 0 && errno != EAGAIN && errno != EWOULDBLOCK) return false;\r
+               if (res > 0) {\r
+                       *pszRxLen += res;\r
+                       pbtRx += res;\r
+               }\r
+               if (*pszRxLen == szMaxRxLen) return true; // we could read all requested bytes in time\r
+               gettimeofday(&t_current, NULL);\r
+               if (timercmp(&t_current, &t_end, >)) return true; // timeout\r
+               // set next select timeout\r
+               struct timeval t_remains;\r
+               timersub(&t_end, &t_current, &t_remains);\r
+               // Set the file descriptor set\r
+               fd_set rfds;\r
+               FD_ZERO(&rfds);\r
+               FD_SET(((serial_port_unix*)sp)->fd, &rfds);\r
+               // wait for more bytes available\r
+               res = select(((serial_port_unix*)sp)->fd+1, &rfds, NULL, NULL, &t_remains);\r
+               if (res < 0) return false;\r
+               if (res == 0) return true; // timeout\r
+       }\r
+       return true; // should never come here\r
+}\r
+\r
+\r
+bool uart_send(const serial_port sp, const uint8_t* pbtTx, const size_t szTxLen) {\r
+\r
+       if (szTxLen == 0) return true;\r
+\r
+       size_t bytes_written = 0;\r
+\r
+       struct timeval t_current;\r
+       gettimeofday(&t_current, NULL);\r
+       struct timeval t_end;\r
+       timeradd(&t_current, &timeout, &t_end);\r
+\r
+       while (true) {\r
+               int res = write(((serial_port_unix*)sp)->fd, pbtTx, szTxLen - bytes_written);\r
+               if (res < 0 && res != EAGAIN && res != EWOULDBLOCK) return false;\r
+               if (res > 0) {\r
+                       pbtTx += res;\r
+                       bytes_written += res;\r
+               }\r
+               if (bytes_written == szTxLen) return true; // we could write all bytes\r
+               gettimeofday(&t_current, NULL);\r
+               if (timercmp(&t_current, &t_end, >)) return false; // timeout\r
+               // set next select timeout\r
+               struct timeval t_remains;\r
+               timersub(&t_end, &t_current, &t_remains);\r
+               // Set the file descriptor set\r
+               fd_set wfds;\r
+               FD_ZERO(&wfds);\r
+               FD_SET(((serial_port_unix*)sp)->fd, &wfds);\r
+               // wait until more bytes can be written\r
+               res = select(((serial_port_unix*)sp)->fd+1, NULL, &wfds, NULL, &t_remains);\r
+               if (res < 0) return false;  // error\r
+               if (res == 0) return false; // timeout\r
+       }\r
+       return true;\r
+}\r
+\r
+\r
+bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {\r
+       const serial_port_unix* spu = (serial_port_unix*)sp;\r
+       speed_t stPortSpeed;\r
+       switch (uiPortSpeed) {\r
+               case 0: stPortSpeed = B0; break;\r
+               case 50: stPortSpeed = B50; break;\r
+               case 75: stPortSpeed = B75; break;\r
+               case 110: stPortSpeed = B110; break;\r
+               case 134: stPortSpeed = B134; break;\r
+               case 150: stPortSpeed = B150; break;\r
+               case 300: stPortSpeed = B300; break;\r
+               case 600: stPortSpeed = B600; break;\r
+               case 1200: stPortSpeed = B1200; break;\r
+               case 1800: stPortSpeed = B1800; break;\r
+               case 2400: stPortSpeed = B2400; break;\r
+               case 4800: stPortSpeed = B4800; break;\r
+               case 9600: stPortSpeed = B9600; break;\r
+               case 19200: stPortSpeed = B19200; break;\r
+               case 38400: stPortSpeed = B38400; break;\r
+#  ifdef B57600\r
+               case 57600: stPortSpeed = B57600; break;\r
+#  endif\r
+#  ifdef B115200\r
+               case 115200: stPortSpeed = B115200; break;\r
+#  endif\r
+#  ifdef B230400\r
+               case 230400: stPortSpeed = B230400; break;\r
+#  endif\r
+#  ifdef B460800\r
+               case 460800: stPortSpeed = B460800; break;\r
+#  endif\r
+#  ifdef B921600\r
+               case 921600: stPortSpeed = B921600; break;\r
+#  endif\r
+               default: return false;\r
+       };\r
+       struct termios ti;\r
+       if (tcgetattr(spu->fd, &ti) == -1) return false;\r
+       // Set port speed (Input and Output)\r
+       cfsetispeed(&ti,stPortSpeed);\r
+       cfsetospeed(&ti,stPortSpeed);\r
+       return (tcsetattr(spu->fd, TCSANOW, &ti) != -1);\r
+}\r
+\r
+uint32_t uart_get_speed(const serial_port sp) {\r
+       struct termios ti;\r
+       uint32_t uiPortSpeed;\r
+       const serial_port_unix* spu = (serial_port_unix*)sp;\r
+       if (tcgetattr(spu->fd, &ti) == -1) return 0;\r
+       // Set port speed (Input)\r
+       speed_t stPortSpeed = cfgetispeed(&ti);\r
+       switch (stPortSpeed) {\r
+               case B0: uiPortSpeed = 0; break;\r
+               case B50: uiPortSpeed = 50; break;\r
+               case B75: uiPortSpeed = 75; break;\r
+               case B110: uiPortSpeed = 110; break;\r
+               case B134: uiPortSpeed = 134; break;\r
+               case B150: uiPortSpeed = 150; break;\r
+               case B300: uiPortSpeed = 300; break;\r
+               case B600: uiPortSpeed = 600; break;\r
+               case B1200: uiPortSpeed = 1200; break;\r
+               case B1800: uiPortSpeed = 1800; break;\r
+               case B2400: uiPortSpeed = 2400; break;\r
+               case B4800: uiPortSpeed = 4800; break;\r
+               case B9600: uiPortSpeed = 9600; break;\r
+               case B19200: uiPortSpeed = 19200; break;\r
+               case B38400: uiPortSpeed = 38400; break;\r
+#  ifdef B57600\r
+               case B57600: uiPortSpeed = 57600; break;\r
+#  endif\r
+#  ifdef B115200\r
+               case B115200: uiPortSpeed = 115200; break;\r
+#  endif\r
+#  ifdef B230400\r
+               case B230400: uiPortSpeed = 230400; break;\r
+#  endif\r
+#  ifdef B460800\r
+               case B460800: uiPortSpeed = 460800; break;\r
+#  endif\r
+#  ifdef B921600\r
+               case B921600: uiPortSpeed = 921600; break;\r
+#  endif\r
+               default: return 0;\r
+       };\r
+       return uiPortSpeed;\r
+}\r
+\r
+#endif\r
index b15e87860e2bbcb1ac3e901084de2d7cfef35895..0e4227de4caf0929fc3d175b8d8ecc6dfc970b3d 100644 (file)
 
 #include "uart.h"
 
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+
 // The windows serial port implementation
 #ifdef _WIN32
 #include <windows.h>
 
 typedef struct {
-  HANDLE hPort;     // Serial port handle
-  DCB dcb;          // Device control settings
-  COMMTIMEOUTS ct;  // Serial port time-out configuration
+       HANDLE hPort;     // Serial port handle
+       DCB dcb;          // Device control settings
+       COMMTIMEOUTS ct;  // Serial port time-out configuration
 } serial_port_windows;
 
+
 void upcase(char *p) {
-  while(*p != '\0') {
-    if(*p >= 97 && *p <= 122) {
-      *p -= 32;
-    }
-    ++p;
-  }
+       while(*p != '\0') {
+               if(*p >= 97 && *p <= 122) {
+                       *p -= 32;
+               }
+               ++p;
+       }
 }
 
-serial_port uart_open(const char* pcPortName) {
-  char acPortName[255];
-  serial_port_windows* sp = malloc(sizeof(serial_port_windows));
-  
-  // Copy the input "com?" to "\\.\COM?" format
-  sprintf(acPortName,"\\\\.\\%s",pcPortName);
-  upcase(acPortName);
-  
-  // Try to open the serial port
-  sp->hPort = CreateFileA(acPortName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
-  if (sp->hPort == INVALID_HANDLE_VALUE) {
-    uart_close(sp);
-    return INVALID_SERIAL_PORT;
-  }
-  
-  // Prepare the device control
-  memset(&sp->dcb, 0, sizeof(DCB));
-  sp->dcb.DCBlength = sizeof(DCB);
-  if(!BuildCommDCBA("baud=9600 data=8 parity=N stop=1",&sp->dcb)) {
-    uart_close(sp);
-    return INVALID_SERIAL_PORT;
-  }
-  
-  // Update the active serial port
-  if(!SetCommState(sp->hPort,&sp->dcb)) {
-    uart_close(sp);
-    return INVALID_SERIAL_PORT;
-  }
-  
-  sp->ct.ReadIntervalTimeout         = 0;
-  sp->ct.ReadTotalTimeoutMultiplier  = 0;
-  sp->ct.ReadTotalTimeoutConstant    = 30;
-  sp->ct.WriteTotalTimeoutMultiplier = 0;
-  sp->ct.WriteTotalTimeoutConstant   = 30;
-  
-  if(!SetCommTimeouts(sp->hPort,&sp->ct)) {
-    uart_close(sp);
-    return INVALID_SERIAL_PORT;
-  }
-  
-  PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
-  
-  return sp;
-}
 
 void uart_close(const serial_port sp) {
-  CloseHandle(((serial_port_windows*)sp)->hPort);
-  free(sp);
+       CloseHandle(((serial_port_windows*)sp)->hPort);
+       free(sp);
 }
 
+
+serial_port uart_open(const char* pcPortName) {
+       char acPortName[255];
+       serial_port_windows* sp = malloc(sizeof(serial_port_windows));
+
+       // Copy the input "com?" to "\\.\COM?" format
+       sprintf(acPortName,"\\\\.\\%s",pcPortName);
+       upcase(acPortName);
+
+       // Try to open the serial port
+       sp->hPort = CreateFileA(acPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+       if (sp->hPort == INVALID_HANDLE_VALUE) {
+               uart_close(sp);
+               return INVALID_SERIAL_PORT;
+       }
+
+       // Prepare the device control
+       memset(&sp->dcb, 0, sizeof(DCB));
+       sp->dcb.DCBlength = sizeof(DCB);
+       if (!BuildCommDCBA("baud=9600 data=8 parity=N stop=1",&sp->dcb)) {
+               uart_close(sp);
+               return INVALID_SERIAL_PORT;
+       }
+
+       // Update the active serial port
+       if (!SetCommState(sp->hPort,&sp->dcb)) {
+               uart_close(sp);
+               return INVALID_SERIAL_PORT;
+       }
+
+       sp->ct.ReadIntervalTimeout         = 0;
+       sp->ct.ReadTotalTimeoutMultiplier  = 0;
+       sp->ct.ReadTotalTimeoutConstant    = 30;
+       sp->ct.WriteTotalTimeoutMultiplier = 0;
+       sp->ct.WriteTotalTimeoutConstant   = 30;
+
+       if (!SetCommTimeouts(sp->hPort, &sp->ct)) {
+               uart_close(sp);
+               return INVALID_SERIAL_PORT;
+       }
+
+       PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
+
+       return sp;
+}
+
+
 bool uart_receive(const serial_port sp, uint8_t *pbtRx, size_t pszMaxRxLen, size_t *pszRxLen) {
-  return ReadFile(((serial_port_windows*)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL);
+       return ReadFile(((serial_port_windows*)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL);
 }
 
+
 bool uart_send(const serial_port sp, const uint8_t* pbtTx, const size_t szTxLen) {
-  DWORD dwTxLen = 0;
-  return WriteFile(((serial_port_windows*)sp)->hPort, pbtTx, szTxLen, &dwTxLen, NULL);
+       DWORD dwTxLen = 0;
+       return WriteFile(((serial_port_windows*)sp)->hPort, pbtTx, szTxLen, &dwTxLen, NULL);
 }
 
+
 bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {
-  serial_port_windows* spw;
-  spw = (serial_port_windows*)sp;
-  spw->dcb.BaudRate = uiPortSpeed;
-  return SetCommState(spw->hPort, &spw->dcb);
+       serial_port_windows* spw;
+       spw = (serial_port_windows*)sp;
+       spw->dcb.BaudRate = uiPortSpeed;
+       return SetCommState(spw->hPort, &spw->dcb);
 }
 
+
 uint32_t uart_get_speed(const serial_port sp) {
-  const serial_port_windows* spw = (serial_port_windows*)sp;
-  if (!GetCommState(spw->hPort, (serial_port)&spw->dcb)) {
-    return spw->dcb.BaudRate;
-  }
-  return 0;
+       const serial_port_windows* spw = (serial_port_windows*)sp;
+       if (!GetCommState(spw->hPort, (serial_port)&spw->dcb)) {
+               return spw->dcb.BaudRate;
+       }
+       return 0;
 }
 
 #endif
Impressum, Datenschutz