Chào các bạn, tiếp tục loạt bài vè chủ đề BLE, hôm nay mình tiếp tục trình bày về Discovery Service và Transfer BLE Data
-
Discovery Service Sau khi kết nối thành công, để phục vụ việc Transfer dữ liệu, điều đầu tiên cần làm khi bạn kết nối với GATT Server trên thiết bị BLE là thực hiện Discovery Service. Điều này cung cấp thông tin về các Available Service trên remote device cũng như các service characteristics và thông tin của chúng. Cụ thể là

3 thông số trên thì device sẽ có một mã code riêng phục vụ việc Discovery và mở cổng transfer dữ liệu giữa App và thiết bị.
-
Turning notifications on and off
Để thực hiện việc Read và Write dữ liệu giữa ứng dụng và Device BLE chúng ta cần Turning notifications sau khi Discovery Service thành công. Cụ thể là việc Call setCharacteristicNotification(). Điều này các bạn hiểu đơn giản là sẽ báo cho ngăn xếp Bluetooth về cái mong đợi nhận thông báo cho characteristic cụ thể của Device BLE đó. Nếu không có điều này hoàn bạn bạn không thể nhận được dữ liệu response từ Device BLE cho dù bạn có thể gọi thành công writeCharacteristic.
Cụ thể về việc gọi Turning notifications. Chú ý về việc thực hiện sau khi Discovery Service thành công. Bạn có thể làm điểu này bằng Callback. Nhưng trong ví dụ của mình thì mình sử dụng 1 SingleSubject của Rx để thực hiện nó. 
-
Read and Write dữ liệu
Đầu tiên các bạn clear rằng, kiểu dữ liệu giao tiếp giữa ứng dụng và Device BLE là ByteArray. Và để nhận biết việc nhận gửi đó giữa ứng dụng và Device BLE nào thì nó sẽ thông qua outputCharacteristic và inputCharacteristic tương ứng với việc Write và Read. 2 thông số outputCharacteristic và inputCharacteristic lấy được từ đối tượng BluetoothGattService khi sau khi chúng ta Discovery Service.
Data ByteArray gửi lên được define cụ thể cho từng Device BLE cụ thể. Đa phần sẽ thuộc về team Hardware và Firmware cung cấp file command request và response tương ứng của thiết bị đó.
Có 1 điểm lưu ý là trong quá trình trao đổi dữ liệu giữa ứng dụng và Device BLE, chúng ta sẽ gửi nhận liên tục. Hoàn toàn bài toán của việc gửi dữ liệu, Device BLE chưa trả về và mình lại đã gửi tiếp dữ liệu 1 lần nữa. Để giải quyết bài toán này, các bạn nên quản lý việc gửi nhận dữ liệu (hay ở đây mình hay gọi là command request ) trong 1 Queue tương ứng. Điều đó sẽ giúp các bạn quản lý dễ dàng cho dù bạn muốn việc thực hiện tuần tự, hay loại nào khác cũng sẽ dễ dàng hơn.
-
Đây là quá trình gửi dữ liệu từ ứng dụng sang Device BLE. Thông qua việc gọi writeCharacteristic qua đối tượng bluetoothGatt.
-
Sau khi gọi thành công. System sẽ trả về hàm callback tương ứng, thông về status đã gửi thành công hay thất bại đến Device BLE.
-
Tiếp đến là quá trình nhận dữ liệu sau khi request gửi đến Device BLE thành công. Thiết bị sẽ trả về response tương ứng tại 1 trong 2 functions.
 Sau khi nhận được dự liệu kiểu ByteArray. Chúng ta sẽ thực hiện việc xử lý dữ liệu tương ứng.
Lưu ý:
Vì BLE là asynchronous nên là có nhiều Thread được tạo ra và thực thi. Cụ thể ở đây là khi nhận callbacks on BluetoothGattCallback, thì các dòng code này sẽ thực thực hiện Binder threads. Các hàm mình muốn nói đến ở đây ví dụ như các hàm onCharacteristicWrite(), onCharacteristicRead(), onCharacteristicChanged(), … đây là 1 số functions quan trọng trong việc xử lý và thực thi gửi nhận dữ liệu.
Vậy tại sao nên tránh xử lý trên Binder threads? Khi bạn nhận được nội dung nào đó trên Binder Thread, Android sẽ không gửi bất kỳ lệnh gọi lại mới nào cho đến khi code của bạn hoàn thành trên Binder Thread. Vì vậy, nói chung, bạn nên tránh thực hiện nhiều thao tác trên các luồng Binder vì bạn đang chặn các cuộc gọi lại mới khi bạn đang sử dụng nó.
Đây là những chia sẻ mang tính overview của mình về BLE của Android. Mong ít nhiều có thể chia sẻ cho mọi người. Cảm ơn mọi người đã theo dõi.