- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我实际上正在开发插入 USB 的指纹读取器(FP 读取器)。这个 FP 阅读器也插在 stm32f4 板上。如果我理解正确的话,FP 阅读器包含一个非常小的数据库 FP 模板。要修改这些模板,我们将 FP 阅读器插入 USB 并使用 Windows 上的程序对其进行修改。由于我在 Linux 上工作(出于好奇),我正在尝试制作一个允许我们在 Linux 上修改模板的程序。
这个 FP 阅读器被看作是一个 CD-ROM 阅读器。我正在尝试在 sg 包的帮助下与其通信(我正在关注此文档 http://www.tldp.org/HOWTO/SCSI-Generic-HOWTO/ )。根据 FP 阅读器的文档(您可以在此处找到 http://www.adh-tech.com.tw/files/GT-511C3_datasheet_V1%201_20131127.pdf),我应该发送一个缓冲区(12 字节),例如 [55 aa 0001 00000000 0001 0101] 来执行“打开”命令。
这是我执行此命令的代码(我试图制作一个可读的最小示例):
#include <errno.h>
#include <fcntl.h>
#include <scsi/sg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define FP_PACKET_SZ 12
const uint8_t fp_packet_sz = FP_PACKET_SZ;
static unsigned char sense_buffer[32];
#define OPEN_CMD
static void init_snd(uint8_t buf[fp_packet_sz]) {
size_t offset = 0;
const uint16_t deviceID = 1;
const uint16_t cmd = 1;
const uint32_t parameter = 0;
buf[offset++] = 0x55;
buf[offset++] = 0xAA;
memcpy(buf + offset, &deviceID, sizeof(deviceID));
offset += sizeof(deviceID);
memcpy(buf + offset, ¶meter, sizeof(parameter));
offset += sizeof(parameter);
memcpy(buf + offset, &cmd, sizeof(cmd));
offset += sizeof(cmd);
uint16_t checksum = 0;
for (unsigned int i = 0 ; i < offset ; i++)
checksum += buf[i];
memcpy(buf + offset, &checksum, sizeof(checksum));
}
int main(int argc, char *argv[]) {
int fd = 0, res = 0;
char * filename = 0;
sg_io_hdr_t header;
uint8_t snd[fp_packet_sz];
uint8_t rcv[fp_packet_sz];
memset (snd, 0, sizeof(snd));
memset (rcv, 0, sizeof(rcv));
if (argc < 2) {
fprintf(stderr, "argument missing\n");
return EXIT_FAILURE;
}
filename = argv[1];
fd = open(filename, O_RDWR);
if (fd < 0) {
fprintf(stderr, "open %s failed\n", filename);
return EXIT_FAILURE;
}
init_snd(snd);
header.interface_id = 'S';
header.dxfer_direction = SG_DXFER_TO_FROM_DEV;
header.cmd_len = fp_packet_sz;
header.cmdp = snd;
header.mx_sb_len = sizeof (sense_buffer);
header.sbp = sense_buffer;
header.iovec_count = 0;
header.dxfer_len = fp_packet_sz;
header.dxferp = rcv;
header.timeout = 60000;
header.flags = 0;
if ((res = ioctl(fd, SG_IO, &header)) < 0) {
fprintf(stderr, "ioctl failed and return errno: %s \n", strerror(errno));
exit(EXIT_FAILURE);
}
fprintf(stdout, "receive buffer:");
for (int i = 0 ; i < fp_packet_sz ; i++)
fprintf(stdout, " %02x", rcv[i]);
fprintf(stdout, "\n");
fprintf(stdout, "sense data:");
for (int i = 0 ; i < header.sb_len_wr ; i++)
fprintf(stdout, " %02x", sense_buffer[i]);
fprintf(stdout, "\n");
return EXIT_SUCCESS;
}
我期望 rcv
具有以下值 [55 aa 00 01 00 00 00 00 00 30 01 30]
。
但是,我没有收到任何东西(或者我不明白的东西)并且 sense_data
得到以下值:70 00 05 00 00 00 00 0A 00 00 00 00 20 00 00 00 00 00
对应于 Illegal Request
(根据 http://blog.disksurvey.org/knowledge-base/scsi-sense/ 博客)。我还尝试使用与该论坛中所述的 scsi_inquiry.c
相同的方案 http://www.linuxquestions.org/questions/programming-9/linux-scsi-passthrough-porting-windows-routine-4175528749/我得到了相同的 sense_data
。我想我真的不明白 sg 驱动程序是如何工作的。是驱动程序提供了 sense_data
还是设备?我还尝试在 /dev/sr1
上制作一些 read()
和 write()
但它没有用(好像我只可以读取一些关于FP阅读器内存格式的信息)
终端中 sg 命令提供的一些附加信息:
>sg_map
/dev/sg3 /dev/sr1
>sg_inq /dev/sg3
invalid VPD response; probably a STANDARD INQUIRY response
standard INQUIRY:
PQual=0 Device_type=5 RMB=1 LU_CONG=0 version=0x06 [SPC-4]
[AERC=0] [TrmTsk=0] NormACA=0 HiSUP=0 Resp_data_format=2
SCCS=0 ACC=0 TPGS=0 3PC=0 Protect=0 [BQue=0]
EncServ=0 MultiP=0 [MChngr=0] [ACKREQQ=0] Addr16=0
[RelAdr=0] WBus16=0 Sync=0 [Linked=0] [TranDis=0] CmdQue=0
length=36 (0x24) Peripheral device type: cd/dvd
Vendor identification:
Product identification: Fingerprint
Product revision level: 0.01
如果您需要更多信息,请告诉我,我会将其添加到该帖子中。
问题摘要:如何在 Linux (sg) 或任何其他程序中使用 scsi 驱动程序将特定命令(缓冲区)发送到指纹读取器?
感谢您(也许)在未来的帮助。
编辑1:这是发送到设备的 snd 缓冲区的确切值(由 gdb 给出)
gdb> x /3xw snd
0x0001aa55 0x00000000 0x01010001
最佳答案
Resume of the question: How can I send a particular command (buffer) to a fingerprint reader by using scsi driver in Linux (sg) or any other program ?
不要。
不幸的是,“SCSI”常常是“有点像 SCSI,但不严格符合 SCSI”的同义词;和 USB 设备通常提供多个接口(interface)(例如,当操作系统没有有用的驱动程序时,“模糊地像 SCSI 但不是 SCSI”的接口(interface)具有残缺的功能,以及当有设备驱动程序时使用的 native 接口(interface))。
这意味着您极有可能需要专门为设备编写 USB 设备驱动程序。
请注意,如果您查看此设备的数据表,您会发现所有命令都与 SCSI 无关,唯一看起来像 CD 的是“升级 ISO CD 镜像 ()”函数记录为“不受支持”。
关于c - 如何在 Linux 中向 scsi 设备发送特定命令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44458916/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,
Linux 管道可以缓冲多少数据?这是可配置的吗? 如果管道的两端在同一个进程中,但线程不同,这会有什么不同吗? 请注意:这个“同一个进程,两个线程”的问题是理论上的边栏,真正的问题是关于缓冲的。 最
我找到了here [最后一页] 一种有趣的通过 Linux 启动 Linux 的方法。不幸的是,它只是被提及,我在网上找不到任何有用的链接。那么有人听说过一种避免引导加载程序而使用 Linux 的方法
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我试图了解 ld-linux.so 如何在 Linux 上解析对版本化符号的引用。我有以下文件: 测试.c: void f(); int main() { f(); } a.c 和 b.c:
与 RetroPie 的工作原理类似,我可以使用 Linux 应用程序作为我的桌面环境吗?我实际上并不需要像实际桌面和安装应用程序这样的东西。我只需要一种干净简单的方法来在 RaspberryPi 上
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
有什么方法可以覆盖现有的源代码,我应该用 PyQt、PyGTK、Java 等从头开始构建吗? 最佳答案 如果您指的是软件本身而不是它所连接的存储库,那么自定义应用程序的方法就是 fork 项目。据我所
我的情况是:我在一个磁盘上安装了两个 linux。我将第一个安装在/dev/sda1 中,然后在/dev/sda2 中安装第二个然后我运行第一个系统,我写了一个脚本来在第一个系统运行时更新它。
我在 i2c-0 总线上使用地址为 0x3f 的系统监视器设备。该设备在设备树中配置有 pmbus 驱动程序。 问题是,加载 linux 内核时,这个“Sysmon”设备没有供电。因此,当我在总线 0
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 11 年前。 Improve thi
我正试图在 linux 模块中分配一大块内存,而 kalloc 做不到。 我知道唯一的方法是使用 alloc_bootmem(unsigned long size) 但我只能从 linux 内核而不是
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
我有 .sh 文件来运行应用程序。在该文件中,我想动态设置服务器名称,而不是每次都配置。 我尝试了以下方法,它在 CentOS 中运行良好。 nohup /voip/java/jdk1.8.0_71/
我是在 Linux 上开发嵌入式 C++ 程序的新手。我有我的 Debian 操作系统,我在其中开发和编译了我的 C++ 项目(一个简单的控制台进程)。 我想将我的应用程序放到另一个 Debian 操
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 4 年前。 Improve this ques
我使用4.19.78版本的稳定内核,我想找到带有企鹅二进制数据的C数组。系统启动时显示。我需要在哪里搜索该内容? 我在 include/linux/linux_logo.h 文件中只找到了一些 Log
我知道可以使用 gdb 的服务器模式远程调试代码,我知道可以调试针对另一种架构交叉编译的代码,但是是否可以更进一步,从远程调试 Linux 应用程序OS X 使用 gdbserver? 最佳答案 当然
是否有任何可能的方法来运行在另一个 Linux 上编译的二进制文件?我知道当然最简单的是在另一台机器上重建它,但假设我们唯一能得到的是一个二进制文件,那么这可能与否? (我知道这可能并不容易,但我只是
我是一名优秀的程序员,十分优秀!