wifihal的实现原理

modified: make/target/product/base_system.mk //这次添加JNI的时候,单边模块是可以生成的jni的库的,但是,整编就是不能生成. 最后,在这个MK文件中添加JNI的模块名,结果还是生成了的.
— a/make/target/product/base_system.mk
+++ b/make/target/product/base_system.mk
@@ -273,6 +273,7 @@ PRODUCT_PACKAGES +=
wificond
wifi.rc
wm \

  • libwifi-service \

( w a r n i n g C F G T E E S U P P O R T = (warning CFG_TEE_SUPPORT= (warningCFGTEESUPPORT=(CFG_TEE_SUPPORT))  //在MAKEFILE中添加LOG

typedef enum {
WIFI_POWER_SCENARIO_INVALID = -2,
WIFI_POWER_SCENARIO_DEFAULT = -1, //wifi_reset_tx_power_scenario
WIFI_POWER_SCENARIO_VOICE_CALL = 0,
WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF = 1,
WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON = 2,
WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF = 3,
WIFI_POWER_SCENARIO_ON_BODY_CELL_ON = 4,
WIFI_POWER_SCENARIO_ON_BODY_BT = 5,
} wifi_power_scenario;

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/u614/android/vendor/mediatek/kernel_modules/connectivity/wlan/core/gen4m/os/linux/gl_init.c //kernel的调用
TINNO_SYSTEM_PROPERTY_OVERRIDES += persist.tinno.sar=true

/* Set Tx Power Scenario */ //初始化命令CMD以及对应的回调函数
{
	{
		.vendor_id = GOOGLE_OUI,
		.subcmd = WIFI_SUBCMD_SELECT_TX_POWER_SCENARIO//CMD 命令
	},
	.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
			WIPHY_VENDOR_CMD_NEED_NETDEV,
	.doit = mtk_cfg80211_vendor_set_tx_power_scenario //CMD 命令调用回调函数 在kernel里实现的++++++++++++++++++++++++++

#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE
,
.policy = VENDOR_CMD_RAW_DATA
#endif
},

/u614/android/vendor/mediatek/proprietary/hardware/connectivity/wlan/wifi_hal/wifi_hal.cpp
class SelectTxPowerCommand : public WifiCommand { //定义了一个SelectTxPowerCommand
private:
int mScenario;
public:
SelectTxPowerCommand(wifi_interface_handle handle, int scenario)
: WifiCommand(“SelectTxPowerCommand”, handle, 0) {
mScenario = scenario;
}
virtual int create() {
int ret;

      ret = mMsg.create(GOOGLE_OUI, WIFI_SUBCMD_SELECT_TX_POWER_SCENARIO); //创建CMD 命令
      if (ret < 0) {
           ALOGE("Can't create message to send to driver - %d", ret);
           return ret;
      }

      nlattr *data = mMsg.attr_start(NL80211_ATTR_VENDOR_DATA);
      if (!data) {
          ALOGE("Failed attr_start for VENDOR_DATA");
          return WIFI_ERROR_UNKNOWN;
      }

      ret = mMsg.put_u32(WIFI_ATTRIBUTE_TX_POWER_SCENARIO, mScenario); //启动CMD 命令
      if (ret < 0) {
          ALOGE("Failed to put TX_POWER_SCENARIO");
          return ret;
      }

      mMsg.attr_end(data);
      return WIFI_SUCCESS;
  }

};

/u614/android/vendor/mediatek/proprietary/hardware/connectivity/wlan/wifi_hal/wifi_hal.cpp  //wifi_hal的调用
wifi_error wifi_select_tx_power_scenario(wifi_interface_handle handle,
wifi_power_scenario scenario)
{
ALOGI(“Select tx power scenario %d”, scenario);
SelectTxPowerCommand command(handle, scenario); //实例化了上面定义的类SelectTxPowerCommand 用于设置tx_power
return (wifi_error) command.requestResponse();
}
wifi_error wifi_reset_tx_power_scenario(wifi_interface_handle handle)
{
ALOGI(“Reset tx power scenario”);
SelectTxPowerCommand command(handle, -1); //实例化了上面定义的类SelectTxPowerCommand 用于恢复reset_tx_power
return (wifi_error) command.requestResponse();
}

=============================================

/u614/android/hardware/interfaces/wifi/1.4/default/wifi_legacy_hal.cpp
wifi_error WifiLegacyHal::selectTxPowerScenario(const std::string& iface_name,
wifi_power_scenario scenario) {  //legacy_hal的调用
return global_func_table_.wifi_select_tx_power_scenario(
getIfaceHandle(iface_name), scenario);
}

/u614/android/hardware/interfaces/wifi/1.4/default/wifi_chip.cpp
WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(
TxPowerScenario scenario) {
LOG(DEBUG) << “zgs 1.4-default-wifiChip-selectTxPowerScenarioInternal_1_2”;
auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
getFirstActiveWlanIfaceName(),

    hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario)); //将HIDL的调用转换为legacy_hal的调用
return createWifiStatusFromLegacyError(legacy_status);

}
=============================================
我们应该用/u614/android/hardware/interfaces/wifi/1.4/default/ 下面的mediatek的/u614/android/vendor/mediatek/proprietary/hardware/connectivity/wlan/wifi_hidl/1.3/wifi_legacy_hal.cpp是没有用的.但是,这里也说明了, wifi_legacy_hal.cpp 这个文件是存在HIDL服务里的. 这个文件有WifiLegacyHal类的实例化,定义全局变量:global_func_table_. 通过init_wifi_vendor_hal_func_table(&global_func_table_); 这个函数,将类型为wifi_hal_fn (这个类型定义在wifi_hal.h中)的全局变量global_func_table_ 和实际用的wifi_hal.cpp 联系起来.wifi_hal_fn 定义了wifi_hal的函数指针.这些指针最后指向了实际用的wifi_hal.cpp的函数实现.init_wifi_vendor_hal_func_table这个函数的实现是wifi_hal.cpp里的. AOSP本身提供的init_wifi_vendor_hal_func_table这个函数的实现是在/frameworks/opt/net/wifi/libwifi_hal/wifi_hal_fallback.cpp这个文件中.并且,函数的实现只有一句话:return WIFI_ERROR_NOT_SUPPORTED; 同时,/frameworks/opt/net/wifi/libwifi_hal 这个目录就是指定当前系统用的LOCAL_MODULE := libwifi-hal . 为了区别AOSP和MEDIATEK的wifi_hal, 在/android/frameworks/opt/net/wifi/libwifi_hal/Android.mk 这个文件中,通过指定LIB_WIFI_HAL := libwifi-hal-mt66xx 来选择对应的wifi_hal参入编译,最终生成libwifi-hal. libwifi-hal最终是通过作为LOCAL_SHARED_LIBRARIES,参与生成android.hardware.wifi@1.0-service. 这个是在/hardware/interfaces/wifi/1.4/default/Android.mk 这文件中完成的.

