บลูทูธ

เอกสารนี้อธิบายวิธีใช้ API บลูทูธ, ซ็อกเก็ตบลูทูธ และบลูทูธพลังงานต่ำเพื่อสื่อสารกับอุปกรณ์บลูทูธและอุปกรณ์บลูทูธพลังงานต่ำ

สำหรับข้อมูลเบื้องต้นเกี่ยวกับบลูทูธ โปรดดูข้อมูลจำเพาะของบลูทูธอย่างเป็นทางการ

ข้อกำหนดของไฟล์ Manifest

สำหรับแอป Chrome ที่ใช้บลูทูธ ให้เพิ่มรายการ bluetooth ลงในไฟล์ Manifest และระบุ UUID ของโปรไฟล์ โปรโตคอล หรือบริการที่คุณต้องการใช้ ถ้ามีความเหมาะสม พร้อมกับใช้ร่วมกับ Socket และ/หรือ Low Energy API

ตัวอย่างเช่น สำหรับการใช้งานซ็อกเก็ต

"bluetooth": {
  "uuids": [ "1105", "1106" ],
  "socket": true
}

และสำหรับการใช้งานพลังงานต่ำ:

"bluetooth": {
  "uuids": [ "180D", "1809", "180F" ],
  "low_energy": true
}

หากต้องการเข้าถึงเฉพาะสถานะของอะแดปเตอร์ ค้นหาอุปกรณ์ที่อยู่ใกล้เคียง และรับข้อมูลพื้นฐานเกี่ยวกับอุปกรณ์ คุณต้องมีรายการของตัวเองเท่านั้น

"bluetooth": {}

ข้อมูลอะแดปเตอร์

กำลังได้รับสถานะอะแดปเตอร์

หากต้องการดูสถานะของอะแดปเตอร์บลูทูธ ให้ใช้เมธอด bluetooth.getAdapterState ดังนี้

chrome.bluetooth.getAdapterState(function(adapter) {
  console.log("Adapter " + adapter.address + ": " + adapter.name);
});

การแจ้งเตือนอะแดปเตอร์

ระบบจะส่งเหตุการณ์ bluetooth.onAdapterStateChanged เมื่อใดก็ตามที่สถานะของอะแดปเตอร์เปลี่ยนแปลง ข้อมูลนี้สามารถใช้เพื่อตัดสินว่าจะเปิดหรือปิดวิทยุของอะแดปเตอร์

var powered = false;
chrome.bluetooth.getAdapterState(function(adapter) {
  powered = adapter.powered;
});

chrome.bluetooth.onAdapterStateChanged.addListener(
  function(adapter) {
    if (adapter.powered != powered) {
      powered = adapter.powered;
      if (powered) {
        console.log("Adapter radio is on");
      } else {
        console.log("Adapter radio is off");
      }
    }
  });

ข้อมูลอุปกรณ์

แสดงรายการอุปกรณ์ที่รู้จัก

หากต้องการดูรายการอุปกรณ์ที่อะแดปเตอร์บลูทูธรู้จัก ให้ใช้เมธอด bluetooth.getDevices ดังนี้

chrome.bluetooth.getDevices(function(devices) {
  for (var i = 0; i < devices.length; i++) {
    console.log(devices[i].address);
  }
});

คุณจะได้รับอุปกรณ์ทั้งหมดคืน ซึ่งรวมถึงอุปกรณ์ที่จับคู่แล้วและอุปกรณ์ที่เพิ่งค้นพบ จะไม่มีการเริ่มการค้นหาอุปกรณ์ใหม่ (ดูการค้นพบอุปกรณ์ที่อยู่ใกล้เคียง)

การรับการแจ้งเตือนของอุปกรณ์

แทนที่จะเรียก bluetooth.getDevices ซ้ำๆ คุณสามารถใช้เหตุการณ์ bluetooth.onDeviceAdded, bluetooth.onDeviceChanged และ bluetooth.onDeviceRemoved เพื่อรับการแจ้งเตือน

ระบบจะส่งเหตุการณ์ bluetooth.onDeviceAdded เมื่อใดก็ตามที่อะแดปเตอร์พบอุปกรณ์หรือทำการเชื่อมต่อกับอะแดปเตอร์ ดังนี้

chrome.bluetooth.onDeviceAdded.addListener(function(device) {
  console.log(device.address);
});

การเพิ่ม Listener สำหรับกิจกรรมนี้ไม่ได้เป็นการเริ่มการค้นหาอุปกรณ์ (โปรดดูการค้นพบอุปกรณ์ใกล้เคียง)

การเปลี่ยนแปลงที่เกิดขึ้นในอุปกรณ์ ซึ่งรวมถึงอุปกรณ์ที่ค้นพบก่อนหน้านี้ซึ่งมีการจับคู่จะได้รับการแจ้งเตือนจากเหตุการณ์ bluetooth.onDeviceChanged ดังนี้

