অভ্যন্তরীণ ইথারনেট নেটওয়ার্ক কনফিগার করুন

অ্যান্ড্রয়েড অটো ওএস ১৩ এবং এর পরবর্তী সংস্করণগুলোতে ইথারনেট নেটওয়ার্ক কনফিগার ও পরিচালনা করার সুবিধা রয়েছে। চিত্র ১-এ একটি গাড়ির নেটওয়ার্ক ডায়াগ্রামের উদাহরণ দেখানো হয়েছে:

অ্যান্ড্রয়েড অটো নেটওয়ার্কিং

চিত্র ১. অ্যান্ড্রয়েড অটো নেটওয়ার্কিং।

এই চিত্রে দেখানো হয়েছে কীভাবে আপনার OEM নেটওয়ার্কিং অ্যাপ অনবোর্ড ইথারনেট নেটওয়ার্কগুলো (eth0.1, eth0.2, এবং eth0.3) কনফিগার ও পরিচালনা করার জন্য EthernetManager ক্লাসের মেথডগুলোকে কল করছে। চিত্র ১-এর বাকি অংশ এই ডকুমেন্টের আওতার বাইরে।

ডিফল্ট ইথারনেট নেটওয়ার্ক সেটিংস সেট করুন

ডিফল্ট নেটওয়ার্ক সেটিংস সেট করতে, রিসোর্স ওভারলে config_ethernet_interfaces ব্যবহার করুন:

<string-array translatable="false" name="config_ethernet_interfaces">
        <!--
        <item>eth1;12,13,14,15;ip=192.168.0.10/24 gateway=192.168.0.1 dns=4.4.4.4,8.8.8.8</item>
        <item>eth2;;ip=192.168.0.11/24</item>
        <item>eth3;12,13,14,15;ip=192.168.0.12/24;1</item>
        -->
    </string-array>

এই উদাহরণটি config.xml থেকে config_ethernet_interfaces রিসোর্স ওভারলে প্রদর্শন করে।

কোড সম্পর্কে মূল বিষয়গুলো

  • eth1 , eth2 এবং eth3 হলো কনফিগার করা হচ্ছে এমন নেটওয়ার্ক ইন্টারফেসগুলোর নাম।
  • 12, 13, 14, 15 এই ধারাবাহিক সংখ্যাগুলো নেটওয়ার্কের সক্ষমতা সক্রিয় হওয়াকে নির্দেশ করে।
  • নেটওয়ার্কের প্রাথমিক আইপি অ্যাড্রেস, গেটওয়ে এবং ডিএনএস সেট করার জন্য ip= , gateway= , এবং dns ব্যবহার করা হয়।

একটি নেটওয়ার্ক ইন্টারফেস সক্রিয় বা নিষ্ক্রিয় করুন

একটি নেটওয়ার্ক ইন্টারফেস সক্রিয় করতে, EthernetManager.enableInterface() কল করুন:

public final class InterfaceEnabler {
    private final Context mApplicationContext;
    private final EthernetManager mEthernetManager;
    private final OutcomeReceiver<String, EthernetNetworkManagementException> mOutcomeReceiver;

    public InterfaceEnabler(Context applicationContext,
            OutcomeReceiver<String, EthernetNetworkManagementException> outcomeReceiver) {
        mApplicationContext = applicationContext;
        mEthernetManager = applicationContext.getSystemService(EthernetManager.class);
        mOutcomeReceiver = outcomeReceiver;
    }

    public void enableInterface(String ifaceName) {
        mEthernetManager.enableInterface(ifaceName,
                mApplicationContext.getMainExecutor(),
                mOutcomeReceiver);
    }
}

কোড সম্পর্কে মূল বিষয়গুলো

  • ifaceName হলো সেই নেটওয়ার্ক ইন্টারফেসের নাম যা সক্রিয় করতে হবে।
  • getMainExecutor() অ্যাপ কনটেক্সট ফেরত দেয়।
  • OutcomeReceiver হলো একটি কলব্যাক যা কাজ সম্পন্ন হওয়ার বিষয়টি জানাতে ব্যবহৃত হয়; সফল হলে এটি আপডেট করা নেটওয়ার্কের নাম ফেরত দেয়, আর ত্রুটি হলে EthernetNetworkManagementException রিটার্ন করে।

