+int gemtag_transform_mifare_key(struct gemtag_handle *gh,
+ unsigned char *key6,unsigned char *key12) {
+
+ unsigned int len;
+
+ gemtag_transceive(gh,GEMTAG_CMD_HOST_CODE_KEY,key6,6,key12,&len);
+
+ return 0;
+}
+
+int gemtag_auth_e2(struct gemtag_handle *gh,unsigned char authmode,
+ int sector,unsigned char *key6) {
+
+ unsigned char buf[32];
+ unsigned int len,ret;
+
+ /* memory layout (sector/block) ? */
+
+ buf[0]=authmode;
+ buf[1]=0;
+ memcpy(buf+2,key6,6);
+ ret=gemtag_transceive(gh,GEMTAG_CMD_PCD_LOAD_KEY_E2,buf,8,buf,&len);
+ if(ret) return -LOAD_E2_FAILED;
+
+ buf[0]=authmode;
+ memcpy(buf+1,gh->serial,4);
+ buf[5]=0;
+ buf[6]=sector;
+ ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_AUTH_E2,buf,7,buf,&len);
+ if(ret) return -AUTH_E2_FAILED;
+
+ return 0;
+
+}
+
+int gemtag_auth_mifare_key(struct gemtag_handle *gh,
+ unsigned char *key6,int sector) {
+
+ unsigned char key12[12];
+ unsigned char buf[32];
+ unsigned int len,ret;
+
+ gemtag_transform_mifare_key(gh,key6,key12);
+
+ buf[0]=GEMTAG_PICC_AUTHENT1A; /* auth mode */
+ memcpy(buf+1,gh->serial,4); /* sreial */
+ memcpy(buf+5,key12,12); /* transformed key */
+ buf[17]=sector; /* sector */
+ ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_AUTH_KEY,buf,18,
+ buf,&len);
+ if(ret) return -AUTH_FAILED;
+
+ return 0;
+}
+
+int gemtag_read16(struct gemtag_handle *gh,int sector,unsigned char *data) {
+
+ unsigned char buf[32];
+ int len,ret;
+
+ buf[0]=sector;
+ ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_READ,buf,1,data,&len);
+ if(ret) return -READ_FAILED;
+
+ return 0;
+}
+
+int gemtag_write16(struct gemtag_handle *gh,int sector,unsigned char *data) {
+
+ unsigned char buf[32];
+ int ret,len;
+
+ buf[0]=sector;
+ memcpy(buf+1,data,16);
+ ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_WRITE,buf,17,buf,&len);
+ if(ret) return -WRITE_FAILED;
+
+ return 0;
+}
+
+int gemtag_select_picc(struct gemtag_handle *gh) {
+
+ unsigned char buf[16];
+ unsigned int len;
+ int ret;
+
+ buf[0]=GEMTAG_PICC_REQIDL;
+ ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_REQUEST,buf,1,buf,&len);
+ if(ret) return -NO_PICC;
+
+ buf[0]=GEMTAG_PICC_STD_SELECT_CODE;
+ memset(buf+1,0,5);
+ ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_CASC_ANTICOLL,buf,6,buf,&len);
+ if(ret) return -NO_PICC;
+ memcpy(gh->serial,buf,4);
+
+ buf[0]=GEMTAG_PICC_STD_SELECT_CODE;
+ memcpy(buf+1,gh->serial,4);
+ ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_CASC_SELECT,buf,5,buf,&len);
+ if(ret) return -PICC_SELECT_ERROR;
+
+ return 0;
+}
+