আলট্রা-ওয়াইডব্যান্ড (UWB) কমিউনিকেশন

আল্ট্রা-ওয়াইডব্যান্ড কমিউনিকেশন হল একটি রেডিও প্রযুক্তি যা ডিভাইসের মধ্যে সুনির্দিষ্ট রেঞ্জিং (১০ সেমি নির্ভুলতার সাথে লোকেশন পরিমাপ করা) এর উপর ফোকাস করে। এই রেডিও প্রযুক্তি স্বল্প-পরিসর পরিমাপের জন্য কম-শক্তি ঘনত্ব ব্যবহার করতে পারে এবং রেডিও স্পেকট্রামের একটি বড় অংশ জুড়ে হাই-ব্যান্ডউইথ সিগন্যালিং করতে পারে। UWB-এর ব্যান্ডউইথ ৫০০ MHz-এর বেশি (অথবা ২০% ফ্র্যাকশনাল ব্যান্ডউইথের বেশি)।

কন্ট্রোলার/ইনিশিয়েটর বনাম কন্ট্রোলে/রেসপন্ডার

দুটি ডিভাইসের মধ্যে UWB কমিউনিকেশন হয়, যার মধ্যে একটি হল কন্ট্রোলার এবং অন্যটি হল কন্ট্রোলি। কন্ট্রোলার জটিল চ্যানেল (UwbComplexChannel) নির্ধারণ করে যা দুটি ডিভাইস শেয়ার করবে এবং এটি হল ইনিশিয়েটর, যেখানে কন্ট্রোলে হল রেসপন্ডার।

একটি কন্ট্রোলার একাধিক কন্ট্রোলি ম্যানেজ করতে পারে, তবে একটি কন্ট্রোলি শুধুমাত্র একটি কন্ট্রোলারে সাবস্ক্রাইব করতে পারে। কন্ট্রোলার/ইনিশিয়েটর এবং কন্ট্রোলে/রেসপন্ডার কনফিগারেশন, দুটিই কাজ করে।

রেঞ্জিং প্যারামিটার

রেঞ্জিং শুরু করার জন্য কন্ট্রোলার ও কন্ট্রোলিকে একে অপরকে শনাক্ত করতে হবে এবং রেঞ্জিং প্যারামিটার কমিউনিকেট করতে হবে। এই এক্সচেঞ্জটি অ্যাপ্লিকেশনগুলির উপর ছেড়ে দেওয়া হয় তাদের পছন্দের একটি নিরাপদ আউট-অফ-ব্যান্ড (OOB) মেকানিজম ব্যবহার করে বাস্তবায়ন করা, যেমন ব্লুটুথ লো এনার্জি (BLE)।

রেঞ্জিং প্যারামিটার অন্যান্য বিষয়ের মধ্যে লোকাল অ্যাড্রেস, কমপ্লেক্স চ্যানেল ও সেশন কী অন্তর্ভুক্ত করে। মনে রাখবেন যে রেঞ্জিং সেশন শেষ হওয়ার পরে এই প্যারামিটারগুলি রোটেট বা অন্যভাবে পরিবর্তিত হতে পারে এবং রেঞ্জিং রিস্টার্ট করার জন্য আবার যোগাযোগ করতে হবে।

ব্যাকগ্রাউন্ড রেঞ্জিং

ডিভাইসে UWB রেঞ্জিং সেশন কাজ করলে, ব্যাকগ্রাউন্ডে চলা অ্যাপ এটি শুরু করতে পারে। আপনার ডিভাইসের ক্ষমতা চেক করতে, RangingCapabilities দেখুন।

ব্যাকগ্রাউন্ডে চলার সময় অ্যাপ রেঞ্জিং রিপোর্ট পায় না; ফোরগ্রাউন্ডে এলে অ্যাপ রেঞ্জিং রিপোর্ট পায়।

STS কনফিগারেশন

