diff options
Diffstat (limited to 'wilink_6_1/CUDK/os/linux/src/cu_wext.c')
-rw-r--r-- | wilink_6_1/CUDK/os/linux/src/cu_wext.c | 468 |
1 files changed, 468 insertions, 0 deletions
diff --git a/wilink_6_1/CUDK/os/linux/src/cu_wext.c b/wilink_6_1/CUDK/os/linux/src/cu_wext.c new file mode 100644 index 0000000..bbb68eb --- /dev/null +++ b/wilink_6_1/CUDK/os/linux/src/cu_wext.c @@ -0,0 +1,468 @@ +/* + * cu_wext.c + * + * Copyright 2001-2009 Texas Instruments, Inc. - http://www.ti.com/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/**************************************************************************** +* +* MODULE: CU_Wext.c +* +* PURPOSE: +* +* DESCRIPTION: +* ============ +* +* +****************************************************************************/ + +/* includes */ +/************/ +#include "cu_osapi.h" +#include "oserr.h" +#include <net/if.h> +#include <linux/rtnetlink.h> +#include <linux/wireless.h> +#include <string.h> +#include <stdlib.h> + +#include "TWDriver.h" +#include "STADExternalIf.h" +#include "ParsEvent.h" +#include "ipc_sta.h" +#include "cu_os.h" + +/* defines */ +/***********/ + +/* local types */ +/***************/ +/* Module control block */ +typedef struct +{ + THandle hIpcSta; + union iwreq_data req_data; + + struct iw_scan_req *scan_req; + U16 scan_flag; +} TCuWext; + +/* local variables */ +/*******************/ + +/* local fucntions */ +/*******************/ +static S32 CuWext_FillBssidList(struct iw_event *iwe, OS_802_11_BSSID_EX* bssidList, S32 index) +{ + S32 res = 0; + switch(iwe->cmd) + { + case SIOCGIWAP: + os_memcpy(bssidList[index].MacAddress, iwe->u.ap_addr.sa_data, MAC_ADDR_LEN); + bssidList[index].Configuration.BeaconPeriod = 0; /* default configuration */ + res = 1; + break; + case SIOCGIWESSID: + bssidList[index-1].Ssid.SsidLength = iwe->u.data.length; + os_memcpy(bssidList[index-1].Ssid.Ssid, iwe->u.data.pointer, bssidList[index-1].Ssid.SsidLength); + if(iwe->u.data.length != MAX_SSID_LEN) + bssidList[index-1].Ssid.Ssid[bssidList[index-1].Ssid.SsidLength] = 0; + break; + case SIOCGIWNAME: + { + unsigned i; + S8 buffer[IFNAMSIZ]; + static const char *ieee80211_modes[] = { + "?", + "IEEE 802.11 B", + "IEEE 802.11 A", + "IEEE 802.11 BG", + "IEEE 802.11 ABG" }; + + os_memset(buffer, 0, IFNAMSIZ); + os_memcpy(buffer, iwe->u.name, IFNAMSIZ); + for(i=0;i<SIZE_ARR(ieee80211_modes); i++) + if (0 == os_strcmp((PS8)ieee80211_modes[i], buffer)) + break; + bssidList[index-1].NetworkTypeInUse = i; + } + break; + case SIOCGIWMODE: + if(iwe->u.mode == IW_MODE_ADHOC) + bssidList[index-1].InfrastructureMode = os802_11IBSS; + else if (iwe->u.mode == IW_MODE_INFRA) + bssidList[index-1].InfrastructureMode = os802_11Infrastructure; + else if (iwe->u.mode == IW_MODE_AUTO) + bssidList[index-1].InfrastructureMode = os802_11AutoUnknown; + else + bssidList[index-1].InfrastructureMode = os802_11InfrastructureMax; + + break; + case SIOCGIWFREQ: + bssidList[index-1].Configuration.Union.channel = iwe->u.freq.m; + break; + case IWEVQUAL: + bssidList[index-1].Rssi = (S8)iwe->u.qual.level; + break; + case SIOCGIWENCODE: + if(iwe->u.data.flags == (IW_ENCODE_ENABLED | IW_ENCODE_NOKEY)) + { + bssidList[index-1].Privacy = TRUE; + bssidList[index-1].Capabilities |= CAP_PRIVACY_MASK<<CAP_PRIVACY_SHIFT; + } + else + { + bssidList[index-1].Privacy = FALSE; + bssidList[index-1].Capabilities &= ~(CAP_PRIVACY_MASK<<CAP_PRIVACY_SHIFT); + } + break; + case SIOCGIWRATE: + break; + case IWEVCUSTOM: + { + S8 buffer[100]; + + os_memset(buffer, 0, 100); + os_memcpy(buffer, iwe->u.data.pointer, iwe->u.data.length); + + if(!os_strncmp(buffer, (PS8)"Bcn", 3)) + { + char *p1; + p1 = strtok(&buffer[10], " "); + bssidList[index-1].Configuration.BeaconPeriod = atoi(p1); + } + } + break; + } + + return res; +} + + +/* functions */ +/*************/ + +THandle CuOs_Create(THandle hIpcSta) +{ + TCuWext* pCuWext = (TCuWext*)os_MemoryCAlloc(sizeof(TCuWext), sizeof(U8)); + if(pCuWext == NULL) + { + os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - CuOs_Create - cant allocate control block\n"); + return NULL; + } + + pCuWext->hIpcSta = hIpcSta; + + return pCuWext; +} + +VOID CuOs_Destroy(THandle hCuWext) +{ + TCuWext* pCuWext = (TCuWext*)hCuWext; + + os_MemoryFree(pCuWext); +} + +S32 CuOs_Get_SSID(THandle hCuWext, OS_802_11_SSID* ssid) +{ + TCuWext* pCuWext = (TCuWext*)hCuWext; + S32 res; + + os_memset(ssid->Ssid, 0, sizeof(OS_802_11_SSID) - sizeof(U32)); + + pCuWext->req_data.essid.pointer = (PVOID)ssid->Ssid; + pCuWext->req_data.essid.length = sizeof(OS_802_11_SSID) - sizeof(U32); + pCuWext->req_data.essid.flags = 0; + + res = IPC_STA_Wext_Send(pCuWext->hIpcSta, SIOCGIWESSID, &pCuWext->req_data, sizeof(struct iw_point)); + if(res != OK) + return res; + + ssid->SsidLength = pCuWext->req_data.essid.length; + + return OK; +} + +S32 CuOs_Get_BSSID(THandle hCuWext, TMacAddr bssid) +{ + TCuWext* pCuWext = (TCuWext*)hCuWext; + S32 res,i; + + os_memset(&pCuWext->req_data.ap_addr, 0x00, sizeof(struct sockaddr)); + + res = IPC_STA_Wext_Send(pCuWext->hIpcSta, SIOCGIWAP, &pCuWext->req_data, sizeof(struct sockaddr)); + if(res != OK) + return res; + + for(i=0;i<MAC_ADDR_LEN;i++) + bssid[i] = pCuWext->req_data.ap_addr.sa_data[i]; + + return OK; +} + +S32 CuOs_GetCurrentChannel(THandle hCuWext, U32* channel) +{ + TCuWext* pCuWext = (TCuWext*)hCuWext; + S32 res; + + pCuWext->req_data.freq.m = 0; + + res = IPC_STA_Wext_Send(pCuWext->hIpcSta, SIOCGIWFREQ, &pCuWext->req_data, sizeof(struct iw_freq )); + if(res != OK) + return res; + + *channel = pCuWext->req_data.freq.m; + + return OK; +} + +S32 CuOs_Start_Scan(THandle hCuWext, OS_802_11_SSID* ssid) +{ + TCuWext* pCuWext = (TCuWext*)hCuWext; + struct iw_scan_req tReq; + S32 res; + + if (ssid->SsidLength > IW_ESSID_MAX_SIZE) + { + os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - CuOs_Start_Scan - too long SSID (%lu)\n",ssid->SsidLength); + return OSAL_ERROR; + } + + if (ssid->Ssid[0] && ssid->SsidLength) + { + os_memset(&tReq, 0, sizeof(tReq)); + tReq.essid_len = ssid->SsidLength; + /* + * tReq.bssid.sa_family = ARPHRD_ETHER; + * os_memset(tReq.bssid.sa_data, 0xff, ETH_ALEN); + */ + os_memcpy(tReq.essid, ssid->Ssid, ssid->SsidLength); + pCuWext->scan_req = &tReq; + pCuWext->req_data.data.flags = IW_SCAN_THIS_ESSID; + } + else + { + pCuWext->req_data.data.flags = 0; + } + + pCuWext->req_data.data.pointer = &tReq; + pCuWext->req_data.data.length = sizeof(struct iw_scan_req); + + res = IPC_STA_Wext_Send(pCuWext->hIpcSta, SIOCSIWSCAN, &pCuWext->req_data, sizeof(struct iw_point)); + if(res != OK) + return res; + + return OK; +} + +S32 CuOs_GetBssidList(THandle hCuWext, OS_802_11_BSSID_LIST_EX *bssidList) +{ + TCuWext* pCuWext = (TCuWext*)hCuWext; + S32 res, NumberOfItems; + + /* allocate the scan result buffer */ + U8* buffer = os_MemoryCAlloc(IW_SCAN_MAX_DATA, sizeof(U8)); + if(buffer == NULL) + { + os_error_printf(CU_MSG_ERROR, (PS8)"ERROR - CuOs_Get_BssidList - cant allocate scan result buffer\n"); + return EOALERR_CU_WEXT_ERROR_CANT_ALLOCATE; + } + + NumberOfItems = 0; + pCuWext->req_data.data.pointer = buffer; + pCuWext->req_data.data.flags = 0; + do + { + pCuWext->req_data.data.length = IW_SCAN_MAX_DATA; + + res = IPC_STA_Wext_Send(pCuWext->hIpcSta, SIOCGIWSCAN, &pCuWext->req_data, sizeof(struct iw_point)); + if(res != OK) + { + os_MemoryFree(buffer); + return res; + } + + /* parse the scan results */ + if(pCuWext->req_data.data.length) + { + struct iw_event iwe; + struct stream_descr stream; + S32 ret; + + /* init the event stream */ + os_memset((char *)&stream, '\0', sizeof(struct stream_descr)); + stream.current = (char *)buffer; + stream.end = (char *)(buffer + pCuWext->req_data.data.length); + + do + { + /* Extract an event and print it */ + ret = ParsEvent_GetEvent(&stream, &iwe); + if(ret > 0) + NumberOfItems += CuWext_FillBssidList(&iwe, bssidList->Bssid, NumberOfItems); + } + while(ret > 0); + } + + } while(pCuWext->req_data.data.flags); + + bssidList->NumberOfItems = NumberOfItems; + + /* free the scan result buffer */ + os_MemoryFree(buffer); + + return OK; +} + + +S32 CuOs_Set_BSSID(THandle hCuWext, TMacAddr bssid) +{ + TCuWext* pCuWext = (TCuWext*)hCuWext; + S32 res; + + os_memcpy(pCuWext->req_data.ap_addr.sa_data, bssid, MAC_ADDR_LEN); + + res = IPC_STA_Wext_Send(pCuWext->hIpcSta, SIOCSIWAP, &pCuWext->req_data, sizeof(struct sockaddr)); + + if(res != OK) + return res; + + return OK; +} + +S32 CuOs_Set_ESSID(THandle hCuWext, OS_802_11_SSID* ssid) +{ + TCuWext* pCuWext = (TCuWext*)hCuWext; + S32 res; + + pCuWext->req_data.essid.pointer = (PVOID)ssid->Ssid; + pCuWext->req_data.essid.length = ssid->SsidLength; + if(ssid->SsidLength) + pCuWext->req_data.essid.flags = 1; + else + pCuWext->req_data.essid.flags = 0; + pCuWext->req_data.essid.flags |= SET_SSID_WITHOUT_SUPPL; + + res = IPC_STA_Wext_Send(pCuWext->hIpcSta, SIOCSIWESSID, &pCuWext->req_data, sizeof(struct sockaddr)); + + if(res != OK) + return res; + + return OK; +} + +S32 CuOs_GetTxPowerLevel(THandle hCuWext, S32* pTxPowerLevel) +{ + TCuWext* pCuWext = (TCuWext*)hCuWext; + S32 res; + + os_memset(&pCuWext->req_data.txpower, 0, sizeof(struct iw_param)); + + res = IPC_STA_Wext_Send(pCuWext->hIpcSta, SIOCGIWTXPOW, &pCuWext->req_data, sizeof(struct iw_param)); + + if(res != OK) + return res; + + *pTxPowerLevel = pCuWext->req_data.txpower.value; + + return OK; +} + +S32 CuOs_SetTxPowerLevel(THandle hCuWext, S32 txPowerLevel) +{ + TCuWext* pCuWext = (TCuWext*)hCuWext; + S32 res; + + os_memset(&pCuWext->req_data.txpower, 0, sizeof(struct iw_param)); + + pCuWext->req_data.txpower.value = txPowerLevel; + + res = IPC_STA_Wext_Send(pCuWext->hIpcSta, SIOCSIWTXPOW, &pCuWext->req_data, sizeof(struct iw_param)); + + if(res != OK) + return res; + + return OK; +} + +S32 CuOs_GetRtsTh(THandle hCuWext, PS32 pRtsTh) +{ + TCuWext* pCuWext = (TCuWext*)hCuWext; + S32 res; + + os_memset(&pCuWext->req_data.rts, 0, sizeof(struct iw_param)); + + res = IPC_STA_Wext_Send(pCuWext->hIpcSta, SIOCGIWRTS, &pCuWext->req_data, sizeof(struct iw_param)); + if(res != OK) + return res; + + *pRtsTh = pCuWext->req_data.rts.value; + + return OK; +} + + +S32 CuOs_SetRtsTh(THandle hCuWext, S32 RtsTh) +{ + TCuWext* pCuWext = (TCuWext*)hCuWext; + S32 res; + + os_memset(&pCuWext->req_data.rts, 0, sizeof(struct iw_param)); + pCuWext->req_data.rts.value = RtsTh; + + res = IPC_STA_Wext_Send(pCuWext->hIpcSta, SIOCSIWRTS, &pCuWext->req_data, sizeof(struct iw_param)); + if(res != OK) + return res; + + + + return OK; +} + +S32 CuOs_GetFragTh(THandle hCuWext, PS32 pFragTh) +{ + TCuWext* pCuWext = (TCuWext*)hCuWext; + S32 res; + + os_memset(&pCuWext->req_data.frag, 0, sizeof(struct iw_param)); + + res = IPC_STA_Wext_Send(pCuWext->hIpcSta, SIOCGIWFRAG, &pCuWext->req_data, sizeof(struct iw_param)); + if(res != OK) + return res; + + *pFragTh = pCuWext->req_data.frag.value; + + return OK; +} + +S32 CuOs_SetFragTh(THandle hCuWext, S32 FragTh) +{ + TCuWext* pCuWext = (TCuWext*)hCuWext; + S32 res; + + os_memset(&pCuWext->req_data.frag, 0, sizeof(struct iw_param)); + pCuWext->req_data.frag.value = FragTh; + + res = IPC_STA_Wext_Send(pCuWext->hIpcSta, SIOCSIWFRAG, &pCuWext->req_data, sizeof(struct iw_param)); + if(res != OK) + return res; + + return OK; +} +/*stab function (should be filled later on for Linux to get ThreadID of the WLAN driver*/ +S32 CuOs_GetDriverThreadId(THandle hCuWext, U32* threadid) +{ + return OK; +} |