ファームウェア更新モードで Nexus-4 ブートローダーと通信するための簡単なプログラムを開発しようとしています。Nexus -4 には 3 つの USB インターフェイスがあります。インターフェイス 1 には 2 つの 2 エンドポイント(2 と 131)があります。
エンドポイント 2 を介してコマンド get-device-info を記述し、エンドポイント 131 で応答をリッスンするプログラムを作成しました。(インターフェイスとエンドポイントのすべての順列を試しました!)。
プログラムはコマンドをデバイスに正常に書き込みますが、デバイスから何も読み取られません。
コマンドフォーマット: Flag(0x7e): CMD: データ(可変長): CRC-16: Flag(0x7e)
デバイス情報取得コマンド: 0x7e 0x00 0x78 0xf0 0x7e
以下がプログラムです。
#include <stdio.h>
#include <stdlib.h>
#include <libusb-1.0/libusb.h>
#define INTERFACE 1
#define EP_OUT 2
#define EP_IN 131
int main() {
libusb_device **devs; // retrieve a list of devices
libusb_device_handle *dev_handle; // device handler
libusb_context *ctx = NULL; //a libusb session
int r, r2, i;
ssize_t cnt; //holding number of devices in list
unsigned char data[30],read_data[512]; //data to write
data[0]=0x7e;data[1]=0x00;data[2]=0x78;data[3]=0xf0;data[4]=0x7e; // get-device-info command in HLDC format
int actual,read_actual;
r = libusb_init(&ctx);
if(r < 0) {
printf("Init Error\n");
return 1;
}
libusb_set_debug(ctx, 3);
cnt = libusb_get_device_list(ctx, &devs); //get the list of devices
if(cnt < 0) {
printf("Get Device Error\n");
return 1;
}
printf("%d Devices in list\n",(int)cnt);
dev_handle = libusb_open_device_with_vid_pid(ctx, 4100, 25371); //these are vendorID and productID I found for Nexus-4 firmware update
if(dev_handle == NULL)
printf("Cannot open device\n");
else
printf("Device opened\n");
libusb_free_device_list(devs, 0); //free the device list
if(libusb_kernel_driver_active(dev_handle, INTERFACE) == 1) { //find out if kernel driver is attached
printf("Kernel Driver Active\n");
if(libusb_detach_kernel_driver(dev_handle, INTERFACE) == 0) //detach it
printf("Kernel Driver Detached!\n");
}
r = libusb_claim_interface(dev_handle, INTERFACE); //claim interface 1 Nexus-5/4 FUM
if(r < 0) {
printf("Cannot Claim Interface\n");
printf("%s\n",libusb_error_name(r));
return 1;
}
printf("Claimed Interface\n");
printf("Data to be send -> %s\n",data); //just to see the data that we are writing
printf("Writing Data...\n");
r = libusb_bulk_transfer(dev_handle, (EP_OUT | LIBUSB_ENDPOINT_OUT), data, 5, &actual, 0);
if(r == 0 && actual == 5){ //we wrote successfully 5 bytes to the device
printf("Writing Successful!\n");
printf("Waiting to read from device!\n");
r2 = libusb_bulk_transfer(dev_handle, (EP_IN | LIBUSB_ENDPOINT_IN), read_data, 512, &read_actual, 5000);
if (r2 >=0){
if (read_actual > 0){
printf("Data received by bulk transfer\n");
printf("Data is ");
for (i=0; i<read_actual; i++)
printf("%x ",read_data[i]);
printf("\n");
}
else{
printf(stderr, "No data received in bulk transfer (%d)\n", r2);
return -1;
}
}
else{
fprintf(stderr, "Error receiving data via bulk transfer %d\n", r2);
return r2;
}
}
else
printf("Write Error\n");
r = libusb_release_interface(dev_handle, INTERFACE); //release the claimed interface
if(r!=0) {
printf("Cannot Release Interface\n");
return 1;
}
printf("Released Interface\n");
libusb_close(dev_handle);
libusb_exit(ctx);
return 0;
}
プログラムはコマンドを電話に正常に送信できますが、電話からの応答を受信できません。プログラムを実行すると、次の出力が得られます。
リスト内の 10 台のデバイス
デバイスが開かれました
カーネル ドライバ アクティブ
カーネル ドライバが切り離されました!
要求されたインターフェイス
送信するデータ -> ~
データを書き込んでいます...
書き込み成功!
デバイスからの読み取りを待機しています!
バルク転送によるデータ受信エラー -7
応答が得られない理由は、コマンド構造が間違っているためなのか、それともプログラムの実装が原因なのかわかりません。