SCSI 命令构造应用:USB指纹模块

来源:互联网 发布:动漫水晶淘宝店 编辑:程序博客网 时间:2024/05/16 02:08
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/statfs.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <execinfo.h>
#include <signal.h>
//for scsi cnd
#include <scsi/sg.h>


#define EXIT_SUCCESS 0
#define EXIT_FAILED 0
static int g_exit =0;
#define DEF_TIMEOUT 60000       /* 60,000 millisecs == 60 seconds */
//公共函数
struct  sg_io_hdr * init_io_hdr() {
  struct sg_io_hdr * p_scsi_hdr = (struct sg_io_hdr *)malloc(sizeof(struct sg_io_hdr));
memset(p_scsi_hdr, 0, sizeof(struct sg_io_hdr));
  if (p_scsi_hdr) {
    p_scsi_hdr->interface_id = 'S'; /* this is the only choice we have! */
    /* this would put the LUN to 2nd byte of cdb*/
    p_scsi_hdr->flags = SG_FLAG_LUN_INHIBIT; 
  }
  return p_scsi_hdr;
}


void destroy_io_hdr(struct sg_io_hdr * p_hdr) {
    if (p_hdr) {
        free(p_hdr);
    }
}


void set_xfer_data(struct sg_io_hdr * p_hdr, void * data, unsigned int length) {
    if (p_hdr) {
        p_hdr->dxferp = data;
        p_hdr->dxfer_len = length;
    }
}


void set_sense_data(struct sg_io_hdr * p_hdr, unsigned char * data,
        unsigned int length) {
    if (p_hdr) {
        p_hdr->sbp = data;
        p_hdr->mx_sb_len = length;
    }
}




void show_vendor(struct sg_io_hdr * hdr) {
    unsigned char * buffer = hdr->dxferp;
    int i;
    printf("vendor id:");
    for (i=8; i<16; ++i) {
        putchar(buffer[i]);
    }
    putchar('\n');
}


void show_product(struct sg_io_hdr * hdr) {
    unsigned char * buffer = hdr->dxferp;
    int i;
    printf("product id:");
    for (i=16; i<32; ++i) {
        putchar(buffer[i]);
    }
    putchar('\n');
}


void show_product_rev(struct sg_io_hdr * hdr) {
    unsigned char * buffer = hdr->dxferp;
    int i;
    printf("product ver:");
    for (i=32; i<36; ++i) {
        putchar(buffer[i]);
    }
    putchar('\n');
}
void show_sense_buffer(struct sg_io_hdr * hdr) 
{  
unsigned char * buffer = hdr->sbp;  
int i;  
for (i=0; i<hdr->mx_sb_len; ++i) {  
  putchar(buffer[i]);  
   }  
}
/////////////////////////////////////////////////公共变量和函数
//#define SENSE_LEN 20
//#define BLOCK_LEN 20
int fd=-1;
unsigned char sense_buffer[64];
unsigned char data_buffer[40];
unsigned char response_buf[20]={0x00};


int execute_cmd(int fd,struct sg_io_hdr * p_hdr) 
{
    p_hdr->timeout = DEF_TIMEOUT;
    int ret = ioctl(fd, SG_IO, p_hdr);
    if (ret<0) {
        printf("Sending SCSI Command failed.\n");
    }
    return p_hdr->status;
}


void build_scsi_cdb()
{


}
///////////////////////////////////////////////
void cmd_Inquiry_info(int evpd, int page_code)
{
     int status = 0;
    struct sg_io_hdr * p_hdr = init_io_hdr();
    //构造命令
     unsigned char cdb[6];
    cdb[0] = 0x12; //查询命令
    cdb[1] = evpd & 1;
    cdb[2] = page_code & 0xff;
    cdb[3] = 0;
    cdb[4] = 0xff;
    cdb[5] = 0;  
    
    p_hdr->dxfer_direction = SG_DXFER_FROM_DEV;
    p_hdr->cmdp = cdb;
    p_hdr->cmd_len = 6;
   //设置缓冲数据区
    set_xfer_data(p_hdr, data_buffer, 40);//
    set_sense_data(p_hdr, sense_buffer, 64);
    
    
//请求设备基本信息
    if (fd>0) {
        status = execute_cmd(fd, p_hdr);
        printf("\n get_device_info the return status is %d\n", status);
        if (status!=0) {
            show_sense_buffer(p_hdr);
        } else{
            show_vendor(p_hdr);
            show_product(p_hdr);
            show_product_rev(p_hdr);
        }
    } else {
        printf("failed to open sg file \n");
    }
     destroy_io_hdr(p_hdr);
}
///////////////////////////////////////////////////////////////////////////////////
//////硬件初始化
//////////////////////////////////////////////////////////////////////////////////
//打开设备和led硬件
unsigned char init_led[8]={0x1b ,0xff, 0x00, 0x00, 0x08, 0x00, 0x01, 0x23};// 打开照明灯