chrome.bluetooth.onDeviceChanged.addListener(function(device) {
  console.log(device.address);
});

สุดท้ายนี้ ระบบจะส่งเหตุการณ์ bluetooth.onDeviceRemoved ทุกครั้งที่มีการนำอุปกรณ์ที่จับคู่ไว้ออกจากระบบ หรือไม่พบอุปกรณ์ที่ค้นพบเมื่อเร็วๆ นี้

chrome.bluetooth.onDeviceRemoved.addListener(function(device) {
  console.log(device.address);
});

กำลังค้นหาอุปกรณ์ที่อยู่ใกล้เคียง

หากต้องการเริ่มค้นหาอุปกรณ์ที่อยู่ใกล้เคียง ให้ใช้เมธอด bluetooth.startDiscovery แต่การค้นพบอาจต้องใช้ทรัพยากรมาก คุณจึงควรเรียกใช้ bluetooth.stopDiscovery เมื่อดำเนินการเสร็จ

คุณควรเรียกใช้ bluetooth.startDiscovery เมื่อใดก็ตามที่แอปต้องการค้นหาอุปกรณ์ที่อยู่ใกล้เคียง อย่าทำให้การโทรมีเงื่อนไขในพร็อพเพอร์ตี้ discovering ของ bluetooth.AdapterState การเรียกจะประสบความสำเร็จแม้ว่าแอปอื่นจะค้นหาอุปกรณ์ใกล้เคียงได้ และอะแดปเตอร์จะดำเนินการค้นหาต่อไปหลังจากแอปอื่นหยุดทำงาน

ระบบจะส่งข้อมูลเกี่ยวกับอุปกรณ์ที่เพิ่งค้นพบแต่ละเครื่องโดยใช้เหตุการณ์ bluetooth.onDeviceAdded ระบบจะไม่ส่งเหตุการณ์สำหรับอุปกรณ์ที่ค้นพบแล้วเมื่อเร็วๆ นี้ หรือเคยมีการจับคู่หรือเชื่อมต่อไว้ก่อนหน้านี้ แต่คุณควรเรียกใช้ bluetooth.getDevices เพื่อขอข้อมูลปัจจุบันและใช้เหตุการณ์ bluetooth.onDeviceChanged เพื่อรับการแจ้งเตือนเกี่ยวกับการเปลี่ยนแปลงของข้อมูลดังกล่าวเมื่อตรวจพบ

ตัวอย่าง

var device_names = {};
var updateDeviceName = function(device) {
  device_names[device.address] = device.name;
};
var removeDeviceName = function(device) {
  delete device_names[device.address];
}

// Add listeners to receive newly found devices and updates
// to the previously known devices.
chrome.bluetooth.onDeviceAdded.addListener(updateDeviceName);
chrome.bluetooth.onDeviceChanged.addListener(updateDeviceName);
chrome.bluetooth.onDeviceRemoved.addListener(removeDeviceName);

// With the listeners in place, get the list of devices found in
// previous discovery sessions, or any currently active ones,
// along with paired devices.
chrome.bluetooth.getDevices(function(devices) {
  for (var i = 0; i < devices.length; i++) {
    updateDeviceName(devices[i]);
  }
});

// Now begin the discovery process.
chrome.bluetooth.startDiscovery(function() {
  // Stop discovery after 30 seconds.
  setTimeout(function() {
    chrome.bluetooth.stopDiscovery(function() {});
  }, 30000);
});

หากผู้ใช้ปิดวิทยุบลูทูธ เซสชันการค้นพบทั้งหมดจะสิ้นสุดลงและระบบจะไม่กลับมาเล่นต่อโดยอัตโนมัติเมื่อเปิดวิทยุ หากเรื่องนี้สำคัญต่อแอป คุณควรดูกิจกรรม bluetooth.onAdapterStateChanged หากพร็อพเพอร์ตี้ discovering เปลี่ยนเป็น false แอปของคุณจะต้องเรียกใช้ bluetooth.startDiscovery อีกครั้งเพื่อกลับมาใช้งานอีกครั้ง โปรดใช้ความระมัดระวังในการค้นพบทรัพยากร จำนวนมาก

การระบุอุปกรณ์

มีตัวเลือกต่างๆ มากมายสำหรับการระบุอุปกรณ์ที่ bluetooth.getDevices และเหตุการณ์ที่เกี่ยวข้องแสดงผล

หากอุปกรณ์รองรับข้อมูลจำเพาะของรหัสอุปกรณ์บลูทูธ ระบบจะเพิ่มพร็อพเพอร์ตี้หลายรายการลงในออบเจ็กต์อุปกรณ์ซึ่งมีช่องต่างๆ ที่ข้อมูลจำเพาะดังกล่าวกำหนด ตัวอย่าง

