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;
89 txhdr=(struct gemtag_cmd_hdr *)txbuf;
90 rxhdr=(struct gemtag_cmd_hdr *)rxbuf;
93 txhdr->seq=++(gh->seq);
95 txhdr->len=htons(tx_len);
96 size=sizeof(struct gemtag_cmd_hdr);
97 memcpy(txbuf+size,tx,tx_len);
100 if(gh->capabilities&GEMTAG_CAP_CRC) {
102 crcptr=(u_int16_t *)(txbuf+size);
103 *crcptr=htons(gemtag_calc_crc(txbuf,size));
110 usb_clear_halt(gh->handle,0x02);
111 ret=usb_bulk_write(gh->handle,0x02,txbuf,size,0);
113 perror("usb bulk write");
118 usb_clear_halt(gh->handle,0x81);
119 ret=usb_bulk_read(gh->handle,0x81,rxbuf,sizeof(rxbuf),0);
122 perror("usb bulk read");
128 if(rxhdr->seq!=txhdr->seq)
129 puts("transmitted/recieved sequence number do not match");
134 *rx_len=ntohs(rxhdr->len);
135 memcpy(rx,rxbuf+sizeof(struct gemtag_cmd_hdr),
136 ret-sizeof(struct gemtag_cmd_hdr)+2);
137 hexdump(rxbuf,ret+2);
142 struct gemtag_handle *gemtag_open(void) {
143 struct usb_device *gemtag;
144 unsigned char rbuf[16];
146 unsigned int i,numconf;
147 unsigned int j,numint;
148 unsigned int k,numalt;
149 struct gemtag_handle *gh;
157 gemtag=find_device(USB_VENDOR_GEMTAG, USB_DEVICE_X501);
158 if(!gemtag) return NULL;
160 gh=malloc(sizeof(struct gemtag_handle));
163 memset(gh,0,sizeof(struct gemtag_handle));
165 numconf=gemtag->descriptor.bNumConfigurations;
166 printf("found gemtag (%02x/%02x), %u configuration(s)\n",
167 gemtag->descriptor.idVendor,
168 gemtag->descriptor.idProduct,numconf);
169 for(i=0;i<numconf;i++) {
170 numint=gemtag->config[i].bNumInterfaces;
171 printf(" config %u [nr %u] has %u interface(s)\n",
172 i,gemtag->config[i].bConfigurationValue,
174 for(j=0;j<numint;j++) {
175 numalt=gemtag->config[i].interface[j].num_altsetting;
176 printf(" interface %u has %u altsetting(s): ",
178 for(k=0;k<numalt;k++)
180 gemtag->config[i].interface[j].altsetting[k].bAlternateSetting);
185 gh->handle=usb_open(gemtag);
188 puts("usb_open successfull");
190 if(usb_set_configuration(gh->handle,1)) {
191 perror("set config");
194 puts("configuration 1 successfully set");
196 if(usb_claim_interface(gh->handle,0)) {
197 perror("claim interface");
200 puts("interface 0 claimed");
202 while(usb_set_altinterface(gh->handle,0))
203 printf("trying to set alt interface\n");
204 puts("alt setting 0 selected");
206 gh->capabilities|=GEMTAG_CAP_CRC;
208 gemtag_transcieve(gh,GEMTAG_CMD_GET_FW_VERSION,
218 int main(int argc, char **argv) {
220 struct gemtag_handle *gh;