basic functions added, problem: altsetting ...
[rfid/librfid.git] / gemtag / gemtag.c
1 /*
2  * (C) 2006 by Frank Zirkelbach <hackbard@hackdaworld.org>
3  *
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
7  *
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.
12  *
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
16  */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <string.h>
22 #include <errno.h>
23
24 #include <usb.h>
25 #include "gemtag.h"
26
27 int hexdump(unsigned char *data,int len) {
28         int i;
29
30         printf("dump: ");
31         for(i=0;i<len;i++) printf("%02x ",data[i]);
32         printf("\n");
33
34         return 0;
35 }
36
37 struct usb_device *find_device(unsigned short vendor,unsigned short device) {
38         
39         struct usb_bus *bus;
40         struct usb_device *dev;
41
42         bus=usb_get_busses();
43         while(bus) {
44                 dev=bus->devices;
45                 while(dev) {
46                         if(dev->descriptor.idVendor==vendor &&
47                            dev->descriptor.idProduct==device)
48                                 return dev;
49                         dev=dev->next;
50                 }
51                 bus=bus->next;
52         }
53         return NULL;
54 }
55
56 u_int16_t gemtag_calc_crc(unsigned char *data,u_int16_t len) {
57
58         u_int16_t crc_polynom;
59         u_int16_t crc_preset;
60         u_int16_t crc;
61         int i,j;
62                 
63         crc_polynom=0x8408;
64         crc_preset=0xffff;
65         crc=0xffff;
66
67         for(i=0;i<len;i++) {
68                 crc^=data[i];
69                 for(j=0;j<8;j++) {
70                         if(crc&0x0001)
71                                 crc=(crc>>1)^crc_polynom;
72                         else
73                                 crc=(crc>>1);
74                 }
75         }
76         return crc;
77 }
78
79 int gemtag_transcieve(struct gemtag_handle *gh,unsigned char cmd,
80                          unsigned char *tx,unsigned int tx_len,
81                          unsigned char *rx,unsigned int *rx_len) {
82
83         unsigned char txbuf[256];
84         unsigned char rxbuf[256];
85         struct gemtag_cmd_hdr *txhdr;
86         struct gemtag_cmd_hdr *rxhdr;
87         u_int16_t *crcptr;
88         int ret,size;
89
90         txhdr=(struct gemtag_cmd_hdr *)txbuf;
91         rxhdr=(struct gemtag_cmd_hdr *)rxbuf;
92
93         txhdr->start=0xa5;
94         txhdr->seq=++(gh->seq);
95         txhdr->cmd=cmd;
96         txhdr->len=htons(tx_len);
97         size=sizeof(struct gemtag_cmd_hdr);
98         memcpy(txbuf+size,tx,tx_len);
99
100         /* crc check */
101         gh->capabilities=GEMTAG_CAP_CRC;
102         if(gh->capabilities&GEMTAG_CAP_CRC) {
103                 size+=tx_len;
104                 crcptr=(u_int16_t *)(txbuf+size);
105                 *crcptr=gemtag_calc_crc(txbuf,size);
106                 size+=2;
107         }
108
109         /* usb write */
110         hexdump(txbuf,size);
111         ret=usb_bulk_write(gh->handle,0x02,txbuf,size,0);
112         if(ret<0) {
113                 perror("usb bulk write");
114                 return ret;
115         }
116         printf("write of %d bytes successfull\n",ret);
117
118         /* usb read */
119         ret=usb_bulk_read(gh->handle,0x81,rxbuf,sizeof(rxbuf),0);
120         size=ret;
121         if(ret<0) {
122                 perror("usb bulk read");
123                 return ret;
124         }
125         printf("received %d bytes\n",ret);
126         
127         if(rxhdr->seq!=txhdr->seq)
128                 puts("transmitted/recieved header are not equal");
129
130         /* crc check */
131         
132
133         *rx_len=ntohs(rxhdr->len);
134         memcpy(rx,rxbuf+sizeof(struct gemtag_cmd_hdr),
135                ret-sizeof(struct gemtag_cmd_hdr)+2);
136         hexdump(rxbuf,ret+2);
137
138         return 0;
139 }
140
141 struct gemtag_handle *gemtag_open(void) {
142         struct usb_device *gemtag;
143         unsigned char rbuf[16];
144         unsigned int rlen;
145         unsigned int i,numconf;
146         unsigned int j,numint;
147         struct gemtag_handle *gh;
148
149         rlen=sizeof(rbuf);
150
151         usb_init();
152         usb_find_busses();
153         usb_find_devices();
154
155         gemtag=find_device(USB_VENDOR_GEMTAG, USB_DEVICE_X501);
156         if(!gemtag) return NULL;
157
158         gh=malloc(sizeof(struct gemtag_handle));
159         if(!gh) return NULL;
160
161         memset(gh,0,sizeof(struct gemtag_handle));
162
163         numconf=gemtag->descriptor.bNumConfigurations;
164         printf("found gemtag, %u configuration(s)\n",numconf);
165         for(i=0;i<numconf;i++) {
166                 numint=gemtag->config[i].bNumInterfaces;
167                 printf("config %u [nr %u] has %u interface(s)\n",
168                        i,gemtag->config[i].bConfigurationValue,
169                        numint);
170                 for(j=0;j<numint;j++) {
171                         printf("config %u interface %u has %u altsetting(s)\n",
172                                i,j,gemtag->config[i].interface[j].num_altsetting);
173                 }
174         }
175
176         gh->handle=usb_open(gemtag);
177         if(!gh->handle)
178                 goto out_free;
179         puts("usb_open successfull");
180
181         if(usb_set_configuration(gh->handle,1)) {
182                 perror("set config");
183                 goto out_free;
184         }
185         puts("configuration 1 successfully set");
186
187         if(usb_claim_interface(gh->handle,0)) {
188                 perror("claim interface");
189                 goto out_free;
190         }
191         puts("interface 0 claimed");
192
193 /*      if(usb_set_altinterface(gh->handle,1)) {
194                 perror("set alt interface");
195                 goto out_free;
196         }
197         puts("alt setting 1 selected");
198 */
199
200         gh->capabilities|=GEMTAG_CAP_CRC;
201
202         gemtag_transcieve(gh,0x22,NULL,0,rbuf,&rlen);
203
204         return gh;
205
206 out_free:
207         free(gh);
208         return NULL;
209 }
210         
211 int main(int argc, char **argv) {
212
213         struct gemtag_handle *gh;
214
215         gh=gemtag_open();
216
217         return 1;
218 }
219