chrome.bluetooth.getDevices(function(devices) {
  for (var i = 0; i < devices.length; i++) {
    if (devices[0].vendorIdSource != undefined) {
      console.log(devices[0].address + ' = ' +
                  devices[0].vendorIdSource + ':' +
                  devices[0].vendorId.toString(16) + ':' +
                  devices[0].productId.toString(16) + ':' +
                  devices[0].deviceId.toString(16));
    }
  }
});

โดยทั่วไปแล้ว ข้อกำหนดรหัสอุปกรณ์จะเพียงพอสำหรับการระบุรุ่นที่เจาะจงและแม้แต่การแก้ไขอุปกรณ์จากผู้ให้บริการ ในกรณีที่ไม่แสดง คุณต้องใช้ข้อมูลเกี่ยวกับคลาสหรือประเภทอุปกรณ์แทน โดยจะใช้ร่วมกับคำนำหน้าของผู้ผลิตใน address แทนก็ได้

อุปกรณ์บลูทูธส่วนใหญ่จะให้ข้อมูลคลาสของอุปกรณ์เป็นฟิลด์บิตที่ตีความตามเอกสารหมายเลขที่กำหนดของเบสแบนด์ ช่องบิตนี้อยู่ในพร็อพเพอร์ตี้ deviceClass

chrome.bluetooth.getDevices(function(devices) {
  for (var i = 0; i < devices.length; i++) {
    if (devices[0].vendorIdSource != undefined) {
      console.log(devices[0].address + ' = ' +
                  devices[0].deviceClass.toString(16));
    }
  }
});

การแยกวิเคราะห์ช่องอาจมีความซับซ้อน ดังนั้นสำหรับประเภทอุปกรณ์ที่พบบ่อยที่สุดที่ Chrome จะจัดการกับเรื่องนี้ให้คุณและตั้งค่าช่อง type ในกรณีที่ไม่พร้อมใช้งานหรือไม่เพียงพอตามความต้องการของคุณ คุณจะต้องแยกวิเคราะห์ deviceClass ด้วยตนเอง

chrome.bluetooth.getDevices(function(devices) {
  for (var i = 0; i < devices.length; i++) {
    if (devices[0].vendorIdSource != undefined) {
      console.log(devices[0].address + ' = ' + devices[0].type);
    }
  }
});

การใช้ RFCOMM และ L2CAP

แอป Chrome อาจเชื่อมต่อกับอุปกรณ์ใดก็ได้ที่รองรับบริการ RFCOMM หรือ L2CAP ซึ่งรวมถึงอุปกรณ์บลูทูธคลาสสิกส่วนใหญ่ในตลาดด้วย

กำลังเชื่อมต่อกับเต้ารับ

ในการสร้างการเชื่อมต่อกับอุปกรณ์ คุณจำเป็นต้องมี 3 สิ่งต่อไปนี้ ซ็อกเก็ตที่ใช้เชื่อมต่อ ซึ่งสร้างขึ้นโดยใช้ bluetoothSocket.create ที่อยู่ของอุปกรณ์ที่ต้องการเชื่อมต่อ และ UUID ของบริการ

ก่อนที่จะเชื่อมต่อ คุณควรตรวจสอบว่าอะแดปเตอร์รู้จักอุปกรณ์โดยใช้ bluetooth.getDevice หรือ Device Discovery API

ข้อมูลที่จำเป็นต่อการสร้างการเชื่อมต่อที่สำคัญ ซึ่งรวมถึงแจ้งว่าควรใช้โปรโตคอล RFCOMM หรือ L2CAP หรือไม่ และแชแนลหรือ PSM ใดที่ได้จากการใช้การค้นพบ SDP ในอุปกรณ์

ตัวอย่าง

var uuid = '1105';
var onConnectedCallback = function() {
  if (chrome.runtime.lastError) {
    console.log("Connection failed: " + chrome.runtime.lastError.message);
  } else {
    // Profile implementation here.
  }
};

chrome.bluetoothSocket.create(function(createInfo) {
  chrome.bluetoothSocket.connect(createInfo.socketId,
    device.address, uuid, onConnectedCallback);
});

เก็บแฮนเดิลไว้ที่ socketId เพื่อให้คุณส่งข้อมูล (bluetoothSocket.send) ไปยังซ็อกเก็ตนี้ได้ภายหลัง

การรับและการส่งไปยังซ็อกเก็ต

การรับข้อมูลจากและการส่งไปยังซ็อกเก็ตจะใช้ออบเจ็กต์ ArrayBuffer รายการ ดูข้อมูลเกี่ยวกับ ArrayBuffers ได้ที่ภาพรวม อาร์เรย์ที่พิมพ์ด้วย JavaScript และบทแนะนำเรื่องวิธีแปลง ArrayBuffers เป็นและจากสตริง

หากต้องการส่งข้อมูลที่คุณมีใน arrayBuffer ให้ใช้ bluetoothSocket.send

chrome.bluetoothSocket.send(socketId, arrayBuffer, function(bytes_sent) {
  if (chrome.runtime.lastError) {
    console.log("Send failed: " + chrome.runtime.lastError.message);
  } else {
    console.log("Sent " + bytes_sent + " bytes")
  }
})

