USB Cihazlar

Bu dokümanda, USB cihazlarıyla iletişim kurmak için USB API'nin nasıl kullanılacağı açıklanmaktadır. Bazı cihazlara USB API üzerinden erişilemez (ayrıntılar için aşağıdaki Uyarılar bölümüne bakın). Chrome uygulamaları ayrıca serial ve Bluetooth cihazlara da bağlanabilir.

USB hakkında arka plan bilgileri için resmi USB özelliklerine bakın. NutShell'de USB, faydalı bulabileceğiniz makul bir hız kursudur.

Manifest gerekliliği

USB API, manifest dosyasında "usb" iznini gerektirir:

"permissions": [
  "usb"
]

Ayrıca, parmak izini önlemek için erişmek istediğiniz tüm cihaz türlerini manifest dosyasında belirtmeniz gerekir. Her USB cihaz türü, bir tedarikçi kimliği/ürün kimliği (VID/PID) çiftine karşılık gelir. Cihazları VID/PID çiftlerine göre numaralandırmak için usb.getDevices'ı kullanabilirsiniz.

Kullanmak istediğiniz her cihaz türü için VID/PID çiftlerini, aşağıdaki örnekte gösterildiği gibi uygulamanızın manifest dosyasında usbDevices izni kapsamında beyan etmeniz gerekir:

"permissions": [
  {
    "usbDevices": [
      {
        "vendorId": 123,
        "productId": 456
      }
    ]
  }
]

Chrome 57'den itibaren ChromeOS kiosk uygulamaları olarak çalışan uygulamalar için uygulama manifestindeki tüm cihaz türlerini belirtme şartı gevşetilmektedir. Kiosk uygulamalarında, interfaceClass izin özelliğini kullanarak aşağıdaki işlemleri yapan USB cihazlarına erişim izni isteyebilirsiniz:

  • belirli bir arayüz sınıfına ait USB arayüzünü uygulama
  • Belirli bir USB cihaz sınıfı varsa

Örneğin, aşağıdaki usbDevices izni, bir uygulamanın bir yazıcı arayüzü (arayüz sınıf kodu 7) uygulayan tüm USB cihazlarına ve USB hub cihazlarına (cihaz sınıfı kodu 9) erişmesine izin verir:

"permissions": [
  {
    "usbDevices": [
      {"interfaceClass": 7},
      {"interfaceClass": 9}
    ]
  }
]

Kabul edilebilir interfaceClass değerlerinin listesi için USB Sınıfı Kodları konusuna bakın.

interfaceClass özelliği, aşağıdaki örnekte gösterildiği gibi yalnızca belirli bir tedarikçi firmanın USB cihazlarına erişim sağlamak için vendorId özelliğiyle birleştirilebilir:

"permissions": [
  {
    "usbDevices": [
      {
        "vendorId": 123,
        "interfaceClass": 7
      }
    ]
  }
]

Cihaz bulma

Bir kullanıcının sistemine belirli bir veya daha fazla cihazın bağlı olup olmadığını belirlemek için usb.getDevices yöntemini kullanın:

chrome.usb.getDevices(enumerateDevicesOptions, callback);
Parametre (tür)Açıklama
EnumerateDevicesOptions (nesne)Otobüste doğru cihaz türünü bulmak için kullanılan hem vendorId (uzun) hem de productId (uzun) belirten bir nesne. Manifest'iniz, uygulamanızın erişmek istediği tüm vendorId ve deviceId çiftlerini listeleyen usbDevices izin bölümünü beyan etmelidir.
geri çağırma (işlev)Cihaz numaralandırması tamamlandığında çağrılır. Geri çağırma, üç özelliği olan Device nesnelerinden oluşan bir dizi olan tek bir parametreyle yürütülür: device, vendorId, productId. Cihaz özelliği, bağlı bir cihazın sabit tanımlayıcısıdır. Cihaz fişe takılana kadar bu ayar değişmez. Tanımlayıcının ayrıntısı opaktır ve değişebilir. Mevcut türüne güvenmeyin.
Herhangi bir cihaz bulunmazsa dizi boş olur.

