আপনার আগেও এমনটি হতে পারে:আপনার ওয়্যারলেস ইয়ারবাডগুলি একদিন নিখুঁতভাবে সংযোগ করে এবং পরের দিন তারা এমনভাবে কাজ করে যেন তারা কখনও আপনার ফোনের সাথে দেখা করেনি। অথবা আপনার স্মার্টওয়াচটি দৌড়ানোর মাঝখানে পড়ে যায়। ব্লুটুথ যখন কাজ করে তখন তা আশ্চর্যজনক, কিন্তু যখন কাজ করে না তখন তা বিস্ময়কর।
আমি স্মার্ট-গ্লাসের মতো পরিধানযোগ্য ডিভাইসগুলিতে একজন ব্লুটুথ সফ্টওয়্যার প্রকৌশলী হিসাবে কাজ করি এবং কেন এই জিনিসগুলি ভেঙে যায় তা অনুসরণ করার জন্য আমি স্বীকার করার চেয়ে বেশি সময় ব্যয় করেছি।
এই নিবন্ধে, আমি আপনাকে পর্দার পিছনে একটি উঁকি দেব:Android এর ব্লুটুথ স্ট্যাক আসলে কীভাবে কাজ করে, কেন এটি কখনও কখনও অপ্রত্যাশিত মনে হয় এবং আপনার অ্যাপ বা সিস্টেমকে আরও নির্ভরযোগ্য করতে আপনি বিকাশকারী হিসাবে কী করতে পারেন৷
সাধারণ ইংরেজিতে ব্লুটুথ
এর মূল অংশে, ব্লুটুথ হল দুটি ডিভাইসের মধ্যে একটি কথোপকথন। তবে এটি যোগাযোগের একটি সহজ লাইন নয় - এটি একে অপরের উপরে একাধিক স্তর স্তুপীকৃত।
-
রেডিও (কন্ট্রোলার): বায়ু মাধ্যমের মাধ্যমে প্রকৃত সংকেত পাঠায় এবং গ্রহণ করে।
-
সফ্টওয়্যার মস্তিষ্ক (হোস্ট স্ট্যাক): কার সাথে এবং কিভাবে কথা বলতে হবে, সেইসাথে যদি এটি চায় তা নির্ধারণ করে।
-
প্রোফাইল: কথোপকথনের উদ্দেশ্য নির্ধারণ করুন - যেমন সঙ্গীত স্ট্রিমিং বা স্বাস্থ্য ডেটা সিঙ্ক করা।
-
প্রটোকল: অন্য ডিভাইসের সাথে কিভাবে কথা বলতে হয় তা নির্ধারণ করুন।
ব্লুটুথের দুটি বড় "স্বাদ" আছে:
-
ক্লাসিক (BR/EDR): হেডফোন এবং গাড়ির কিটের মতো জিনিসের জন্য ব্যবহৃত হয়। বেশি ওজন তুলতে পারে।
-
নিম্ন শক্তি (LE): ফিটনেস ব্যান্ড, বীকন এবং সর্বাধিক পরিধানযোগ্য জিনিসগুলির জন্য ব্যবহৃত হয়। দীর্ঘ সময় ধরে রাখতে পারে।
বেশিরভাগ আধুনিক গ্যাজেট একসাথে উভয়ই ব্যবহার করে। এটি শক্তিশালী, কিন্তু এটি আরও কিছু ভুল হওয়ার দরজাও খুলে দেয়৷
৷কেন অ্যান্ড্রয়েড তার নিজস্ব কুয়ার্ক যোগ করে