ระบบจะรับข้อมูลในเหตุการณ์ (bluetoothSocket.onReceive) ตรงข้ามกับวิธีส่งข้อมูล ซ็อกเก็ตสร้างขึ้นโดยยกเลิกการหยุดชั่วคราว (ดู bluetoothSocket.setPaused) ดังนั้นโดยทั่วไปจะเพิ่ม Listener สำหรับเหตุการณ์นี้ระหว่าง bluetoothSocket.create กับ bluetoothSocket.connect

chrome.bluetoothSocket.onRecieve.addListener(function(receiveInfo) {
  if (receiveInfo.socketId != socketId)
    return;
  // receiveInfo.data is an ArrayBuffer.
});

การได้รับข้อผิดพลาดและการเชื่อมต่อซ็อกเก็ต

หากต้องการรับการแจ้งเตือนข้อผิดพลาดของซ็อกเก็ต ซึ่งรวมถึงการยกเลิกการเชื่อมต่อ ให้เพิ่ม Listener ลงในเหตุการณ์ bluetoothSocket.onReceiveError

chrome.bluetoothSocket.onReceiveError.addListener(function(errorInfo) {
  // Cause is in errorInfo.error.
  console.log(errorInfo.errorMessage);
});

ยกเลิกการเชื่อมต่อจากเต้ารับ

หากต้องการวางสายและยกเลิกการเชื่อมต่อซ็อกเก็ต ให้ใช้ bluetoothSocket.disconnect

chrome.bluetoothSocket.disconnect(socketId);

บริการเผยแพร่

นอกเหนือจากการเชื่อมต่อขาออกกับอุปกรณ์แล้ว แอป Chrome อาจเผยแพร่บริการที่อุปกรณ์ต่างๆ ที่รองรับ RFCOMM หรือ L2CAP อาจใช้งาน

ฟังผ่านเต้ารับ

ระบบรองรับบริการที่เผยแพร่แล้ว 2 ประเภท RFCOMM มีการใช้งานบ่อยที่สุดและครอบคลุมอุปกรณ์และโปรไฟล์ส่วนใหญ่ ดังนี้

var uuid = '1105';
chrome.bluetoothSocket.create(function(createInfo) {
  chrome.bluetoothSocket.listenUsingRfcomm(createInfo.socketId,
    uuid, onListenCallback);
});

L2CAP จึงเป็นอีกประเภทหนึ่งที่ครอบคลุมถึงอุปกรณ์ประเภทอื่นๆ และการใช้งานเฉพาะผู้ให้บริการ เช่น การอัปโหลดเฟิร์มแวร์

var uuid = '0b87367c-f188-47cd-bc20-a5f4f70973c6';
chrome.bluetoothSocket.create(function(createInfo) {
  chrome.bluetoothSocket.listenUsingL2cap(createInfo.socketId,
    uuid, onListenCallback);
});

ในทั้ง 2 กรณี ระบบอาจส่ง bluetoothSocket.ListenOptions เพื่อจัดสรรช่องหรือ PSM ที่เจาะจง โค้ดเรียกกลับจะระบุข้อผิดพลาดผ่าน chrome.runtime.lastError และดำเนินการสำเร็จ เก็บแฮนเดิลไว้กับ socketId เพื่อให้คุณสามารถยอมรับการเชื่อมต่อได้ภายหลัง (bluetoothSocket.onAccept) จากซ็อกเก็ตนี้

การยอมรับการเชื่อมต่อกับไคลเอ็นต์

ระบบจะยอมรับการเชื่อมต่อไคลเอ็นต์และส่งไปยังแอปพลิเคชันของคุณผ่านเหตุการณ์ bluetoothSocket.onAccept

chrome.bluetoothSocket.onAccept.addListener(function(acceptInfo) {
  if (info.socketId != serverSocketId)
    return;

  // Say hello...
  chrome.bluetoothSocket.send(acceptInfo.clientSocketId,
    data, onSendCallback);

  // Accepted sockets are initially paused,
  // set the onReceive listener first.
  chrome.bluetoothSocket.onReceive.addListener(onReceive);
  chrome.bluetoothSocket.setPaused(false);
});

หยุดการยอมรับการเชื่อมต่อกับไคลเอ็นต์

หากต้องการหยุดยอมรับการเชื่อมต่อกับไคลเอ็นต์และยกเลิกการเผยแพร่บริการ ให้ใช้ bluetoothSocket.disconnect

chrome.bluetoothSocket.disconnect(serverSocketId);

การโต้ตอบกับอุปกรณ์พลังงานต่ำ