Örnek:

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);

Cihazı açma

Device nesneleri iade edildikten sonra, bağlantı yeri edinmek için usb.openDevice'ı kullanarak bir cihazı açabilirsiniz. USB cihazlarıyla yalnızca bağlantı tutma yerlerini kullanarak iletişim kurabilirsiniz.

ÖzellikAçıklama
cihazNesne usb.getDevices geri çağırmasında alındı.
veri (dizi arabelleği)Aktarım gelen olarak yapıldıysa cihaz tarafından gönderilen verileri içerir.

Örnek:

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);

Açma işlemini basitleştirmek için usb.findDevices yöntemini kullanabilirsiniz. Bu yöntem, cihazları tek bir çağrıda sıralayan, erişim isteğinde bulunan ve açan cihazlar:

chrome.usb.findDevices({"vendorId": vendorId, "productId": productId, "interfaceId": interfaceId}, callback);

Bu, şuna eşittir:

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);
        }
      });
    });
  })
});

USB aktarımları ve cihazdan veri alma

USB protokolü dört aktarım türünü tanımlar: kontrol, toplu, eşzamanlı ve kesme. Bu aktarımlar aşağıda açıklanmıştır.

Aktarımlar cihazdan ana makineye (gelen) ve ana makineden cihaza (giden) olmak üzere iki yönde de gerçekleşebilir. USB protokolünün yapısı nedeniyle, hem gelen hem de giden iletilerin ana makine (Chrome uygulamasını çalıştıran bilgisayar) tarafından başlatılması gerekir. Gelen (cihazdan ana makineye) mesajlar için ana makine (JavaScript kodunuz tarafından başlatılan) cihaza "gelen" olarak işaretlenmiş bir ileti gönderir. Mesajın ayrıntıları cihaza bağlı olarak değişir, ancak genellikle cihazdan ne istediğinize dair birtakım tanımlar bulunur. Cihaz, istenen verilerle yanıt verir. Cihazın yanıtı Chrome tarafından işlenir ve aktarım yönteminde belirttiğiniz geri çağırmaya eşzamansız bir şekilde iletilir. Giden (ana makineden cihaza) mesaj da benzerdir ancak yanıt cihazdan döndürülen verileri içermez.

Belirtilen geri çağırma, cihazdan gelen her mesaj için aşağıdaki özelliklere sahip bir etkinlik nesnesi alır:

ÖzellikAçıklama
resultsCode (tam sayı)0 başarılı, diğer değerler başarısız olduğunu gösterir. Bir hata belirtildiğinde
chrome.extension.lastError öğesinden bir hata dizesi
okunabilir.
veri (dizi arabelleği)Aktarım gelen olarak yapıldıysa cihaz tarafından gönderilen verileri içerir.

Örnek:

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 aktarım

Kontrol aktarımları genellikle bir USB cihazına yapılandırma veya komut parametreleri göndermek ya da almak için kullanılır. controlTransfer yöntemi her zaman uç nokta 0'a gönderim yapar ve bunları uç nokta 0'dan okur veClaimInterface gerekli değildir. Yöntem basittir ve üç parametre alır:

chrome.usb.controlTransfer(connectionHandle, transferInfo, transferCallback)
Parametre (türler)Açıklama
connectionHandleNesne usb.openDevice geri çağırmasında alındı.
transferInfoAşağıdaki tabloda yer alan değerlere sahip parametre nesnesi. Ayrıntılar için USB cihazınızın protokol özelliklerini kontrol edin.
transferCallback()Aktarım tamamlandığında çağrılır.

transferInfo nesnesinin değerleri:

