بلوتوث

این سند نحوه استفاده از بلوتوث ، سوکت بلوتوث و APIهای کم مصرف بلوتوث را برای برقراری ارتباط با دستگاه‌های بلوتوث و بلوتوث کم مصرف توضیح می‌دهد.

برای اطلاعات پس زمینه درباره بلوتوث، مشخصات رسمی بلوتوث را ببینید.

الزامات آشکار

برای برنامه‌های Chrome که از بلوتوث استفاده می‌کنند، ورودی بلوتوث را به مانیفست اضافه کنید و در صورت لزوم، UUID نمایه‌ها، پروتکل‌ها یا سرویس‌هایی را که می‌خواهید پیاده‌سازی کنید و اینکه آیا می‌خواهید اینها را با سوکت و/یا 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);
});

افزودن شنونده برای این رویداد، کشف دستگاه‌ها را آغاز نمی‌کند ( به کشف دستگاه‌های اطراف مراجعه کنید).

تغییرات در دستگاه‌ها، از جمله دستگاه‌هایی که قبلاً کشف شده‌اند مرتبط می‌شوند، توسط رویداد 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 استفاده کنید. Discovery می‌تواند منابع زیادی داشته باشد، بنابراین باید پس از اتمام با 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 و رویدادهای مرتبط ارائه شده است.

اگر دستگاه از مشخصات شناسه دستگاه بلوتوث پشتیبانی می‌کند، چندین ویژگی به شی Device اضافه می‌شود که حاوی فیلدهای تعریف‌شده توسط آن مشخصات است. مثال:

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

مشخصات Device ID معمولاً برای شناسایی یک مدل خاص و حتی بازبینی یک دستگاه از یک فروشنده کافی است. در جایی که وجود ندارد، باید به جای آن به اطلاعات مربوط به کلاس یا نوع دستگاه تکیه کنید، که به صورت اختیاری با پیشوند سازنده در 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 Apps ممکن است به هر دستگاهی که از خدمات RFCOMM یا L2CAP پشتیبانی می‌کند، اتصال برقرار کند. این شامل اکثر دستگاه های بلوتوث کلاسیک موجود در بازار می شود.

اتصال به سوکت

برای برقراری اتصال به یک دستگاه به سه چیز نیاز دارید. سوکتی برای برقراری ارتباط با استفاده از bluetoothSocket.create ایجاد شده است. آدرس دستگاهی که می خواهید به آن متصل شوید و UUID خود سرویس.

قبل از برقراری اتصال، باید با استفاده از bluetooth.getDevice یا 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 استفاده می کند. برای آشنایی با ArrayBuffer ها، نمای کلی، آرایه های تایپ شده جاوا اسکریپت و آموزش نحوه تبدیل ArrayBuffer به و از String را بررسی کنید.

برای ارسال داده هایی که در 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 مراجعه کنید) بنابراین شنونده این رویداد معمولاً بین bluetoothSocket.create و bluetoothSocket.connect اضافه می‌شود.

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

دریافت خطاهای سوکت و قطع اتصال

برای اطلاع از خطاهای سوکت، از جمله قطع اتصال، یک شنونده به رویداد bluetoothSocket.onReceiveError اضافه کنید.

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

قطع شدن از پریز

برای قطع اتصال و قطع سوکت از bluetoothSocket.disconnect استفاده کنید.

chrome.bluetoothSocket.disconnect(socketId);

خدمات انتشاراتی

علاوه بر ایجاد اتصالات خروجی به دستگاه‌ها، Chrome Apps ممکن است خدماتی را منتشر کند که ممکن است توسط هر دستگاهی که از RFCOMM یا L2CAP پشتیبانی می‌کند استفاده شود.

گوش دادن روی سوکت

دو نوع سرویس منتشر شده پشتیبانی می شود. 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);
});

در هر دو مورد، یک بلوتوث اختیاری سوکت.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);

تعامل با دستگاه های کم انرژی

بلوتوث کم انرژی یا (Bluetooth Smart) یک فناوری بی سیم با هدف کاهش مصرف انرژی است. Bluetooth Low Energy API به برنامه‌ها اجازه می‌دهد تا نقش اصلی را در اتصال LE به یک دستگاه جانبی اجرا کنند. بخش‌های زیر نحوه کشف، اتصال و تعامل با دستگاه‌های جانبی کم‌انرژی بلوتوث را شرح می‌دهند.

کشف و اتصال به تجهیزات جانبی

