• 怎样从C++代码直接訪问android framework层的WifiService


        说究竟,Java层的service就是就C++层的binder的封装。所以从原理上来讲通过C++代码直接訪问android framework层的service是全然可能的,这篇文章以訪问WifiService为例,解说怎样去实现这个功能。


    费话少说。直接上代码:


    WifiTest.cpp


    #include <sys/types.h>
    #include <unistd.h>
    #include <grp.h>
    
    #include <binder/IPCThreadState.h>
    #include <binder/ProcessState.h>
    #include <binder/IServiceManager.h>
    #include <utils/Log.h>
    
    #include <utils/String16.h>
    //#include <utils/Vector.h>
    #include <utils/List.h>
    #include <utils/PropertyMap.h>
    
    using namespace android;
    
    
    #define WIFI_SERVICE  "wifi"
    const String16 WIFI_DESCRIPTOR("android.net.wifi.IWifiManager");
    
    class ScanResult
    {
    
    private:
        ScanResult& operator=(const ScanResult& o);
    
    public:
        ScanResult(const ScanResult& o):
            mSsid(o.mSsid),mBssid(o.mBssid),mCaps(o.mCaps),mLevel(o.mLevel),mFrequency(o.mFrequency),mTimestamp(o.mTimestamp)
        {
        }
    
        ScanResult(String8 ssid,String16 bssid,String16 caps,int level,int freq,int64_t timeStamp):
            mSsid(ssid),mBssid(bssid),mCaps(caps),mLevel(level),mFrequency(freq),mTimestamp(timeStamp)
        {
        }
        void dump()
        {
            char temp[130];
            int size;
            memset(temp,0,sizeof(temp));
            printf("ssid %s 
    ",mSsid.string());
    
            size = mBssid.size();
            if(size > sizeof(temp)/2 - 1)
            {
                size = sizeof(temp)/2 - 1;
            }
            utf16_to_utf8(mBssid.string(), size, temp);
            printf("Bssid %s 
    ",temp);
    
            size = mCaps.size();
            if(size > sizeof(temp)/2 - 1)
            {
                size = sizeof(temp)/2 - 1;
            }
            utf16_to_utf8(mCaps.string(), size, temp);
            printf("ssid %s 
    ",temp);
    
    
            printf("level %d 
    ",mLevel);
            printf("freq %d 
    ",mFrequency);
            printf("freq %ld 
    ",mTimestamp);
        }
    private:
        String8 mSsid;
        String16 mBssid;
        String16 mCaps;
        int mLevel;
        int mFrequency;
        int64_t mTimestamp;
    };
    
    class IWifiService: public android::IInterface {
    public:
            DECLARE_META_INTERFACE(WifiService)
    
            virtual void startScan(int forceActive) = 0;
            virtual int getScanResults(List<ScanResult> &list) = 0;
            virtual bool setWifiEnabled(bool enable) = 0;
    };
    
    class BpWifiService: public android::BpInterface<IWifiService>
    {
        enum
        {
            FIRST_CALL_TRANSACTION = 1,
            TRANSACTION_getConfiguredNetworks = (android::IBinder::FIRST_CALL_TRANSACTION + 0),
            TRANSACTION_addOrUpdateNetwork = (android::IBinder::FIRST_CALL_TRANSACTION + 1),
            TRANSACTION_removeNetwork = (android::IBinder::FIRST_CALL_TRANSACTION + 2),
            TRANSACTION_enableNetwork = (android::IBinder::FIRST_CALL_TRANSACTION + 3),
            TRANSACTION_disableNetwork = (android::IBinder::FIRST_CALL_TRANSACTION + 4),
            TRANSACTION_pingSupplicant = (android::IBinder::FIRST_CALL_TRANSACTION + 5),
            TRANSACTION_startScan = (android::IBinder::FIRST_CALL_TRANSACTION + 6),
            TRANSACTION_getScanResults = (android::IBinder::FIRST_CALL_TRANSACTION + 7),
            TRANSACTION_disconnect = (android::IBinder::FIRST_CALL_TRANSACTION + 8),
            TRANSACTION_reconnect = (android::IBinder::FIRST_CALL_TRANSACTION + 9),
            TRANSACTION_reassociate = (android::IBinder::FIRST_CALL_TRANSACTION + 10),
            TRANSACTION_getConnectionInfo = (android::IBinder::FIRST_CALL_TRANSACTION + 11),
            TRANSACTION_setWifiEnabled = (android::IBinder::FIRST_CALL_TRANSACTION + 12),
            TRANSACTION_getWifiEnabledState = (android::IBinder::FIRST_CALL_TRANSACTION + 13),
            TRANSACTION_setCountryCode = (android::IBinder::FIRST_CALL_TRANSACTION + 14),
            TRANSACTION_setFrequencyBand = (android::IBinder::FIRST_CALL_TRANSACTION + 15),
            TRANSACTION_getFrequencyBand = (android::IBinder::FIRST_CALL_TRANSACTION + 16),
            TRANSACTION_isDualBandSupported = (android::IBinder::FIRST_CALL_TRANSACTION + 17),
            TRANSACTION_saveConfiguration = (android::IBinder::FIRST_CALL_TRANSACTION + 18),
            TRANSACTION_getDhcpInfo = (android::IBinder::FIRST_CALL_TRANSACTION + 19),
            TRANSACTION_acquireWifiLock = (android::IBinder::FIRST_CALL_TRANSACTION + 20),
            TRANSACTION_updateWifiLockWorkSource = (android::IBinder::FIRST_CALL_TRANSACTION + 21),
            TRANSACTION_releaseWifiLock = (android::IBinder::FIRST_CALL_TRANSACTION + 22),
            TRANSACTION_initializeMulticastFiltering = (android::IBinder::FIRST_CALL_TRANSACTION + 23),
            TRANSACTION_isMulticastEnabled = (android::IBinder::FIRST_CALL_TRANSACTION + 24),
            TRANSACTION_acquireMulticastLock = (android::IBinder::FIRST_CALL_TRANSACTION + 25),
            TRANSACTION_releaseMulticastLock = (android::IBinder::FIRST_CALL_TRANSACTION + 26),
            TRANSACTION_setWifiApEnabled = (android::IBinder::FIRST_CALL_TRANSACTION + 27),
            TRANSACTION_getWifiApEnabledState = (android::IBinder::FIRST_CALL_TRANSACTION + 28),
            TRANSACTION_getWifiApConfiguration = (android::IBinder::FIRST_CALL_TRANSACTION + 29),
            TRANSACTION_setWifiApConfiguration = (android::IBinder::FIRST_CALL_TRANSACTION + 30),
            TRANSACTION_startWifi = (android::IBinder::FIRST_CALL_TRANSACTION + 31),
            TRANSACTION_stopWifi = (android::IBinder::FIRST_CALL_TRANSACTION + 32),
            TRANSACTION_addToBlacklist = (android::IBinder::FIRST_CALL_TRANSACTION + 33),
            TRANSACTION_clearBlacklist = (android::IBinder::FIRST_CALL_TRANSACTION + 34),
            TRANSACTION_getWifiServiceMessenger = (android::IBinder::FIRST_CALL_TRANSACTION + 35),
            TRANSACTION_getWifiStateMachineMessenger = (android::IBinder::FIRST_CALL_TRANSACTION + 36),
            TRANSACTION_getConfigFile = (android::IBinder::FIRST_CALL_TRANSACTION + 37),
            TRANSACTION_captivePortalCheckComplete = (android::IBinder::FIRST_CALL_TRANSACTION + 38),
        };
    public:
            BpWifiService(const android::sp<android::IBinder>& impl): android::BpInterface<IWifiService>(impl)
            {
            }
    
            void startScan(int forceActive)
            {
                android::Parcel data, reply;
                data.writeInterfaceToken(WIFI_DESCRIPTOR);
                if (forceActive)
                {
                    data.writeInt32(1);
                }
                else
                {
                    data.writeInt32(0);
                }
                remote()->transact(TRANSACTION_startScan, data, &reply, 0);
            }
    
            virtual int getScanResults(List<ScanResult> &list)
            {
                Parcel data, reply;
                data.writeInterfaceToken(WIFI_DESCRIPTOR);
                remote()->transact(TRANSACTION_getScanResults, data, &reply, 0);
                if (0 != reply.readExceptionCode())
                {
                    return 0;
                }
                int count = reply.readInt32();
                for (int i=0;i<count;i++)
                {
                    String8 ssid;
                    int res =  reply.readInt32();
                    if (res != 0)
                    {
                        reply.readInt32();
                        reply.readInt32();
                        int length = reply.readInt32();
                        ssid = String8((const char*)reply.readInplace(length),length);
                    }
    
    //                utf16_to_utf8(const char16_t* src, size_t src_len, char* dst);
    
                    String16 BSSID = reply.readString16();
                    String16 caps = reply.readString16();
                    int level = reply.readInt32();
                    int frequency = reply.readInt32();
                    int64_t timestamp = reply.readInt64();
                    ScanResult result(ssid,BSSID,caps,level,frequency,timestamp);
                    list.push_back(result);
                }
                return count;
            }
    
            bool setWifiEnabled(bool enable)
            {
                Parcel data, reply;
                data.writeInterfaceToken(WIFI_DESCRIPTOR);
    
                if(enable)
                    data.writeInt32(1);
                else
                    data.writeInt32(0);
                remote()->transact(TRANSACTION_setWifiEnabled, data,&reply,0);
                reply.readExceptionCode();
                return 0!=reply.readInt32();
            }
    
    };
    
    IMPLEMENT_META_INTERFACE(WifiService, WIFI_DESCRIPTOR)
    
    
    int main(int argc, char *argv[])
    {
    
        android::sp<android::IServiceManager> sm = android::defaultServiceManager();
        android::sp<android::IBinder> binder;
        android::sp<IWifiService> wifi;
    
    
        binder = sm->getService(android::String16(WIFI_SERVICE));
    
        if (binder == 0)
        {
            return 1;
        }
    
        wifi = android::interface_cast<IWifiService>(binder);
    
        wifi->setWifiEnabled(true);
    	printf("+++++scan start");
    	wifi->startScan(1);
    	
    	for(int i=0;i<10;i++)
    	{
    		usleep(1*1000*1000);
    		List<ScanResult> list;
    		wifi->getScanResults(list);
    		if(list.size() > 0)
    	    {
    	        for(List<ScanResult>::iterator it = list.begin();it != list.end();++it)
    	        {
    	            (*it).dump();
    	        }
    	        break;
    	    }
    	}
    
        return(0);
    }



    主要的思路非常easy:

    先通过:

    android::defaultServiceManager()->getService(android::String16(WIFI_SERVICE));

    获取binder接口。再通过Parcel读与binder,详细的实现能够參考IWifiManager.java的代码。


    编译后执行以上的代码能够得到类似下面的输出:


    ssid wifitest
    Bssid b8:55:10:84:13:57
    ssid [WPA-PSK-CCMP][WPA2-PSK-CCMP][WPS][ESS]
    level -55
    freq 2447
    time stamp 1073922473

    ssid test
    Bssid 08:bd:43:c3:a9:96
    ssid [WPA2-PSK-CCMP][WPS][ESS]
    level -66
    freq 2462
    time stamp 1073922473


    完整代码下载:

    http://download.csdn.net/detail/i2cbus/7613361



  • 相关阅读:
    git升级
    redis集群
    redis安装
    escript
    git搭建仓库与服务器
    svnsync
    post_commit.sh
    nvm安装和使用
    quartz 定时器
    Oracle flashback恢复误删的数据或表
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/6918139.html
Copyright © 2020-2023  润新知