Android系统硬件抽象层原理与实现之WIFI

AI使用指南:6个超实用的Prompt提示词模板 最近越来越多人开始接触AI,但其实想要让AI更懂你,关键是掌握对的提示词模板!今天就给大家分享6种超实用的Prompt提示词模板,不管你是小白还是老手都能用 阅读详情

作者:朱克锋

转载请注明出处:http://blog.youkuaiyun.com/linux_zkf/article/details/7492391

 

Android系统硬件抽象层原理与实现之WIFI

本文我将主要分析wifi的硬件抽象层的实现和WPA相关的东西,wifi是一种无线网路通信技术,相关的介绍网络上有很多,介绍的也很全面,这里我就不在过多的介绍了,作为一种无线网络产品,其在android系统中也有其功能体现。

在android系统中wifi系统包括:linux kernel 中的驱动,协议,本地部分,java框架。本文主要介绍的是本地部分也就是HAL层的实现

首先看看wifi在android系统中的结构:

 

WIFI APP

 

FRAMEWORK

 

JNI

 

WIFI HAL

 

WPA

 

DRIVER + PROTOCOL

 

由上图可以看出wifi本地部分主要是HAL+WPA两部分,其中HAL部分对上层提供接口,并且与WPA交互,最终具体的实现是有WPA层实现的,可以说WIFI HAL是一个适配层更加合适。

 Wifi硬件抽象层代码在源码种的位置:

hardware/libhardware_legacy/wifi/wifi.c

hardware/libhardware_legacy/include/libhardware_legacy/wifi.h

wpa在external/wpa_supplicant/

 

整个WIFIHAL实现都很简单,都是对wpa_supplicant的操作和使用,如果需要自己实现WIFIHAL可以参考wifi.c来实现wifi.h中所定义的接口,并且设置驱动的路径、名称、模块的名称等参数,具体操作都将由wpa_supplicant来完成。

其中wifi.h定义了Android系统中WIFI硬件抽象层接口,wifi.h定义

//装载wifi驱动

int wifi_load_driver();

//缷载wifi驱动

int wifi_unload_driver();

//开始、停止supplicant

int wifi_start_supplicant();

int wifi_stop_supplicant();

//连接supplicant

int wifi_connect_to_supplicant();

//关闭supplicant连接

voidwifi_close_supplicant_connection();

int wifi_wait_for_event(char *buf,size_t len);

int wifi_command(const char *command,char *reply, size_t *reply_len);

// DHCP请求

int do_dhcp_request(int *ipaddr, int*gateway, int *mask, int *dns1, int *dns2, int *server, int *lease);

const char *get_dhcp_error_string();

操作接口都很简单,其中比较重要的是wifi_wait_for_event和wifi_command函数,前者用于接收wpa_supplicant上报的事件,而后者用于向wpa_supplicant进程发送命令.

下面来看看wifi_wait_for_event的实现

int wifi_wait_for_event(char *buf, size_t buflen)

{

   size_t nread = buflen - 1;

   int fd;

   fd_set rfds;

   int result;

   struct timeval tval;

   struct timeval *tptr;

 

   if (monitor_conn == NULL) {

       LOGD("Connection closed\n");

       strncpy(buf, WPA_EVENT_TERMINATING " - connection closed", buflen-1);

       buf[buflen-1] = '\0';

       return strlen(buf);

   }

 

   result = wifi_ctrl_recv(monitor_conn, buf, &nread);

   if (result < 0) {

       LOGD("wifi_ctrl_recv failed: %s\n", strerror(errno));

       strncpy(buf, WPA_EVENT_TERMINATING " - recv error", buflen-1);

       buf[buflen-1] = '\0';

       return strlen(buf);

   }

   buf[nread] = '\0';

   /* LOGD("wait_for_event: result=%d nread=%d string=\"%s\"\n", result, nread, buf); */

   /* Check for EOF on the socket */

   if (result == 0 && nread == 0) {

       /* Fabricate an event to pass up */

       LOGD("Received EOF on supplicant socket\n");

       strncpy(buf, WPA_EVENT_TERMINATING " - signal 0 received", buflen-1);

       buf[buflen-1] = '\0';

       return strlen(buf);

   }

   /*

    * Events strings are in the format

    *

    *     <N>CTRL-EVENT-XXX

    *

    * where N is the message level in numerical form (0=VERBOSE, 1=DEBUG,

    * etc.) and XXX is the event name. The level information is not useful

    * to us, so strip it off.

    */

   if (buf[0] == '<') {

       char *match = strchr(buf, '>');

       if (match != NULL) {

           nread -= (match+1-buf);

           memmove(buf, match+1, nread+1);

       }

   }

   return nread;

}