যখন একটি নেটওয়ার্ক ইন্টারফেস সক্রিয় করা হয়, তখন এটি EthernetManager.updateConfiguration() দ্বারা সেট করা কনফিগারেশন ব্যবহার করে। যদি EthernetManager.updateConfiguration() দ্বারা কোনো কনফিগারেশন সেট করা না হয়ে থাকে, তাহলে নেটওয়ার্ক ইন্টারফেসটি রিসোর্স ওভারলে config_ethernet_interfaces ব্যবহার করে অথবা কোনো ওভারলে উপলব্ধ না থাকলে ডিফল্ট ইথারনেট নেটওয়ার্ক কনফিগারেশন ব্যবহার করে।

একটি নেটওয়ার্ক ইন্টারফেস নিষ্ক্রিয় করতে, EthernetManager.disableInterface() কল করুন:

public final class InterfaceEnabler {
    private final Context mApplicationContext;
    private final EthernetManager mEthernetManager;
    private final OutcomeReceiver<String, EthernetNetworkManagementException> mOutcomeReceiver;

    public InterfaceEnabler(Context applicationContext,
            OutcomeReceiver<String, EthernetNetworkManagementException> outcomeReceiver) {
        mApplicationContext = applicationContext;
        mEthernetManager = applicationContext.getSystemService(EthernetManager.class);
        mOutcomeReceiver = outcomeReceiver;
    }

    public void disableInterface(String ifaceName) {
        mEthernetManager.disableInterface(ifaceName,
                mApplicationContext.getMainExecutor(),
                mOutcomeReceiver);
    }
}

কোড সম্পর্কে মূল বিষয়গুলো

  • ifaceName হলো সেই নেটওয়ার্ক ইন্টারফেসের নাম যা নিষ্ক্রিয় করতে হবে।
  • getMainExecutor() অ্যাপ কনটেক্সট ফেরত দেয়।
  • OutcomeReceiver হলো একটি কলব্যাক যা কাজ সম্পন্ন হওয়ার বিষয়টি জানাতে ব্যবহৃত হয়; সফল হলে এটি আপডেট করা নেটওয়ার্কের নাম ফেরত দেয়, আর ত্রুটি হলে EthernetNetworkManagementException রিটার্ন করে।

নেটওয়ার্ক কনফিগারেশন আপডেট করুন

ইথারনেট নেটওয়ার্ক কনফিগারেশন আপডেট করতে, EthernetManager.updateConfiguration() কল করুন:

public final class ConfigurationUpdater {
    private final Context mApplicationContext;
    private final EthernetManager mEthernetManager;
    private final OutcomeReceiver<String, EthernetNetworkManagementException> mCallback;

    public ConfigurationUpdater(Context applicationContext,
            OutcomeReceiver<String, EthernetNetworkManagementException> callback) {
        mApplicationContext = applicationContext;
        mEthernetManager = applicationContext.getSystemService(EthernetManager.class);
        mCallback = callback;
    }

    public void updateNetworkConfiguration(String packageNames,
            String ipConfigurationText,
            String networkCapabilitiesText,
            String interfaceName)
            throws IllegalArgumentException, PackageManager.NameNotFoundException {

        EthernetNetworkUpdateRequest request = new EthernetNetworkUpdateRequest.Builder()
                .setIpConfiguration(getIpConfiguration(ipConfigurationText))
                .setNetworkCapabilities(getCapabilities(
                        interfaceName, networkCapabilitiesText, packageNames))
                .build();

        mEthernetManager.updateConfiguration(interfaceName, request,
                mApplicationContext.getMainExecutor(), mCallback);

    }
}

কোড সম্পর্কে মূল বিষয়গুলো

  • getCapabilities() একটি হেল্পার মেথড যা বর্তমান নেটওয়ার্ক ক্যাপাবিলিটিগুলো সংগ্রহ করে এবং মানুষের পাঠযোগ্য প্যাকেজের নামগুলোকে লিনাক্স ইউনিক আইডেন্টিফায়ার (UID)- এ রূপান্তর করার জন্য convertToUIDs() মেথডকে কল করে। সাধারণত, আপনি সংশ্লিষ্ট প্যাকেজগুলোর UID আগে থেকে জানেন না। তাই, যদি আপনি EthernetManager.updateConfiguration() ব্যবহার করে অ্যাপের একটি নির্দিষ্ট অংশের অ্যাক্সেস সীমিত করতে চান, তাহলে আপনাকে তাদের UID ব্যবহার করতে হবে।
  • request হলো অভ্যন্তরীণ নেটওয়ার্কের জন্য ব্যবহৃত কনফিগারেশন। এই অনুরোধে আইপি কনফিগারেশন এবং নেটওয়ার্ক সক্ষমতার জন্য নতুন সেটিংস থাকতে পারে। যদি নেটওয়ার্কটি কানেক্টিভিটি স্ট্যাকে নিবন্ধিত থাকে, তবে এটি কনফিগারেশন অনুযায়ী আপডেট করা হয়। এই কনফিগারেশনটি রিবুটের পর স্থায়ী থাকে না।
  • getMainExecutor() সেই এক্সিকিউটরটি রিটার্ন করে যার উপর লিসেনারটি কল করা হয়।
  • mCallback হলো একটি কলব্যাক যা কাজ সম্পন্ন হওয়ার বিষয়টি জানাতে ব্যবহৃত হয়; সফল হলে এটি আপডেট করা নেটওয়ার্কের নাম রিটার্ন করে, আর ত্রুটি হলে EthernetNetworkManagementException রিটার্ন করে।

