#include <usb.h>
#include "gemtag.h"
+int asciidump(unsigned char *data,int len) {
+ int i;
+
+ for(i=0;i<len;i++)
+ if((data[i]>0x19)&&(data[i]<0x7f)) printf("%c",data[i]);
+ else printf("_");
+ printf("\n");
+
+ return 0;
+}
+
int hexdump(unsigned char *data,int len) {
int i;
unsigned char rxbuf[256];
struct gemtag_cmd_hdr *txhdr;
struct gemtag_cmd_hdr *rxhdr;
- unsigned char buf[32];
u_int16_t crc,*crcptr;
- int ret,size;
+ int i,ret,size,rest;
txhdr=(struct gemtag_cmd_hdr *)txbuf;
rxhdr=(struct gemtag_cmd_hdr *)rxbuf;
txhdr->start=0xa5;
txhdr->seq=++(gh->seq);
txhdr->cmd=cmd;
- txhdr->len=(tx_len>>8)|(tx_len<<8);
+ txhdr->len=tx_len;
size=sizeof(struct gemtag_cmd_hdr);
memcpy(txbuf+size,tx,tx_len);
size+=tx_len;
/* crc check */
- if(gh->capabilities&GEMTAG_CAP_CRC) {
+ if(gh->caps&GEMTAG_CAP_CRC) {
crcptr=(u_int16_t *)(txbuf+size);
crc=gemtag_calc_crc(txbuf,size);
- *crcptr=(crc>>8)|(crc<<8);
+ //*crcptr=(crc>>8)|(crc<<8);
+ *crcptr=crc;
size+=2;
}
/* usb write */
- printf("(%02d) -> ",size);
- hexdump(txbuf,size);
+ if(gh->caps&GEMTAG_CAP_VERB_TRANSMIT) {
+ printf("(%02d) -> ",size);
+ hexdump(txbuf,size);
+ }
ret=usb_interrupt_write(gh->handle,0x02,txbuf,size,0);
if(ret<=0) {
perror("usb interrupt write");
}
/* usb read */
- ret=usb_interrupt_read(gh->handle,0x81,buf,32,0);
+ ret=usb_interrupt_read(gh->handle,0x81,rxbuf,32,0);
if(ret<=0) {
perror("usb interrupt read");
return ret;
}
- memcpy(rxbuf,buf,ret);
- printf("(%02d) <- ",ret);
- hexdump(rxbuf,ret);
+ if(ret<5) {
+ if(gh->caps&GEMTAG_CAP_VERB_TRANSMIT)
+ printf("short answer (%d)\n",ret);
+ return -SHORT_ANSWER;
+ }
- *rx_len=buf[3]|(buf[4]<<8);
- printf("debug: length according to header -> %d 0x%04x\n",
- *rx_len,*rx_len);
- size=*rx_len+5;
+ *rx_len=rxbuf[3]|(rxbuf[4]<<8);
+ size=*rx_len+sizeof(struct gemtag_cmd_hdr);
+ if(gh->caps&GEMTAG_CAP_CRC) size+=2;
+
+ i=1;
+ rest=size-ret;
+ while(rest>=0) {
+ ret=usb_interrupt_read(gh->handle,0x81,rxbuf+i*32,32,0);
+ if(ret<=0) {
+ perror("usb interrupt read (missing bytes)");
+ return ret;
+ }
+ i++;
+ rest-=ret;
+ }
+
+ if(gh->caps&GEMTAG_CAP_VERB_TRANSMIT) {
+ printf("(%02d) <- ",size);
+ hexdump(rxbuf,size);
+ }
/* crc check */
- if(gh->capabilities&GEMTAG_CAP_CRC) {
- size=ret-2;
+ if(gh->caps&GEMTAG_CAP_CRC) {
+ size-=2;
crcptr=(u_int16_t *)(rxbuf+size);
crc=gemtag_calc_crc(rxbuf,size);
if(((crc>>8)!=rxbuf[size+1])||((crc&0xff)!=rxbuf[size])) {
printf("bad crc! (%04x)\n",crc);
- //return -BAD_CRC;
+ return -BAD_CRC;
}
}
/* check sequence number */
if(rxhdr->seq!=txhdr->seq) {
puts("transmitted/recieved sequence number do not match");
- //return -SEQ_MISMATCH;
+ return -SEQ_MISMATCH;
}
memcpy(rx,rxbuf+sizeof(struct gemtag_cmd_hdr),*rx_len);
struct gemtag_handle *gemtag_open(void) {
struct usb_device *gemtag;
- unsigned char rbuf[256];
- unsigned int i,rlen;
+ unsigned int i;
struct gemtag_handle *gh;
char info[64];
- rlen=sizeof(rbuf);
-
usb_init();
usb_find_busses();
usb_find_devices();
perror("set alt interface");
printf("activated alt setting 0\n");
- gh->capabilities|=GEMTAG_CAP_CRC;
-
- gemtag_transcieve(gh,GEMTAG_CMD_GET_FW_VERSION,
- NULL,0,rbuf,&rlen);
- gemtag_transcieve(gh,GEMTAG_CMD_GET_SERIAL_NUMBER,
- NULL,0,rbuf,&rlen);
-
return gh;
out_free:
free(gh);
return NULL;
}
+
+int gemtag_close(struct gemtag_handle *gh) {
+
+ if(gh->handle) usb_close(gh->handle);
+ if(gh) free(gh);
+
+ return 0;
+}
+
int main(int argc, char **argv) {
struct gemtag_handle *gh;
+ unsigned char buf[256];
+ unsigned int buflen;
gh=gemtag_open();
+ gh->caps|=GEMTAG_CAP_CRC;
+ gh->caps|=GEMTAG_CAP_VERB_TRANSMIT;
+
+ printf("Device:\n");
+ gemtag_transcieve(gh,GEMTAG_CMD_GET_FW_VERSION,
+ NULL,0,buf,&buflen);
+ asciidump(buf,buflen);
+ printf("\n");
+
+ printf("Serial Number:\n");
+ gemtag_transcieve(gh,GEMTAG_CMD_GET_SERIAL_NUMBER,
+ NULL,0,buf,&buflen);
+ printf("Snr: %d (%04x)\n",buf[1]<<8|buf[0],buf[1]<<8|buf[0]);
+ printf("\n");
+
+ printf("RC632 Version:\n");
+ gemtag_transcieve(gh,GEMTAG_CMD_GET_RIC_VERSION,
+ NULL,0,buf,&buflen);
+ printf("\n");
+
+ printf("Switching off the LED!\n");
+ buf[0]=GEMTAG_LED_OFF;
+ gemtag_transcieve(gh,GEMTAG_CMD_SWITCH_LED,
+ buf,1,buf,&buflen);
+ printf("\n");
+
+ printf("Detecting Card ...\n");
+ gemtag_transcieve(gh,GEMTAG_CMD_DETECT_CARD,
+ NULL,0,buf,&buflen);
+ asciidump(buf,buflen);
+ printf("\n");
+
+ gemtag_close(gh);
+
return 1;
}
struct gemtag_handle {
struct usb_dev_handle *handle;
unsigned char seq;
- unsigned char capabilities;
+ unsigned char caps;
unsigned char snr[4];
};
-#define GEMTAG_CAP_CRC 0x01
+#define GEMTAG_CAP_CRC 0x01
+#define GEMTAG_CAP_VERB_TRANSMIT 0x02
struct gemtag_cmd_hdr {
unsigned char start;
u_int16_t len;
} __attribute__ ((packed));
+#define BAD_CRC 0x01
+#define SEQ_MISMATCH 0x02
+#define SHORT_ANSWER 0x03
+
+/* gemtag commands */
+
#define GEMTAG_CMD_GET_FW_VERSION 0x63
-#define GEMTAG_CMD_GET_SERIAL_NUMBER 0x22
#define GEMTAG_CMD_GET_RIC_VERSION 0x64
-#define GEMTAG_CMD_PCD_SET_TMO 0x27
+
#define GEMTAG_CMD_SET_CPU_TIMEOUT 0x88
-#define GEMTAG_CMD_TEST 0xfe
-#define BAD_CRC 0x01
-#define SEQ_MISMATCH 0x02
+
+#define GEMTAG_CMD_PICC_EXCHANGE_BLOCK 0x48
+
+
+
+#define GEMTAG_CMD_PICC_ACTIVATE_IDLE 0x43
+#define GEMTAG_CMD_PICC_ACTIVATE_WAKEUP 0x44
+
+#define GEMTAG_CMD_PICC_REQUEST 0x40
+#define GEMTAG_PICC_REQALL 0x52
+#define GEMTAG_PICC_REQIDL 0x26
+
+#define GEMTAG_CMD_PICC_CASC_ANTICOLL 0x41
+#define GEMTAG_CMD_PICC_CASC_SELECT 0x42
+#define GEMTAG_PICC_STD_SELECT_CODE 0x93
+#define GEMTAG_PICC_CASC_LEVEL1 0x95
+#define GEMTAG_PICC_CASC_LEVEL2 0x97
+
+#define GEMTAG_CMD_PCD_CONFIG 0x10
+#define GEMTAG_CMD_PICC_ANTICOLL 0x12
+#define GEMTAG_CMD_PICC_SELECT 0x13
+
+#define GEMTAG_CMD_PICC_AUTH 0x14
+#define GEMTAG_CMD_PICC_AUTH_E2 0x15
+#define GEMTAG_CMD_HOST_CODE_KEY 0x16
+#define GEMTAG_CMD_PCD_LOAD_KEY_E2 0x17
+#define GEMTAG_CMD_PICC_AUTH_KEY 0x18
+#define GEMTAG_PICC_AUTHENT1A
+#define GEMTAG_PICC_AUTHENT1B
+
+#define GEMTAG_CMD_PICC_READ 0x19
+#define GEMTAG_CMD_PICC_WRITE 0x1a
+#define GEMTAG_CMD_PICC_VALUE 0x1b
+#define GEMTAG_CMD_PICC_VALUE_DEBIT 0x1c
+#define GEMTAG_PICC_INCREMENT
+#define GEMTAG_PICC_DECREMENT
+#define GEMTAG_PICC_RESTORE
+#define GEMTAG_CMD_PICC_HALT 0x1d
+#define GEMTAG_CMD_PICC_WRITE4 0x1e
+#define GEMTAG_CMD_COMMON_WRITE 0x1f
+#define GEMTAG_PICC_WRITE16
+#define GEMTAG_PICC_WRITE4
+
+#define GEMTAG_CMD_PCD_RF_RESET 0x20
+
+#define GEMTAG_CMD_GET_SERIAL_NUMBER 0x22
+
+#define GEMTAG_CMD_PCD_READ_E2 0x23
+#define GEMTAG_CMD_PCD_WRITE_E2 0x24
+
+#define GEMTAG_CMD_PCD_SET_TMO 0x27
+
+#define GEMTAG_CMD_PICC_COMMON_READ 0x28
+#define GEMTAG_PICC_READ16
+
+#define GEMTAG_CMD_SET_ATTRIBUTES 0x46
+#define GEMTAG_CMD_SET_DFLT_ATTRIBUTES 0x45
+
+#define GEMTAG_CMD_PPS_REQUEST 0xa0
+#define GEMTAG_CMD_DESELECT 0xa1
+
+#define GEMTAG_CMD_SET_DEFAULT_BAUDRATE 0x81
+#define GEMTAG_CMD_SET_ONLINE_BAUDRATE 0x82
+
+#define GEMTAG_CMD_SWITCH_LED 0x60
+#define GEMTAG_LED_OFF 0x00
+#define GEMTAG_LED_ON 0x01
+
+#define GEMTAG_CMD_DETECT_CARD 0x92
+#define GEMTAG_CMD_DETECT_ISO15693_CARD 0x93
+
#endif