অ্যান্ড্রয়েডে, ব্লুটুথ শুধুমাত্র একটি ঝরঝরে প্যাকেজ নয়। এটি চলমান অংশগুলির একটি চেইন:
-
আপনার অ্যাপ
BluetoothAdapterকল করে . -
সেগুলি সিস্টেম পরিষেবাগুলিতে যায়৷ যেমন
AdapterService. -
তারপর JNI এর মাধ্যমে নেটিভ কোডে প্রবেশ করুন (জাভা নেটিভ ইন্টারফেস)।
-
তারপর চিপ বিক্রেতার ব্লুটুথ স্ট্যাকের মধ্যে .
-
অবশেষে, এটি রেডিও হার্ডওয়্যারে আঘাত করে৷ .
প্রতিটি ফোন নির্মাতা একটি সামান্য ভিন্ন ব্লুটুথ চিপ এবং ফার্মওয়্যার পাঠায়। এর মানে হল একই ব্লুটুথ অ্যাপটি স্যামসাং, পিক্সেল বা Android চালিত অন্য কোনও বাজেট ফোনে ভিন্নভাবে আচরণ করতে পারে।
"এটি শুধু সংযোগ বিচ্ছিন্ন" এর পিছনে আসল সমস্যাগুলি
এখানে কয়েকটি সাধারণ মাথাব্যথা আমি দেখছি, সহজভাবে ব্যাখ্যা করা হয়েছে:
বন্ডিং সমস্যা ("হারানো কী" সমস্যা)
যখন দুটি ব্লুটুথ ডিভাইস জোড়া হয়, তখন তারা এনক্রিপশন কী (ক্লাসিকের জন্য লিঙ্ক কী, LE-এর জন্য দীর্ঘমেয়াদী কী) বিনিময় করে এবং সেগুলিকে অ-উদ্বায়ী মেমরিতে সংরক্ষণ করে। এই কীগুলি যা ডিভাইসগুলিকে পরে একে অপরকে চিনতে দেয় এবং ব্যবহারকারীকে আবার জিজ্ঞাসা না করে নিরাপদে পুনরায় সংযোগ করতে দেয়৷
একটি "অমিল মেমরি" সমস্যা ঘটে যখন একটি ডিভাইসের সঞ্চিত কীগুলি অন্যটির সাথে আর মেলে না। এটি এর কারণে হতে পারে:
-
একটি ফার্মওয়্যার আপডেট বা OS আপগ্রেড যা কীগুলি মুছে বা পুনরুত্পাদন করে৷
৷ -
ফ্যাক্টরি রিসেট বা "ডিভাইস ভুলে যান" একদিকে কিন্তু অন্য দিকে নয়।
-
সঞ্চয়স্থান খালি করতে সিস্টেম দ্বারা কীগুলি দূষিত বা উচ্ছেদ করা হচ্ছে৷
৷
ব্যবহারকারীর দৃষ্টিকোণ থেকে, ডিভাইসটি এখনও দেখতে হতে পারে জোড়া হয়েছে (ব্লুটুথ মেনুতে দেখায়), কিন্তু সংযোগগুলি রহস্যজনকভাবে "প্রমাণিকরণ ব্যর্থ" বা "অপর্যাপ্ত এনক্রিপশন" এর মতো ত্রুটির সাথে ব্যর্থ হয়। একমাত্র প্রতিকার হল সাধারণত ডিভাইসটিকে উভয় প্রান্তে মুছে ফেলা এবং পুনরায় জোড়া দেওয়া, যা অ-প্রযুক্তিগত ব্যবহারকারীদের কাছে হাস্যকর মনে হয়।
সময়ের মিল নেই
ব্লুটুথ ডিভাইসগুলি যখনই তারা চায় তখনই কেবল চ্যাট করে না, তারা একটি সংযোগ ব্যবধানে সম্মত হয় - মূলত প্রতিটি পক্ষ কখন "জাগবে" এবং প্যাকেট বিনিময় করবে তার জন্য একটি সময়সূচী। এটিকে একটি ক্যাফেতে প্রতি 30 মিনিটে দেখা করতে সম্মত হওয়া দুই ব্যক্তি হিসাবে ভাবুন৷
৷একটি অমিল ঘটে যখন:
-
দুই পক্ষ বিভিন্ন ব্যবধানে আলোচনা করে কিন্তু পুরোপুরি একমত হয় না (উদাহরণস্বরূপ, একজন মনে করে এটি 30ms, অন্যটি 50ms)।
-
এক পক্ষের ফার্মওয়্যার আপডেট বা কনফিগারেশন পরিবর্তন এর সময় নীতি পরিবর্তন করে।
-
রেডিও অবস্থার কারণে এক পক্ষ একাধিক নির্ধারিত চেক-ইন মিস করে, ঘড়ির কাঁটা আলাদা করে দেয়।
-
পাওয়ার-সেভিং লজিক (যেমন একটি ফোন ডোজ মোডে যাচ্ছে) নিঃশব্দে ব্যবধানকে প্রসারিত করে।
এটি ব্যাখ্যা করে কেন একটি সংযোগ প্রথমে ভাল কাজ করতে পারে কিন্তু পরে ব্যর্থ হতে শুরু করে:ডিভাইসগুলি প্রাথমিকভাবে একটি ব্যবধানে সিঙ্ক করা হয়েছিল, কিন্তু তারপরে এক পক্ষের নীতি বা আচরণ স্থানান্তরিত হয়েছে৷ ব্যবহারকারীর দৃষ্টিকোণ থেকে, এটি অডিও তোতলানো, ল্যাজি ইনপুট (গেম কন্ট্রোলারগুলিতে) বা "এটি আগে ঠিক কাজ করছিল" এর পরে র্যান্ডম সংযোগ বিচ্ছিন্ন হওয়ার মতো দেখায়৷
অপ্রত্যাশিত সংযোগ বিচ্ছিন্ন
যখন একটি ব্লুটুথ লিঙ্ক শেষ হয়, তখন রেডিও স্তর (নিয়ন্ত্রক) এবং উচ্চ-স্তরের OS স্ট্যাক (হোস্ট) স্পষ্ট সংকেত বিনিময় করার কথা। কন্ট্রোলার একটি HCI সংযোগ বিচ্ছিন্ন সম্পূর্ণ ইভেন্ট পাঠায় (মূলত:"বিদায়, আমরা শেষ" ) এবং হোস্টকে তার অভ্যন্তরীণ অবস্থা আপডেট করতে হবে, GATT/ACL সেশন পরিষ্কার করতে হবে এবং পুনরায় সংযোগের জন্য প্রস্তুত থাকতে হবে।
কিন্তু বাস্তবে, এটি সবসময় লাইন আপ হয় না:
-
কখনও কখনও কন্ট্রোলার পরিষ্কারভাবে বিদায় জানায়, কিন্তু হোস্ট স্ট্যাক সঠিকভাবে তার অবস্থা আপডেট করে না। অ্যাপটি এখনও "মনে করে" সংযোগটি সক্রিয় আছে, তাই পুনরায় সংযোগের প্রচেষ্টা নিঃশব্দে ব্যর্থ হয়৷
-
কিছু প্ল্যাটফর্ম আক্রমনাত্মকভাবে ক্যাশে সংযোগের অবস্থা (বিশেষ করে iOS)। যদি ওএস বিশ্বাস করে যে সংযোগটি এখনও বৈধ, তবে আপনি ব্লুটুথ টগল বা রিবুট না করা পর্যন্ত এটি একটি নতুন সংযোগের প্রচেষ্টা ট্রিগার করবে না৷
-
একটি রেস অবস্থা ঘটতে পারে যদি সংযোগ বিচ্ছিন্ন ঘটনা ঘটে যখন অন্য একটি অপারেশন (উদাহরণস্বরূপ, পরিষেবা আবিষ্কার, বন্ধন, বা এনক্রিপশন সেটআপ) ফ্লাইটে থাকে। ডিভাইসটি সত্যি কি অবস্থায় আছে তা নিয়ে ওএস বিভ্রান্ত হতে পারে মধ্যে।
-
কিছু ডিভাইসে, অভ্যন্তরীণ কুলডাউন টাইমারগুলির সাথে একটি পরিষ্কার সংযোগ বিচ্ছিন্ন হওয়ার পরে দ্রুত পুনরায় সংযোগের প্রচেষ্টা। কন্ট্রোলার এটি উপেক্ষা করে, অ্যাপটিকে অপেক্ষায় রেখে।
ব্যবহারকারীর দৃষ্টিকোণ থেকে, ডিভাইসটিকে "আটকে" দেখায়। পুনরুদ্ধার করার একমাত্র উপায় হল ব্লুটুথ টগল করা, অ্যাপ রিস্টার্ট করা বা অ্যাকসেসরির পাওয়ার সাইকেল করা, যদিও প্রযুক্তিগতভাবে কিছুই "ব্যর্থ হয়নি।"
বিকাশকারীরা কীভাবে আরও ভাল করতে পারে
আপনি যদি একটি ব্লুটুথ অ্যাপ তৈরি করেন, তাহলে এখানে কয়েকটি অভ্যাস রয়েছে যা অনেক ব্যথা বাঁচায়:
প্রথমে বন্ডেড ডিভাইসগুলি পরীক্ষা করুন৷
ব্যর্থ সংযোগগুলির সবচেয়ে সাধারণ কারণগুলির মধ্যে একটি হল অমিল বন্ডিং তথ্য:ফোন এবং আনুষঙ্গিকগুলি আর একই এনক্রিপশন কীগুলি ভাগ করে না৷ ডিভাইসটি UI-তে উপস্থিত হলেও, OS এর কীগুলি হারিয়ে যেতে পারে৷
৷
সংযোগের চেষ্টা করার আগে, সর্বদা BluetoothAdapter.getBondedDevices() দিয়ে সিস্টেমের বন্ডেড ডিভাইসের তালিকাটি জিজ্ঞাসা করুন . যেমন:
if (adapter.getBondedDevices().contains(targetDevice)) {
targetDevice.connectGatt(context, false, gattCallback);
} else {
showToast("Please re-pair this device to restore the connection.");
}
এটি নিশ্চিত করে যে আপনি কেবলমাত্র OS এখনও বিশ্বাস করে এমন ডিভাইসগুলিতে সুরক্ষিত সংযোগের চেষ্টা করছেন৷ টার্গেট ডিভাইসটি বন্ডেড তালিকায় না থাকলে, আপনি ব্যবহারকারীকে একটি পরিষ্কার নির্দেশ দিতে পারেন ("দয়া করে এই ডিভাইসটি পুনরায় জোড়া লাগান") বিভ্রান্তিকর সংযোগ ত্রুটির সাথে তাদের ছেড়ে না দিয়ে৷
সাবধানে কলব্যাক পরিচালনা করুন
আরেকটি সূক্ষ্ম সমস্যা অনুমান করা হচ্ছে যে একটি STATE_CONNECTED ইভেন্ট মানে একটি সংযোগ সফল হয়েছে। বাস্তবে, onConnectionStateChange() অন্তর্নিহিত অপারেশন ব্যর্থ হলেও একটি সংযুক্ত অবস্থার প্রতিবেদন করতে পারে, প্রকৃত ফলাফল status এ যুক্তি ফ্যান্টম কানেকশন এড়াতে, সবসময় status দুটোই চেক করুন এবং newState :
if (status == BluetoothGatt.GATT_SUCCESS &&
newState == BluetoothProfile.STATE_CONNECTED) {
gatt.discoverServices();
} else {
gatt.close();
}
এই প্যাটার্নটি আপনাকে একটি মৃত সংযোগে পরিষেবা আবিষ্কারের চেষ্টা করতে বাধা দেয় এবং নিশ্চিত করে যে পুরানো সেশনগুলি অবিলম্বে বন্ধ হয়ে গেছে, স্ট্যাকটিকে একটি পরিষ্কার পুনঃপ্রচেষ্টার জন্য প্রস্তুত রেখে৷
ব্যর্থতার প্রত্যাশা করুন
ব্লুটুথ সংযোগগুলি বাস্তব বিশ্বে সর্বদা ব্যর্থ হয় - ডিভাইসগুলি পরিসীমার বাইরে চলে যায়, 2.4 GHz ব্যান্ডে হস্তক্ষেপ স্পাইক হয় বা রেডিও কেবল ব্যস্ত থাকে৷ একটি অ্যাপ যা করতে পারে তা হল সবচেয়ে খারাপ জিনিস হল একটি টাইট লুপে অবিলম্বে পুনরায় চেষ্টা করা, যা ব্যাটারি নিষ্কাশন করে এবং স্ট্যাকটিকে অস্থির করে তোলে৷
একটি ভাল পন্থা হল এই মত সূচকীয় ব্যাকঅফ প্রয়োগ করা:
long delay = (long) Math.min(250 * Math.pow(2, attempt), 30000);
new Handler(Looper.getMainLooper()).postDelayed(connectAction, delay);
এর মানে হল আপনার প্রথম পুনঃপ্রচেষ্টা দ্রুত হয় (~250 ms), কিন্তু পরবর্তী পুনঃপ্রচেষ্টাগুলি ধীর হয়ে যায় (500 ms, 1 s, 2 s…), একটি যুক্তিসঙ্গত সর্বোচ্চ সীমাবদ্ধ। ব্যাকঅফ আপনার অ্যাপটিকে রেডিও বা ওএসকে অপ্রতিরোধ্য না করে স্থিতিস্থাপক করে তোলে।
সঠিক টুল ব্যবহার করুন
হুডের নীচে কী ঘটছে তা দৃশ্যমানতা ছাড়াই, সংযোগ সমস্যাগুলি এলোমেলো দেখায়। nRF কানেক্ট এর মত টুল আপনাকে ইন্টারেক্টিভভাবে স্ক্যান করতে, সংযোগ করতে এবং আপনার ডিভাইসের বিরুদ্ধে GATT অপারেশন চালাতে দেয়, যখন Android এর ব্লুটুথ এইচসিআই স্নুপ লগ প্রকৃত প্যাকেটগুলি বিনিময় হচ্ছে তা প্রকাশ করে৷ যেমন:
Settings.Secure.putInt(context.getContentResolver(), "bluetooth_hci_log", 1);
একবার সক্ষম হয়ে গেলে, আপনি একটি লগক্যাট ট্রেস ক্যাপচার করতে পারেন এবং নিশ্চিত করতে পারেন যে ব্যর্থতা কি অনুপস্থিত কীগুলির কারণে হয়েছে (Insufficient Authentication ), একটি সময়ের অমিল, বা হস্তক্ষেপ। এই টুলগুলি ব্যবহার করা শুধুমাত্র আপনাকে আপনার অ্যাপ ডিবাগ করতে সাহায্য করে না, এটি প্রমাণ করে যে সমস্যাটি আপনার কোড, OS, বা আনুষঙ্গিক ফার্মওয়্যারে রয়েছে।