DeğerAçıklama
requestType (dize)"tedarikçi", "standart", "sınıf" veya "ayrılmış".
alıcı (dize)"device", "arayüz", "uç nokta" veya "diğer".
yön (dize)"giriş" ya da "çıkış". "İçeri" yönü, cihaza, ana makineye bilgi göndermesi
gerektiğini bildirmek için kullanılır. USB veri yolu üzerindeki tüm iletişim
ana makine tarafından başlatılır. Bu nedenle cihazın bilgileri geri
gönderebilmesi için "gelen" aktarım işlemini kullanın.
istek (tam sayı)Cihazınızın protokolü tarafından tanımlanır.
değer (tam sayı)Cihazınızın protokolü tarafından tanımlanır.
dizin (tam sayı)Cihazınızın protokolü tarafından tanımlanır.
uzunluk (tam sayı)Yalnızca yön "in" olduğunda kullanılır. Cihaza, ana makinenin yanıt olarak almayı beklediği veri miktarı olduğunu bildirir.
veri (dizi arabelleği)Cihazınızın protokolü tarafından tanımlanır, yön "out" olduğunda gereklidir.

Örnek:

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);

ISOCHRONOUS aktarımları

Eş zamansız aktarımlar, USB aktarımının en karmaşık türüdür. Bunlar genellikle video ve ses gibi veri akışları için kullanılır. Eşzamanlı aktarım (gelen veya giden) başlatmak için usb.isochronousTransfer yöntemini kullanmanız gerekir:

chrome.usb.isochronousTransfer(connectionHandle, isochronousTransferInfo, transferCallback)
ParametreAçıklama
connectionHandleNesne usb.openDevice geri çağırmasında alındı.
isochronousTransferInfoAşağıdaki tabloda bulunan değerlere sahip parametre nesnesi.
transferCallback()Aktarım tamamlandığında çağrılır.

isochronousTransferInfo nesnesinin değerleri:

DeğerAçıklama
transferInfo (nesne)Şu özelliklere sahip bir nesne:
direction (dize): "in" veya "out".
uç nokta (tamsayı): Cihazınız tarafından tanımlanır. Genellikle bir USB inceleme aracına bakarak bulunabilir (ör. lsusb -v
length (integer): ): Yalnızca yön "in" olduğunda kullanılır. Cihaza, ana makinenin yanıt vermeyi beklediği veri miktarı olduğunu bildirir.
EN AZ packets × packetLength olmalıdır.
veri (dizi arabelleği): Cihazınızın protokolü tarafından tanımlanır; yalnızca yön "out" olduğunda kullanılır.
paketler (tam sayı)Bu aktarımda beklenen toplam paket sayısı.
BundleLength (tam sayı)Bu aktarımdaki her paketin beklenen uzunluğu.

Örnek:

var transferInfo = {
  "direction": "in",
  "endpoint": 1,
  "length": 2560
};

var isoTransferInfo = {
  "transferInfo": transferInfo,
  "packets": 20,
  "packetLength": 128
};

chrome.usb.isochronousTransfer(connectionHandle, isoTransferInfo, optionalCallback);

BULK aktarımları

Toplu aktarımlar, zamana bağlı olmayan büyük miktarda veriyi güvenilir bir şekilde aktarmak için yaygın olarak kullanılır. usb.bulkTransfer'de üç parametre bulunur:

chrome.usb.bulkTransfer(connectionHandle, transferInfo, transferCallback);
ParametreAçıklama
connectionHandleNesne usb.openDevice geri çağırmasında alındı.
transferInfoAşağıdaki tabloda bulunan değerlere sahip parametre nesnesi.
transferCallbackAktarım tamamlandığında çağrılır.

transferInfo nesnesinin değerleri:

DeğerAçıklama
yön (dize)"giriş" ya da "çıkış".
uç nokta (tam sayı)Cihazınızın protokolü tarafından tanımlanır.
uzunluk (tam sayı)Yalnızca yön "in" olduğunda kullanılır. Cihaza, ana makinenin yanıt olarak almayı beklediği veri miktarı olduğunu bildirir.
veri (ArrayBuffer)Cihazınızın protokolü tarafından tanımlanır; yalnızca yön "out" olduğunda kullanılır.