updateConfiguration() অ্যান্ড্রয়েড কানেক্টিভিটি স্ট্যাক দ্বারা অপরিবর্তনীয় বলে বিবেচিত কোনো নেটওয়ার্কের বৈশিষ্ট্য আপডেট করতে পারে। এই অপরিবর্তনীয় অ্যাট্রিবিউটগুলো আপডেট করার জন্য নেটওয়ার্কটিকে ডাউন করা হয়, আপডেট করা হয় এবং আবার আপ করা হয়।

একটি নেটওয়ার্ককে অ্যাপের একটি উপসেটে সীমাবদ্ধ করুন

আপনি EthernetManager#updateConfiguration ব্যবহার করে শুধুমাত্র অনুমোদিত UID-গুলোর একটি নির্দিষ্ট অংশের জন্য অ্যাক্সেস সীমিত করতে পারেন। যেসব ক্ষেত্রে এটি প্রয়োজন, যেমন অভ্যন্তরীণ যানবাহন নেটওয়ার্কের জন্য যা শুধুমাত্র অল্প সংখ্যক OEM অ্যাপ ব্যবহার করতে পারে, সেসব ক্ষেত্রে এই পদ্ধতিটি ব্যবহার করুন।

অ্যান্ড্রয়েড মূলত অ্যাপগুলোকে তাদের UID দ্বারা ট্র্যাক করে। UIDToPackageNameConverter.java এর নিম্নলিখিত কোডটি দেখায় কিভাবে প্যাকেজ নামের একটি স্ট্রিং থেকে একাধিক UID পাওয়া যায়:

public static Set<Integer> convertToUids(Context applicationContext, String packageNames)
            throws PackageManager.NameNotFoundException {
        final PackageManager packageManager = applicationContext.getPackageManager();
        final UserManager userManager = applicationContext.getSystemService(UserManager.class);

        final Set<Integer> uids = new ArraySet<>();
        final List<UserHandle> users = userManager.getUserHandles(true);

        String[] packageNamesArray = packageNames.split(",");
        for (String packageName : packageNamesArray) {
            boolean nameNotFound = true;
            packageName = packageName.trim();
            for (final UserHandle user : users) {
                try {
                    final int uid =
                            packageManager.getApplicationInfoAsUser(packageName, 0, user).uid;
                    uids.add(uid);
                    nameNotFound = false;
                } catch (PackageManager.NameNotFoundException e) {
                    // Although this may seem like an error scenario, it is OK as all packages are
                    // not expected to be installed for all users.
                    continue;
                }
            }

            if (nameNotFound) {
                throw new PackageManager.NameNotFoundException("Not installed: " + packageName);
            }
        }
        return uids;

কোড সম্পর্কে মূল বিষয়গুলো

  • প্যাকেজ নাম থেকে UID বের করার জন্য getApplicationInfoAsuser().uid ব্যবহার করা হয়।
  • uids হলো পূর্ণসংখ্যার একটি জেনারেটেড অ্যারে।

EthernetManagerTest.kt ফাইলের নিম্নলিখিত কোডটি দেখায়, কীভাবে নেটওয়ার্ক ব্যবহারের অনুমতিপ্রাপ্ত অ্যাপগুলির UID ব্যবহার করে আপনার নেটওয়ার্ক ইন্টারফেস কনফিগারেশন আপডেট করতে হয়:

val allowedUids = setOf(Process.myUid())
        val nc = NetworkCapabilities.Builder(request.networkCapabilities)
                .setAllowedUids(allowedUids).build()
        updateConfiguration(iface, capabilities = nc).expectResult(iface.name)

কোড সম্পর্কে মূল বিষয়গুলো

  • allowUids হলো নেটওয়ার্ক ব্যবহারের জন্য অনুমোদিত অ্যাপ UID-গুলোর সেট।
  • updateConfiguration() ফাংশনটি নেটওয়ার্ককে প্রদত্ত UID-গুলোর মধ্যে সীমাবদ্ধ করার জন্য কনফিগারেশন আপডেট করে।