অ্যাপ বা পরিষেবাটি স্ক্র্যাম্বলড টাইমস্ট্যাম্প সিকোয়েন্স (STS) ব্যবহার করে প্রতিটি সেশনের জন্য একটি সেশন কী প্রদান করে। প্রভিশন করা STS, স্ট্যাটিক STS কনফিগারেশনের চেয়ে বেশি সুরক্ষিত। Android 14 বা তার পরবর্তী যেকোনও ভার্সনে চলে এমন সব UWB-চালু ডিভাইসে প্রভিশন করা STS কাজ করে।

হুমকির বিভাগ স্ট্যাটিক STS প্রভিশন করা STS
Air: প্যাসিভ পর্যবেক্ষক ঝুঁকি কমে গেছে ঝুঁকি কমে গেছে
এয়ার: সিগন্যাল অ্যামপ্লিফিকেশন ঝুঁকি কমে গেছে ঝুঁকি কমে গেছে
Air: রিপ্লে/রিলে অ্যাটাক সংবেদনশীল ঝুঁকি কমে গেছে

প্রভিশন করা STS-এর জন্য:

  1. RangingParameters-এ uwbConfigType ব্যবহার করুন যা প্রভিশন করা STS-এ কাজ করে।

  2. sessionKeyInfo ফিল্ডে ১৬-বাইটের কী লিখুন।

স্ট্যাটিক STS-এর জন্য:

  1. RangingParameters-এ uwbConfigType ব্যবহার করুন যা স্ট্যাটিক STS-এ কাজ করে।

  2. sessionKeyInfo ফিল্ডে ৮-বাইট কী লিখুন।

ধাপ

UWB API ব্যবহার করতে, এইসব ধাপ অনুসরণ করুন:

  1. Android ডিভাইসগুলি Android 12 বা তার পরবর্তী যেকোনও ভার্সনে চলছে কিনা এবং সেগুলি PackageManager#hasSystemFeature("android.hardware.uwb") ব্যবহার করে UWB-কে সাপোর্ট করে কিনা তা নিশ্চিত করুন।
  2. IoT ডিভাইসের ক্ষেত্রে রেঞ্জিং করা হলে, সেগুলি FiRa MAC 1.3 কমপ্লায়েন্ট কিনা তা নিশ্চিত করুন।
  3. আপনার পছন্দের OOB মেকানিজম ব্যবহার করে UWB-উপযোগী পিয়ার ডিভাইস খুঁজুন, যেমন BluetoothLeScanner।
  4. আপনার পছন্দের একটি সুরক্ষিত OOB মেকানিজম ব্যবহার করে রেঞ্জিং প্যারামিটার এক্সচেঞ্জ করুন, যেমন BluetoothGatt।
  5. ব্যবহারকারী সেশন বন্ধ করতে চাইলে, সেশনের স্কোপ বাতিল করুন।

ব্যবহার সংক্রান্ত বিধিনিষেধ

UWB API ব্যবহারের ক্ষেত্রে নিম্নলিখিত বিধিনিষেধ প্রযোজ্য:

  1. নতুন UWB রেঞ্জিং সেশন শুরু করা অ্যাপটি অবশ্যই একটি ফোরগ্রাউন্ড অ্যাপ বা পরিষেবা হতে হবে, যদি না ব্যাকগ্রাউন্ড রেঞ্জিং আগে যেমন দেখানো হয়েছে তেমনভাবে কাজ করে।
  2. অ্যাপ ব্যাকগ্রাউন্ডে চলে গেলে (সেশন চলাকালীন), অ্যাপটি আর রেঞ্জিং রিপোর্ট নাও পেতে পারে। তবে UWB সেশন নিচের লেয়ারে বজায় রাখা চালিয়ে যাওয়া হবে। অ্যাপটি আবার ফোরগ্রাউন্ডে ফিরে এলে, রেঞ্জিং রিপোর্ট আবার শুরু হবে।

কোডের নমুনা

স্যাম্পেল অ্যাপ