void cmd_device_setsys(int evpd, int page_code)
{
    int status = 0;
    int i = 0;
    struct sg_io_hdr * p_hdr = init_io_hdr();
//构造命令
     unsigned char cdb[6]={0};
    cdb[0] = 0x86; //指纹模块自定义的写命令 
    //length-start
    cdb[1] = 0x00;
    cdb[2] = 0x00;
    cdb[3] = 0x00;
//length-end
    cdb[4] = 0x00;//256
    cdb[5] = 0x00;  
    
    p_hdr->dxfer_direction = SG_DXFER_TO_DEV;
    p_hdr->cmdp = cdb;
    p_hdr->cmd_len = 6;
   //设置缓冲数据区
    set_xfer_data(p_hdr, init_led, 8);//发送包
    set_sense_data(p_hdr, response_buf, 5);//状态值



    if (fd>0) {
       status = execute_cmd(fd, p_hdr);//
        printf("\n cmd_device_open the  status is %d\n", status);
        if (status!=0) 
{
//failed
        } else
        {
        //读取应答包
        cdb[0] = 0x85; //指纹模块自定义的写命令
        p_hdr->dxfer_direction = SG_DXFER_FROM_DEV;
        set_xfer_data(p_hdr, response_buf, 5);//返回数据包
status = execute_cmd(fd, p_hdr);//
printf("\n return the  status is %d \n", status);
printf("response packet: \n");
for (i=0; i<5; ++i)
{
        printf("%x ",response_buf[i]);
      }
printf("\n");
}
    } else {
        printf("failed to open sg file \n" );
    }
     destroy_io_hdr(p_hdr);
}
unsigned char led_close[8]={0x1b ,0xff, 0x00, 0x00, 0x08, 0x00, 0x02, 0x24};// 关闭led
unsigned char free_device[8]={0x1b ,0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A};// free device
void cmd_device_close(int evpd, int page_code,char * buf)
{
    int status = 0;
int i = 0;
    struct sg_io_hdr * p_hdr = init_io_hdr();
//构造命令
     unsigned char cdb[6]={0};
    cdb[0] = 0x86; //指纹模块自定义的写命令 
    //length-start
    cdb[1] = 0x00;
    cdb[2] = 0x00;
    cdb[3] = 0x00;
//length-end
    cdb[4] = 0x00;//256
    cdb[5] = 0x00;  
    
    p_hdr->dxfer_direction = SG_DXFER_TO_DEV;
    p_hdr->cmdp = cdb;
    p_hdr->cmd_len = 6;
   //设置缓冲数据区
    set_xfer_data(p_hdr, buf, 8);
    set_sense_data(p_hdr, response_buf, 5);

    if (fd>0) {
       status = execute_cmd(fd, p_hdr);//
        printf("\n cmd_device_close the  status is %d\n", status);
        if (status!=0) {
//do nothinig
        } else{
//do nothiing
}
    } else {
        printf("failed to open sg file \n" );
    }
     destroy_io_hdr(p_hdr);
}
//////////////////////////////////////////////////////////////////////
/////测试readinfo 模块的功能
//////////////////////////////////////////////////////////////////////
unsigned char info_buf[8]={0x1b,0xff,0x01,0x00,0x08,0x00,0x01,0x24};//探测手指功能
void cmd_device_readinfo_module(int evpd, int page_code)
{
    int status = 0;
int i = 0;
    struct sg_io_hdr * p_hdr = init_io_hdr();
//构造命令
    unsigned char cdb[6]={0};
    cdb[0] = 0x86;//写
    cdb[1] = 0x00;
    cdb[2] = 0x00;
    cdb[3] = 0x00;
    cdb[4] = 0x00;//256
    cdb[5] = 0x00;  
    
    p_hdr->dxfer_direction = SG_DXFER_TO_DEV;
    p_hdr->cmdp = cdb;
    p_hdr->cmd_len = 6;
   //设置缓冲数据区
    set_xfer_data(p_hdr, info_buf, 8);
    set_sense_data(p_hdr, response_buf, 10);

    if (fd>0) {
       status = execute_cmd(fd, p_hdr);//
        printf("\n cmd_device_get_packet the  status is %d\n", status);
        if (status!=0) {
//none
        } else{
//读取应答包
        cdb[0] = 0x85; //指纹模块自定义的读
        p_hdr->dxfer_direction = SG_DXFER_FROM_DEV;
        set_xfer_data(p_hdr, response_buf, 10);//返回数据包
status = execute_cmd(fd, p_hdr);//
printf("\n return the  status is %d \n", status);
printf("readinfo response packet: \n");
for (i=0; i<10; ++i)
{
        printf("%x ",response_buf[i]);
      }
        }
    } else {
        printf("failed to open sg file \n" );
    }
     destroy_io_hdr(p_hdr);
}