int wifi_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len)

{

   int res;

   int ctrlfd = wpa_ctrl_get_fd(ctrl);

   struct pollfd rfds[2];

 

   memset(rfds, 0, 2 * sizeof(struct pollfd));

   rfds[0].fd = ctrlfd;

   rfds[0].events |= POLLIN;

   rfds[1].fd = exit_sockets[1];

   rfds[1].events |= POLLIN;

   res = poll(rfds, 2, -1);

   if (res < 0) {

       LOGE("Error poll = %d", res);

       return res;

   }

   if (rfds[0].revents & POLLIN) {

       return wpa_ctrl_recv(ctrl, reply, reply_len);

   } else {

       LOGD("Received on exit socket, terminate");

       return -1;

   }

   return 0;

}

 

其中wifi_ctrl_recv中的wpa_ctrl_recv(ctrl, reply, reply_len)是wpa_ctrl提供的wpa_ctrl_recv接口,来接收事件。

wifi_command函数,用于向wpa_supplicant进程发送命令

int wifi_command(const char *command, char *reply, size_t *reply_len)

{

   return wifi_send_command(ctrl_conn, command, reply, reply_len);

}

wifi_command函数会调用wifi_send_command来实现命令的发送,发送过程同样使用wpa_ctrl提供的wpa_ctrl_request接口来完成

 

int wifi_send_command(struct wpa_ctrl *ctrl, const char *cmd, char *reply, size_t *reply_len)

{

   int ret;

 

   if (ctrl_conn == NULL) {

       LOGV("Not connected to wpa_supplicant - \"%s\" command dropped.\n", cmd);

       return -1;

   }

   ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), reply, reply_len, NULL);

   if (ret == -2) {

       LOGD("'%s' command timed out.\n", cmd);

       /* unblocks the monitor receive socket for termination */

       write(exit_sockets[0], "T", 1);

       return -2;

   } else if (ret < 0 || strncmp(reply, "FAIL", 4) == 0) {

       return -1;

   }

   if (strncmp(cmd, "PING", 4) == 0) {

       reply[*reply_len] = '\0';

   }

   return 0;

}

 

在wifi.c中还有一点很重要,就是在wifi_connect_to_supplicant函数中调用wpa_ctrl_open函数创建两个socket,一个是ctrlinterface,另一个是 monitorinterface。Monitorinterface用于监测从wpa_supplicant发出的event事件,当两个socket创建成功后,monitorinterface会调用wpa_ctrl_attach函数发送ATTACH到wpa_supplicant模块,wpa_supplicant模块收到后,会将该客户端的socket信息记录下来,用于以后发送事件时用。

 

#define SUPPLICANT_TIMEOUT     3000000  // microseconds

#define SUPPLICANT_TIMEOUT_STEP 100000  // microseconds

int wifi_connect_to_supplicant()

