如何從C++代碼直接存取android framework層的WifiService

來源:互聯網
上載者:User

標籤:android   binder   

    說到底,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 \n",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 \n",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 \n",temp);        printf("level %d \n",mLevel);        printf("freq %d \n",mFrequency);        printf("freq %ld \n",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);}



基本的思路很簡單:

先通過:

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



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.