บลูทูธพลังงานต่ำหรือ (บลูทูธ Smart) เป็นเทคโนโลยีไร้สายที่มีไว้เพื่อลดการใช้พลังงาน API บลูทูธพลังงานต่ำช่วยให้แอปพลิเคชันใช้บทบาทส่วนกลางในการเชื่อมต่อ LE กับอุปกรณ์ต่อพ่วงได้ ส่วนต่อไปนี้จะอธิบายวิธีการค้นหา เชื่อมต่อ และโต้ตอบกับอุปกรณ์ต่อพ่วงบลูทูธพลังงานต่ำ

การค้นหาและเชื่อมต่อกับอุปกรณ์ต่อพ่วง

เช่นเดียวกับอุปกรณ์บลูทูธแบบดั้งเดิม คุณจะค้นหาอุปกรณ์ต่อพ่วง LE ได้โดยใช้วิธีการที่อธิบายไว้ใน การค้นพบอุปกรณ์ที่อยู่ใกล้เคียง อุปกรณ์ LE จะช่วยให้ผู้คนค้นพบตัวเองได้โดยการส่งแพ็กเก็ตข้อมูลที่เรียกว่า "ข้อมูลการโฆษณา" และระบบระบุว่าอุปกรณ์อยู่ในโหมดการโฆษณา ข้อมูลการโฆษณาอาจมี UUID ของบริการที่พร้อมใช้งานในอุปกรณ์ หากมี UUID เหล่านี้จะเข้าถึงได้โดยใช้พร็อพเพอร์ตี้ uuids ของออบเจ็กต์ bluetooth.Device ที่เกี่ยวข้อง

เมื่อค้นพบแล้ว คุณสามารถเชื่อมต่ออุปกรณ์ LE ด้วยการเรียก bluetoothLowEnergy.connect เพื่อให้แอปพลิเคชันโต้ตอบกับบริการได้

chrome.bluetooth.onDeviceAdded.addListener(function(device) {
  var uuid = '0000180d-0000-1000-8000-00805f9b34fb';
  if (!device.uuids || device.uuids.indexOf(uuid) < 0)
    return;

  // The device has a service with the desired UUID.
  chrome.bluetoothLowEnergy.connect(device.address, function () {
    if (chrome.runtime.lastError) {
      console.log('Failed to connect: ' + chrome.runtime.lastError.message);
      return;
    }

    // Connected! Do stuff...
    ...
  });
});

เมื่อเชื่อมต่อแล้ว พร็อพเพอร์ตี้ connected ของออบเจ็กต์ bluetooth.Device ที่เกี่ยวข้องจะมีค่า true การเรียกใช้ bluetoothLowEnergy.connect จะสร้างการอ้างสิทธิ์จากแอปพลิเคชันบนการเชื่อมต่อจริงกับอุปกรณ์ การเชื่อมต่อจริงกับอุปกรณ์อาจอยู่ได้โดยไม่ต้องเรียก bluetoothLowEnergy.connect (เช่น เพราะเป็นเพราะแอปพลิเคชันอื่น) ในกรณีนี้ แม้ว่าแอปพลิเคชันจะยังคงโต้ตอบกับบริการของอุปกรณ์ได้ แต่ก็ควรเรียก bluetoothLowEnergy.connect ทุกครั้งเพื่อป้องกันไม่ให้แอปพลิเคชันอื่นยกเลิกการเชื่อมต่อลิงก์จริงด้วย

เมื่อไม่จำเป็นต้องเชื่อมต่อแอปพลิเคชันของคุณแล้ว คุณสามารถนำการอ้างสิทธิ์ออกจากการเชื่อมต่อได้โดยเรียก bluetoothLowEnergy.disconnect

chrome.bluetoothLowEnergy.disconnect(deviceAddress);

โปรดทราบว่าวิธีนี้จะไม่ทำลายการลิงก์จริงไปยังอุปกรณ์ เนื่องจากอาจมีแอปพลิเคชันอื่นๆ ที่มีการเชื่อมต่อกับอุปกรณ์อยู่ บางครั้งอุปกรณ์อาจถูกตัดการเชื่อมต่อเนื่องจากเหตุผลที่อยู่นอกเหนือการควบคุมของแอปพลิเคชัน (เช่น ในกรณีที่อุปกรณ์สูญหายหรือถูกตัดการเชื่อมต่อโดยผู้ใช้อย่างชัดแจ้งผ่านยูทิลิตีของระบบปฏิบัติการ) แอปพลิเคชันของคุณควรสังเกตเหตุการณ์ bluetooth.onDeviceChanged เพื่อรับการแจ้งเตือนเกี่ยวกับการเปลี่ยนแปลงของการเชื่อมต่อและเชื่อมต่อใหม่หากจำเป็น

เมื่อเชื่อมต่อแล้ว อุปกรณ์ที่ใช้ Chrome จะอยู่ในบทบาทส่วนกลาง ขณะที่อุปกรณ์ระยะไกลจะอยู่ในบทบาทของอุปกรณ์ต่อพ่วง ที่จุดนี้ แอปพลิเคชันของคุณสามารถโต้ตอบกับบริการในอุปกรณ์โดยใช้วิธีการที่อธิบายไว้ในส่วนต่อไปนี้ หมายเหตุ: ปัจจุบัน API ยังไม่รองรับการทําหน้าที่เป็นอุปกรณ์ต่อพ่วงของ LE แอปจะใช้ได้เฉพาะบทบาทส่วนกลางเท่านั้น