void readinfo_data( int evpd, int page_code)

    int status = 0;
    int i = 0;
    struct sg_io_hdr  p_hdr;
//构造命令
    memset(&p_hdr,0,sizeof(struct sg_io_hdr));
    memset(&response_buf,0,sizeof(response_buf));
// //1.发送命令包
    unsigned char cdb[6]={0};
    cdb[0] = 0x86; 
    cdb[1] = 0x00;
    cdb[2] = 0x00;
    cdb[3] = 0x00;
    cdb[4] = 0x00;//256
    cdb[5] = 0x00;  


    p_hdr.interface_id = 'S'; 
   p_hdr.flags = SG_FLAG_LUN_INHIBIT; 
    p_hdr.dxfer_direction = SG_DXFER_TO_DEV;
    p_hdr.cmdp = cdb;
    p_hdr.cmd_len = 6;
   //设置缓冲数据区
    p_hdr.dxferp = info_buf;
    p_hdr.dxfer_len = 8;
   p_hdr.sbp = response_buf;
    p_hdr.mx_sb_len = 10;

     status = execute_cmd(fd, &p_hdr);//
     printf("\n readinfo_data return the  status is %d \n", status);
 
  //   //2.读取应答包
        cdb[0] = 0x85; //指纹模块自定义的读
p_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
p_hdr.dxferp = response_buf;
        p_hdr.dxfer_len = 10;
status = execute_cmd(fd, &p_hdr);//

printf("readinfo response packet: \n");
    for (i=0; i<10; ++i)
    {
          printf("%x ",response_buf[i]);
    }
printf("\n");
}
////////////////////////////////////////////////////////////////////////
////自动保存指纹图像
///////////////////////////////////////////////////////////////////////
unsigned char autoimg_buf[8]={0x1b,0xff,0x10,0x00,0x01,0x00,0x01,0x2C};//自动保存指纹图像
void cmd_AutoGetImg( int evpd, int page_code)

    int status = 0;
    int i = 0;
    struct sg_io_hdr  p_hdr;
//构造命令
    memset(&p_hdr,0,sizeof(struct sg_io_hdr));
    memset(&response_buf,0,sizeof(response_buf));
// //1.发送命令包
    unsigned char cdb[6]={0};
    cdb[0] = 0x86; 
    cdb[1] = 0x00;
    cdb[2] = 0x00;
    cdb[3] = 0x00;
    cdb[4] = 0x00;//256
    cdb[5] = 0x00;  


    p_hdr.interface_id = 'S'; 
   p_hdr.flags = SG_FLAG_LUN_INHIBIT; 
    p_hdr.dxfer_direction = SG_DXFER_TO_DEV;
    p_hdr.cmdp = cdb;
    p_hdr.cmd_len = 6;
   //设置缓冲数据区
    p_hdr.dxferp = autoimg_buf;
    p_hdr.dxfer_len = 8;
   p_hdr.sbp = response_buf;
    p_hdr.mx_sb_len = 10;

     status = execute_cmd(fd, &p_hdr);//
     printf("\n AutoGetImg return the  status is %d \n", status);