/u614/android/hardware/interfaces/wifi/1.4/default/
A D wifi_legacy_hal_stubs.cpp 137 populateStubFor(&hal_fn->wifi_select_tx_power_scenario); in initHalFuncTableWithStubs()
A D wifi_legacy_hal.cpp 806 return global_func_table_.wifi_select_tx_power_scenario( in selectTxPowerScenario()
/u614/android/vendor/mediatek/proprietary/hardware/connectivity/wlan/wifi_hidl/1.3/
A D wifi_legacy_hal_stubs.cpp 137 populateStubFor(&hal_fn->wifi_select_tx_power_scenario); in initHalFuncTableWithStubs()
A D wifi_legacy_hal.cpp 812 return global_func_table_.wifi_select_tx_power_scenario( in selectTxPowerScenario()
WifiLegacyHal类的实例化:
WifiLegacyHal::WifiLegacyHal(
const std::weak_ptr<wifi_system::InterfaceTool> iface_tool)
{}
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

android.bp 放在哪里都可以被识别.但是,在整个项目编译的时候,不一定会编译到,需要将这个模块添加到项目中.
broadcastReceiver 广播是谁注册了,谁接收.
NIC(Network Interface Card)或简称为网卡

error: frameworks/base/services/core/Android.bp:93:13: unrecognized property “jni_libs” ? 生成的native库如何导入?
System.loadLibrary(“wifi-service”);  //加载JNI的LIB库

error: vendor/mediatek/proprietary/frameworks/opt/net/services/Android.bp:18:1: module “mediatek-framework-net” variant “android_common”: depends on //frameworks/opt/net/wifi/service:service-wifi which is not visible to this module
error: frameworks/opt/net/wifi/service/Android.bp:128:15: module “service-wifi”: visibility: “//vendor/mediatek/proprietary/frameworks/opt/net/services/core/java/com/android/server” is not allowed. Packages outside //vendor cannot make themselves visible to specific targets within //vendor, they can only use //vendor:subpackages.

error: frameworks/base/services/core/Android.bp:75:1: module “services.core.unboosted” variant “android_common”: depends on //frameworks/opt/net/wifi/service:service-wifi which is not visible to this module

/u614/android/frameworks/base/services/core/java/com/mediatek/server/display/MtkWifiDisplayController.java  //java 反射的应用.
import java.lang.reflect.Field;
import java.lang.reflect.Method;
try {
// Get WifiInjector
Method method = Class.forName(
“com.android.server.wifi.WifiInjector”, false,
this.getClass().getClassLoader()).getDeclaredMethod(“getInstance”);
method.setAccessible(true);
Object wi = method.invoke(null);
// Get WifiStatemachine

private void sendStickyBroadcastToAll(Intent intent) {
    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
    final long ident = Binder.clearCallingIdentity();
    try {
        mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
    } finally {
        Binder.restoreCallingIdentity(ident);
    }
}