บริการ ลักษณะเฉพาะ และข้อบ่งชี้

บลูทูธพลังงานต่ำอิงตามโปรโตคอลการตอบกลับคำของ่ายๆ ที่เรียกว่า Attribute Protocol (ATT) เมื่อใช้ ATT อุปกรณ์ส่วนกลางจะโต้ตอบกับแอตทริบิวต์ที่เรียกว่า ในอุปกรณ์ต่อพ่วง โดยยึดตามโปรไฟล์บลูทูธพิเศษที่เรียกว่า โปรไฟล์แอตทริบิวต์ทั่วไป (GATT) GATT กำหนดแนวคิดระดับสูงดังต่อไปนี้

  • บริการ: บริการ GATT แสดงถึงการรวบรวมข้อมูลและลักษณะการทํางานที่เกี่ยวข้องเพื่อทําฟังก์ชันบางอย่างของอุปกรณ์ให้เสร็จสมบูรณ์ เช่น เครื่องวัดอัตราการเต้นของหัวใจจะมี "บริการวัดอัตราการเต้นของหัวใจ" อย่างน้อย 1 อย่าง ข้อมูลเกี่ยวกับบริการ GATT จะอยู่ในออบเจ็กต์ bluetoothLowEnergy.Service
  • ลักษณะเฉพาะ: ลักษณะ GATT คือองค์ประกอบข้อมูลพื้นฐานที่ใช้สร้างบริการ GATT โดยมีค่าพร้อมกับพร็อพเพอร์ตี้ที่กําหนดวิธีเข้าถึงค่านั้น ตัวอย่างเช่น "บริการวัดอัตราการเต้นของหัวใจ" มีลักษณะ "การวัดอัตราการเต้นของหัวใจ" ซึ่งใช้เพื่อหาค่าของอัตราการเต้นของหัวใจของผู้ใช้ ข้อมูลเกี่ยวกับลักษณะ GATT จะอยู่ในออบเจ็กต์ bluetoothLowEnergy.Characteristic
  • ข้อบ่งชี้: ข้อบ่งชี้ลักษณะเฉพาะ GATT มีข้อมูลเพิ่มเติมเกี่ยวกับลักษณะเฉพาะนั้นๆ ข้อมูลเกี่ยวกับข้อบ่งชี้ลักษณะ GATT จะอยู่ในออบเจ็กต์ bluetoothLowEnergy.Descriptor

API บลูทูธพลังงานต่ำช่วยให้แอปพลิเคชันค้นหาข้อมูลเกี่ยวกับบริการ ลักษณะ และข้อบ่งชี้ของอุปกรณ์ได้โดยเรียกใช้ bluetoothLowEnergy.getServices, bluetoothLowEnergy.getCharacteristics และ bluetoothLowEnergy.getDescriptors แอปสามารถกรองข้อมูลบริการ ลักษณะเฉพาะ และข้อบ่งชี้โดยเปรียบเทียบช่อง uuid กับ GATT UUID ที่ต้องการ

chrome.bluetoothLowEnergy.getServices(deviceAddress, function(services) {
  ...
  for (var i = 0; i < services.length; i++) {
    if (services[i].uuid == HEART_RATE_SERVICE_UUID) {
      heartRateService = services[i];
      break;
    }
  }
  ...
});

บริการ ลักษณะเฉพาะ และข้อบ่งชี้แต่ละรายการที่เข้าถึงได้ผ่าน API จะได้รับการกำหนดตัวระบุอินสแตนซ์ที่ไม่ซ้ำกัน ซึ่งรับได้โดยใช้ช่อง instanceId รหัสอินสแตนซ์นี้ใช้เพื่อระบุออบเจ็กต์ GATT และดำเนินการที่เฉพาะเจาะจงกับออบเจ็กต์นั้นได้

chrome.bluetoothLowEnergy.getCharacteristics(heartRateService.instanceId,
                                             function(chracteristics) {
  ...
  for (var i = 0; i < characteristics.length; i++) {
    if (characteristics[i].uuid == HEART_RATE_MEASUREMENT_UUID) {
      measurementChar = characteristics[i];
      break;
    }
  }
  ...
  chrome.bluetoothLowEnergy.getDescriptors(measurementChar.instanceId,
                                           function(descriptors) {
    ...
  });
});

เหตุการณ์เกี่ยวกับบริการ

