+       // strip
+       while (*cmd==' ' || *cmd=='\t') cmd++;
+
+       while (cmd[i]!='\0') {
+               if (cmd[i]==' ' || cmd[i]=='\t') { i++; continue; }
+               if (cmd[i]=='-') {
+                       switch (cmd[i+1]) {
+                               case 'r': 
+                                       reply = false;
+                                       break;
+                               case 'c':
+                                       crc = true;
+                                       break;
+                               case 'p':
+                                       power = true;
+                                       break;
+                               case 'a':
+                                       active = true;
+                                       break;
+                               case 's':
+                                       active_select = true;
+                                       break;
+                               case 'b': 
+                                       sscanf(cmd+i+2,"%d",&temp);
+                                       numbits = temp & 0xFFFF;
+                                       i+=3;
+                                       while(cmd[i]!=' ' && cmd[i]!='\0') { i++; }
+                                       i-=2;
+                                       break;
+                               case 't':
+                                       bTimeout = true;
+                                       sscanf(cmd+i+2,"%d",&temp);
+                                       timeout = temp;
+                                       i+=3;
+                                       while(cmd[i]!=' ' && cmd[i]!='\0') { i++; }
+                                       i-=2;
+                                       break;
+                               case 'T':
+                                       topazmode = true;
+                                       break;
+                               default:
+                                       PrintAndLog("Invalid option");
+                                       return 0;
+                       }
+                       i+=2;
+                       continue;
+               }
+               if ((cmd[i]>='0' && cmd[i]<='9') ||
+                   (cmd[i]>='a' && cmd[i]<='f') ||
+                   (cmd[i]>='A' && cmd[i]<='F') ) {
+                       buf[strlen(buf)+1]=0;
+                       buf[strlen(buf)]=cmd[i];
+                       i++;
+
+                       if (strlen(buf)>=2) {
+                               sscanf(buf,"%x",&temp);
+                               data[datalen]=(uint8_t)(temp & 0xff);
+                               *buf=0;
+                               if (datalen > sizeof(data)-1) {
+                                       if (crc)
+                                               PrintAndLog("Buffer is full, we can't add CRC to your data");
+                                       break;
+                               } else {
+                                       datalen++;
+                               }
+                       }
+                       continue;
+               }
+               PrintAndLog("Invalid char on input");
+               return 0;
+       }
+
+       if(crc && datalen>0 && datalen<sizeof(data)-2)
+       {
+               uint8_t first, second;
+               if (topazmode) {
+                       ComputeCrc14443(CRC_14443_B, data, datalen, &first, &second);
+               } else {
+                       ComputeCrc14443(CRC_14443_A, data, datalen, &first, &second);
+               }
+               data[datalen++] = first;
+               data[datalen++] = second;
+       }
+
+       if(active || active_select)
+       {
+               c.arg[0] |= ISO14A_CONNECT;
+               if(active)
+                       c.arg[0] |= ISO14A_NO_SELECT;
+       }
+
+       if(bTimeout){
+               #define MAX_TIMEOUT 40542464    // = (2^32-1) * (8*16) / 13560000Hz * 1000ms/s
+               c.arg[0] |= ISO14A_SET_TIMEOUT;
+               if(timeout > MAX_TIMEOUT) {
+                       timeout = MAX_TIMEOUT;
+                       PrintAndLog("Set timeout to 40542 seconds (11.26 hours). The max we can wait for response");
+               }
+               c.arg[2] = 13560000 / 1000 / (8*16) * timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us)
+       }
+
+       if(power) {
+               c.arg[0] |= ISO14A_NO_DISCONNECT;
+       }
+
+       if(datalen > 0) {
+               c.arg[0] |= ISO14A_RAW;
+       }
+
+       if(topazmode) {
+               c.arg[0] |= ISO14A_TOPAZMODE;
+       }
+
+       // Max buffer is USB_CMD_DATA_SIZE (512)
+       c.arg[1] = (datalen & 0xFFFF) | ((uint32_t)numbits << 16);
+       memcpy(c.d.asBytes,data,datalen);
+
+       SendCommand(&c);
+
+       if (reply) {
+               if(active_select)
+                       waitCmd(1);
+               if(datalen>0)
+                       waitCmd(0);
+       } // if reply
+       return 0;