07. February 2016

BLE

ဒီတစ်ပတ် အလုပ်နဲ့ပတ်သက်ပြီးတော့ BLE (Bluetooth Low Energy) ကိုသုံးပြီး Android Chat Application သေးသေးလေးတစ်ခု ရေးဖြစ်တယ်။ BLE နဲ့ တစ်ခါမှ မလုပ်ဖူးသေးပေမယ့် scope ကလည်းသေးတယ်၊ အချိန်ကလည်း ၃ ရက်လောက် ရတယ်ဆိုတော့ အေးဆေးပေါ့။ နောက်ပြီး BLE ဆိုတာကိုလည်း အရင်က iBaecon နဲ့တွဲပြီး ကြားဖူးထားတော့ Reference တွေ Sample Project တွေ လုံလုံလောက်လောက်ရှိမှာပဲလို့ ထင်ထားမိလိုက်တာ ငါးပါးကို မှောက်တာပဲ :3 ။



Bluetooth Low Energy (LE) (also called Bluetooth Smart or Version 4.0+ of the Bluetooth specification) is the power- and application-friendly version of Bluetooth that was built for the Internet of Things (IoT).


ပထမဆုံး Reference အနေနဲ့ သွားကြည့်ဖြစ်တာက Android Developer guide က BLE အကြောင်းပေါ့။ အကြမ်းဖျင်းဖတ်ကြည့်တော့ Android 4.3 (API Level 18) ကနေစပြီး support လုပ်တယ်။ အဓိက ကတော့ power consuming နည်းနည်းနဲ့ ကြာကြာ အလုပ်လုပ်ရတဲ့ proximity sensors, heart rate monitors, fitness devices တွေမှာ သုံးတယ်ပေါ့။ Generic Attribute Profile (GATT) ဆိုတာက device တစ်ခုရဲ့ Profile ပေါ့။ ဘယ်လို device မျိုးဖြစ်တယ် ဘာလုပ်တယ်ဆိုတာကို define လုပ်ပေးတာပေါ့။ အဲဒီ Profile တွေကို Bluetooth SIG သတ်မှတ်ပေးပြီးသား ရှိတယ်။ အဲဒီ GATT က Attribute Protocol (ATT) ပေါ်မှာ တည်ဆောက်ထားတယ်။ Attributes တွေကို Universally Unique Identifier (UUID) နဲ့ unique ဖြစ်အောင် define လုပ်တယ်။ သူ့ထဲမှာမှ Service -> Characteristic -> Descriptor ဆိုပြီး အဆင့်ဆင့်ရှိတယ်။ ပြီးတော့ device အချင်းချင်း interact လုပ်တဲ့အခါ Central vs. peripheral (OR) GATT server vs. GATT client ဆိုပြီး ရှိမယ်ပေါ့။ အဓိကပြဿနာက အဲဒီ interaction ကို သေချာနားလည်အောင် မလုပ်မိလိုက်တာပါပဲ။



GATT Profiles https://developer.bluetooth.org/TechnologyOverview/Pages/GATT.aspx


နမူနာပြထားတာက google sample projects တွေထဲက BluetoothLeGatt က code တွေ။ Reference ယူဖို့ code တွေရှိတယ်၊ စမ်းဖို့ android 4.3 အထက် ၂ လုံး လိုတယ်ဆိုတော့ အစ်မရုံးကပြန်တာစောင့်ရင်း UI ကို အရင်ရေးနေလိုက်တယ်။ ဖုန်း ၂ လုံးရလို့ BLE အပိုင်းကိုလည်း စရေးရော တိုင်စပတ်တာပဲ။



    // Deprecated in API level 21
    mBluetoothAdapter.startLeScan(mLeScanCallback);
    mBluetoothAdapter.stopLeScan(mLeScanCallback);
    // Usage in API level 21 and above
    mLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
    mLEScanner.startScan(mFilters, mSettings, mLEScanCallback);
    mLEScanner.stopScan(mLEScanCallback);

ပြဿနာက Scan လုပ်လိုက်ရင် device တွေကို detect မဖြစ်တော့ callback တွေကို trigger မလုပ်တာပဲ။ code ကို သေချာပြန်စစ်တော့လည်း မမှားဘူး။ မဟုတ်သေးပါဘူး ဆိုပြီး BluetoothLeGatt project ကို run ကြည့်တော့လည်း detect မဖြစ်ဘူး။ ဒါဆို တစ်ခုခုတော့ လွဲနေပြီပေါ့။ stackoverflow မှာရှာတော့လည်း သိပ်မထူးဘူး။ ဒါနဲ့ Google Play မှာ BLE Scanner ဆိုတဲ့ app ကို install လုပ်၊ scan လုပ်ကြည့်တော့လည်း detect မဖြစ်ဘူး။ ကံကောင်းချင်တော့ အဲဒီ app မှာပါတဲ့ About Device က Bluetooth Smart category အောက်မှာ Bluetooth Smart supported ကတော့ Yes, Peripheral mode supported က No ဆိုတာကို တွေ့မှ လမ်းစရသွားတယ်။ အဲတော့မှ guide မှာရေးထားတဲ့ Central vs. peripheral ကိုသွား သတိရတယ်။ ပြီးတော့ Peripheral mode ရတဲ့ Device လိုတာဖြစ်မယ်၊ Device ရရင် ok ပြီဆိုပြီး အိပ်ပစ်လိုက်တယ်။ သို့သော်လည်း နောက်နေ့ မနက် ရုံးမှာ လိုတဲ့ device ရတော့လည်း detect မဖြစ်ပြန်ဘူး။ SO မှာလည်းမေး။ ဟိုရှာဒီရှာပေါ့။ အဲလို ဟိုရှာဒီရှာနဲ့ပဲ Android 5.0 API မှာ BluetoothLeAdvertiser အကြောင်း သွားတွေ့တယ်။