เมื่ออุปกรณ์เชื่อมต่อแล้ว Chrome จะค้นพบบริการต่างๆ เมื่อระบบพบและ นำแต่ละบริการออก แอปพลิเคชันจะได้รับเหตุการณ์ bluetoothLowEnergy.onServiceAdded และ bluetoothLowEnergy.onServiceRemoved ดังนี้

  var initializeService = function(service) {
    if (!service) {
      console.log('No service selected!');
      // Reset UI, etc.
      ...
      return;
    }

    myService = service;

    // Get all the characteristics and descriptors and bootstrap the app.
    ...
  };

  chrome.bluetoothLowEnergy.onServiceAdded.addListener(function(service) {
    if (service.uuid == MY_SERVICE_UUID)
      initializeService(service);
  });

  chrome.bluetoothLowEnergy.onServiceRemoved.addListener(function(service) {
    if (service.instanceId == myService.instanceId)
      initializeService(null);
  });

Chrome จะค้นพบลักษณะและข้อบ่งชี้ทั้งหมดของบริการแบบไม่พร้อมกัน และส่งเหตุการณ์ bluetoothLowEnergy.onServiceAdded เมื่อการค้นหาเสร็จสมบูรณ์ หากการเชื่อมต่อกับอุปกรณ์ต่อพ่วงสิ้นสุดการทำงาน Chrome จะนำบริการที่เกี่ยวข้องทั้งหมดออกและส่งเหตุการณ์ bluetoothLowEnergy.onServiceRemoved

อุปกรณ์ต่อพ่วงบางอย่างอาจปรับเปลี่ยนบริการ เช่น ลักษณะของบริการอาจมีการเปลี่ยนแปลง หรืออาจมีการเพิ่มและนำบริการออกทั้งหมด Chrome จะแจ้งเตือนแอปต่างๆ เกี่ยวกับการเปลี่ยนแปลงเหล่านี้โดยใช้เหตุการณ์ bluetoothLowEnergy.onServiceChanged, bluetoothLowEnergy.onServiceAdded และ bluetoothLowEnergy.onServiceRemoved

  chrome.bluetoothLowEnergy.onServiceChanged.addListener(function(service) {
    if (service.instanceId != myService.instanceId)
      return;

    updateMyService(service);
  });

การอ่านและเขียนคุณค่าของลักษณะเฉพาะ

ลักษณะ GATT เข้ารหัสแง่มุมหนึ่งของบริการของตน แอปส่วนกลางจะอ่าน ดำเนินการ และแก้ไขสถานะบริการของอุปกรณ์ต่อพ่วงโดยการดำเนินการตามค่าของลักษณะเฉพาะ ค่าลักษณะเฉพาะคือลําดับของไบต์ และความหมายของค่าตามข้อกําหนดขั้นสูงซึ่งเป็นการกําหนดลักษณะบางอย่าง ตัวอย่างเช่น ค่าของคุณลักษณะการวัดอัตราการเต้นของหัวใจจะเข้ารหัสอัตราการเต้นของหัวใจและปริมาณแคลอรี่ทั้งหมดที่เผาผลาญไป ส่วนคุณลักษณะตำแหน่งของเซ็นเซอร์ร่างกายจะเข้ารหัสตำแหน่งที่ควรสวมใส่เซ็นเซอร์วัดอัตราการเต้นของหัวใจในร่างกาย

Chrome มอบเมธอด bluetoothLowEnergy.readCharacteristicValue อ่านค่าของลักษณะเฉพาะ ดังนี้

chrome.bluetoothLowEnergy.readCharacteristicValue(chrc.instanceId,
                                                  function(result) {
  if (chrome.runtime.lastError) {
    console.log('Failed to read value: ' + chrome.runtime.lastError.message);
    return;
  }

  var bytes = new Uint8Array(result.value);

  // Do stuff with the bytes.
  ...
});

คุณลักษณะบางอย่างเขียนได้ โดยเฉพาะลักษณะที่เป็น "จุดควบคุม" ซึ่งการเขียนค่าจะมีผลกระทบข้างเคียง ตัวอย่างเช่น คุณลักษณะจุดควบคุมอัตราการเต้นของหัวใจใช้เพื่อบอกเซ็นเซอร์วัดอัตราการเต้นของหัวใจให้รีเซ็ตจำนวนแคลอรี่ทั้งหมดที่เผาผลาญไปและรองรับการเขียนเท่านั้น ด้วยเหตุนี้ Chrome จึงเสนอเมธอด bluetoothLowEnergy.writeCharacteristicValue ดังนี้

var myBytes = new Uint8Array([ ... ]);
chrome.bluetoothLowEnergy.writeCharacteristicValue(chrc.instanceId,
                                                   myBytes.buffer,
                                                   function() {
  if (chrome.runtime.lastError) {
    console.log('Failed to write value: ' +
                chrome.runtime.lastError.message);
    return;
  }

  // Value is written now.
});

โดยข้อบ่งชี้ลักษณะเฉพาะจะมีพฤติกรรมเหมือนเดิมซึ่งสามารถอ่านและ/หรือเขียนได้ Chrome มอบเมธอด bluetoothLowEnergy.readDescriptorValue และ bluetoothLowEnergy.writeDescriptorValue ในการอ่านและเขียนค่าของตัวบ่งชี้

