阿娇开发978 发表于 2015-9-30 14:17:47

wifi enable

wifiservice.java wifistateMachine.java中
/**
* see {@link android.net.wifi.WifiManager#setWifiEnabled(boolean)}
* @param enable {@code true} to enable, {@code false} to disable.
* @return {@code true} if the enable/disable operation was
*         started or is already in the queue.
*/
public synchronized boolean setWifiEnabled(boolean enable) {
enforceChangePermission();
Slog.d(TAG, "setWifiEnabled: " + enable + " pid=" + Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid());
if (DBG) {
Slog.e(TAG, "Invoking mWifiStateMachine.setWifiEnabled\n");
}
if (enable) {
reportStartWorkSource();
}
mWifiStateMachine.setWifiEnabled(enable);
/*
* Caller might not have WRITE_SECURE_SETTINGS,
* only CHANGE_WIFI_STATE is enforced
*/
long ident = Binder.clearCallingIdentity();
try {
handleWifiToggled(enable);
} finally {
Binder.restoreCallingIdentity(ident);
}
if (enable) {
if (!mIsReceiverRegistered) {
registerForBroadcasts();
mIsReceiverRegistered = true;
}
} else if (mIsReceiverRegistered) {
mContext.unregisterReceiver(mReceiver);
mIsReceiverRegistered = false;
}
return true;
}
  



public void setWifiEnabled(boolean enable) {
mLastEnableUid.set(Binder.getCallingUid());
if (enable) {
/* Argument is the state that is entered prior to load */
            sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));
sendMessage(CMD_START_SUPPLICANT);
} else {
sendMessage(CMD_STOP_SUPPLICANT);
/* Argument is the state that is entered upon success */
sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0));
}
}
  当前stateMachine应为DriverUnloadedState,转到mDriverLoadingState状态



class DriverUnloadedState extends State {
@Override
public void enter() {
if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
if (DBG) log(getName() + message.toString() + "\n");
switch (message.what) {
case CMD_LOAD_DRIVER:
transitionTo(mDriverLoadingState);
break;
default:
return NOT_HANDLED;
}
return HANDLED;
}
}


class DriverLoadingState extends State {
@Override
public void enter() {
if (DBG) log(getName() + "\n");
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
final Message message = new Message();
message.copyFrom(getCurrentMessage());
/* TODO: add a timeout to fail when driver load is hung.
* Similarly for driver unload.
*/
new Thread(new Runnable() {
public void run() {
mWakeLock.acquire();
//enabling state
switch(message.arg1) {
case WIFI_STATE_ENABLING:
setWifiState(WIFI_STATE_ENABLING);
break;
case WIFI_AP_STATE_ENABLING:
setWifiApState(WIFI_AP_STATE_ENABLING);
break;
}
if(mWifiNative.loadDriver()) {
if (DBG) log("Driver load successful");
sendMessage(CMD_LOAD_DRIVER_SUCCESS);
} else {
loge("Failed to load driver!");
switch(message.arg1) {
case WIFI_STATE_ENABLING:
setWifiState(WIFI_STATE_UNKNOWN);
break;
case WIFI_AP_STATE_ENABLING:
setWifiApState(WIFI_AP_STATE_FAILED);
break;
}
sendMessage(CMD_LOAD_DRIVER_FAILURE);
}
mWakeLock.release();
}
}).start();
}
@Override
public boolean processMessage(Message message) {
if (DBG) log(getName() + message.toString() + "\n");
switch (message.what) {
case CMD_LOAD_DRIVER_SUCCESS:
transitionTo(mDriverLoadedState);
break;
case CMD_LOAD_DRIVER_FAILURE:
transitionTo(mDriverFailedState);
break;
case CMD_LOAD_DRIVER:
case CMD_UNLOAD_DRIVER:
case CMD_START_SUPPLICANT:
case CMD_STOP_SUPPLICANT:
case CMD_START_AP:
case CMD_STOP_AP:
case CMD_START_DRIVER:
case CMD_STOP_DRIVER:
case CMD_SET_SCAN_MODE:
case CMD_SET_SCAN_TYPE:
case CMD_SET_COUNTRY_CODE:
case CMD_SET_FREQUENCY_BAND:
case CMD_START_PACKET_FILTERING:
case CMD_STOP_PACKET_FILTERING:
deferMessage(message);
break;
default:
return NOT_HANDLED;
}
return HANDLED;
}
}
  在DriverLoadingState 中产生第一个native函数:mWifiNative.loadDriver
  通过JNI最终调用到wifi.c,