UWB Jetpack লাইব্রেরি কীভাবে ব্যবহার করতে হয় তার শুরু থেকে শেষ পর্যন্ত উদাহরণ দেখতে, Github-এ আমাদের স্যাম্পেল অ্যাপ্লিকেশন চেক করুন। এই স্যাম্পেল অ্যাপে Android ডিভাইসে UWB কম্প্যাটিবিলিটি যাচাই করা, OOB মেকানিজম ব্যবহার করে ডিসকভারি প্রসেস চালু করা এবং দুটি UWB-সক্ষম ডিভাইসের মধ্যে UWB রেঞ্জিং সেট-আপ করার মতো বিষয়গুলি কভার করা হয়েছে। এছাড়াও, স্যাম্পেলে ডিভাইস কন্ট্রোল ও মিডিয়া শেয়ারিংয়ের ব্যবহারের উদাহরণও কভার করা হয়েছে।

UWB রেঞ্জিং

এই কোড স্যাম্পেল কন্ট্রোলির জন্য UWB রেঞ্জিং শুরু ও শেষ করে:

// The coroutineScope responsible for handling uwb ranging.
// This will be initialized when startRanging is called.
var job: Job?

// A code snippet that initiates uwb ranging for a Controlee.
suspend fun startRanging() {

    // Get the ranging parameter of a partnering Controller using an OOB mechanism of choice.
    val partnerAddress : Pair<UwbAddress, UwbComplexChannel> = listenForPartnersAddress()

    // Create the ranging parameters.
    val partnerParameters = RangingParameters(
        uwbConfigType = UwbRangingParameters.UWB_CONFIG_ID_1,
        // SessionKeyInfo is used to encrypt the ranging session.
        sessionKeyInfo = null,
        complexChannel = partnerAddress.second,
        peerDevices = listOf(UwbDevice.createForAddress(partnerAddress.first)),
        updateRateType = UwbRangingParameters.RANGING_UPDATE_RATE_AUTOMATIC
    )

    // Initiate a session that will be valid for a single ranging session.
    val clientSession = uwbManager.clientSessionScope()

    // Share the localAddress of the current session to the partner device.
    broadcastMyParameters(clientSession.localAddress)

    val sessionFlow = clientSession.prepareSession(partnerParameters)

    // Start a coroutine scope that initiates ranging.
    CoroutineScope(Dispatchers.Main.immediate).launch {
        sessionFlow.collect {
            when(it) {
                is RangingResultPosition -> doSomethingWithPosition(it.position)
                is RangingResultPeerDisconnected -> peerDisconnected(it)
            }
        }
    }
}

// A code snippet that cancels uwb ranging.
fun cancelRanging() {

    // Canceling the CoroutineScope will stop the ranging.
    job?.let {
        it.cancel()
    }
}

RxJava3 সহায়তা

Java ক্লায়েন্টের সাথে ইন্টারঅপারেবিলিটি অর্জন করতে সাহায্য করার জন্য Rxjava3 সহায়তা এখন উপলভ্য। এই লাইব্রেরি Observable বা Flowable স্ট্রিম হিসেবে রেঞ্জিং ফলাফল পাওয়ার এবং Single অবজেক্ট হিসেবে UwbClientSessionScope ফিরিয়ে আনার উপায় প্রদান করে।

private final UwbManager uwbManager;

// Retrieve uwbManager.clientSessionScope as a Single object
Single<UwbClientSessionScope> clientSessionScopeSingle =
                UwbManagerRx.clientSessionScopeSingle(uwbManager);
UwbClientSessionScope uwbClientSessionScope = clientSessionScopeSingle.blockingGet();

// Retrieve uwbClientSessionScope.prepareSession Flow as an Observable object
Observable<RangingResult> rangingResultObservable =
                UwbClientSessionScopeRx.rangingResultsObservable(clientSessionScope,
                        rangingParameters);

// Consume ranging results from Observable
rangingResultObservable.subscribe(
   rangingResult -> doSomethingWithRangingResult(result), // onNext
   (error) -> doSomethingWithError(error), // onError
   () -> doSomethingOnResultEventsCompleted(), //onCompleted
);
// Unsubscribe
rangingResultObservable.unsubscribe();
   