همانند دستگاه‌های بلوتوث سنتی، لوازم جانبی LE را می‌توان با استفاده از روش‌های شرح داده شده در کشف دستگاه‌های نزدیک کشف کرد. یک دستگاه LE با ارسال بسته های داده ای به نام "داده های تبلیغاتی" خود را قابل کشف می کند و گفته می شود که دستگاه در حالت تبلیغاتی است. داده‌های تبلیغات ممکن است حاوی UUID خدماتی باشد که در دستگاه موجود است. در صورت وجود، این UUID ها با استفاده از ویژگی uuids شی بلوتوث.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 شیء بلوتوث.دستگاه مربوطه مقدار true را خواهد داشت. فراخوانی bluetoothLowEnergy.connect ادعایی را توسط برنامه در مورد اتصال فیزیکی به دستگاه ایجاد می کند. اتصال فیزیکی به دستگاه می‌تواند بدون تماس با bluetoothLowEnergy.connect (به عنوان مثال به دلیل برنامه دیگری) وجود داشته باشد. در این حالت، در حالی که برنامه شما هنوز می‌تواند با سرویس‌های دستگاه تعامل داشته باشد، همیشه باید bluetoothLowEnergy.connect را فراخوانی کند تا از قطع ارتباط فیزیکی یک برنامه دیگر جلوگیری شود.

هنگامی که برنامه شما دیگر نیازی به اتصال ندارد، می تواند با فراخوانی bluetoothLowEnergy.disconnect ادعای خود را در مورد اتصال حذف کند:

chrome.bluetoothLowEnergy.disconnect(deviceAddress);

توجه داشته باشید که این لزوماً پیوند فیزیکی دستگاه را از بین نمی برد، زیرا ممکن است برنامه های دیگری وجود داشته باشند که اتصالات فعالی به دستگاه داشته باشند. گاهی اوقات ممکن است دستگاه به دلایلی که خارج از کنترل برنامه است قطع شود (مثلاً اگر دستگاه ناپدید شود یا به صراحت توسط کاربر از طریق برنامه های کاربردی سیستم عامل قطع شود). برنامه شما باید رویداد bluetooth.onDeviceChanged را مشاهده کند تا از تغییرات اتصال مطلع شود و در صورت لزوم دوباره متصل شود.

پس از اتصال، دستگاهی که Chrome را اجرا می کند در نقش مرکزی قرار می گیرد، در حالی که گفته می شود دستگاه راه دور در نقش جانبی قرار دارد. در این مرحله، برنامه شما می تواند با استفاده از روش هایی که در بخش زیر توضیح داده شده است، با سرویس های موجود در دستگاه تعامل داشته باشد. توجه: API ها در حال حاضر از عمل به عنوان یک LE جانبی پشتیبانی نمی کنند. برنامه ها فقط می توانند نقش مرکزی را اجرا کنند.

خدمات، ویژگی ها و توصیفگرها

بلوتوث کم انرژی بر اساس یک پروتکل ساده درخواست پاسخ به نام پروتکل ویژگی (ATT) است. با استفاده از ATT، یک دستگاه مرکزی با انطباق با یک نمایه بلوتوث ویژه به نام نمایه ویژگی عمومی (GATT) با به اصطلاح ویژگی ها در یک دستگاه جانبی تعامل می کند. گات مفاهیم سطح بالا زیر را تعریف می کند:

  • سرویس: یک سرویس گات مجموعه ای از داده ها و رفتارهای مرتبط را برای انجام یک عملکرد خاص از یک دستگاه نشان می دهد. برای مثال، یک مانیتور ضربان قلب معمولاً حداقل یک «سرویس ضربان قلب» دارد. اطلاعات مربوط به یک سرویس GATT در یک شی bluetoothLowEnergy.Service موجود است.
  • مشخصه: مشخصه GATT یک عنصر داده پایه است که برای ساخت یک سرویس GATT استفاده می شود و حاوی یک مقدار به همراه ویژگی هایی است که نحوه دسترسی به آن مقدار را مشخص می کند. به عنوان مثال، "سرویس ضربان قلب" دارای ویژگی "اندازه گیری ضربان قلب" است که برای به دست آوردن مقدار ضربان قلب کاربر استفاده می شود. اطلاعات مربوط به یک مشخصه GATT در یک شیء بلوتوث LowEnergy.Characteristic موجود است.
  • توصیفگر: توصیفگر مشخصه GATT حاوی اطلاعات بیشتر در مورد یک مشخصه است. اطلاعات مربوط به یک توصیفگر مشخصه GATT در یک شیء بلوتوث LowEnergy.Descriptor موجود است.

Bluetooth Low Energy 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 یک شی بلوتوث LowEnergy.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.onCharacteristicValueChanged ، یک برنامه کاربردی باید متدهای bluetoothLowEnergy.startCharacteristicNotifications و bluetoothLowEnergy.stopCharacteristicNotifications را فراخوانی کند.

  // 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 برای کنترل رفتار اعلان‌ها استفاده کنند.

،

این سند نحوه استفاده از بلوتوث ، سوکت بلوتوث و APIهای کم مصرف بلوتوث را برای برقراری ارتباط با دستگاه‌های بلوتوث و بلوتوث کم مصرف توضیح می‌دهد.