int wifi_load_driver()
{
do_wifi_workaround();// leon 1
#ifdef WIFI_DRIVER_MODULE_PATH
char driver_status;
int count = 100; /* wait at most 20 seconds for completion */
if (is_wifi_driver_loaded()) {
      return 0;
}
if (insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0)// leon 2
return -1;
#ifdef BOARD_WIFI_ATHEROS
if (insmod(DRIVER_MODULE_PATH_2, DRIVER_MODULE_ARG_2) < 0)
return -1;
if (insmod(DRIVER_MODULE_PATH_3, DRIVER_MODULE_ARG_3) < 0)
return -1;      
property_set(&quot;ctl.start&quot;, ADD_P2P);   
#endif
if (strcmp(FIRMWARE_LOADER,&quot;&quot;) == 0) {
if (strcmp(WIFI_DRIVER_MODULE_NAME, &quot;8192cu&quot;) == 0)
usleep(1600000);
else
usleep(WIFI_DRIVER_LOADER_DELAY);
property_set(DRIVER_PROP_NAME, &quot;ok&quot;);
}
else {
property_set(&quot;ctl.start&quot;, FIRMWARE_LOADER);
}
sched_yield();
while (count-- > 0) {
if (property_get(DRIVER_PROP_NAME, driver_status, NULL)) {
if (strcmp(driver_status, &quot;ok&quot;) == 0)
return 0;
else if (strcmp(DRIVER_PROP_NAME, &quot;failed&quot;) == 0) {
wifi_unload_driver();
return -1;
}
}
usleep(200000);
}
property_set(DRIVER_PROP_NAME, &quot;timeout&quot;);
wifi_unload_driver();
return -1;
#else
property_set(DRIVER_PROP_NAME, &quot;ok&quot;);
return 0;
#endif
}




#define WIFI_FIX_SVC    &quot;wififix&quot;
int do_wifi_workaround() {                                                                                                                                                                                 
property_set(&quot;ctl.start&quot;, WIFI_FIX_SVC);
return 0;
}
  
driver 加载成功后,将状态转移到transitionTo(mDriverLoadedState); 接下来执行sendMessage(CMD_START_SUPPLICANT);



class DriverLoadedState extends State {
@Override
public void enter() {
if (DBG) log(getName() + &quot;\n&quot;);
EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
}
@Override
public boolean processMessage(Message message) {
if (DBG) log(getName() + message.toString() + &quot;\n&quot;);
switch(message.what) {
case CMD_UNLOAD_DRIVER:
transitionTo(mDriverUnloadingState);
break;
case CMD_START_SUPPLICANT:
try {
mNwService.wifiFirmwareReload(mInterfaceName, &quot;STA&quot;);
} catch (Exception e) {
loge(&quot;Failed to reload STA firmware &quot; + e);
// continue
                  }
try {
//A runtime crash can leave the interface up and
//this affects connectivity when supplicant starts up.
//Ensure interface is down before a supplicant start.




                        mNwService.setInterfaceDown(mInterfaceName);
//Set privacy extensions
mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
} catch (RemoteException re) {
loge(&quot;Unable to change interface settings: &quot; + re);
} catch (IllegalStateException ie) {
loge(&quot;Unable to change interface settings: &quot; + ie);
}
/* Stop a running supplicant after a runtime restart
* Avoids issues with drivers that do not handle interface down
* on a running supplicant properly.
*/
if (DBG) log(&quot;Kill any running supplicant&quot;);
mWifiNative.killSupplicant(mP2pSupported);
if(mWifiNative.startSupplicant(mP2pSupported)) {
if (DBG) log(&quot;Supplicant start successful&quot;);
mWifiMonitor.startMonitoring();
transitionTo(mSupplicantStartingState);
} else {
loge(&quot;Failed to start supplicant!&quot;);
sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_UNKNOWN, 0));
}
break;
case CMD_START_AP:
transitionTo(mSoftApStartingState);
break;
default:
return NOT_HANDLED;
}
return HANDLED;
}
}
  



/* @param mode can be &quot;AP&quot;, &quot;STA&quot; or &quot;P2P&quot; */
@Override
public void wifiFirmwareReload(String wlanIface, String mode) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
mConnector.execute(&quot;softap&quot;, &quot;fwreload&quot;, wlanIface, mode);
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
}
  
  
  
  
  
  
  property_set(&quot;ctl.start&quot;, &quot;wififix&quot; );
  insmod /system/lib/dhd.ko
  usleep 1000,000
  property_set(DRIVER_PROP_NAME, &quot;ok&quot;);//static const char DRIVER_PROP_NAME[]    = &quot;wlan.driver.status&quot;;
  //间隔0.2s,总计20s
  reload firmware,没有搞清楚是如何加载的。
  killall wps
  mWifiNative.startSupplicant(mP2pSupported)
页: [1]
查看完整版本: wifi enable