বড় পাঠ
ব্লুটুথের সাথে কাজ করা আমাকে এমন পাঠ শিখিয়েছে যা সাধারণভাবে ইঞ্জিনিয়ারিংয়ের ক্ষেত্রে প্রযোজ্য:
-
ওয়্যারলেস কখনই নিখুঁত হয় না, তাই সর্বদা পুনরুদ্ধারের কথা মাথায় রেখে তৈরি করুন৷
-
লগ এবং মেট্রিক্স ঐচ্ছিক নয়। তারা বিশৃঙ্খলার মাধ্যমে আপনার মানচিত্র।
-
সবচেয়ে সহজ সমাধান সাধারণত অগোছালো বাস্তব জগতে সবচেয়ে ভালোভাবে বেঁচে থাকে।
উপসংহার
ব্লুটুথ অগোছালো কারণ এটি হার্ডওয়্যার, ফার্মওয়্যার এবং সফ্টওয়্যারের একটি চেইন যা সকলে সহযোগিতা করার চেষ্টা করে। অ্যান্ড্রয়েডে, চিপ এবং বিক্রেতাদের বিভিন্নতা এটিকে আরও জটিল করে তোলে৷
৷কিন্তু তার মানে এই নয় যে আপনি অসহায়। স্তরগুলি কীভাবে কাজ করে তা বোঝার মাধ্যমে এবং পুনরায় চেষ্টা, পরীক্ষা এবং সঠিক লগিং সহ আপনার অ্যাপগুলিকে ডিজাইন করে, আপনি আপনার ব্যবহারকারীদের জন্য ব্লুটুথকে অনেক কম "অদ্ভুত" অনুভব করতে পারেন৷
পরের বার যখন আপনার ইয়ারবাড খারাপ ব্যবহার করবে, আপনি জানতে পারবেন - এটি আপনি নন। এটা শুধু ব্লুটুথ হচ্ছে ব্লুটুথ।
⚡ ব্লুটুথ ডেভেলপমেন্টের উপর আমি যে কয়েকটি নিবন্ধ লিখতে যাচ্ছি তার মধ্যে এটিই প্রথম। পরেরটিতে, আমরা কীভাবে একটি সুরক্ষিত ব্লুটুথ লো এনার্জি (BLE) GATT ক্লায়েন্ট এবং অ্যান্ড্রয়েডে সার্ভার তৈরি করতে হয় সে সম্পর্কে আরও গভীরে প্রবেশ করব। সাথে থাকুন!
বিনামূল্যে কোড শিখুন. freeCodeCamp-এর ওপেন সোর্স পাঠ্যক্রম 40,000-এরও বেশি লোককে ডেভেলপার হিসেবে চাকরি পেতে সাহায্য করেছে। শুরু করুন