Take the following blog information as a referrence:
http://blog.csdn.net/hongjiujing/archive/2010/05/07/5565431.aspx
Android WIFI state: DISABLED, DISABLING, ENABLED, ENABLING, UNKNOWN.
1. Porting WIFI driver on Android
--> #create filesystem for wifi &dhcp (add this in the init.rc file)
++++++++++++++++++++++++++++++++++++++++
mkdir /data/misc/wifi 0771 wifi system
chown wifi system /data/misc/wifi
chmod 0771 /data/misc/wifi
mkdir /data/misc/wifi/sockets 0771 wifi system
chown wifi system /data/misc/wifi/sockets
chmod 07771 /data/misc/wifi/sockets
mkdir /data/misc/dhcp 0770 dhcp dhcp
chown dhcp dhcp /data/misc/dhcp
chmod 0770 /data/misc/dhcp
++++++++++++++++++++++++++++++++++++++++
2. WPA and WPA2 implement
--> init.rc configuration
++++++++++++++++++++++++++++++++++++++++
mkdir /data/system/wpa_supplicant 0771 wifi system
chown wifi system /data/system/wpa_supplicant
chmod 0771 /data/eth0
setprop wifi.interface mlan0
service wpa_supplicant /system/bin/wpa_supplicant -Dwext -imlan0 -c/data/misc/wifi/wpa_supplicant.conf
user root
group system wifi
disabled
service dhcpcd /system/bin/dhcpcd -BKL mlan0
disabled
one shot
++++++++++++++++++++++++++++++++++++++++
--> useful tool: wpa_cli
--> requirement: driver_wext.c expects the wifi kernel driver to implement the SIOCSIWPRIV ioctrl and respond to android commands like RSSI, MACADDR, LINKSPEED and etc.
--> implement: add the upper ioctl to kernel wifi driver. (in wlan_wext.c). The following is the detail implement source code.
Add the "BOARD_WPA_SUPPLICANT_DRIVER := WEXT" in BoardConfig.mk
++++++++++++++++++++++++++++++++++++++++
/**
* @brief Set priv command
*
* @param dev A pointer to net_device structure
* @param info A pointer to iw_request_info structure
* @param dwrq A pointer to iw_point structure
* @param extra A pointer to extra data buf
*
* @return 0 --success, otherwise fail
*/
static int wlan_set_priv(struct net_device *dev, struct iw_request_info *info,
struct iw_point* dwrq, char *extra)
{
int ret = 0;
wlan_private* priv = (wlan_private *) netdev_priv(dev);
char * buf = NULL;
int len = 0;
int rssi = 0;
BSSDescriptor_t* pBSSDesc = NULL;
ENTER();
if (!(buf = kmalloc(dwrq->length, GFP_KERNEL))) {
ret = -ENOMEM;
goto done;
}
if (copy_from_user(buf, dwrq->pointer, dwrq->length)) {
ret = -EFAULT;
goto done;
}
PRINTM(CMND,"SIOCSIWPRIV requst = %s/n",buf);
if(strncmp(buf,"RSSI",strlen("RSSI")) == 0){
if (priv->adapter->MediaConnectStatus == WlanMediaStateConnected){
if(wlan_prepare_cmd(priv,
HostCmd_CMD_RSSI_INFO,
HostCmd_ACT_GEN_GET,HostCmd_OPTION_WAITFORRSP,
0, NULL)) {
ret = -EFAULT;
goto done;
}
rssi = priv->adapter->BcnRSSIAvg;
pBSSDesc = &priv->adapter->CurBssParams.BSSDescriptor;
len = sprintf(buf,"%s rssi %d/n",pBSSDesc->Ssid.Ssid,rssi) + 1;
}
}
else if(strncmp(buf, "LINKSPEED",strlen("LINKSPEED")) == 0) {
if(wlan_prepare_cmd(priv, HostCmd_CMD_802_11_TX_RATE_QUERY,
HostCmd_ACT_GEN_GET, HostCmd_OPTION_WAITFORRSP,
0, NULL)){
ret = -EFAULT;
goto done;
}
PRINTM(CMND, "tx rate=%d/n",(int)priv->adapter->TxRate);
len = sprintf(buf,"LinkSpeed %d/n",(int)(index_to_data_rate(priv->adapter->TxRate) * 500000 / 1000000)) + 1;
}
else if(strncmp(buf,"MACADDR",strlen("MACADDR")) == 0) {
len = sprintf(buf,"Macaddr = %02X:%02X:%02X:%02X:%02X:%02X/n",priv->adapter->CurrentAddr[0],
priv->adapter->CurrentAddr[1],priv->adapter->CurrentAddr[2],priv->adapter->CurrentAddr[3],
priv->adapter->CurrentAddr[4],priv->adapter->CurrentAddr[5]);
}
else {
len = sprintf(buf,"OK/n") + 1;
PRINTM(WARN,"Unknow PRIVATE command: %s, ignored/n", buf);
}
PRINTM(CMND,"PRIV Command return: %s, length=%d/n", buf, len);
dwrq->length = len;
if(copy_to_user(dwrq->pointer,buf,dwrq->length)){
ret = -EFAULT;
}
done:
if(buf)
kfree(buf);
LEAVE();
return ret;
}
(iw_handler) wlan_set_priv, /* SIOCSIWPRIV */
++++++++++++++++++++++++++++++++++++++++
3. WIFI Service
--> android/frameworks/base/services/java/com/android/server/WifiService.java
4. WIFI Power Management
--> Take the following webpage for a reference
http://www.cnmsdn.com/html/201003/1268408234ID1814.html
5. Problem:
--> after successfully connect to AP with WPA2 encryption, then disconnect with this AP, and reconnect with it, then it can not connect with this AP successfully.
workaroud: turn off the wifi and then turn on it.