2 * (C) 2006 by Frank Zirkelbach <hackbard@hackdaworld.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2
6 * as published by the Free Software Foundation
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 int asciidump(unsigned char *data,int len) {
31 if((data[i]>0x19)&&(data[i]<0x7f)) printf("%c",data[i]);
38 int hexdump(unsigned char *data,int len) {
41 for(i=0;i<len;i++) printf("%02x ",data[i]);
47 struct usb_device *find_device(unsigned short vendor,unsigned short device) {
50 struct usb_device *dev;
56 if(dev->descriptor.idVendor==vendor &&
57 dev->descriptor.idProduct==device)
66 u_int16_t gemtag_calc_crc(unsigned char *data,u_int16_t len) {
68 u_int16_t crc_polynom;
81 crc=(crc>>1)^crc_polynom;
89 int gemtag_transcieve(struct gemtag_handle *gh,unsigned char cmd,
90 unsigned char *tx,unsigned int tx_len,
91 unsigned char *rx,unsigned int *rx_len) {
93 unsigned char txbuf[256];
94 unsigned char rxbuf[256];
95 struct gemtag_cmd_hdr *txhdr;
96 struct gemtag_cmd_hdr *rxhdr;
97 u_int16_t crc,*crcptr;
100 txhdr=(struct gemtag_cmd_hdr *)txbuf;
101 rxhdr=(struct gemtag_cmd_hdr *)rxbuf;
104 txhdr->seq=++(gh->seq);
107 size=sizeof(struct gemtag_cmd_hdr);
108 memcpy(txbuf+size,tx,tx_len);
112 if(gh->caps&GEMTAG_CAP_CRC) {
113 crcptr=(u_int16_t *)(txbuf+size);
114 crc=gemtag_calc_crc(txbuf,size);
115 //*crcptr=(crc>>8)|(crc<<8);
121 if(gh->caps&GEMTAG_CAP_VERB_TRANSMIT) {
122 printf("(%02d) -> ",size);
125 ret=usb_interrupt_write(gh->handle,0x02,txbuf,size,0);
127 perror("usb interrupt write");
132 ret=usb_interrupt_read(gh->handle,0x81,rxbuf,32,0);
134 perror("usb interrupt read");
138 if(gh->caps&GEMTAG_CAP_VERB_TRANSMIT)
139 printf("short answer (%d)\n",ret);
140 return -SHORT_ANSWER;
143 *rx_len=rxbuf[3]|(rxbuf[4]<<8);
144 size=*rx_len+sizeof(struct gemtag_cmd_hdr);
145 if(gh->caps&GEMTAG_CAP_CRC) size+=2;
150 ret=usb_interrupt_read(gh->handle,0x81,rxbuf+i*32,32,0);
152 perror("usb interrupt read (missing bytes)");
159 if(gh->caps&GEMTAG_CAP_VERB_TRANSMIT) {
160 printf("(%02d) <- ",size);
165 if(gh->caps&GEMTAG_CAP_CRC) {
167 crcptr=(u_int16_t *)(rxbuf+size);
168 crc=gemtag_calc_crc(rxbuf,size);
169 if(((crc>>8)!=rxbuf[size+1])||((crc&0xff)!=rxbuf[size])) {
170 printf("bad crc! (%04x)\n",crc);
175 /* check sequence number */
176 if(rxhdr->seq!=txhdr->seq) {
177 puts("transmitted/recieved sequence number do not match");
178 return -SEQ_MISMATCH;
181 memcpy(rx,rxbuf+sizeof(struct gemtag_cmd_hdr),*rx_len);
186 struct gemtag_handle *gemtag_open(void) {
187 struct usb_device *gemtag;
189 struct gemtag_handle *gh;
196 gemtag=find_device(USB_VENDOR_GEMTAG,USB_DEVICE_X501);
197 if(!gemtag) return NULL;
199 gh=malloc(sizeof(struct gemtag_handle));
202 memset(gh,0,sizeof(struct gemtag_handle));
204 gh->handle=usb_open(gemtag);
209 memset(info,0,sizeof(info));
210 usb_get_string_simple(gh->handle,i,info,sizeof(info));
213 printf("opened successfully\n");
215 if(usb_set_configuration(gh->handle,1)) {
216 perror("set config");
219 printf("set configuration 1, ");
221 if(usb_claim_interface(gh->handle,0)) {
222 perror("claim interface");
225 printf("claimed interface 0, ");
227 if(usb_set_altinterface(gh->handle,0))
228 perror("set alt interface");
229 printf("activated alt setting 0\n");
238 int gemtag_close(struct gemtag_handle *gh) {
240 if(gh->handle) usb_close(gh->handle);
247 int main(int argc, char **argv) {
249 struct gemtag_handle *gh;
250 unsigned char buf[256];
255 gh->caps|=GEMTAG_CAP_CRC;
256 gh->caps|=GEMTAG_CAP_VERB_TRANSMIT;
259 gemtag_transcieve(gh,GEMTAG_CMD_GET_FW_VERSION,
261 asciidump(buf,buflen);
264 printf("Serial Number:\n");
265 gemtag_transcieve(gh,GEMTAG_CMD_GET_SERIAL_NUMBER,
267 printf("Snr: %d (%04x)\n",buf[1]<<8|buf[0],buf[1]<<8|buf[0]);
270 printf("RC632 Version:\n");
271 gemtag_transcieve(gh,GEMTAG_CMD_GET_RIC_VERSION,
275 printf("Switching off the LED!\n");
276 buf[0]=GEMTAG_LED_OFF;
277 gemtag_transcieve(gh,GEMTAG_CMD_SWITCH_LED,
281 printf("Detecting Card ...\n");
282 gemtag_transcieve(gh,GEMTAG_CMD_DETECT_CARD,
284 asciidump(buf,buflen);