برای اطلاعات پس زمینه درباره بلوتوث، مشخصات رسمی بلوتوث را ببینید.

الزامات آشکار

برای برنامه‌های Chrome که از بلوتوث استفاده می‌کنند، ورودی بلوتوث را به مانیفست اضافه کنید و در صورت لزوم، UUID نمایه‌ها، پروتکل‌ها یا سرویس‌هایی را که می‌خواهید پیاده‌سازی کنید و اینکه آیا می‌خواهید اینها را با سوکت و/یا 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);
});

افزودن شنونده برای این رویداد، کشف دستگاه‌ها را آغاز نمی‌کند ( به کشف دستگاه‌های اطراف مراجعه کنید).

تغییرات در دستگاه‌ها، از جمله دستگاه‌هایی که قبلاً کشف شده‌اند مرتبط می‌شوند، توسط رویداد 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 استفاده کنید. Discovery می‌تواند منابع زیادی داشته باشد، بنابراین باید پس از اتمام با 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 و رویدادهای مرتبط ارائه شده است.

اگر دستگاه از مشخصات شناسه دستگاه بلوتوث پشتیبانی می‌کند، چندین ویژگی به شی Device اضافه می‌شود که حاوی فیلدهای تعریف‌شده توسط آن مشخصات است. مثال:

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

مشخصات Device ID معمولاً برای شناسایی یک مدل خاص و حتی بازبینی یک دستگاه از یک فروشنده کافی است. در جایی که وجود ندارد، باید به جای آن به اطلاعات مربوط به کلاس یا نوع دستگاه تکیه کنید، که به صورت اختیاری با پیشوند سازنده در 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 Apps ممکن است به هر دستگاهی که از خدمات RFCOMM یا L2CAP پشتیبانی می‌کند، اتصال برقرار کند. این شامل اکثر دستگاه های بلوتوث کلاسیک موجود در بازار می شود.

اتصال به سوکت

برای برقراری اتصال به یک دستگاه به سه چیز نیاز دارید. سوکتی برای برقراری ارتباط با استفاده از bluetoothSocket.create ایجاد شده است. آدرس دستگاهی که می خواهید به آن متصل شوید و UUID خود سرویس.

قبل از برقراری اتصال، باید با استفاده از bluetooth.getDevice یا 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 استفاده می کند. برای آشنایی با ArrayBuffer ها، نمای کلی، آرایه های تایپ شده جاوا اسکریپت و آموزش نحوه تبدیل ArrayBuffer به و از String را بررسی کنید.

برای ارسال داده هایی که در 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 مراجعه کنید) بنابراین شنونده این رویداد معمولاً بین bluetoothSocket.create و bluetoothSocket.connect اضافه می‌شود.

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

دریافت خطاهای سوکت و قطع اتصال

برای اطلاع از خطاهای سوکت، از جمله قطع اتصال، یک شنونده به رویداد bluetoothSocket.onReceiveError اضافه کنید.

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

قطع شدن از پریز

برای قطع اتصال و قطع سوکت از bluetoothSocket.disconnect استفاده کنید.

chrome.bluetoothSocket.disconnect(socketId);

خدمات انتشاراتی

علاوه بر ایجاد اتصالات خروجی به دستگاه‌ها، Chrome Apps ممکن است خدماتی را منتشر کند که ممکن است توسط هر دستگاهی که از RFCOMM یا L2CAP پشتیبانی می‌کند استفاده شود.

گوش دادن روی سوکت

دو نوع سرویس منتشر شده پشتیبانی می شود. 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);
});

در هر دو مورد، یک بلوتوث اختیاری سوکت.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);

تعامل با دستگاه های کم انرژی

بلوتوث کم انرژی یا (Bluetooth Smart) یک فناوری بی سیم با هدف کاهش مصرف انرژی است. Bluetooth Low Energy API به برنامه‌ها اجازه می‌دهد تا نقش اصلی را در اتصال LE به یک دستگاه جانبی اجرا کنند. بخش‌های زیر نحوه کشف، اتصال و تعامل با دستگاه‌های جانبی کم‌انرژی بلوتوث را شرح می‌دهند.

کشف و اتصال به تجهیزات جانبی

