Dokumen ini menjelaskan cara menggunakan USB API untuk berkomunikasi dengan perangkat USB. Beberapa perangkat tidak dapat diakses melalui USB API (lihat bagian Peringatan di bawah untuk detailnya). Aplikasi Chrome juga dapat terhubung ke perangkat serial dan Bluetooth.
Untuk mengetahui informasi latar belakang tentang USB, lihat spesifikasi USB resmi. USB di NutShell adalah kursus kilat yang wajar dan mungkin berguna bagi Anda.
Persyaratan manifes
USB API memerlukan "usb" dalam file manifes:
"permissions": [
"usb"
]
Selain itu, untuk mencegah sidik jari, Anda harus mendeklarasikan semua jenis perangkat yang diakses dalam file manifes. Setiap jenis perangkat USB sesuai dengan ID vendor/ID produk (VID/PID). Anda dapat menggunakan usb.getDevices untuk menghitung perangkat berdasarkan pasangan VID/PID.
Anda harus mendeklarasikan pasangan VID/PID untuk setiap jenis perangkat yang ingin Anda gunakan berdasarkan usbDevices
dalam file manifes aplikasi Anda, seperti yang ditunjukkan dalam contoh di bawah ini:
"permissions": [
{
"usbDevices": [
{
"vendorId": 123,
"productId": 456
}
]
}
]
Mulai Chrome 57, persyaratan untuk mendeklarasikan semua jenis perangkat dalam manifes aplikasi adalah
tidak lagi digunakan untuk aplikasi yang berjalan sebagai aplikasi kios ChromeOS. Untuk aplikasi kios, Anda dapat menggunakan
interfaceClass
untuk meminta izin guna mengakses perangkat USB yang:
- mengimplementasikan antarmuka USB kelas antarmuka tertentu
- memiliki kelas perangkat USB tertentu
Misalnya, izin usbDevices
berikut akan memberikan akses aplikasi ke semua perangkat USB yang
mengimplementasikan antarmuka printer (kode kelas antarmuka 7), dan ke perangkat hub USB (kode kelas perangkat
9):
"permissions": [
{
"usbDevices": [
{"interfaceClass": 7},
{"interfaceClass": 9}
]
}
]
Untuk mengetahui daftar nilai interfaceClass
yang dapat diterima, lihat Kode Kelas USB.
Properti interfaceClass
dapat digabungkan dengan properti vendorId
untuk mendapatkan akses hanya ke USB
perangkat dari vendor tertentu, seperti yang ditunjukkan oleh contoh berikut:
"permissions": [
{
"usbDevices": [
{
"vendorId": 123,
"interfaceClass": 7
}
]
}
]
Mencari perangkat
Untuk menentukan apakah satu atau beberapa perangkat tertentu terhubung ke sistem pengguna, gunakan Metode usb.getDevices:
chrome.usb.getDevices(enumerateDevicesOptions, callback);
Parameter (jenis) | Deskripsi |
---|---|
EnumerateDevicesOptions (objek) | Objek yang menentukan vendorId (panjang) dan productId (panjang) yang digunakan untuk menemukan jenis perangkat yang benar di bus. Manifes Anda harus mendeklarasikan bagian izin usbDevices yang mencantumkan semua pasangan vendorId dan deviceId yang ingin diakses oleh aplikasi Anda. |
callback (fungsi) | Dipanggil saat enumerasi perangkat selesai. Callback akan dieksekusi dengan satu parameter, yaitu array objek Device dengan tiga properti: device , vendorId , productId . Properti perangkat adalah ID yang stabil untuk perangkat terhubung. Parameter tidak akan berubah hingga perangkat dicabut. Detail ID buram dan dapat berubah. Jangan mengandalkan jenisnya saat ini.Jika tidak ada perangkat yang ditemukan, array akan kosong. |
Contoh:
function onDeviceFound(devices) {
this.devices=devices;
if (devices) {
if (devices.length > 0) {
console.log("Device(s) found: "+devices.length);
} else {
console.log("Device could not be found");
}
} else {
console.log("Permission denied.");
}
}
chrome.usb.getDevices({"vendorId": vendorId, "productId": productId}, onDeviceFound);
Membuka perangkat
Setelah objek Device
ditampilkan, Anda dapat membuka perangkat menggunakan usb.openDevice untuk mendapatkan
{i>connection handle<i}. Anda hanya dapat berkomunikasi dengan perangkat USB menggunakan tuas koneksi.
Properti | Deskripsi |
---|---|
perangkat | Objek diterima di callback usb.getDevices. |
data (buffer) | Berisi data yang dikirim oleh perangkat jika transfer masuk. |
Contoh:
var usbConnection = null;
var onOpenCallback = function(connection) {
if (connection) {
usbConnection = connection;
console.log("Device opened.");
} else {
console.log("Device failed to open.");
}
};
chrome.usb.openDevice(device, onOpenCallback);
Untuk menyederhanakan proses pembukaan, Anda dapat menggunakan metode usb.findDevices, yang menghitung, meminta akses, dan membuka perangkat dalam satu panggilan:
chrome.usb.findDevices({"vendorId": vendorId, "productId": productId, "interfaceId": interfaceId}, callback);
yang setara dengan:
chrome.usb.getDevices({"vendorId": vendorId, "productId": productId}, function (devices) {
if (!devices) {
console.log("Error enumerating devices.");
callback();
return;
}
var connections = [], pendingAccessRequests = devices.length;
devices.forEach(function (device) {
chrome.usb.requestAccess(interfaceId, function () {
// No need to check for errors at this point.
// Nothing can be done if an error occurs anyway. You should always try
// to open the device.
chrome.usb.openDevices(device, function (connection) {
if (connection) connections.push(connection);
pendingAccessRequests--;
if (pendingAccessRequests == 0) {
callback(connections);
}
});
});
})
});
Transfer USB dan menerima data dari perangkat
Protokol USB menentukan empat jenis transfer: control, massal, isocronus, dan interupsi. Transfer ini dijelaskan di bawah.
Transfer dapat terjadi dua arah: perangkat-ke-host (masuk), dan host-ke-perangkat (keluar). Tenggat pada sifat protokol USB, baik pesan masuk dan keluar harus dimulai oleh {i>host<i} (komputer yang menjalankan aplikasi Chrome). Untuk pesan masuk (perangkat-ke-host), host (dimulai oleh kode JavaScript) akan mengirimkan pesan yang ditandai sebagai "masuk" ke perangkat. Detail informasi bergantung pada perangkat, namun biasanya akan memiliki beberapa identifikasi tentang apa yang Anda minta dari sumber tersebut. Perangkat kemudian merespons dengan data yang diminta. Respons perangkat ditangani oleh Chrome dan dikirimkan secara asinkron ke callback yang Anda tetapkan di metode transfer. Perjalanan keluar (host ke perangkat) serupa, tetapi responsnya tidak berisi data yang ditampilkan dari perangkat.
Untuk setiap pesan dari perangkat, callback yang ditentukan akan menerima objek peristiwa dengan properti berikut:
Properti | Deskripsi |
---|---|
resultCode (bilangan bulat) | 0 berarti berhasil; jika nilai lain mengindikasikan kegagalan. String error dapat dibaca dari chrome.extension.lastError jika adaindikasi kegagalan. |
data (buffer) | Berisi data yang dikirim oleh perangkat jika transfer masuk. |
Contoh:
var onTransferCallback = function(event) {
if (event && event.resultCode === 0 && event.data) {
console.log("got " + event.data.byteLength + " bytes");
}
};
chrome.usb.bulkTransfer(connectionHandle, transferInfo, onTransferCallback);
CONTROL transfer
Transfer kontrol umumnya digunakan untuk mengirim atau menerima parameter konfigurasi atau perintah ke USB. perangkat seluler. Metode controlTransfer selalu mengirim ke/membaca dari endpoint 0, dan tidak ada klaimInterface yang tidak diperlukan. Metode ini sederhana dan menerima tiga parameter:
chrome.usb.controlTransfer(connectionHandle, transferInfo, transferCallback)
Parameter (jenis) | Deskripsi |
---|---|
connectionHandle | Objek diterima di callback usb.openDevice. |
transferInfo | Objek parameter dengan nilai dari tabel di bawah ini. Periksa spesifikasi protokol perangkat USB untuk mengetahui detailnya. |
transferCallback() | Dipanggil saat transfer selesai. |
Nilai untuk objek transferInfo
:
Nilai | Deskripsi |
---|---|
requestType (string) | "vendor", "standard", "class" atau "dicadangkan". |
penerima (string) | "perangkat", "antarmuka", "endpoint" atau "lainnya". |
arah ({i>string<i}) | "dalam" atau "keluar". "Di dalam" arah digunakan untuk memberi tahu perangkat bahwa perangkat harus mengirimkan informasi ke host. Semua komunikasi pada bus USB dimulai oleh host, jadi gunakan "in" transfer agar perangkat dapat mengirim informasi kembali. |
permintaan (bilangan bulat) | Ditentukan oleh protokol perangkat. |
nilai (bilangan bulat) | Ditentukan oleh protokol perangkat. |
indeks (bilangan bulat) | Ditentukan oleh protokol perangkat. |
panjang (bilangan bulat) | Hanya digunakan saat arah berada di "in". Memberi tahu perangkat bahwa ini adalah jumlah data yang diharapkan oleh host sebagai respons. |
data (buffer) | Ditentukan oleh protokol perangkat, diperlukan jika arahnya "keluar". |
Contoh:
var transferInfo = {
"requestType": "vendor",
"recipient": "device",
"direction": "out",
"request": 0x31,
"value": 120,
"index": 0,
// Note that the ArrayBuffer, not the TypedArray itself is used.
"data": new Uint8Array([4, 8, 15, 16, 23, 42]).buffer
};
chrome.usb.controlTransfer(connectionHandle, transferInfo, optionalCallback);
Transfer ISOCHRONOUS
Transfer isokronus adalah jenis transfer USB yang paling kompleks. Umumnya digunakan untuk feed data, seperti video dan suara. Untuk memulai transfer isocron (baik masuk maupun keluar), Anda harus menggunakan metode usb.isochronousTransfer:
chrome.usb.isochronousTransfer(connectionHandle, isochronousTransferInfo, transferCallback)
Parameter | Deskripsi |
---|---|
connectionHandle | Objek diterima di callback usb.openDevice. |
isochronousTransferInfo | Objek parameter dengan nilai dalam tabel di bawah ini. |
transferCallback() | Dipanggil saat transfer selesai. |
Nilai untuk objek isochronousTransferInfo
:
Nilai | Deskripsi |
---|---|
transferInfo (objek) | Objek dengan atribut berikut: direction (string): "in" atau "out". endpoint (bilangan bulat): yang ditentukan oleh perangkat Anda. Biasanya dapat ditemukan dengan melihat alat instrospeksi USB, seperti lsusb -v panjang (bilangan bulat): hanya digunakan saat arah berada di "in". Memberi tahu perangkat bahwa ini adalah jumlah data yang diharapkan oleh host dalam respons. Sekurang-kurangnya harus packets × packetLength .data (arraybuffer): yang ditentukan oleh protokol perangkat Anda; hanya digunakan saat arah adalah "keluar". |
paket (bilangan bulat) | Jumlah total paket yang diharapkan dalam transfer ini. |
paketPanjang (bilangan bulat) | Perkiraan panjang setiap paket dalam transfer ini. |
Contoh:
var transferInfo = {
"direction": "in",
"endpoint": 1,
"length": 2560
};
var isoTransferInfo = {
"transferInfo": transferInfo,
"packets": 20,
"packetLength": 128
};
chrome.usb.isochronousTransfer(connectionHandle, isoTransferInfo, optionalCallback);
Transfer BESAR
Transfer massal biasanya digunakan untuk mentransfer sejumlah besar data yang tidak mendesak sebelumnya. usb.bulkTransfer memiliki tiga parameter:
chrome.usb.bulkTransfer(connectionHandle, transferInfo, transferCallback);
Parameter | Deskripsi |
---|---|
connectionHandle | Objek diterima di callback usb.openDevice. |
transferInfo | Objek parameter dengan nilai dalam tabel di bawah ini. |
transferCallback | Dipanggil saat transfer selesai. |
Nilai untuk objek transferInfo
:
Nilai | Deskripsi |
---|---|
arah ({i>string<i}) | "dalam" atau "keluar". |
endpoint (bilangan bulat) | Ditentukan oleh protokol perangkat. |
panjang (bilangan bulat) | Hanya digunakan saat arah berada di "in". Memberi tahu perangkat bahwa ini adalah jumlah data yang diharapkan oleh host sebagai respons. |
data (ArrayBuffer) | Ditentukan oleh protokol perangkat Anda; hanya digunakan saat arah adalah "keluar". |
Contoh:
var transferInfo = {
"direction": "out",
"endpoint": 1,
"data": new Uint8Array([4, 8, 15, 16, 23, 42]).buffer
};
Transfer INTERUPT
Transfer interupsi digunakan untuk data sensitif waktu dalam jumlah kecil. Karena semua komunikasi USB dimulai oleh {i>host<i}, kode {i>host<i} biasanya memeriksa perangkat secara berkala, mengirim interupsi transfer yang akan membuat perangkat mengirim data kembali jika ada apa pun di antrean interupsi (dikelola oleh perangkat). usb.interruptTransfer memiliki tiga parameter:
chrome.usb.interruptTransfer(connectionHandle, transferInfo, transferCallback);
Parameter | Deskripsi |
---|---|
connectionHandle | Objek diterima di callback usb.openDevice. |
transferInfo | Objek parameter dengan nilai dalam tabel di bawah ini. |
transferCallback | Dipanggil saat transfer selesai. Perhatikan bahwa callback ini tidak berisi respons perangkat. Tujuan callback ini hanya untuk memberi tahu kode Anda bahwa permintaan transfer asinkron telah diproses. |
Nilai untuk objek transferInfo
:
Nilai | Deskripsi |
---|---|
arah ({i>string<i}) | "dalam" atau "keluar". |
endpoint (bilangan bulat) | Ditentukan oleh protokol perangkat. |
panjang (bilangan bulat) | Hanya digunakan saat arah berada di "in". Memberi tahu perangkat bahwa ini adalah jumlah data yang diharapkan oleh host sebagai respons. |
data (ArrayBuffer) | Ditentukan oleh protokol perangkat Anda; hanya digunakan saat arah adalah "keluar". |
Contoh:
var transferInfo = {
"direction": "in",
"endpoint": 1,
"length": 2
};
chrome.usb.interruptTransfer(connectionHandle, transferInfo, optionalCallback);
Peringatan
Tidak semua perangkat dapat diakses melalui USB API. Pada umumnya, perangkat tidak dapat diakses karena baik {i>kernel<i} Sistem Operasi atau {i>driver<i} asli menahannya dari kode ruang pengguna. Agak besar contohnya adalah perangkat dengan profil HID pada sistem OSX, dan {i>pen drive<i} USB.
Pada sebagian besar sistem Linux, perangkat USB dipetakan dengan izin hanya baca secara default. Untuk membuka
perangkat seluler melalui API ini, pengguna Anda juga harus memiliki akses tulis ke API tersebut. Solusi sederhananya adalah
mengatur aturan udev. Buat file /etc/udev/rules.d/50-yourdevicename.rules
dengan hal berikut
konten:
SUBSYSTEM=="usb", ATTR{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"
Kemudian, cukup mulai ulang daemon udev: service udev restart
. Anda dapat memeriksa apakah izin perangkat
tetapkan secara benar dengan mengikuti langkah-langkah berikut:
- Jalankan
lsusb
untuk menemukan nomor bus dan perangkat. - Jalankan
ls -al /dev/bus/usb/[bus]/[device]
. File ini harus dimiliki oleh grup "plugdev" dan memiliki izin akses tulis grup.
Aplikasi Anda tidak dapat melakukannya secara otomatis karena prosedur ini memerlukan akses root. Saran dari kami Anda memberikan petunjuk kepada pengguna akhir dan menautkan ke bagian Peringatan di halaman ini untuk penjelasan.
Di ChromeOS, cukup panggil usb.requestAccess. Perantara izin melakukan ini untuk Anda.