#include <usb.h>
#include "gemtag.h"
-/* variables */
+int hexdump(unsigned char *data,int len) {
+ int i;
-struct gemtag_handle {
- struct usb_dev_handle *handle;
-};
+ for(i=0;i<len;i++) printf("%02x ",data[i]);
+ printf("\n");
-/* functions */
+ return 0;
+}
-struct usb_device *find_device(unsigned short vendor, unsigned short device) {
+struct usb_device *find_device(unsigned short vendor,unsigned short device) {
struct usb_bus *bus;
struct usb_device *dev;
return NULL;
}
+u_int16_t gemtag_calc_crc(unsigned char *data,u_int16_t len) {
+
+ u_int16_t crc_polynom;
+ u_int16_t crc_preset;
+ u_int16_t crc;
+ int i,j;
+
+ crc_polynom=0x8408;
+ crc_preset=0xffff;
+ crc=0xffff;
+
+ for(i=0;i<len;i++) {
+ crc^=data[i];
+ for(j=0;j<8;j++) {
+ if(crc&0x0001)
+ crc=(crc>>1)^crc_polynom;
+ else
+ crc=(crc>>1);
+ }
+ }
+ return crc;
+}
+
+int gemtag_transcieve(struct gemtag_handle *gh,unsigned char cmd,
+ unsigned char *tx,unsigned int tx_len,
+ unsigned char *rx,unsigned int *rx_len) {
+
+ unsigned char txbuf[256];
+ unsigned char rxbuf[256];
+ struct gemtag_cmd_hdr *txhdr;
+ struct gemtag_cmd_hdr *rxhdr;
+ u_int16_t *crcptr;
+ int ret,size;
+
+ txhdr=(struct gemtag_cmd_hdr *)txbuf;
+ rxhdr=(struct gemtag_cmd_hdr *)rxbuf;
+
+ txhdr->start=0xa5;
+ txhdr->seq=++(gh->seq);
+ txhdr->cmd=cmd;
+ txhdr->len=htons(tx_len);
+ size=sizeof(struct gemtag_cmd_hdr);
+ memcpy(txbuf+size,tx,tx_len);
+
+ /* crc check */
+ if(gh->capabilities&GEMTAG_CAP_CRC) {
+ size+=tx_len;
+ crcptr=(u_int16_t *)(txbuf+size);
+ *crcptr=htons(gemtag_calc_crc(txbuf,size));
+ size+=2;
+ }
+
+ /* usb write */
+ printf("-> ");
+ hexdump(txbuf,size);
+ if(usb_clear_halt(gh->handle,0x02))
+ perror("clear halt (out)");
+ ret=usb_bulk_write(gh->handle,0x02,txbuf,size,0);
+ if(ret<=0) {
+ perror("usb bulk write");
+ return ret;
+ }
+
+ /* usb read */
+ if(usb_clear_halt(gh->handle,0x81))
+ perror("clear halt (in)");
+ ret=usb_bulk_read(gh->handle,0x81,rxbuf,sizeof(rxbuf),0);
+ size=ret;
+ if(ret<=0) {
+ perror("usb bulk read");
+ return ret;
+ }
+ printf("<- ");
+ hexdump(rxbuf,ret);
+
+ if(rxhdr->seq!=txhdr->seq)
+ puts("transmitted/recieved sequence number do not match");
+
+ /* crc check */
+
+
+ *rx_len=ntohs(rxhdr->len);
+ memcpy(rx,rxbuf+sizeof(struct gemtag_cmd_hdr),
+ ret-sizeof(struct gemtag_cmd_hdr)+2);
+ hexdump(rxbuf,ret+2);
+
+ return 0;
+}
+
struct gemtag_handle *gemtag_open(void) {
struct usb_device *gemtag;
unsigned char rbuf[16];
unsigned int rlen;
unsigned int i,numconf;
unsigned int j,numint;
+ unsigned int k,numalt;
struct gemtag_handle *gh;
rlen=sizeof(rbuf);
memset(gh,0,sizeof(struct gemtag_handle));
numconf=gemtag->descriptor.bNumConfigurations;
- printf("found gemtag, %u configurations\n",numconf);
+ printf("found gemtag (%02x/%02x), %u configuration(s)\n",
+ gemtag->descriptor.idVendor,
+ gemtag->descriptor.idProduct,numconf);
for(i=0;i<numconf;i++) {
numint=gemtag->config[i].bNumInterfaces;
- printf("config %u [nr %u] has %u interfaces\n",
+ printf(" config %u [nr %u] has %u interface(s)\n",
i,gemtag->config[i].bConfigurationValue,
numint);
for(j=0;j<numint;j++) {
- printf("config %u interface %u has %u altsettings\n",
- i,j,gemtag->config[i].interface[j].num_altsetting);
+ numalt=gemtag->config[i].interface[j].num_altsetting;
+ printf(" interface %u has %u altsetting(s): ",
+ j,numalt);
+ for(k=0;k<numalt;k++)
+ printf("%u ",
+ gemtag->config[i].interface[j].altsetting[k].bAlternateSetting);
+ printf("\n");
}
}
gh->handle=usb_open(gemtag);
if(!gh->handle)
goto out_free;
+ puts("usb_open successfull");
+
+ if(usb_set_configuration(gh->handle,1)) {
+ perror("set config");
+ goto out_free;
+ }
+ puts("configuration 1 successfully set");
+
+ if(usb_claim_interface(gh->handle,0)) {
+ perror("claim interface");
+ goto out_free;
+ }
+ puts("interface 0 claimed");
+
+ while(usb_set_altinterface(gh->handle,0))
+ printf("trying to set alt interface\n");
+ puts("alt setting 0 selected");
+
+ gh->capabilities|=GEMTAG_CAP_CRC;
+
+ gemtag_transcieve(gh,GEMTAG_CMD_GET_FW_VERSION,
+ NULL,0,rbuf,&rlen);
+
+ return gh;
out_free:
free(gh);