WiFi Driver Design Principle

Source: Internet
Author: User
Tags bssid

Initialization
When systemserver is started, a connectivityservice instance is generated,
Try {
Log. I (TAG, "Starting connectivity service .");
Servicemanager. addservice (context. connectivity_service, new
Connectivityservice (context ));
} Catch (throwable e ){
Log. E (TAG, "Failure starting connectivity service", e );
}
The connectivityservice constructor will create wifiservice,
If (DBG) log. V (TAG, "Starting WiFi service .");
Mwifistatetracker = new wifistatetracker (context, Handler );
Wifiservice = new wifiservice (context, mwifistatetracker );
Servicemanager. addservice (context. wifi_service, wifiservice );
Wifistatetracker creates a wifimonitor to receive events from the underlying layer.
Module core. Wifiservice is responsible for starting and disabling wpa_supplicant and the wifimonitor monitoring thread.
And send the command to wpa_supplicant, while wifimonitor is responsible for receiving Event Notifications from wpa_supplicant.
Connect to AP
1. Enable WiFi
Wirelesssettings configures the wifienabler to process the WiFi button during initialization,
Private void inittoggles (){
Mwifienabler = new wifienabler (
This,
(Wifimanager) getsystemservice (wifi_service ),
(Checkboxpreference) findpreference (key_toggle_wifi ));
When the user presses the WiFi button, Android will call the onpreferencechange of wifienabler, and then the wifienabler
Call the setwifienabled interface function of wifimanager. Through aidl, wifiservice actually calls
Setwifienabled function, wifiservice then sends a message_enable_wifi message to itself, in
The real enable work is done in the code that processes the message: First load the WiFi kernel module (the location of the module is hard-coded
"/System/lib/modules/WLAN. Ko"), and then start wpa_supplicant (the hardcoded configuration file is
"/Data/MISC/WiFi/wpa_supplicant.conf") and then start monitoring in wifimonitor through wifistatetracker
,
Thread.
Private Boolean setwifienabledblocking (Boolean enable ){
Final int eventualwifistate = Enable? Wifi_state_enabled:
Wifi_state_disabled;
Updatewifistate (enable? Wifi_state_enabling: wifi_state_disabling );
If (enable ){
If (! Wifinative. loaddriver ()){
Log. E (TAG, "failed to load wi-fi Driver .");
Updatewifistate (wifi_state_unknown );
Return false;
}
If (! Wifinative. startsupplicant ()){
Wifinative. unloaddriver ();
Log. E (TAG, "failed to start supplicant daemon .");
Updatewifistate (wifi_state_unknown );
Return false;
}
Mwifistatetracker. starteventloop ();
}
// Success!
Persistwifienabled (enable );
Updatewifistate (eventualwifistate );
Return true;
}
When the enabling succeeds, the intent wifi_state_changed_action will be broadcast to notify the outside WiFi
It has been successfully performed. When wifienabler is created, it will be collected to the android book
Wifi_state_changed_action, so it receives the intent and starts scanning.
Private void handlewifistatechanged (INT wifistate ){
If (wifistate = wifi_state_enabled ){
Loadconfiguredaccesspoints ();
Attemptscan ();
}
2. Find the AP
The scanning entry function is startscan of wifiservice, which actually sends scan messages to wpa_supplicant.
.
Static jboolean android_net_wifi_scancommand (jnienv * ENV, jobjectclazz)
{
Jboolean result;
// Ignore any error from setting the scan mode.
// The scan will still work.
(Void) dobooleancommand ("Driver scan-active", "OK ");
Result = dobooleancommand ("scan", "OK ");
(Void) dobooleancommand ("Driver scan-Passive", "OK ");
Return result;
}
After wpa_supplicant processes the scan command, it sends an event notification to the control channel to complete the scan.
The wifi_wait_for_event function will receive this event, so the monitorthread in the wifimonitor will be executed
This event,
Void handleevent (INT event, string remainder ){
Case scan_results:
Mwifistatetracker. yyscanresultsavailable ();
Break;
Wifistatetracker then broadcasts the intent scan_results_available_action.
Case event_scan_results_available:
Mcontext. sendbroadcast (New
Intent (wifimanager. scan_results_available_action ));
Wifilayer registers the intent that receives scan_results_available_action.
The handlescanresultsavailable processing function is called. In this function, the result of scan is obtained first (
The scan_result command is sent to wpa_supplicant and the return value is read ),
List <scanresult> List = mwifimanager. getscanresults ();
For each AP returned by a scan, wifilayer calls the onaccesspointsetchanged function of wifisettings,
Then, the AP is added to the GUI display list.
Public void onaccesspointsetchanged (accesspointstate AP, booleanadded ){
Accesspointpreference Pref = maps. Get (AP );
If (Added ){
If (Pref = NULL ){
Pref = new accesspointpreference (this, AP );
Maps. Put (AP, Pref );
} Else {
Pref. setenabled (true );
}
Mapcategory. addpreference (Pref );
}
}
3. Configure AP Parameters
After you select an AP on the wifisettings interface, a dialog box for configuring AP parameters is displayed,
Public Boolean onpreferencetreeclick (preferencescreenpreferencescreen, preference
Preference ){
If (preference instanceof accesspointpreference ){
Accesspointstate state = (accesspointpreference)
Preference). getaccesspointstate ();
Showaccesspointdialog (State, accesspointdialog. mode_info );
}
}
4. Connection
After you select the encryption method and enter the key in acesspointdialog, click Connect. Android
Connect to the AP.
Private void handleconnect (){
String Password = getenteredpassword ();
If (! Textutils. isempty (password )){
Mstate. setpassword (password );
}
Mwifilayer. connecttonetwork (mstate );
}
Wifilayer first checks whether the AP has been configured before, and sends a message to wpa_supplicant.
The list_network command and compare the returned values,
// Need wificonfiguration for the AP
Wificonfiguration Config = findconfigurednetwork (State );
If wpa_supplicant does not have the configuration information of this AP, it will send add_network to wpa_supplicant
Command to add the AP,
If (Config = NULL ){
// Connecting for the first time, need to create it
Config = addconfiguration (state,
Add_configuration_enable | add_configuration_save );
}
The add_network command returns an ID, and the wifilayer uses the returned ID as a parameter
Wpa_supplicant sends the enable_network command to connect wpa_supplicant to the AP.
// Make sure that network is enabled, and disable others
Mreenableapsonnetworkstatechange = true;
If (! Mwifimanager. enablenetwork (State. networkid, true )){
Log. E (TAG, "cocould not enable network ID" + state. networkid );
Error (R. String. error_connecting );
Return false;
}
5. Configure the IP address
After wpa_supplicant successfully connects to the AP, it will send an event notification to the control channel to connect to the AP.
The wifi_wait_for_event function will receive this event, so the monitorthread in the wifimonitor will be executed
This event,
Void handleevent (INT event, string remainder ){
Case connected:
Handlenetworkstatechange (networkinfo. detailedstate. connected,
Remainder );
Break;
Wifimonitor then calls the policystatechange of wifistatetracker.
Send the event_dhcp_start message to start DHCP to obtain the IP address,
Private void handleconnectedstate (){
Setpolltimer ();
Mlastsignallevel =-1;
If (! Mhaveipaddress &&! Mobtainingipaddress ){
Mobtainingipaddress = true;
Mdhcptarget. obtainmessage (event_dhcp_start). sendtotarget ();
}
}
Then broadcast and send the network_state_changed_action intent.
Case event_network_state_changed:
If (result. State! = Detailedstate. Disconnected |! Mdisconnectpending ){
Intent = new
Intent (wifimanager. network_state_changed_action );
Intent. putextra (wifimanager. extra_network_info,
Mnetworkinfo );
If (result. bssid! = NULL)
Intent. putextra (wifimanager. extra_bssid, result. bssid );
Mcontext. sendstickybroadcast (intent );
}
Break;
Wifilayer registers the intent that receives network_state_changed_action.
Handlenetworkstatechanged will be called,
After DHCP receives the IP address, it will send the event_dhcp_succeeded message,
Private class dhcphandler extends handler {
Public void handlemessage (Message MSG ){
Switch (msg. What ){
Case event_dhcp_start:
If (networkutils. rundhcp (minterfacename, mdhcpinfo )){
Event = event_dhcp_succeeded;
}
Wifilayer handles event_dhcp_succeeded message and sends it to the broadcasting system again.
Network_state_changed_action intent, which carries the complete IP address information this time.
Case event_dhcp_succeeded:
Mwifiinfo. setipaddress (mdhcpinfo. IPaddress );
Setdetailedstate (detailedstate. Connected );
Intent = new
Intent (wifimanager. network_state_changed_action );
Intent. putextra (wifimanager. extra_network_info, mnetworkinfo );
Mcontext. sendstickybroadcast (intent );
Break;
So far, the entire connection process has been completed.
Problem:
The current implementation does not support the ad-hoc method.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.