當前位置:編程學習大全網 - 源碼下載 - 如何從C++代碼直接訪問android framework層的WifiService

如何從C++代碼直接訪問android framework層的WifiService

說到底,Java層的service就是就C++層的binder的封裝,所以從原理上來講通過C++代碼直接訪問android framework層的service是完全可能的,這篇文章以訪問WifiService為例,講解如何去實現這個功能。

費話少說,直接上代碼:

WifiTest.cpp

[cpp] view plaincopy在CODE上查看代碼片派生到我的代碼片

#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

  • 上一篇:方形爬蟲源代碼
  • 下一篇:c語言的語言組成
  • copyright 2024編程學習大全網