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 hexdump(unsigned char *data,int len) {
30 for(i=0;i<len;i++) printf("%02x ",data[i]);
36 struct usb_device *find_device(unsigned short vendor,unsigned short device) {
39 struct usb_device *dev;
45 if(dev->descriptor.idVendor==vendor &&
46 dev->descriptor.idProduct==device)
55 u_int16_t gemtag_calc_crc(unsigned char *data,u_int16_t len) {
57 u_int16_t crc_polynom;
70 crc=(crc>>1)^crc_polynom;
78 int gemtag_transcieve(struct gemtag_handle *gh,unsigned char cmd,
79 unsigned char *tx,unsigned int tx_len,
80 unsigned char *rx,unsigned int *rx_len) {
82 unsigned char txbuf[256];
83 unsigned char rxbuf[256];
84 struct gemtag_cmd_hdr *txhdr;
85 struct gemtag_cmd_hdr *rxhdr;
86 unsigned char buf[32];
87 u_int16_t crc,*crcptr;
90 txhdr=(struct gemtag_cmd_hdr *)txbuf;
91 rxhdr=(struct gemtag_cmd_hdr *)rxbuf;
94 txhdr->seq=++(gh->seq);
96 txhdr->len=(tx_len>>8)|(tx_len<<8);
97 size=sizeof(struct gemtag_cmd_hdr);
98 memcpy(txbuf+size,tx,tx_len);
102 if(gh->capabilities&GEMTAG_CAP_CRC) {
103 crcptr=(u_int16_t *)(txbuf+size);
104 crc=gemtag_calc_crc(txbuf,size);
105 *crcptr=(crc>>8)|(crc<<8);
110 printf("(%02d) -> ",size);
112 ret=usb_interrupt_write(gh->handle,0x02,txbuf,size,0);
114 perror("usb interrupt write");
119 ret=usb_interrupt_read(gh->handle,0x81,buf,32,0);
121 perror("usb interrupt read");
124 memcpy(rxbuf,buf,ret);
125 printf("(%02d) <- ",ret);
128 *rx_len=buf[3]|(buf[4]<<8);
129 printf("debug: length according to header -> %d 0x%04x\n",
134 if(gh->capabilities&GEMTAG_CAP_CRC) {
136 crcptr=(u_int16_t *)(rxbuf+size);
137 crc=gemtag_calc_crc(rxbuf,size);
138 if(((crc>>8)!=rxbuf[size+1])||((crc&0xff)!=rxbuf[size])) {
139 printf("bad crc! (%04x)\n",crc);
144 /* check sequence number */
145 if(rxhdr->seq!=txhdr->seq) {
146 puts("transmitted/recieved sequence number do not match");
147 //return -SEQ_MISMATCH;
150 memcpy(rx,rxbuf+sizeof(struct gemtag_cmd_hdr),*rx_len);
155 struct gemtag_handle *gemtag_open(void) {
156 struct usb_device *gemtag;
157 unsigned char rbuf[256];
159 struct gemtag_handle *gh;
168 gemtag=find_device(USB_VENDOR_GEMTAG,USB_DEVICE_X501);
169 if(!gemtag) return NULL;
171 gh=malloc(sizeof(struct gemtag_handle));
174 memset(gh,0,sizeof(struct gemtag_handle));
176 gh->handle=usb_open(gemtag);
181 memset(info,0,sizeof(info));
182 usb_get_string_simple(gh->handle,i,info,sizeof(info));
185 printf("opened successfully\n");
187 if(usb_set_configuration(gh->handle,1)) {
188 perror("set config");
191 printf("set configuration 1, ");
193 if(usb_claim_interface(gh->handle,0)) {
194 perror("claim interface");
197 printf("claimed interface 0, ");
199 if(usb_set_altinterface(gh->handle,0))
200 perror("set alt interface");
201 printf("activated alt setting 0\n");
203 gh->capabilities|=GEMTAG_CAP_CRC;
205 gemtag_transcieve(gh,GEMTAG_CMD_GET_FW_VERSION,
207 gemtag_transcieve(gh,GEMTAG_CMD_GET_SERIAL_NUMBER,
217 int main(int argc, char **argv) {
219 struct gemtag_handle *gh;