반응형
각 wifi 의 정보얻기
- NDIS Interface 를 통해서 각종 Wifi 정보를 얻을때 아래와 같이 사용한다.
- 해당 코드들은 APP Level 에서 동작한다.
테스트 환경 : Windows Mobile / Windows CE / EVC
NDIS interface 를 이용하기전에.. open / close
아래와 같은 file interface 를 이용한다. NDIS 를 이용하기 위한 핸들은 대부분 전역으로 설정하며 아래와 같이 사용한다. open 과 close 는 아래와 같이 사용한다.
HANDLE g_hNdisUio = NULL;
#define AR6002_ADAPTERNAME _T("AR6K_SD1")
void InitializeNdisUio(void)
{
if(g_hNdisUio == NULL)
g_hNdisUio = CreateFile(
NDISUIO_DEVICE_NAME, //Object name.
0x00, //Desired access.
0x00, //Share Mode.
NULL, //Security Attr
OPEN_EXISTING, //Creation Disposition.
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, //Flag and Attributes..
(HANDLE)INVALID_HANDLE_VALUE);
}
void CloseNdisUio( void )
{
if(g_hNdisUio)
CloseHandle(g_hNdisUio);
}
이름으로 네트워크 장치찾기
이름으로 네트워크 드라이버를 찾아야 할경우는 아래와 같이 사용한다.
HRESULT FindAdapter( WCHAR* ptcDeviceName )
{
BOOL fRetVal = FALSE;
HRESULT hr = E_FAIL;
WCHAR buf[1024] = {0};
WCHAR* pAdapterName;
PNDISUIO_QUERY_BINDING pQueryBinding;
DWORD dwBytesReturned = 0;
DWORD i = 0;
pQueryBinding = (PNDISUIO_QUERY_BINDING)&buf[0];
for( pQueryBinding->BindingIndex = i; ; ++i )
{
fRetVal = DeviceIoControl(
g_hNdisUio,
IOCTL_NDISUIO_QUERY_BINDING,
pQueryBinding,
sizeof(NDISUIO_QUERY_BINDING),
pQueryBinding,
1024,
&dwBytesReturned,
NULL);
if( fRetVal == TRUE )
{
pAdapterName = (PTCHAR)&buf[pQueryBinding->DeviceNameOffset-1];
pAdapterName[(pQueryBinding->DeviceNameLength / sizeof(TCHAR)) - 1] = 0x00;
if( !wcsncmp(ptcDeviceName, pAdapterName, (pQueryBinding->DeviceNameLength)/sizeof(TCHAR)) )
{
hr = S_OK;
//AfxMessageBox(_T("Find AR"));
break;
}
}
else
{
break;
}
}
return hr;
}
위의 API는 아래와 같이 사용할때 쓴다..
초기화 함수에서.. 네트워크 장치 찾을때..
if(FindAdapter(AR6002_ADAPTERNAME) == E_FAIL ) {
AfxMessageBox(_T("can't find AR6001 WLAN Adapter"));
}
SSID 얻어오기
HRESULT getSSID( WCHAR* ptcDeviceName, WCHAR* wSsid, BOOL* bAssociated )
{
BOOL fRetVal = FALSE;
HRESULT hr = E_FAIL;
PNDISUIO_QUERY_OIDpQueryOid = NULL;
DWORD dwBytesReturned = 0;
PNDIS_802_11_SSID pSsid;
UCHAR QueryBuffer[sizeof(NDISUIO_QUERY_OID)+sizeof(NDIS_802_11_SSID)];
pQueryOid = (PNDISUIO_QUERY_OID)&QueryBuffer[0];
pQueryOid->ptcDeviceName = ptcDeviceName;
pQueryOid->Oid = OID_802_11_SSID;
fRetVal = DeviceIoControl(
g_hNdisUio,
IOCTL_NDISUIO_QUERY_OID_VALUE,
(LPVOID) pQueryOid,
sizeof(NDISUIO_QUERY_OID) + sizeof(NDIS_802_11_SSID),
(LPVOID) pQueryOid,
sizeof(NDISUIO_QUERY_OID) + sizeof(NDIS_802_11_SSID),
&dwBytesReturned,
NULL);
if( fRetVal == TRUE )
{
hr = S_OK;
pSsid = (PNDIS_802_11_SSID)&pQueryOid->Data;
if( pSsid->SsidLength != 0 )
{
*bAssociated = TRUE;
mbstowcs( wSsid, (const char*)pSsid->Ssid, pSsid->SsidLength );
wSsid[pSsid->SsidLength] = 0x00;
}
}
else
{
wprintf(L"roamctrl: OID_802_11_SSID ioctl fail!\r\n");
hr = E_FAIL;
}
return hr;
}
RSSI 얻어오기
void CROM_CTRLDlg::OnGetRssi()
{
// TODO: Add your control notification handler code here
PUCHAR buffer = NULL;
NDIS_802_11_RSSI rssi,rssiAbs;
PNDISUIO_QUERY_OID rssiOid;
unsigned int lenReq;
DWORD dwReturnedBytes = 0;
buffer = (PUCHAR) malloc( sizeof(NDISUIO_QUERY_OID) + sizeof(ULONG) );
memset( buffer, 0, sizeof(NDISUIO_QUERY_OID) + sizeof(ULONG) );
lenReq = sizeof(NDISUIO_QUERY_OID) + sizeof(ULONG);
rssiOid = (NDISUIO_QUERY_OID *)buffer;
//Send OID_802_11_RSSI Oid to the driver
rssiOid->Oid = OID_802_11_RSSI;
rssiOid->ptcDeviceName = AR6002_ADAPTERNAME;
// Pass the IOCTL to the device
if (!DeviceIoControl(g_hNdisUio, IOCTL_NDISUIO_QUERY_OID_VALUE, buffer,
sizeof(NDISUIO_QUERY_OID), buffer, lenReq,
&dwReturnedBytes, NULL)) {
AfxMessageBox(_T("Error opening device and query"));
return;
}
rssi=(*(NDIS_802_11_RSSI *)(rssiOid->Data));
//rssiAbs=RSSI_NDIS2ABS(rssi);
m_rssi.Format(_T("%d"),rssi);
UpdateData(FALSE);
}
Power State Get / Set
void CROM_CTRLDlg::OnGetpower()
{
// TODO: Add your control notification handler code here
PNDISUIO_QUERY_OID powerModeOid;
PUCHAR buffer = NULL;
unsigned int lenReq;
DWORD dwReturnedBytes = 0;
buffer = (PUCHAR) malloc( sizeof(NDISUIO_QUERY_OID) + sizeof(UCHAR));
memset( buffer, 0, sizeof(NDISUIO_SET_OID) + sizeof(UCHAR));
lenReq = sizeof(NDISUIO_QUERY_OID) + sizeof(UCHAR);
powerModeOid = (NDISUIO_QUERY_OID *)buffer;
// Send OID to the driver
powerModeOid->Oid = OID_802_11_POWER_MODE;
powerModeOid->ptcDeviceName = AR6002_ADAPTERNAME;
// Pass the IOCTL to the device
if(!DeviceIoControl(g_hNdisUio, IOCTL_NDISUIO_QUERY_OID_VALUE, buffer,
sizeof(NDISUIO_QUERY_OID), buffer, lenReq,
&dwReturnedBytes, NULL)) {
AfxMessageBox(_T("Get Power Mode failed"));
}
else {
CString str;
str.Format(_T("%x %x %x %x") , powerModeOid->Data[0] , powerModeOid->Data[1] ,powerModeOid->Data[2] , powerModeOid->Data[3]);
switch(powerModeOid->Data[0]) {
case 0:
m_curpower.Format(_T("CAM mode"));
break;
case 1:
m_curpower.Format(_T("MAX mode"));
break;
case 2:
m_curpower.Format(_T("FAST mode"));
break;
default:
m_curpower.Format(_T("FAIL"));
break;
}
UpdateData(FALSE);
}
free(buffer);
}
int SetPowerMode(int mode)
{
PNDISUIO_SET_OID powerModeOid;
PUCHAR buffer = NULL;
DWORD dwReturnedBytes = 0;
buffer = (PUCHAR) malloc( sizeof(NDISUIO_SET_OID) );
memset( buffer, 0, sizeof(NDISUIO_SET_OID) );
powerModeOid = (NDISUIO_SET_OID *)buffer;
// Send OID to the driver
powerModeOid->Oid = OID_802_11_POWER_MODE;
powerModeOid->ptcDeviceName = AR6002_ADAPTERNAME;
(*(unsigned int *)(powerModeOid->Data)) = mode;
// Pass the IOCTL to the device
if (!DeviceIoControl(g_hNdisUio, IOCTL_NDISUIO_SET_OID_VALUE, buffer,
sizeof(NDISUIO_SET_OID), NULL, 0, &dwReturnedBytes, NULL ) ) {
AfxMessageBox(_T("Set Power Mode failed"));
free(buffer);
return 1;
}
free(buffer);
return 0;
}
Tx Power Level Get / Set
Tx Power Level 의 경우 해당 Network Driver 에서 Tx Power 조정 관련 OID 가 구현되어 있어야 한다.
void CROM_CTRLDlg::OnTxpower()
{
// TODO: Add your control notification handler code here
PNDISUIO_SET_OID txPowerOid;
PUCHAR buffer = NULL;
DWORD dwReturnedBytes = 0;
UpdateData();
buffer = (PUCHAR) malloc( sizeof(NDISUIO_SET_OID) );
memset( buffer, 0, sizeof(NDISUIO_SET_OID) );
txPowerOid = (NDISUIO_SET_OID *)buffer;
// Send OID to the driver
txPowerOid->Oid = OID_802_11_TX_POWER_LEVEL;
txPowerOid->ptcDeviceName = AR6002_ADAPTERNAME;
(*(unsigned int *)(txPowerOid->Data)) = m_txpower;
// Pass the IOCTL to the device
if (!DeviceIoControl(g_hNdisUio, IOCTL_NDISUIO_SET_OID_VALUE, buffer,
sizeof(NDISUIO_SET_OID), NULL, 0, &dwReturnedBytes, NULL ) ) {
AfxMessageBox(_T("Set Power Mode failed"));
free(buffer);
return;
}
free(buffer);
}
void CROM_CTRLDlg::OnGettx()
{
// TODO: Add your control notification handler code here
PNDISUIO_QUERY_OID txPowerOid;
PUCHAR buffer = NULL;
unsigned int lenReq;
DWORD dwReturnedBytes = 0;
buffer = (PUCHAR) malloc( sizeof(NDISUIO_QUERY_OID) + sizeof(ULONG));
memset(buffer, 0, sizeof(NDISUIO_SET_OID) + sizeof(ULONG));
lenReq = sizeof(NDISUIO_QUERY_OID) + sizeof(ULONG);
txPowerOid = (NDISUIO_QUERY_OID *)buffer;
// Send OID to the driver
txPowerOid->Oid = OID_802_11_TX_POWER_LEVEL;
txPowerOid->ptcDeviceName = AR6002_ADAPTERNAME;
if(!DeviceIoControl(g_hNdisUio, IOCTL_NDISUIO_QUERY_OID_VALUE, buffer,
sizeof(NDISUIO_QUERY_OID), buffer, lenReq,
&dwReturnedBytes, NULL)) {
AfxMessageBox(_T("Get Taget Version failed"));
return;
}
m_txpower = *(ULONG *)&txPowerOid->Data;
UpdateData(FALSE);
free(buffer);
}
반응형