]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
added missing files
authorroel@libnfc.org <roel@libnfc.org@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Tue, 4 Dec 2012 23:41:54 +0000 (23:41 +0000)
committerroel@libnfc.org <roel@libnfc.org@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Tue, 4 Dec 2012 23:41:54 +0000 (23:41 +0000)
armsrc/cmd.c [new file with mode: 0644]
armsrc/cmd.h [new file with mode: 0644]
armsrc/usb_cdc.c [new file with mode: 0644]
armsrc/usb_cdc.h [new file with mode: 0644]
client/uart.c [new file with mode: 0644]
client/uart.h [new file with mode: 0644]

diff --git a/armsrc/cmd.c b/armsrc/cmd.c
new file mode 100644 (file)
index 0000000..f64b4e4
--- /dev/null
@@ -0,0 +1,75 @@
+/*\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.c\r
+ * @brief\r
+ */\r
+\r
+#include "cmd.h"\r
+#include "string.h"\r
+#include "util.h"\r
+#include "proxmark3.h"\r
+\r
+//static UsbCommand txcmd;\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, byte_t* data, size_t len) {\r
+  UsbCommand txcmd;\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
+    memcpy(txcmd.d.asBytes,data,MIN(len,USB_CMD_DATA_SIZE));\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/armsrc/cmd.h b/armsrc/cmd.h
new file mode 100644 (file)
index 0000000..c10a534
--- /dev/null
@@ -0,0 +1,44 @@
+/*\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, byte_t* data, size_t len);\r
+\r
+#endif // _PROXMARK_CMD_H_\r
+\r
diff --git a/armsrc/usb_cdc.c b/armsrc/usb_cdc.c
new file mode 100644 (file)
index 0000000..c3975f1
--- /dev/null
@@ -0,0 +1,548 @@
+/*\r
+ * at91sam7s USB CDC device implementation\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
+ * based on the "Basic USB Example" from ATMEL (doc6123.pdf)\r
+ *\r
+ * @file usb_cdc.c\r
+ * @brief\r
+ */\r
+\r
+#include "usb_cdc.h"\r
+\r
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))\r
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))\r
+#define AT91C_EP_IN_SIZE  0x40\r
+#define AT91C_EP_OUT         1\r
+#define AT91C_EP_OUT_SIZE 0x40\r
+#define AT91C_EP_IN          2\r
+\r
+const char devDescriptor[] = {\r
+       /* Device descriptor */\r
+       0x12,      // bLength\r
+       0x01,      // bDescriptorType\r
+       0x10,0x01, // Complies with USB Spec. Release (0110h = release 1.10)\r
+       0x02,      // bDeviceClass:    CDC class code\r
+       0x00,      // bDeviceSubclass: CDC class sub code\r
+       0x00,      // bDeviceProtocol: CDC Device protocol\r
+       0x08,      // bMaxPacketSize0\r
+       0xeb,0x03, // Vendor ID (random numbers)\r
+       0x25,0x61, // Product ID (random numbers)\r
+       0x01,0x00, // Device release number (0001)\r
+       0x01,      // iManufacturer    // 0x01\r
+       0x00,      // iProduct\r
+       0x00,      // SerialNumber\r
+       0x01       // bNumConfigs\r
+};\r
+\r
+const char cfgDescriptor[] = {\r
+       /* ============== CONFIGURATION 1 =========== */\r
+       /* Configuration 1 descriptor */\r
+       0x09,   // CbLength\r
+       0x02,   // CbDescriptorType\r
+       0x43,   // CwTotalLength 2 EP + Control\r
+       0x00,\r
+       0x02,   // CbNumInterfaces\r
+       0x01,   // CbConfigurationValue\r
+       0x00,   // CiConfiguration\r
+       0xC0,   // CbmAttributes 0xA0\r
+       0x00,   // CMaxPower\r
+\r
+       /* Communication Class Interface Descriptor Requirement */\r
+       0x09, // bLength\r
+       0x04, // bDescriptorType\r
+       0x00, // bInterfaceNumber\r
+       0x00, // bAlternateSetting\r
+       0x01, // bNumEndpoints\r
+       0x02, // bInterfaceClass\r
+       0x02, // bInterfaceSubclass\r
+       0x00, // bInterfaceProtocol\r
+       0x00, // iInterface\r
+\r
+       /* Header Functional Descriptor */\r
+       0x05, // bFunction Length\r
+       0x24, // bDescriptor type: CS_INTERFACE\r
+       0x00, // bDescriptor subtype: Header Func Desc\r
+       0x10, // bcdCDC:1.1\r
+       0x01,\r
+\r
+       /* ACM Functional Descriptor */\r
+       0x04, // bFunctionLength\r
+       0x24, // bDescriptor Type: CS_INTERFACE\r
+       0x02, // bDescriptor Subtype: ACM Func Desc\r
+       0x00, // bmCapabilities\r
+\r
+       /* Union Functional Descriptor */\r
+       0x05, // bFunctionLength\r
+       0x24, // bDescriptorType: CS_INTERFACE\r
+       0x06, // bDescriptor Subtype: Union Func Desc\r
+       0x00, // bMasterInterface: Communication Class Interface\r
+       0x01, // bSlaveInterface0: Data Class Interface\r
+\r
+       /* Call Management Functional Descriptor */\r
+       0x05, // bFunctionLength\r
+       0x24, // bDescriptor Type: CS_INTERFACE\r
+       0x01, // bDescriptor Subtype: Call Management Func Desc\r
+       0x00, // bmCapabilities: D1 + D0\r
+       0x01, // bDataInterface: Data Class Interface 1\r
+\r
+       /* Endpoint 1 descriptor */\r
+       0x07,   // bLength\r
+       0x05,   // bDescriptorType\r
+       0x83,   // bEndpointAddress, Endpoint 03 - IN\r
+       0x03,   // bmAttributes      INT\r
+       0x08,   // wMaxPacketSize\r
+       0x00,\r
+       0xFF,   // bInterval\r
+\r
+       /* Data Class Interface Descriptor Requirement */\r
+       0x09, // bLength\r
+       0x04, // bDescriptorType\r
+       0x01, // bInterfaceNumber\r
+       0x00, // bAlternateSetting\r
+       0x02, // bNumEndpoints\r
+       0x0A, // bInterfaceClass\r
+       0x00, // bInterfaceSubclass\r
+       0x00, // bInterfaceProtocol\r
+       0x00, // iInterface\r
+\r
+       /* First alternate setting */\r
+       /* Endpoint 1 descriptor */\r
+       0x07,   // bLength\r
+       0x05,   // bDescriptorType\r
+       0x01,   // bEndpointAddress, Endpoint 01 - OUT\r
+       0x02,   // bmAttributes      BULK\r
+       AT91C_EP_OUT_SIZE,   // wMaxPacketSize\r
+       0x00,\r
+       0x00,   // bInterval\r
+\r
+       /* Endpoint 2 descriptor */\r
+       0x07,   // bLength\r
+       0x05,   // bDescriptorType\r
+       0x82,   // bEndpointAddress, Endpoint 02 - IN\r
+       0x02,   // bmAttributes      BULK\r
+       AT91C_EP_IN_SIZE,   // wMaxPacketSize\r
+       0x00,\r
+       0x00    // bInterval\r
+};\r
+\r
+const char strDescriptor[] = {\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
+/* USB standard request code */\r
+#define STD_GET_STATUS_ZERO           0x0080\r
+#define STD_GET_STATUS_INTERFACE      0x0081\r
+#define STD_GET_STATUS_ENDPOINT       0x0082\r
+\r
+#define STD_CLEAR_FEATURE_ZERO        0x0100\r
+#define STD_CLEAR_FEATURE_INTERFACE   0x0101\r
+#define STD_CLEAR_FEATURE_ENDPOINT    0x0102\r
+\r
+#define STD_SET_FEATURE_ZERO          0x0300\r
+#define STD_SET_FEATURE_INTERFACE     0x0301\r
+#define STD_SET_FEATURE_ENDPOINT      0x0302\r
+\r
+#define STD_SET_ADDRESS               0x0500\r
+#define STD_GET_DESCRIPTOR            0x0680\r
+#define STD_SET_DESCRIPTOR            0x0700\r
+#define STD_GET_CONFIGURATION         0x0880\r
+#define STD_SET_CONFIGURATION         0x0900\r
+#define STD_GET_INTERFACE             0x0A81\r
+#define STD_SET_INTERFACE             0x0B01\r
+#define STD_SYNCH_FRAME               0x0C82\r
+\r
+/* CDC Class Specific Request Code */\r
+#define GET_LINE_CODING               0x21A1\r
+#define SET_LINE_CODING               0x2021\r
+#define SET_CONTROL_LINE_STATE        0x2221\r
+\r
+typedef struct {\r
+       unsigned int dwDTERRate;\r
+       char bCharFormat;\r
+       char bParityType;\r
+       char bDataBits;\r
+} AT91S_CDC_LINE_CODING, *AT91PS_CDC_LINE_CODING;\r
+\r
+AT91S_CDC_LINE_CODING line = {\r
+       115200, // baudrate\r
+       0,      // 1 Stop Bit\r
+       0,      // None Parity\r
+       8};     // 8 Data bits\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
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn    AT91F_USB_Enable\r
+//* \brief This function Activates the USB device\r
+//*----------------------------------------------------------------------------\r
+void usb_enable()\r
+{\r
+  // Set the PLL USB Divider\r
+  AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;\r
+  \r
+  // Specific Chip USB Initialisation\r
+  // Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock\r
+  AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;\r
+  AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);\r
+  \r
+  // Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO\r
+  // Set in PIO mode and Configure in Output\r
+  AT91C_BASE_PIOA->PIO_PER = AT91C_PIO_PA16; // Set in PIO mode\r
+       AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA16; // Configure as Output\r
+  \r
+  // Clear for set the Pul up resistor\r
+       AT91C_BASE_PIOA->PIO_CODR = AT91C_PIO_PA16;\r
+}\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn    AT91F_UDP_IsConfigured\r
+//* \brief Test if the device is configured and handle enumeration\r
+//*----------------------------------------------------------------------------\r
+bool usb_check()\r
+{\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[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);\r
+       }\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
+//* \fn    AT91F_UDP_Read\r
+//* \brief Read available data from Endpoint OUT\r
+//*----------------------------------------------------------------------------\r
+uint32_t usb_read(byte_t* data, size_t len)\r
+{\r
+  byte_t bank = btReceiveBank;\r
+       uint32_t packetSize, nbBytesRcv = 0;\r
+  uint32_t time_out = 0;\r
+  \r
+       while (len)\r
+  {\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
+                       pUdp->UDP_CSR[AT91C_EP_OUT] &= ~(bank);\r
+                       if (bank == AT91C_UDP_RX_DATA_BK0)\r
+      {\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
+//* \fn    AT91F_CDC_Write\r
+//* \brief Send through endpoint 2\r
+//*----------------------------------------------------------------------------\r
+uint32_t usb_write(const byte_t* data, const size_t len)\r
+{\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-1);\r
+       length -= cpt;\r
+       while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++;\r
+       pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY;\r
+\r
+       while (length) {\r
+               // Fill the second bank\r
+               cpt = MIN(length, AT91C_EP_IN_SIZE-1);\r
+               length -= cpt;\r
+               while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++;\r
+               // Wait for the the first bank to be sent\r
+               while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {\r
+                       if (!usb_check()) return length;\r
+    }\r
+               pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);\r
+               while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);\r
+               pUdp->UDP_CSR[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
+       pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);\r
+       while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);\r
+\r
+       return length;\r
+}\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn    AT91F_USB_SendData\r
+//* \brief Send Data through the control endpoint\r
+//*----------------------------------------------------------------------------\r
+unsigned int csrTab[100];\r
+unsigned char csrIdx = 0;\r
+\r
+static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length)\r
+{\r
+       uint32_t cpt = 0;\r
+       AT91_REG csr;\r
+\r
+       do {\r
+               cpt = MIN(length, 8);\r
+               length -= cpt;\r
+\r
+               while (cpt--)\r
+                       pUdp->UDP_FDR[0] = *pData++;\r
+\r
+               if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {\r
+                       pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);\r
+                       while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);\r
+               }\r
+\r
+               pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;\r
+               do {\r
+                       csr = pUdp->UDP_CSR[0];\r
+\r
+                       // Data IN stage has been stopped by a status OUT\r
+                       if (csr & AT91C_UDP_RX_DATA_BK0) {\r
+                               pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);\r
+                               return;\r
+                       }\r
+               } while ( !(csr & AT91C_UDP_TXCOMP) );\r
+\r
+       } while (length);\r
+\r
+       if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {\r
+               pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);\r
+               while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);\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
+{\r
+       pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;\r
+       while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) );\r
+       pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);\r
+       while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);\r
+}\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn    AT91F_USB_SendStall\r
+//* \brief Stall the control endpoint\r
+//*----------------------------------------------------------------------------\r
+void AT91F_USB_SendStall(AT91PS_UDP pUdp)\r
+{\r
+       pUdp->UDP_CSR[0] |= AT91C_UDP_FORCESTALL;\r
+       while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_ISOERROR) );\r
+       pUdp->UDP_CSR[0] &= ~(AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);\r
+       while (pUdp->UDP_CSR[0] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR));\r
+}\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \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
+{\r
+       byte_t bmRequestType, bRequest;\r
+       uint16_t wValue, wIndex, wLength, wStatus;\r
+\r
+       if ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP) )\r
+               return;\r
+\r
+       bmRequestType = pUdp->UDP_FDR[0];\r
+       bRequest      = pUdp->UDP_FDR[0];\r
+       wValue        = (pUdp->UDP_FDR[0] & 0xFF);\r
+       wValue       |= (pUdp->UDP_FDR[0] << 8);\r
+       wIndex        = (pUdp->UDP_FDR[0] & 0xFF);\r
+       wIndex       |= (pUdp->UDP_FDR[0] << 8);\r
+       wLength       = (pUdp->UDP_FDR[0] & 0xFF);\r
+       wLength      |= (pUdp->UDP_FDR[0] << 8);\r
+\r
+       if (bmRequestType & 0x80) {\r
+               pUdp->UDP_CSR[0] |= AT91C_UDP_DIR;\r
+               while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_DIR) );\r
+       }\r
+       pUdp->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP;\r
+       while ( (pUdp->UDP_CSR[0]  & AT91C_UDP_RXSETUP)  );\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
+               else if (wValue == 0x200)  // Return Configuration Descriptor\r
+                       AT91F_USB_SendData(pUdp, cfgDescriptor, MIN(sizeof(cfgDescriptor), wLength));\r
+               else if ((wValue & 0x300) == 0x300)  // Return String Descriptor\r
+                       AT91F_USB_SendData(pUdp, strDescriptor, MIN(sizeof(strDescriptor), wLength));\r
+               else\r
+                       AT91F_USB_SendStall(pUdp);\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
+               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[1] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0;\r
+               pUdp->UDP_CSR[2] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN)  : 0;\r
+               pUdp->UDP_CSR[3] = (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
+               break;\r
+       case STD_GET_STATUS_ZERO:\r
+               wStatus = 0;\r
+               AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
+               break;\r
+       case STD_GET_STATUS_INTERFACE:\r
+               wStatus = 0;\r
+               AT91F_USB_SendData(pUdp, (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 <= 3)) {\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 == 0)) {\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
+               break;\r
+       case STD_SET_FEATURE_ZERO:\r
+               AT91F_USB_SendStall(pUdp);\r
+           break;\r
+       case STD_SET_FEATURE_INTERFACE:\r
+               AT91F_USB_SendZlp(pUdp);\r
+               break;\r
+       case STD_SET_FEATURE_ENDPOINT:\r
+               wIndex &= 0x0F;\r
+               if ((wValue == 0) && wIndex && (wIndex <= 3)) {\r
+                       pUdp->UDP_CSR[wIndex] = 0;\r
+                       AT91F_USB_SendZlp(pUdp);\r
+               }\r
+               else\r
+                       AT91F_USB_SendStall(pUdp);\r
+               break;\r
+       case STD_CLEAR_FEATURE_ZERO:\r
+               AT91F_USB_SendStall(pUdp);\r
+           break;\r
+       case STD_CLEAR_FEATURE_INTERFACE:\r
+               AT91F_USB_SendZlp(pUdp);\r
+               break;\r
+       case STD_CLEAR_FEATURE_ENDPOINT:\r
+               wIndex &= 0x0F;\r
+               if ((wValue == 0) && wIndex && (wIndex <= 3)) {\r
+                       if (wIndex == 1)\r
+                               pUdp->UDP_CSR[1] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);\r
+                       else if (wIndex == 2)\r
+                               pUdp->UDP_CSR[2] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);\r
+                       else if (wIndex == 3)\r
+                               pUdp->UDP_CSR[3] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_ISO_IN);\r
+                       AT91F_USB_SendZlp(pUdp);\r
+               }\r
+               else\r
+                       AT91F_USB_SendStall(pUdp);\r
+               break;\r
+\r
+       // handle CDC class requests\r
+       case SET_LINE_CODING:\r
+               while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RX_DATA_BK0) );\r
+               pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);\r
+               AT91F_USB_SendZlp(pUdp);\r
+               break;\r
+       case GET_LINE_CODING:\r
+               AT91F_USB_SendData(pUdp, (char *) &line, MIN(sizeof(line), wLength));\r
+               break;\r
+       case SET_CONTROL_LINE_STATE:\r
+               btConnection = wValue;\r
+               AT91F_USB_SendZlp(pUdp);\r
+               break;\r
+       default:\r
+               AT91F_USB_SendStall(pUdp);\r
+           break;\r
+       }\r
+}\r
diff --git a/armsrc/usb_cdc.h b/armsrc/usb_cdc.h
new file mode 100644 (file)
index 0000000..8a5cd6b
--- /dev/null
@@ -0,0 +1,47 @@
+/*\r
+ * at91sam7s USB CDC device implementation\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
+ * based on the "Basic USB Example" from ATMEL (doc6123.pdf)\r
+ *\r
+ * @file usb_cdc.c\r
+ * @brief\r
+ */\r
+\r
+#ifndef _USB_CDC_H_\r
+#define _USB_CDC_H_\r
+\r
+#include <common.h>\r
+\r
+void usb_enable();\r
+bool usb_check();\r
+bool usb_poll();\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
+\r
diff --git a/client/uart.c b/client/uart.c
new file mode 100644 (file)
index 0000000..e4da195
--- /dev/null
@@ -0,0 +1,390 @@
+/*
+ * Proxmark3 generic uart / rs232/ serial port library
+ *
+ * Copyright (c) 2012, Roel Verdult
+ * 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.c
+ * @brief
+ *
+ * Partly based on uart-code written by Teunis van Beelen, available:
+ * http://www.teuniz.net/RS-232/index.html
+ *
+ */
+
+#include "uart.h"
+#include "messages.h"
+
+// Test if we are dealing with unix operating systems
+#ifndef _WIN32
+
+#include <termios.h>
+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
+const struct timeval timeout = { 
+  .tv_sec  =     0, // 0 second
+  .tv_usec = 30000  // 30000 micro seconds
+};
+
+// Work-around to claim uart interface using the c_iflag (software input processing) from the termios struct
+#define CCLAIMED 0x80000000
+
+serial_port uart_open(const char* pcPortName)
+{
+  serial_port_unix* sp = malloc(sizeof(serial_port_unix));
+
+  if (sp == 0) return INVALID_SERIAL_PORT;
+
+  sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
+  if(sp->fd == -1)
+  {
+    uart_close(sp);
+    return INVALID_SERIAL_PORT;
+  }
+
+  if(tcgetattr(sp->fd,&sp->tiOld) == -1)
+  {
+    uart_close(sp);
+    return INVALID_SERIAL_PORT;
+  }
+
+  // Make sure the port is not claimed already
+  if (sp->tiOld.c_iflag & CCLAIMED)
+  {
+    uart_close(sp);
+    return CLAIMED_SERIAL_PORT;
+  }
+
+  // Copy the old terminal info struct
+  sp->tiNew = sp->tiOld;
+
+  sp->tiNew.c_cflag = CS8 | CLOCAL | CREAD;
+  sp->tiNew.c_iflag = CCLAIMED | IGNPAR;
+  sp->tiNew.c_oflag = 0;
+  sp->tiNew.c_lflag = 0;
+
+  sp->tiNew.c_cc[VMIN] = 0;      // block until n bytes are received
+  sp->tiNew.c_cc[VTIME] = 0;     // block until a timer expires (n * 100 mSec.)
+
+  if(tcsetattr(sp->fd,TCSANOW,&sp->tiNew) == -1)
+  {
+    uart_close(sp);
+    return INVALID_SERIAL_PORT;
+  }
+
+  tcflush(sp->fd, TCIFLUSH);
+  return sp;
+}
+
+void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
+{
+  DBG("Serial port speed requested to be set to %d bauds.", uiPortSpeed);
+  // Set port speed (Input and Output)
+  speed_t stPortSpeed = B9600;
+  switch(uiPortSpeed) {
+    case 9600: stPortSpeed = B9600;
+    break;
+    case 19200: stPortSpeed = B19200;
+    break;
+    case 38400: stPortSpeed = B38400;
+    break;
+    case 57600: stPortSpeed = B57600;
+    break;
+    case 115200: stPortSpeed = B115200;
+    break;
+    case 230400: stPortSpeed = B230400;
+    break;
+#ifdef B460800
+    case 460800: stPortSpeed = B460800;
+    break;
+#endif
+    default:
+#ifdef B460800
+      ERR("Unable to set serial port speed to %d bauds. Speed value must be one of these constants: 9600 (default), 19200, 38400, 57600, 115200, 230400 or 460800.", uiPortSpeed);
+#else
+      ERR("Unable to set serial port speed to %d bauds. Speed value must be one of these constants: 9600 (default), 19200, 38400, 57600, 115200 or 230400.", uiPortSpeed);
+#endif
+  };
+  const serial_port_unix* spu = (serial_port_unix*)sp;
+  cfsetispeed((struct termios*)&spu->tiNew, stPortSpeed);
+  cfsetospeed((struct termios*)&spu->tiNew, stPortSpeed);
+  if( tcsetattr(spu->fd, TCSADRAIN, &spu->tiNew)  == -1)
+  {
+    ERR("Unable to apply new speed settings.");
+  }
+}
+
+uint32_t uart_get_speed(const serial_port sp)
+{
+  uint32_t uiPortSpeed = 0;
+  const serial_port_unix* spu = (serial_port_unix*)sp;
+  switch (cfgetispeed(&spu->tiNew))
+  {
+    case B9600: uiPortSpeed = 9600;
+    break;
+    case B19200: uiPortSpeed = 19200;
+    break;
+    case B38400: uiPortSpeed = 38400;
+    break;
+    case B57600: uiPortSpeed = 57600;
+    break;
+    case B115200: uiPortSpeed = 115200;
+    break;
+    case B230400: uiPortSpeed = 230400;
+    break;
+#ifdef B460800
+    case B460800: uiPortSpeed = 460800;
+    break;
+#endif
+  }
+
+  return uiPortSpeed;
+}
+
+void uart_close(const serial_port sp)
+{
+  tcsetattr(((serial_port_unix*)sp)->fd,TCSANOW,&((serial_port_unix*)sp)->tiOld);
+  close(((serial_port_unix*)sp)->fd);
+  free(sp);
+}
+
+bool uart_cts(const serial_port sp)
+{
+  char status;
+  if (ioctl(((serial_port_unix*)sp)->fd,TIOCMGET,&status) < 0) return false;
+  return (status & TIOCM_CTS);
+}
+
+bool uart_receive(const serial_port sp, byte_t* pbtRx, 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) {
+      DBG("RX error.");
+      return false;
+    }
+
+    // Read time-out
+    if (res == 0) {
+      if (*pszRxLen == 0) {
+        // Error, we received no data
+        DBG("RX time-out, buffer empty.");
+        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;
+
+    // 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;
+
+  } while (byteCount);
+
+  return true;
+}
+
+bool uart_send(const serial_port sp, const byte_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) {
+      DBG("TX error.");
+      return false;
+    }
+
+    // Write time-out
+    if (res == 0) {
+      DBG("TX time-out.");
+      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;
+}
+
+#else
+// The windows serial port implementation
+
+typedef struct { 
+  HANDLE hPort;     // Serial port handle
+  DCB dcb;          // Device control settings
+  COMMTIMEOUTS ct;  // Serial port time-out configuration
+} serial_port_windows;
+
+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);
+  _strupr(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);
+}
+
+void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
+{
+  serial_port_windows* spw;
+
+  DBG("Serial port speed requested to be set to %d bauds.", uiPortSpeed);
+  // Set port speed (Input and Output)
+  switch(uiPortSpeed) {
+    case 9600:
+    case 19200:
+    case 38400:
+    case 57600:
+    case 115200:
+    case 230400:
+    case 460800:
+    break;
+    default:
+      ERR("Unable to set serial port speed to %d bauds. Speed value must be one of these constants: 9600 (default), 19200, 38400, 57600, 115200, 230400 or 460800.", uiPortSpeed);
+  };
+
+  spw = (serial_port_windows*)sp;
+  spw->dcb.BaudRate = uiPortSpeed;
+  if (!SetCommState(spw->hPort, &spw->dcb))
+  {
+    ERR("Unable to apply new speed settings.");
+  }
+}
+
+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;
+}
+
+bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
+{
+  ReadFile(((serial_port_windows*)sp)->hPort,pbtRx,*pszRxLen,(LPDWORD)pszRxLen,NULL);
+  return (*pszRxLen != 0);
+}
+
+bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
+{
+  DWORD dwTxLen = 0;
+  return WriteFile(((serial_port_windows*)sp)->hPort,pbtTx,szTxLen,&dwTxLen,NULL);
+  return (dwTxLen != 0);
+}
+
+#endif
diff --git a/client/uart.h b/client/uart.h
new file mode 100644 (file)
index 0000000..7b00641
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Proxmark3 generic uart / rs232/ serial port library
+ *
+ * Copyright (c) 2012, Roel Verdult
+ * 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.h
+ * @brief
+ *
+ */
+
+#ifndef _PROXMARK3_RS232_H_
+#define _PROXMARK3_RS232_H_
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef unsigned char byte_t;
+
+// Handle platform specific includes
+#ifndef _WIN32
+  #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>
+#else
+  #include <windows.h>
+#endif
+
+// Define shortcut to types to make code more readable
+typedef void* serial_port;
+#define INVALID_SERIAL_PORT (void*)(~1)
+#define CLAIMED_SERIAL_PORT (void*)(~2)
+
+serial_port uart_open(const char* pcPortName);
+void uart_close(const serial_port sp);
+
+void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed);
+uint32_t uart_get_speed(const serial_port sp);
+
+bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen);
+bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen);
+
+#endif // _PROXMARK3_RS232_H_
+
+
Impressum, Datenschutz