همانند دستگاه‌های بلوتوث سنتی، لوازم جانبی LE را می‌توان با استفاده از روش‌های شرح داده شده در کشف دستگاه‌های نزدیک کشف کرد. یک دستگاه LE با ارسال بسته های داده ای به نام "داده های تبلیغاتی" خود را قابل کشف می کند و گفته می شود که دستگاه در حالت تبلیغاتی است. داده‌های تبلیغات ممکن است حاوی UUID خدماتی باشد که در دستگاه موجود است. در صورت وجود، این UUID ها با استفاده از ویژگی uuids شی بلوتوث.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 شیء بلوتوث.دستگاه مربوطه مقدار true را خواهد داشت. فراخوانی bluetoothLowEnergy.connect ادعایی را توسط برنامه در مورد اتصال فیزیکی به دستگاه ایجاد می کند. اتصال فیزیکی به دستگاه می‌تواند بدون تماس با bluetoothLowEnergy.connect (به عنوان مثال به دلیل برنامه دیگری) وجود داشته باشد. در این حالت، در حالی که برنامه شما هنوز می‌تواند با سرویس‌های دستگاه تعامل داشته باشد، همیشه باید bluetoothLowEnergy.connect را فراخوانی کند تا از قطع ارتباط فیزیکی یک برنامه دیگر جلوگیری شود.

هنگامی که برنامه شما دیگر نیازی به اتصال ندارد، می تواند با فراخوانی bluetoothLowEnergy.disconnect ادعای خود را در مورد اتصال حذف کند:

chrome.bluetoothLowEnergy.disconnect(deviceAddress);

توجه داشته باشید که این لزوماً پیوند فیزیکی دستگاه را از بین نمی برد، زیرا ممکن است برنامه های دیگری وجود داشته باشند که اتصالات فعالی به دستگاه داشته باشند. گاهی اوقات ممکن است دستگاه به دلایلی که خارج از کنترل برنامه است قطع شود (مثلاً اگر دستگاه ناپدید شود یا به صراحت توسط کاربر از طریق برنامه های کاربردی سیستم عامل قطع شود). برنامه شما باید رویداد bluetooth.onDeviceChanged را مشاهده کند تا از تغییرات اتصال مطلع شود و در صورت لزوم دوباره متصل شود.

پس از اتصال، دستگاهی که Chrome را اجرا می کند در نقش مرکزی قرار می گیرد، در حالی که گفته می شود دستگاه راه دور در نقش جانبی قرار دارد. در این مرحله، برنامه شما می تواند با استفاده از روش هایی که در بخش زیر توضیح داده شده است، با سرویس های موجود در دستگاه تعامل داشته باشد. توجه: API ها در حال حاضر از عمل به عنوان یک LE جانبی پشتیبانی نمی کنند. برنامه ها فقط می توانند نقش مرکزی را اجرا کنند.

خدمات، ویژگی ها و توصیفگرها

بلوتوث کم انرژی بر اساس یک پروتکل ساده درخواست پاسخ به نام پروتکل ویژگی (ATT) است. با استفاده از ATT، یک دستگاه مرکزی با انطباق با یک نمایه بلوتوث ویژه به نام نمایه ویژگی عمومی (GATT) با به اصطلاح ویژگی ها در یک دستگاه جانبی تعامل می کند. گات مفاهیم سطح بالا زیر را تعریف می کند:

  • سرویس: یک سرویس گات مجموعه ای از داده ها و رفتارهای مرتبط را برای انجام یک عملکرد خاص از یک دستگاه نشان می دهد. برای مثال، یک مانیتور ضربان قلب معمولاً حداقل یک «سرویس ضربان قلب» دارد. اطلاعات مربوط به یک سرویس GATT در یک شی bluetoothLowEnergy.Service موجود است.
  • مشخصه: مشخصه GATT یک عنصر داده پایه است که برای ساخت یک سرویس GATT استفاده می شود و حاوی یک مقدار به همراه ویژگی هایی است که نحوه دسترسی به آن مقدار را مشخص می کند. به عنوان مثال، "سرویس ضربان قلب" دارای ویژگی "اندازه گیری ضربان قلب" است که برای به دست آوردن مقدار ضربان قلب کاربر استفاده می شود. اطلاعات مربوط به یک مشخصه GATT در یک شیء بلوتوث LowEnergy.Characteristic موجود است.
  • توصیفگر: توصیفگر مشخصه GATT حاوی اطلاعات بیشتر در مورد یک مشخصه است. اطلاعات مربوط به یک توصیفگر مشخصه GATT در یک شیء بلوتوث LowEnergy.Descriptor موجود است.

Bluetooth Low Energy 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 یک شی بلوتوث LowEnergy.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.startartaracticisticnotifications و Bluetoothlowenergy.stopcaractictionnotifications برای شروع یا متوقف کردن دریافت Bluetoothlowenergy.oncharacteristictoraluechanged فراخوانی شود.

  // 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.ReadCharactericationValue ، این رویداد نیز ارسال می شود. این به برنامه ها اجازه می دهد تا جریان کنترل یک به روزرسانی مقدار را که از طریق یک درخواست خوانده شده و اعلان ها ایجاد می شود متحد کنند:

  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 استفاده کنند. روشهای تنظیم کننده برای کنترل رفتار اعلان.