{

   char ifname[256];

   char supp_status[PROPERTY_VALUE_MAX] = {'\0'};

   int  supplicant_timeout = SUPPLICANT_TIMEOUT;

 

   /* Make sure supplicant is running */

   if (!property_get(SUPP_PROP_NAME, supp_status, NULL)

           || strcmp(supp_status, "running") != 0) {

       LOGE("Supplicant not running, cannot connect");

       return -1;

   }

 

   if (access(IFACE_DIR, F_OK) == 0) {

       snprintf(ifname, sizeof(ifname), "%s/%s", IFACE_DIR, iface);

   } else {

       strlcpy(ifname, iface, sizeof(ifname));

   }

 

   ctrl_conn = wpa_ctrl_open(ifname);

   while (ctrl_conn == NULL && supplicant_timeout > 0) {

       usleep(SUPPLICANT_TIMEOUT_STEP);

       supplicant_timeout -= SUPPLICANT_TIMEOUT_STEP;

       ctrl_conn = wpa_ctrl_open(ifname);

   }

   if (ctrl_conn == NULL) {

       LOGE("1.Unable to open connection to supplicant on \"%s\": %s",

            ifname, strerror(errno));

       return -1;

   }

   monitor_conn = wpa_ctrl_open(ifname);

   if (monitor_conn == NULL) {

       wpa_ctrl_close(ctrl_conn);

       ctrl_conn = NULL;

       LOGE("2. Unable to open connection to supplicant on \"%s\": %s",

            ifname, strerror(errno));       

       return -1;

   }

   if (wpa_ctrl_attach(monitor_conn) != 0) {

       wpa_ctrl_close(monitor_conn);

       wpa_ctrl_close(ctrl_conn);

       ctrl_conn = monitor_conn = NULL;

       return -1;

   }

 

   if (socketpair(AF_UNIX, SOCK_STREAM, 0, exit_sockets) == -1) {

       wpa_ctrl_close(monitor_conn);

       wpa_ctrl_close(ctrl_conn);

       ctrl_conn = monitor_conn = NULL;

       return -1;

   }

 

   return 0;

}

 

在android系统中对wifi驱动的加载与卸载有些特殊注意下面两个方法

 

static int insmod(const char *filename, const char *args)

{

   void *module;

   unsigned int size;

   int ret;

 

   module = load_file(filename, &size);

   if (!module)

       return -1;

 

   ret = init_module(module, size, args);

 

   free(module);

 

   return ret;

}

 

static int rmmod(const char *modname)

{

   int ret = -1;

   int maxtry = 10;

 

   while (maxtry-- > 0) {

       ret = delete_module(modname, O_NONBLOCK | O_EXCL);

       if (ret < 0 && errno == EAGAIN)

           usleep(500000);

       else

           break;

   }

 

   if (ret != 0)

       LOGD("Unable to unload driver module \"%s\": %s\n",

            modname, strerror(errno));

   return ret;

}

一般的驱动都是在系统启动是加在好的而wifi驱动实在使用时加载,不使用时卸载

《C/C++等级考试(1~8级)历届真题解析》专栏总目录 中国电子学会《全国青少年软件编程等级考试》C/C++编程(1~8级)历届真题解析。订阅后可阅读专栏内所有真题解析,真题持续更新中! 阅读详情

相关推荐

LTspice introduction - 2 LTspice的界面

LTspice的界面主要有两个:Schematic Capture和Waveform Viewer Schematic Capture 它主要是用来画电路图的,画完电路图之后,添加一些dot 命令同时选择一些仿真的参数,点击执行(Run)Waveform Viewer 如果你的仿真不是op point的话,一个都会打开它,在它里面你可以画图相应的图形。 有两种方式可以在Viewer

贾亮的专栏 3220

wpa_supplicant--EVENT 分析