// Retrieve uwbClientSessionScope.prepareSession Flow as a Flowable object
Flowable<RangingResult> rangingResultFlowable =
                UwbClientSessionScopeRx.rangingResultsFlowable(clientSessionScope,
                        rangingParameters);

// Consume ranging results from Flowable using Disposable
Disposable disposable = rangingResultFlowable
   .delay(1, TimeUnit.SECONDS)
   .subscribeWith(new DisposableSubscriber<RangingResult> () {
      @Override public void onStart() {
          request(1);
      }
      
      @Override public void onNext(RangingResult rangingResult) {
             doSomethingWithRangingResult(rangingResult);
             request(1);
      }


      @Override public void onError(Throwable t) {
             t.printStackTrace();
      }


         @Override public void onComplete() {
            doSomethingOnEventsCompleted();
         }
   });

// Stop subscription
disposable.dispose();

ইকোসিস্টেম সংক্রান্ত সহায়তা

এখানে কাজ করে এমন পার্টনার ডিভাইস ও থার্ড-পার্টি SDK-এর তালিকা দেওয়া হল।

UWB-চালু থাকা মোবাইল ডিভাইস

জানুয়ারি ২০২৫ থেকে, এইসব ডিভাইসে Android UWB Jetpack লাইব্রেরি কাজ করে:

ভেন্ডর ডিভাইসের মডেল
Google Pixel Pro (6 pro এবং তার পরবর্তী যেকোনও ভার্সন), Fold, Tablet
Motorola Edge 50 Ultra
Samsung Galaxy Note 20, Galaxy Plus এবং Ultra (S21 এবং এর পরবর্তী ভার্সন), Galaxy Z Fold (Fold2 এবং এর পরবর্তী ভার্সন)

মনে রাখবেন: নিম্নলিখিত ডিভাইসগুলি ছাড়া সব ডিভাইসে ব্যাকগ্রাউন্ড UWB রেঞ্জিং কাজ করে:

  • Pixel 6 Pro, Pixel 7 Pro এবং Pixel Fold।
  • Android 13 বা তার আগের যেকোনও ভার্সন সহ Samsung ফোন।
  • Android 14 বা তার আগের যেকোনও ভার্সন সহ Samsung চাইনিজ ফোন।

থার্ড-পার্টি SDK

এপ্রিল ২০২৩ থেকে, এই পার্টনার সলিউশনগুলি বর্তমান Jetpack লাইব্রেরি-র সাথে মানানসই।

পরিচিত সমস্যা: MAC অ্যাড্রেস এবং স্ট্যাটিক STS ভেন্ডর আইডি ফিল্ডের জন্য বাইট অর্ডার উল্টে গেছে

Android 13 ও এর আগের যেকোনও ভার্সনে, Android UWB স্ট্যাক ভুলভাবে নিম্নলিখিত ফিল্ডের জন্য বাইট অর্ডার উল্টে দেয়:

  • ডিভাইস MAC অ্যাড্রেস
  • ডেস্টিনেশন MAC অ্যাড্রেস
  • স্ট্যাটিক STS ভেন্ডর আইডি

বাইট অর্ডারের রিভার্সাল হয় কারণ Android স্ট্যাক এই ফিল্ডগুলিকে ভ্যালু হিসেবে বিবেচনা করে, অ্যারে হিসেবে নয়। আমরা FiRa-এর সাথে UCI স্পেসিফিকেশন (CR-1112) আপডেট করার জন্য কাজ করছি যাতে স্পষ্টভাবে বলা যায় যে এই ফিল্ডগুলিকে অ্যারে হিসেবে বিবেচনা করা উচিত।

2320XXXX রিলিজের GMS Core আপডেটের মাধ্যমে এই সমস্যার সমাধান করা হবে। সেই সময় থেকে Android ডিভাইসের সাথে সামঞ্জস্যপূর্ণ হতে, IOT ভেন্ডরদের আপনার ইমপ্লিমেন্টেশন পরিবর্তন করতে হবে যাতে এইসব ফিল্ডের বাইট অর্ডারিং রিভার্স না হয়।