หากต้องการตรวจสอบว่าลักษณะเฉพาะรองรับการอ่านหรือการเขียนหรือไม่ แอปพลิเคชันจะตรวจสอบช่อง properties ของออบเจ็กต์ bluetoothLowEnergy.Characteristic ได้ แม้ว่าช่องนี้จะไม่มีข้อมูลเกี่ยวกับข้อกำหนดด้านความปลอดภัยในการเข้าถึงค่า แต่จะอธิบายถึงค่าการดำเนินการที่ลักษณะเฉพาะนี้รองรับโดยทั่วไป

การจัดการการแจ้งเตือนมูลค่า

คุณลักษณะบางอย่างทำให้คุณค่าของคุณลักษณะนั้นเป็นที่รู้จักโดยใช้การแจ้งเตือนหรือตัวบ่งชี้ ตัวอย่างเช่น คุณลักษณะการวัดอัตราการเต้นของหัวใจจะไม่สามารถอ่านหรือเขียนได้ แต่จะส่งการอัปเดตของค่าปัจจุบันในช่วงเวลาที่สม่ำเสมอ แอปพลิเคชันจะฟังการแจ้งเตือนเหล่านี้ได้โดยใช้เหตุการณ์ bluetoothLowEnergy.onCharacteristicValueChanged

  chrome.bluetoothLowEnergy.onCharacteristicValueChanged.addListener(
      function(chrc) {
    if (chrc.instanceId != myCharId)
      return;

    var bytes = new Uint8Array(chrc.value);

    // Do stuff with the bytes.
    ...
  });

แม้ว่าลักษณะเฉพาะจะรองรับการแจ้งเตือน/ตัวบ่งชี้ แต่การแจ้งเตือน/ตัวบ่งชี้จะไม่เปิดใช้อยู่โดยค่าเริ่มต้น แอปพลิเคชันควรเรียกใช้เมธอด bluetoothLowEnergy.startCharacteristicNotifications และ bluetoothLowEnergy.stopCharacteristicNotifications เพื่อเริ่มหรือหยุดรับเหตุการณ์ bluetoothLowEnergy.onCharacteristicValueChanged

  // Start receiving characteristic value notifications.
  var notifying = false;
  chrome.bluetoothLowEnergy.startCharacteristicNotifications(chrc.instanceId,
                                                             function() {
    if (chrome.runtime.lastError) {
      console.log('Failed to enable notifications: ' +
                  chrome.runtime.lastError.message);
      return;
    }

    notifying = true;
  });

  ...

  // No longer interested in notifications from this characteristic.
  if (notifying) {
    chrome.bluetoothLowEnergy.stopCharacteristicNotifications(
        chrc.instanceId);
  }

เมื่อเริ่มการแจ้งเตือน แอปพลิเคชันจะได้รับ bluetoothLowEnergy.onCharacteristicValueChanged ทุกครั้งที่ได้รับการแจ้งเตือนหรือตัวบ่งชี้จากคุณลักษณะนั้นๆ หากลักษณะรองรับการอ่าน ระบบจะส่งเหตุการณ์นี้หลังจากการเรียก bluetoothLowEnergy.readCharacteristicValue ที่สำเร็จด้วย วิธีนี้จะช่วยให้แอปรวมขั้นตอนการควบคุมการอัปเดตค่าที่เกิดขึ้นผ่านคำขออ่านและการแจ้งเตือนได้

  chrome.bluetoothLowEnergy.onCharacteristicValueChanged.addListener(
      function(chrc) {
    // Process the value.
    ...
  });

  chrome.bluetoothLowEnergy.startCharacteristicNotifications(chrc.instanceId,
                                                             function() {
    // Notifications started. Read the initial value.
    chrome.bluetoothLowEnergy.readCharacteristicValue(chrc.instanceId,
                                                      function(result) {
      ...
      // No need to do anything here since onCharacteristicValueChanged
      // will handle it.
    });
  });

หากมีลักษณะเฉพาะรองรับการแจ้งเตือน ช่อง properties จะมีพร็อพเพอร์ตี้ "notify" หรือ "indicate"

หมายเหตุ: หากลักษณะเฉพาะรองรับการแจ้งเตือน/ตัวบ่งชี้ จะมีคำอธิบาย "การกำหนดค่าลักษณะเฉพาะของไคลเอ็นต์" เพื่อเปิด/ปิดใช้การแจ้งเตือน Chrome ไม่อนุญาตให้ แอปเขียนไปยังข้อบ่งชี้นี้ แอปควรใช้เมธอด bluetoothLowEnergy.startCharacteristicNotifications และ bluetoothLowEnergy.stopCharacteristicNotifications แทนเพื่อควบคุมลักษณะการทำงานของการแจ้งเตือนแทน