1、确认wifi 工作是否正常
wifi打不开的问题:就要确认wifi 模块加载是否正常;
Wifi连接过程的问题:wifi扫描不到AP,连接不上AP等,需要从wpa_supplicant查找问题。
1.1 确认wifi 驱动模块加载是否正常
1)由于72平台wifi 模块是开机后自动加载:init.project.rc 中:insmod /system/lib/modules/mtk_wmt_wifi.ko
如果wifi insmod 成功,可以通过adb shell 看到相应设备:cat /proc/devices 看到:
如果看到该设备,说明wifi设备模块已经加载到kernel中了,开机后打开wifi
1) 当上层打开wifi后,上层会向下层发指令,到mtk_wmt_wifi.ko中去打开wifi 驱动。 init.project.rc 中 :mknod /dev/wmtWifi c 153 0
开机后创建一个wmtWifi文件结点 主设备号为153 次设备号0 正好与wifi 模块设备号关连起来,这样上层对wifi的操作就直接对wmtWifi 文件结点,通过该文件结点去操作mt_wmt_WIFI_chrdev设备
通过adb shell 查看/dev/wmtWifi文件结点
1.2 Wifi 连接过程中的问题,在wpa_supplicant中定位问题,通过main_log(或者logcat)信息确认wifi的状态
手机要连接上一个AP要走下面一个流程:
wlan0: State: DISCONNECTED -> DISCONNECTED
wlan0: State: DISCONNECTED -> SCANNING
wlan0: State: SCANNING -> ASSOCIATING
wlan0: State: ASSOCIATING -> ASSOCIATED
wlan0: State: ASSOCIATED -> 4WAY_HANDSHAKE
wlan0: State: 4WAY_HANDSHAKE -> 4WAY_HANDSHAKE
wlan0: State: 4WAY_HANDSHAKE -> GROUP_HANDSHAKE
wlan0: State: GROUP_HANDSHAKE -> COMPLETED
1)wlan0: State: DISCONNECTED -> DISCONNECTED
Wap_supplicant 初始化
2)wlan0: State: DISCONNECTED -> SCANNING
进入扫描状态:
通过搜索wlan0: BSS: Start scan resul:看到扫描到可以用的AP
wlan0: BSS: Add new id 0 BSSID 02:08:22:ea:d4:ff SSID 'f'
wlan0: BSS: Add new id 1 BSSID 38:83:45:72:96:ae SSID 'wingtech-009'
wlan0: BSS: Add new id 2 BSSID d8:5d:4c:36:d8:22 SSID 'zz'
wlan0: BSS: Add new id 3 BSSID f4:ec:38:42:5b:a6 SSID 'wingtech-gao'
......
在我们手机界面看到可用AP列表就是这扫描到的SSID 名字
3)wlan0: State: SCANNING -> ASSOCIATING
wlan0: State: ASSOCIATING -> ASSOCIATED
该过程是我们从所显示的AP 列表中去选择一个AP进行连接(AP 关连阶段)
4)wlan0: State: ASSOCIATED -> 4WAY_HANDSHAKE
wlan0: State: 4WAY_HANDSHAKE -> 4WAY_HANDSHAKE
密码校验过程:该过程是我们选择一个AP,输入密码点击连接按钮后,进行密码校验,如果AP密码不正确,就会停止在该状态,(这个就是我们平时经常遇到的,输入密码不正确时,连接不上AP的状态)
5)wlan0: State: 4WAY_HANDSHAKE -> GROUP_HANDSHAKE
密码验证通过后才会进入该状态
6)wlan0: State: GROUP_HANDSHAKE -> COMPLETED
表示,AP 连结成功。
在wifi 连接过程中出的问题,我们都可以通过以上几个状态变化,来定位问题的出处。
2、Wifi 驱动启动
2.1 wifi 驱动模块:编译生成mtk_wmt_wifi.ko
1)代码路径:mediatek\kernel\drivers\conn_soc\common\linux\pub\ wmt_chrdev_wifi.c
该模块初始化时,会向平台注册一个主设备号为153,
dev_t dev = MKDEV(WIFI_major, 0); // WIFI_major==153
alloc_ret = register_chrdev_region(dev, 1, WIFI_DRIVER_NAME);
cdev_init(&WIFI_cdev, &WIFI_fops);
WIFI_cdev.owner = THIS_MODULE;
cdev_err = cdev_add(&WIFI_cdev, dev, WIFI_devs);
2)该模块结构如下:
.open = WIFI_open,
.release = WIFI_close,
.write = WIFI_write,
该模块加载后,当上层打开wifi时加载驱动时,就会向下发指令,接收到指令通过WIFI_writ 去加载驱动
2.2 frameworks 涉及到的代码
1)代码路径:
alps\frameworks\base\services\java\com\android\server
alps\frameworks\base\wifi\java\android\net\wifi
在WifiManager.java 中通过setWifiEnabled函数打开wifi 会调用WifiService.java中的setWifiEnabled
public synchronized boolean setWifiEnabled(boolean enable) {
......
mWifiStateMachine.setWifiEnabled(enable);
......
}
最终会调用到WifiStateMachine.java中打开wifi ,wifi的大部分状态变化都是在该文件中进行的
2)在WifiStateMachine.java 中会两个信息,
public void setWifiEnabled(boolean enable) {
......
sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));
sendMessage(CMD_START_SUPPLICANT);
......
}
CMD_LOAD_DRIVER加载驱动,CMD_START_SUPPLICANT 启动wpa_supplicant
3)wifi的状态机中,会对上面的消息进行处理的,首先会在InitialState状态中判断isDriverLoaded,如果没有加载,就会进入DriverUnloadedState状态中去,在该状态中会对CMD_LOAD_DRIVER消息进行处理,转入DriverLoadingState状态中,在该状态中会去加载驱动if (mWifiNative.loadDriver()
4)有上面的函数,进入WifiNative.java中public native static boolean loadDriver();
5)通过JNI 调用到 hardware 层
android_net_wifi_Wifi.cpp中android_net_wifi_loadDriver函数
static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject)
{
.....
return (jboolean)(::wifi_load_driver() == 0);
}
6)hardware层中接着去加载驱动,在mtk_wifi.c中的wifi_load_driver()函数进行处理:
int wifi_load_driver()
{
//由于 6572开机后就开始加载wifi 模块,所以前面的代码都没走到
......
if(0 > wifi_set_power(1))
return -1;
......
}
wifi_set_power(1)--> halDoCommand("load wifi");通过socket发送“load wifi”指令给wifi 设备 要求打开wifi
7)external\mtk_wifi\hald\ CommandListener.cpp中,通过socket 收到“load wifi”,过滤出“load ”进入loadDriver()
int CommandListener::HaldCmd::runCommand(SocketClient *cli, int argc, char **argv) {
int rc = 0;
......
}
ALOGD("======Receive cmd======");
ALOGD("cmd <%s %s>", argv[1], argv[2]);
//Load xxx driver
if (!strcmp(argv[1], "load")) {
pthread_mutex_lock(&mLock);
rc = sHaldCtrl->loadDriver(argv[2]);
pthread_mutex_unlock(&mLock);
......
8)HaldController.cpp 中
nt HaldController::loadDriver(const char *ifname){
......
/*LOAD WIFI*/
if (!strcmp(ifname, "wifi")) {
......
ALOGD("Start load wifi driver.");
/*load wifi driver*/
sDriverCtrl->load(NETWORK_IFACE_WIFI);
/*turn on wifi power*/
if(0 > powerOn())
return -1;
......
}
......
9)调用powerOn()
int HaldController::powerOn() {
ALOGD("Power on wlan.");
return (setPower(1));
}
====》
nt HaldController::setPower(int enable) {
......
const char buffer = (enable ? '1' : '0');
fd = open(WIFI_POWER_PATH, O_WRONLY); //
// #define WIFI_POWER_PATH "/dev/wmtWifi"
if (fd < 0) {
ALOGE("Open \"%s\" failed", WIFI_POWER_PATH);
goto out;
}
sz = write(fd, &buffer, 1);
......
可以看到最终是把enable值写入wifi 设备结点(/dev/wmtWifi)
10)通过向设备结点上写入值后,会在该结点的关联的wifi 驱动代码中找到相应的处理。
wmt_chrdev_wifi.c 中
struct file_operations WIFI_fops = {
.open = WIFI_open,
.release = WIFI_close,
.write = WIFI_write,
};
ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
......
if (count > 0) {
if (0 == copy_from_user(local, buf, (count > 4) ? 4 : count)) {
WIFI_INFO_FUNC("WIFI_write %c\n", local[0]);
if (local[0] == '0' && opened == 1) {
//关闭wifi
if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI)) {
WIFI_INFO_FUNC("WMT turn off WIFI fail!\n");
}
......
}
//打开wifi
else if (local[0] == '1') {
if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) {
WIFI_WARN_FUNC("WMT turn on WIFI fail!\n");
}
3、wap_supplicant的启动
wifi驱动加载完成后,接着就去启动wap_supplicant
3.1 frameworks层流程和wifi驱动的流程是一样的
在WifiStateMachine.java中wifi驱动加载成功后会发一个成功的消息:
if (mWifiNative.loadDriver()) {
......
sendMessage(CMD_LOAD_DRIVER_SUCCESS);
......
在该状态的处理函数中收到CMD_LOAD_DRIVER_SUCCESS消息后就会转到DriverLoadedState状态中去,在该状态才去处理CMD_START_SUPPLICANT(该消息是在:setWifiEnabled是就发出两个消息中的一个,在wifi驱动成功后才对该消息处理)。
class DriverLoadedState extends State {
......
public boolean processMessage(Message message) {
......
case CMD_START_SUPPLICANT:
try {
mNwService.wifiFirmwareReload(mInterfaceName, "STA");
//加载wifif firmware
......
try {
......
mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
......
if (mWifiNative.startSupplicant(mP2pSupported)) {
......
3.2 JNI 传送到hardware层
mWifiNative.startSupplicant(mP2pSupported)-> WifiNative.java(startSupplicant)-> android_net_wifi_Wifi.cpp(android_net_wifi_startSupplicant) :
static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject, jboolean p2pSupported)
{
return (jboolean)(::wifi_start_supplicant(p2pSupported) == 0);
}
3.3 hardware层:
mtk_wifi.c中,wifi_start_supplicant函数:
int wifi_start_supplicant(int p2p_supported)
{
......
ALOGD("Start \"%s\"", supplicant_name);
property_set("ctl.start", supplicant_name);
sched_yield();
......
}
通过设置 wap_supplicant网络端口的属性来启动wap_supplicant ,
3.4 通过属性来启动wap_suppkciant 是因为在开机后,我们已经启动了 wap_supplicant服务了,只是默认设置为disabled,
init.rc
service wpa_supplicant /system/bin/logwrapper /system/bin/wpa_supplicant \
-iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf -e/data/misc/wifi/entropy.bin -ddd
# we will start as root and wpa_supplicant will switch to user wifi
# after setting up the capabilities required for WEXT
# user wifi
# group wifi inet keystore
class main
socket wpa_wlan0 dgram 660 wifi wifi
disabled
oneshot
4、有关wpa_supplciant
wpa_supplciant代码是开源的,wpa_supplicant用来管理无线网络的:wifi 的网络搜索,建立连接,加密等都由wap_supplicant 来处理的,当wpa_supplicant启动后,wifi上层代码framework层 通过调用wifinativ.java 中的函数接口,会向下层发指令(SCAN 扫描,ADD_NETWORK添加网络等):WifiNative.java(函数接口)->mtk_wifi.c(wifi_command) -> ctrl_iface.c(是通过socket 实现的,)->Wpa_suppliant通过ioctl->wifi驱动
5、wifi出现的问题
5.1 有GSM包异常,引起“打开wifi下待机电流大“:可以通过逐步删除GSM中的apk,进行确认。例如:98511项目 由于客户提供的GoogleServicesFramework.apk有问题,引起的“打开wifi待机电流大“。
5.2 wifi 降低功率:在alps\wingcust\xxxxxx\base\custom\cgen\cfgdefault\CFG_WIFI_Default.h中修改
WIFI_CFG_PARAM_STRUCT stWifiCfgDefault =
{
0x0104, /* Own Version For MT6628*/
0x0000, /* Peer Version */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* MAC ADDRESS */
{ 0x00, 0x00 }, /* COUNTRY CODE */
{ 0x1e, 0x00, { 0x00, 0x00 }, /*cTxPwr2G4Cck*/ /*cTxPwr2G4Dsss*/
0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, /*cTxPwr2G4OFDM*/
0x1a, 0x1a,0x1a,0x1a, 0x1a, 0x1a, /*cTxPwr2G4HT20*/
0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, /*cTxPwr2G4HT40*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*cTxPwr5GOFDM*/
......
修改该文件,需要手机格式化下载,才能生效
5.3 wifi 第一信道比其他的信道接收功率低:在alps\wingcust\xxxxxx\base\custom\cgen\cfgdefault\CFG_WIFI_Default.h
WIFI_CFG_PARAM_STRUCT stWifiCfgDefault =
{
......
0x00, // 5G band is unsupported
0x01, // 2.4GHz band edge power disabled 修改为0x00
0x26, // cBandEdgeMaxPwrCCK
......
修改该文件,需要手机格式化下载,才能生效
5.4 mac地址:Wifi 工厂模式下测试失败,首先要确认wifi mac地址是否存在

187

被折叠的 条评论
为什么被折叠?