sleep(1);
  //   //2.读取应答包
        cdb[0] = 0x85; //指纹模块自定义的读
p_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
p_hdr.dxferp = response_buf;
        p_hdr.dxfer_len = 10;
status = execute_cmd(fd, &p_hdr);//

printf("AutoGetImg response packet: \n");
    for (i=0; i<10; ++i)
    {
          printf("%x ",response_buf[i]);
    }
printf("\n");
}
/*
将图像缓冲区中的图像数据生成指纹特征数据(256Byte)并保存于指定的特征缓冲区
*/
unsigned char img2chr[8]={0x1b,0xff,0x11,0x00,0x01,0x00,0x01,0x2D};
void cmd_img2chr( int evpd, int page_code)

    int status = 0;
    int i = 0;
    struct sg_io_hdr  p_hdr;
//构造命令
    memset(&p_hdr,0,sizeof(struct sg_io_hdr));
    memset(&response_buf,0,sizeof(response_buf));
// //1.发送命令包
    unsigned char cdb[6]={0};
    cdb[0] = 0x86; 
    cdb[1] = 0x00;
    cdb[2] = 0x00;
    cdb[3] = 0x00;
    cdb[4] = 0x00;//256
    cdb[5] = 0x00;  


    p_hdr.interface_id = 'S'; 
   p_hdr.flags = SG_FLAG_LUN_INHIBIT; 
    p_hdr.dxfer_direction = SG_DXFER_TO_DEV;
    p_hdr.cmdp = cdb;
    p_hdr.cmd_len = 6;
   //设置缓冲数据区
    p_hdr.dxferp = img2chr;
    p_hdr.dxfer_len = 8;
   p_hdr.sbp = response_buf;
    p_hdr.mx_sb_len = 10;

     status = execute_cmd(fd, &p_hdr);//
     printf("\n cmd_img2chr return the  status is %d \n", status);
sleep(1);
  //   //2.读取应答包
        cdb[0] = 0x85; //指纹模块自定义的读
p_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
p_hdr.dxferp = response_buf;
        p_hdr.dxfer_len = 10;
status = execute_cmd(fd, &p_hdr);//

printf("cmd_img2chr response packet: \n");
    for (i=0; i<10; ++i)
    {
          printf("%x ",response_buf[i]);
    }
printf("\n");
}
void cmd_execute_Inquiry( int evpd, int page_code) 
{
  cmd_Inquiry_info(evpd,page_code);
}
/////////////////////////////////////////////////////////////////////


void cmd_device_detect_finger()
{
//cmd_device_readinfo_module(0,0);
do{
printf("cmd_device_detect_finger\n" );
//readinfo_data(0,0);
cmd_AutoGetImg(0,0);
sleep(1);
cmd_img2chr(0,0);
sleep(1);
}while(!g_exit);
cmd_device_close(0,0,free_device);
}
///////////////////////////////////////////////////////////////////


static void sigprocess(int inSigno)
{
printf("need to exit the Demo!\n" );

g_exit = 1;
}


int main(int argc, char * argv[]) 
{
    signal(SIGINT, sigprocess);

     fd = open(argv[1], O_RDWR);
//获取设备信息
    //cmd_execute_Inquiry(0, 0);
//打开和激活设备
    if(*argv[2] == '1')
    {
    cmd_device_setsys(0,0);
//发送读写命令获取数据?
//do....while(1)
         cmd_device_detect_finger();
    }
     else
     {
cmd_device_close(0,0,led_close);
      }




    close(fd);
    printf("\n exit the Demo!\n" );
    return EXIT_SUCCESS;

}

二   makfile:

all:clean sg
.PHONY:all
#arm-hisiv200-linux-
#arm_v5t_le-gcc
CC = arm-none-linux-gnueabi-gcc
sr:
$(CC) -g -o sg sg.c
#sudo xcp bmp /home/chen_guangjian/nfs1/anyka/targetfs-v.1/platform/rootfs/data-kaoqin/
clean:
rm *.o -rf
rm sg -rf


0 0
原创粉丝点击