To begin Bluetooth LE advertising so that other devices can discover your app, call startAdvertising() and pass in an implementation of the AdvertiseCallback class. The callback object receives a report of the success or failure of the advertising operation.


အဲဒီကနေပဲ BluetoothGattServer ကိုတွေ့တယ်၊ တကယ်တော့ Peripheral Device ဘက်က Presence ဖြစ်နေကြောင်းကို Advertise လုပ်ပေးရတယ်။ တစ်ခါတည်း GattServer ကိုပါ create လုပ်ထားရတယ်။ ဒီတော့မှ Central/Client ဘက်က Scan လုပ်တဲ့အခါ detect ဖြစ်သွားတယ်။ Detected device ရဲ့ MAC Address နဲ့ GattServer ကို connect လုပ်လိုက်ရုံပါပဲ။ ပထမအဆင့်အနေနဲ့ device ကို scan လုပ် connect လုပ်လို့ ရသွားတယ်။ အဲတော့မှ သဘောတရားကိုလည်း သေချာနားလည် သွားတယ်။ များသောအားဖြင့် BLE app တွေက Central/Client ဘက်ကနေ အလုပ်လုပ်တာ များတယ်။ အဲဒါကြောင့် BLE project တော်တော်များများ ကလည်း Central/Client app တွေများတယ်။ Peripheral/Server အနေနဲ့က device တွေဘက်မှာ implement လုပ်ပြီးသား ဆိုတော့ reference ယူဖို့ တော်တော်လေးကို ရှာယူရတယ်။ ရှားရှားပါးပါး BLE Test Peripheral ဆိုတဲ့ Github repo တစ်ခုပဲ တွေ့မိသေးတယ်။ နောက်ပြီးတော့ Peripheral Mode ကို support လုပ်တဲ့ ဖုန်းတွေကလည်း နည်းသေးတာ ပါပါတယ်။



နောက်ပြဿနာ တစ်ခုကတော့ Chat app ဆိုတော့ အပြန်အလှန် message တွေပို့ရမယ် ဆိုတော့လည်း Central/Client ဘက်မှာ နမူနာတွေများတော့ လွယ်ပေမယ့် Peripheral ဘက်ကတော့ ဟိုရှာဒီရှာနဲ့ စမ်းတဝါးဝါး ရေးလိုက်ရတယ်။ မှတ်မှတ်ရရ Central/Client ဘက်က characteristic ကို write လိုက်ရင် Peripheral ဘက်က Acknowledgement ပြန်တဲ့ သဘောမျိုး response ပြန်ပေးရတယ်။ မဟုတ်ရင် Acknowledgement မရမချင်း message က နောက်တခါ မထွက်တော့ဘူး ဖြစ်သွားတယ်။ နောက်တစ်ခုက Data packet တွေ transfer လုပ်တဲ့အခါ 20 bytes အထိပဲ လက်ခံတယ်။ Character အလုံး 20 ပေါ့။ အဲဒီအတွက်တော့ SO မှာ အဖြေ ရှိပြီးသားပါ။ ပြီးတော့ တစ်ချို့ဖုန်းတွေက connected ဖြစ်သွားပြီး 10 sec လောက်ကြာမှ Message တွေ စလက်ခံတယ်။ အစလေးပဲ delay ရှိပေမယ့် အဲဒီနောက်ပိုင်း ချက်ခြင်းရောက်တာ တွေ့ရတယ်။



တကယ်တော့ BLE က android မှာ အရမ်းကြီး တွင်တွင်ကျယ်ကျယ် မသုံးသေးတော့ resources တွေ ရှားပြီး နည်းနည်း ခက်နေသေးတယ်။ IOS မှာက အများကြီး ပိုလွယ်တယ်လို့ SO မှာပြောထားတာလည်း တွေ့လိုက်တယ်။ နောက်တစ်ခုက ကိုယ့်အမှား မကင်းတာလည်း ပါပါတယ်။ စာကို စေ့စေ့စပ်စပ် သေသေချာချာ မဖတ်တာရယ်၊ လုပ်ချင်ကိုင်ချင်စိတ်များ ပြီးတော့ ရေးဖို့ပဲ စိတ်စောနေတာရယ်ကြောင့် ခက်သင့်တာတက် ပိုခက်သွားတယ်။ ဘယ်လို အလုပ်လုပ်လဲ ဆိုတာကို သေချာနားလည်အောင် လုပ်ပြီးမှ ဘယ်လို လုပ်ရမယ် ဆိုတာကို ရှာတာက ပိုအစီအစဉ်ကျတယ်။ How it works ကို မေ့ထားပြီး How to တွေပဲ Google မှာ သွားသွားရှာနေတဲ့ အကျင့်ကို ဖျောက်မှရတော့မယ်။ :3





#android #tech