Örnek:

var transferInfo = {
  "direction": "out",
  "endpoint": 1,
  "data": new Uint8Array([4, 8, 15, 16, 23, 42]).buffer
};

INTERRUPT aktarımları

Kesme aktarımları, zamana duyarlı küçük verilerde kullanılır. Tüm USB iletişimleri ana makine tarafından başlatıldığından, ana makine kodu genellikle cihazı düzenli aralıklarla yoklar. Bu sırada, kesme sırasında bir şey olduğunda cihazın tekrar veri göndermesini sağlayacak aktarım içi aktarımlar göndererek (cihaz tarafından yönetilir) usb.interruptTransfer'in üç parametresi bulunur:

chrome.usb.interruptTransfer(connectionHandle, transferInfo, transferCallback);
ParametreAçıklama
connectionHandleNesne usb.openDevice geri çağırmasında alındı.
transferInfoAşağıdaki tabloda bulunan değerlere sahip parametre nesnesi.
transferCallbackAktarım tamamlandığında çağrılır. Bu geri çağırmanın cihazın yanıtını içermediğine dikkat edin. Geri çağırmanın amacı, eşzamansız aktarım isteklerinin işlendiğini kodunuza bildirmektir.

transferInfo nesnesinin değerleri:

DeğerAçıklama
yön (dize)"giriş" ya da "çıkış".
uç nokta (tam sayı)Cihazınızın protokolü tarafından tanımlanır.
uzunluk (tam sayı)Yalnızca yön "in" olduğunda kullanılır. Cihaza, ana makinenin yanıt olarak almayı beklediği veri miktarı olduğunu bildirir.
veri (ArrayBuffer)Cihazınızın protokolü tarafından tanımlanır; yalnızca yön "out" olduğunda kullanılır.

Örnek:

var transferInfo = {
  "direction": "in",
  "endpoint": 1,
  "length": 2
};
chrome.usb.interruptTransfer(connectionHandle, transferInfo, optionalCallback);

Uyarılar

Tüm cihazlara USB API üzerinden erişilemez. Genel olarak, İşletim Sisteminin çekirdeği veya yerel bir sürücü tarafından kullanıcı alan kodundan uzak tutulması nedeniyle cihazlara erişilemez. OSX sistemlerinde HID profillerine ve USB kalem sürücülerine sahip cihazlar buna örnek gösterilebilir.

Çoğu Linux sisteminde USB cihazları varsayılan olarak salt okuma izinleriyle eşlenir. Bir cihazı bu API aracılığıyla açmak için kullanıcınızın da cihaza yazma erişimine sahip olması gerekir. Basit bir çözüm udev kuralı ayarlamaktır. Aşağıdaki içeriğe sahip bir /etc/udev/rules.d/50-yourdevicename.rules dosyası oluşturun:

SUBSYSTEM=="usb", ATTR{idVendor}=="[yourdevicevendor]", MODE="0664", GROUP="plugdev"

Ardından udev arka plan programını yeniden başlatın: service udev restart. Şu adımları uygulayarak cihaz izinlerinin doğru ayarlanıp ayarlanmadığını kontrol edebilirsiniz:

  • Otobüs ve cihaz numaralarını bulmak için lsusb komutunu çalıştırın.
  • ls -al /dev/bus/usb/[bus]/[device] komutunu çalıştırın. Bu dosya "plugdev" grubuna ait olmalı ve grup yazma izinlerine sahip olmalıdır.

Bu prosedür kök erişimi gerektirdiğinden uygulamanız bunu otomatik olarak yapamaz. Son kullanıcılara talimatlar sağlamanızı ve açıklama için bu sayfadaki Uyarılar bölümüne bağlantı vermenizi öneririz.

ChromeOS'te usb.requestAccess'i çağırmanız yeterlidir. İzin aracısı bunu sizin için yapar.