wifiMonitor Event 前面的章节已经大致介绍了wifiMonitor的作用,在wifi工作过程中,会产生一些交换的消息,这个时候在wifiMonitor里面会有一个线程运行: String eventStr = WifiNative.waitForEvent();轮询一直等到消息的到来。下面是所有的事件: /** All eventscoming from the supplic

ltm157的专栏 7595

别再死记硬背参数了!用ADS手把手教你仿真一个4GHz镜像抑制混频器(附完整工程文件)

本文详细解析了4GHz镜像抑制混频器的ADS仿真全流程,从理论到实践,涵盖混频器设计基础、ADS工程搭建、二极管选型、非线性仿真及性能优化。通过实战案例,帮助工程师掌握关键参数平衡与调试技巧,提升射频电路设计效率。

weixin_42552716的博客 338

Linux(树莓派)系统中判断WiFi是否连接上路由器的方法

之前(https://blog.youkuaiyun.com/u010299133/article/details/105823339)介绍过在Linux系统中使用wpa_supplicant连接到指定的WiFi路由器的方法,现在需要判断是否连接上路由器,以及如何获取因为WiFi密码错误造成的无法连接路由器的方法。大致思路是在使用wpa_suppliant工具连接WiFi路由器的时候使用参数(-f )指定一个log文件存放的路径文件。如:-f /tmp/wpa.log。

仗劍走天涯 5927

带有验证码的爆破(包含Burp suite工具爆破)

关于含有验证码爆破的一些总结!

weixin_43960066的博客 8693

HFSS实战项目——基片集成波导(SIW)带通滤波器

设计了一款直接耦合的SIW带通滤波器, 采用直接耦合的形式, 工作频率覆盖19~21 GHz, 通带内插入损耗小于1.5 dB, 回波损耗小于-20 dB, 带外抑制特性良好.

2401_87464239的博客 4896

android wifi子系统

orgin link is as the below: http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=23602891&id=3333288 --------------------------------------------------------------------------------------

yipie的专栏 2135

【WLAN】【基础知识】WIFI那些事儿之AP扫描周边AP和STA

如本文对你有些许帮助,欢迎大佬打赏: 支付宝及微信打赏方式

一介草民,只为生活。 2882

wpa_supplicant 状态机的切换以及事件驱动

[cpp] view plain copyWIFI事件类型  pre-shared key may be incorrect  认证密码错误  EVENT_ASSOC_TIMED_OUT 连接超时  EVENT_AUTH_TIMED_OUT  认证超时  EVENT_SCAN_RESULTS 扫描完成,返回扫描结果  EVENT_AUTH 认证完成事件  EVENT_DEAUTH 认证解除  EV...

蓝精灵的专栏 7446

基于 Qt C++ 的智能工厂数字孪生系统

你想要实现一个基于 Qt C++ 的智能工厂数字孪生系统,核心是 **Qt 3D** 场景搭建 + **实时数据驱动** 设备模型。下面我将为你提供一个完整的解决方案,包含 **核心思路、实现步骤、完整代码示例** 和 **注意事项**。| **渲染层** | 3D 场景搭建、设备模型加载、实时动画渲染、用户交互。| **业务逻辑层** | 数据处理(滤波、转换)、设备状态管理、动画逻辑控制。| **数据层** | 实时采集设备数据(如传感器、PLC、MES 系统),提供数据接口。

寒寒豆豆软件公司的博客 193

基于Simulink的占空比调制DTC降低转矩脉动

修改传统SVPWM模块,输入占空比d和有效矢量索引,计算Ton​=d∗Tc​、Toff​=(1−d)∗Tc​,生成对称PWM波形(替代开关表直接输出)。:低速时(n<500rpm)减小dmax​=0.6(避免磁链畸变),高速时(n>2000rpm)增大dmax​=0.8(提升动态响应);kT​/kψ​:转矩/磁链误差增益(需整定,如kT​=0.02/(N⋅m),kψ​=0.1/Wb);(θ为电压矢量与磁链夹角)。② SVM-DTC(占空比计算模块启用,d0​=0.5,kT​=0.02,kψ​=0.1)。

amy_mhd的博客 87

Android Wi-Fi源码分析之WifiService操作Wi-Fi(一):分析Wifi.c中的wifi_load_driver()函数

Wi-Fi源码分析之WifiService操作Wi-Fi(一)分析Wifi.c中的wifi_load_driver()函数int wifi_load_driver() { ALOGD("============wifi_load_driver================"); /* WIFI_DRIVER_MODULE_PATH定义wlan driver的文件路径名. 我这里并没

迷之月光的专栏 4266

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Android Wi-Fi 系统硬件抽象层原理与实现

Android系统硬件抽象层原理与实现之WIFI 本文我将主要分析wifi的硬件抽象层的实现和WPA相关的东西,wifi是一种无线网路通信技术,相关的介绍网络上有很多,介绍的也很全面,这里我就不在过多的介绍了,作为一种无线网络产品,其在android系统中也有其功能体现。 在android系统中wifi系统包括:Linux kernel 中的驱动,协议,本地部分,Java框架。本文主要

DonnyCoy 1056

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

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

weixin_38503885的博客 1875

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

4wpa_supplicant适配层 -- 详解

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33912453的博客 171

Android系统硬件抽象层原理与实现之GPS

作者:朱克锋 转载请注明出处:http://blog.youkuaiyun.com/linux_zkf/article/details/7493129   Android系统硬件抽象层原理与实现之GPS 本文我将系统分析一下GPS HAL的实现,GPS大家都很熟悉,原理就不再介绍了。 GPS在android系统中的结构如图   GOS APP

linux_zkf的专栏 2998

Android HAL(硬件抽象层)介绍以及调用

<br />1 HAL简介<br /><br /> Android 的 HAL(Hardware Abstract Layer硬件抽象层)是Google因应厂商「希望不公开源码」的要求下,所推出的新观念,其架构如下图。虽然 HAL 现在的「抽象程度」还不足,现阶段实作还不是全面符合 HAL的架构规划,不过也确实给了我们很好的思考空间。<br /><br /><br /> 图1:Android HAL 架构规划<br /><br /> 这是 Patrick Brady (Google) 在200

Mr.瑞的专栏 2万+

Android系统架构

Android系统架构 Android系统架构分为五层,从下到上依次是应用层、应用框架层、系统运行库层、硬件抽象层和Linux内核层。 应用层(System Apps) 系统内置的应用程序以及非系统级别的应用程序都属于应用层,负责与用户进行直接交互,通常都是用Java进行开发的。 应用框架层(Java API Framework) **应用框架层是为开发人员提供了开发应用程序所需要的API,**我们平时开发应用程序都是调用着一层所提供的API,当然也包括系统应用。这一层是由Java代码编写的,可以称为Ja

xingyu19911016的博客 1万+

安卓系统框架和Framework概述

安卓系统框架和Framework概述

似霰的博客 1万+

例说Android 硬件抽象层

Android系统从宏观上可以看成一个图形系统,类似于QT,迷你GUI等开源的图形用户界面系统。但是android作为手机软件包,它还具有很多的其他功能是QT、MINIGUI不具备的,比如电话、定位、WIFI、sensor、摄像头等功能。Android集成了很多开源的代码,我们只需要在Linux层做好硬件的驱动程序剩下的很多软件开发工作android都是做好了的。烧写过手机固件的都知道,andro

Eliot_shao的专栏 3972

Android 硬件抽象层概览

在 Android 8.0 及更高版本中,较低级别的层已重新编写以采用更加模块化的新架构。搭载 Android 8.0 或更高版本的设备必须支持使用 HIDL 语言编写的 HAL,下面列出了一些例外情况。这些 HAL 可以是绑定式 HAL 也可以是直通式 HAL。Android 11 也支持使用 AIDL 编写的 HAL。所有 AIDL HAL 均为绑定式。绑定式 HAL。以 HAL 接口定义语言 (HIDL) 或 Android 接口定义语言 (AIDL) 表示的 HAL。

华南烹鱼宴 920

Android WiFi BT 模组移植 分层详解

Android WiFi BT 模组移植 分层详解

Witheart 的博客。 1753
上一篇: android系统硬件抽象层(HAL)原理及实现之原理
下一篇: Android系统硬件抽象层原理与实现之GPS
朱克锋-盒子人
博客等级 码龄15年 136粉丝 136原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值