wifi学习

WIFI驱动详细设计说明书 目录 引言 4 1.1. 文档目的 4 1.2. 参考文献 4 1.3. 符号和缩略语 4 总体设计介绍 4 2.1. 概述 4 2.2. 功能定义 5 2.2.1. WIFI驱动功能定义 5 2.2.2. WIFI安全定义 6 2.3. 系统资源需求与依赖 7 2.3.1. 硬件资源框图 7 2.3.2. 软件资源 8 2.4. 软件设计方案 8 2.4.1. WIFI驱动框架结构 8 2.4.2. LIBWIFI模块驱动软件方框图 10 2.4.2.1. 无线网卡控制模块 11 2.4.2.2. 阅读详情
  对上层WIFI的应用,基本流程为:(1)WIFI 初始化   (2)Wifi启动      (3)开始扫描AP        (4)显示扫描的AP      (5)配置AP        (6)连接AP     (7)获取IP地址      (8)上网             

一、Android WIFI模块初始化

上文Android系统启动分析  讲到在SystemServer中实例化了ConnectivityService,接着的便是WIFI初始化:
frameworks/base/services/java/com/android/server/ConnectivityService.java
ConnectivityService 的构造函数会创建WifiService,

if (DBG) Log.v(TAG, "Starting Wifi Service.");
      WifiStateTracker wst = new WifiStateTracker(context, mHandler);
      WifiService wifiService = new WifiService(context, wst);
      ServiceManager.addService(Context.WIFI_SERVICE, wifiService);

WifiStateTracker 会创建WifiMonitor接收来自底层的事件,WifiService 和WifiMonitor 是整个模块的核心。WifiService负责启动关闭wpa_supplicant、启动关闭WifiMonitor监视线程和把命令下发给wpa_supplicant,而WifiMonitor 则负责从wpa_supplicant 接收事件通知。
具体流程图如下:

二、WIFI模块启动

         WirelessSettings 在初始化的时候配置了由WifiEnabler 来处理Wifi 按钮 WirelessSettings 在初始化的时候配置了由WifiEnabler 来处理Wifi 按钮     

Packages\apps\settings\src\com\android\settings\WirelessSettings.java
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.wireless_settings);
        initToggles();
        mAirplaneModePreference = (CheckBoxPreference) findPreference(KEY_TOGGLE_AIRPLANE);
    }
private void initToggles() {
    …………
    mWifiEnabler = new WifiEnabler(
                this, (WifiManager) getSystemService(WIFI_SERVICE),
                (CheckBoxPreference) wifiPreference);
…………
}

        当用户按下Wifi 按钮后,Android 会调用WifiEnabler的onPreferenceChange,再由WifiEnabler调用WifiManager 的setWifiEnabled接口函数,通过AIDL,实际调用的是WifiService 的setWifiEnabled 函数,WifiService接着向自身发送一条MESSAGE_ENABLE_WIFI 消息,在处理该消息的代码中做真正的使能工作:
首先装载WIFI 内核模块(该模块的位置硬编码为"/system/lib/modules/libertas_sdio.ko" ),
然后启动wpa_supplicant ( 配置文件硬编码为"/data/misc/wifi/wpa_supplicant.conf"),再通过WifiStateTracker 来启动WifiMonitor 中的监视线程。
WifiEnabler.java

public boolean onPreferenceChange(Preference preference, Object value) {
        // Turn on/off Wi-Fi
        setWifiEnabled((Boolean) value);        
    }
private void setWifiEnabled(final boolean enable) {
        if (!mWifiManager.setWifiEnabled(enable)) {
        }
    }  

WifiManager.java
 public boolean setWifiEnabled(boolean enabled) {
            return mService.setWifiEnabled(enabled);
    }
 IWifiManager mService;
 interface IWifiManager{
    …………
    boolean startScan(boolean forceActive);
    boolean setWifiEnabled(boolean enable);
 …………
 }
IWifiManger.aidl编译后生成了IWifiManger.java,并生成IWifiManger.Stub(服务器端抽象类)和IWifiManger.Stub.Proxy(客户端代理实现类)。WifiService通过继承IWifiManger.Stub实现,而客户端通过getService()函数获取IWifiManger.Stub.Proxy(即Service的代理类),将其作为参数传递给WifiManger,供其与WifiService通信时使用。
WifiService.java 

public boolean setWifiEnabled(boolean enable) {
…………
sendEnableMessage(enable, true, Binder.getCallingUid());
    …………
}
private void sendEnableMessage(boolean enable, boolean persist, int uid) {
        Message msg = Message.obtain(mWifiHandler,
                                     (enable ? MESSAGE_ENABLE_WIFI : MESSAGE_DISABLE_WIFI),
                                     (persist ? 1 : 0), uid);
        msg.sendToTarget();
    }
public void handleMessage(Message msg) {
            switch (msg.what) {
                case MESSAGE_ENABLE_WIFI:
                    setWifiEnabledBlocking(true, msg.arg1 == 1, msg.arg2);
                case MESSAGE_START_WIFI:                  
                    mWifiStateTracker.restart(); 
               case MESSAGE_DISABLE_WIFI:                 
                    setWifiEnabledBlocking(false, msg.arg1 == 1, msg.arg2);              
                case MESSAGE_STOP_WIFI:
                    mWifiStateTracker.disconnectAndStop();
                    break;
            }
        }
    }
private boolean setWifiEnabledBlocking(boolean enable, boolean persist, int uid) {
if (enable) {
            if (!WifiNative.loadDriver()) {               
                setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);
            }
            if (!WifiNative.startSupplicant()) {
                WifiNative.unloadDriver();             
                setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);
            }
            registerForBroadcasts();
            mWifiStateTracker.startEventLoop();
        } else {
  ………………
  }
    // Success!       
        setWifiEnabledState(eventualWifiState, uid);
}
private void setWifiEnabledState(int wifiState, int uid) {
 // Broadcast
        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
}
 JNI android_net_wifi_wifi.cpp
// ----------------------------------------------------------------------------

/*
* JNI registration.
*/
static JNINativeMethod gWifiMethods[] = {
    /* name, signature, funcPtr */
    { "loadDriver", "()Z",  (void *)android_net_wifi_loadDriver },   
    { "startSupplicant", "()Z",  (void *)android_net_wifi_startSupplicant },   
    { "scanResultsCommand", "()Ljava/lang/String;", (void*) android_net_wifi_scanResultsCommand },      
    { "reconnectCommand", "()Z",  (void *)android_net_wifi_reconnectCommand },  
    { "scanCommand", "(Z)Z", (void*) android_net_wifi_scanCommand },
}
1)static jboolean android_net_wifi_loadDriver(JNIEnv* env, jobject clazz)
{
    return (jboolean)(::wifi_load_driver() == 0);
}
2)static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject clazz)
{
    return (jboolean)(::wifi_start_supplicant() == 0);
}
3)WifiStateTracker.java
mWifiStateTracker.startEventLoop();
public void startEventLoop() {
        mWifiMonitor.startMonitoring();
    }
//WifiMonitor.java
public void startMonitoring() {
        new MonitorThread().start();
    }

当使能成功后,会广播发送WIFI_STATE_CHANGED_ACTION 这个Intent 通知外界WIFI已经成功使能了。// Success!后广播的。

http://blog.youkuaiyun.com/yicao821/article/details/6895044


上文讲到WIFI的启动流程,当然接着便扫描热点(AP),然后显示扫描到的AP、配置AP(填写IP地址等信息)、连接AP、获取IP地址、最后就是想要的上网咯!

一、扫描热点(AP)

上文启动WIFI成功后:// Success!       
        setWifiEnabledState(eventualWifiState, uid);
private void setWifiEnabledState(int wifiState, int uid) {
 // Broadcast
        final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
}

当使能成功后,会广播发送WIFI_STATE_CHANGED_ACTION 这个Intent 通知外界WIFI已经成功使能了。WifiLayer 创建的时候就会向Android 注册接收WIFI_STATE_CHANGED_ACTION,因此它会收到该Intent,从而开始扫描。

WifiSetting.java:

protected void onCreate(Bundle savedInstanceState) {
    mWifiLayer.onCreate();
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

WifiLayer.java:
public void onCreate() {
        mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
       
        mIntentFilter = new IntentFilter();
        mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);        
    }
public void onResume() {
        mContext.registerReceiver(mReceiver, mIntentFilter);       
        if (isWifiEnabled()) {
            // Kick start the continual scan
            queueContinuousScan();
        }
    }

以上就是WifiLayer.java注册接收的部分事件。接收部分事件处理有:
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
                handleNetworkStateChanged(
                        (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO),
                        intent.getStringExtra(WifiManager.EXTRA_BSSID));
            } else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
                handleScanResultsAvailable();
            } ……

           else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
                handleWifiStateChanged(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
                        WifiManager.WIFI_STATE_UNKNOWN));
            }           
        }
    };

从可接受的事件看,当WIFI_STATE_CHANGED_ACTION时,对应的处理函数有:

handleWifiStateChanged(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
                        WifiManager.WIFI_STATE_UNKNOWN));

private void handleWifiStateChanged(int wifiState) {
   attemptScan();
   …………
 }

public void attemptScan() {
  if (!mWifiManager.startScanActive()) {
            postAttemptScan();
        }
}

WifiManager.java:
public boolean startScanActive() {
 return mService.startScan(true);
}

-------AIDL-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

WifiService.java:
public boolean startScan(boolean forceActive) {
 …………
 return WifiNative.scanCommand(forceActive);
}

---------JNI---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

android_net_wifi_wifi.cpp:
{ "scanCommand", "(Z)Z", (void*) android_net_wifi_scanCommand },
static jboolean android_net_wifi_scanCommand(JNIEnv* env, jobject clazz, jboolean forceActive)
{
 …………
 result = doBooleanCommand("SCAN", "OK");
}
static jboolean doBooleanCommand(const char *cmd, const char *expect)
{
 if (doCommand(cmd, reply, sizeof(reply)) != 0) {
        return (jboolean)JNI_FALSE;
    }
}
static int doCommand(const char *cmd, char *replybuf, int replybuflen)
{
 if (::wifi_command(cmd, replybuf, &reply_len) != 0)
        return -1;
 …………
}

-------HAL------------------------------------------------------------------------------------------------------------------------------------------------------------------------

wifi.c:
int wifi_command(const char *command, char *reply, size_t *reply_len)
{
    return wifi_send_command(ctrl_conn, command, reply, reply_len);
}
int wifi_send_command(struct wpa_ctrl *ctrl, const char *cmd, char *reply, size_t *reply_len)
{
 ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), reply, reply_len, NULL);
 …………
}
wpa_ctrl.c:
int wpa_ctrl_request()在wpa_ctrl.c中其实就是执行SCAN命令。

二、显示扫描的AP

当扫描成后,WifiMonitor 中的MonitorThread 会被执行来出来这个事件:

  void handleEvent(int event, String remainder) {
            switch (event) {   
                case SCAN_RESULTS:
                    mWifiStateTracker.notifyScanResultsAvailable();
->sendEmptyMessage(EVENT_SCAN_RESULTS_AVAILABLE);
    break;
}

 WifiStateTracker.java
public void handleMessage(Message msg) {              
  switch (msg.what) {
               case EVENT_SCAN_RESULTS_AVAILABLE:
                        if (ActivityManagerNative.isSystemReady()) {
                                mContext.sendBroadcast(new   Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));       
                     }
}

WifiLayer注册接收SCAN_RESULTS_AVAILABLE_ACTION这个Intent:

private BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
 else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))
       {             

             handleScanResultsAvailable();     

     }
 handleScanResultsAvailable();
       -> list = mWifiManager.getScanResults();
        -> mCallback.onAccessPointSetChanged(ap, true);

handleScanResultsAvailable()中首先会去拿到SCAN的结果(最终是往wpa_supplicant中发送SCAN_RESULT命令并读取返回值来实现的),对每一个扫描返回的AP,WifiLayer会回调WifiSetting的onAccessPointSetChanged函数,从而最终把该AP加到GUI显示列表中。

三、配置AP

当用户在 WifiSettings 界面上选择了一个AP 后,会显示配置AP 参数的一个对话框:

public boolean onPreferenceTreeClick()
          ->showAccessPointDialog(state, AccessPointDialog.MODE_INFO);
                    ->AccessPointDialog dialog   =
                                            new AccessPointDialog(this,    mWifiLayer);
                                     showDialog(dialog);

当用户在AccessPointDialog中选择好加密方式和输入密钥之后,再点击连接按钮,Android就会去连接这个AP。

四、连接AP

在AccessPointDialog.java中点击连接后会执行:

public void onClick(DialogInterface dialog, int which) {
           handleConnect();
   -> mWifiLayer.connectToNetwork(mState);
    ->  // Need WifiConfiguration for the AP
                               WifiConfiguration config = findConfiguredNetwork(state);
                                config = addConfiguration(state, 0);
                                managerEnableNetwork(state, false)
          ->mWifiManager.enableNetwork()
                                         ->mService.enalbeNetwork()
                     ->WifiNative.enableNetworkCommand() 

接下去就JNI { "enableNetworkCommand", "(IZ)Z", (void*)android_net_wifi_enableNetworkCommand},最终就是向wpa_supplicant发送连接命令
五、获取IP地址

当wpa_supplicant成功连接上AP之后,它会向控制通道发送事件通知连接上AP了,从而wifi_wait_for_event函数会接收到该事件,由此WifiMonitor中的MonitorThread会被执行来出来这个事件:

void handleEvent(int event, String remainder) {
       switch (event) {   
              case CONNECTED:
                  handleNetworkStateChange();
                  -> mWifiStateTracker.notifyStateChange(newState, BSSID, networkId);
  ->msg.sendToTarget();
                  break;
}

WifiStateTracker.java
public void handleMessage(Message msg) {         
  switch (msg.what) {              
            case EVENT_NETWORK_STATE_CHANGED:
                       sendNetworkStateChangeBroadcast(mWifiInfo.getBSSID());      
                     }
}
WifiStateTracker中注册的对Wifi相关数据库的观察者if(changed)   则启动:
 private void configureInterface()
   ->  mDhcpTarget.sendEmptyMessage();
 private class DhcpHandler extends Handler
          handleMessage()
              ->switch (msg.what) {
                      case EVENT_DHCP_START:
                              Target.sendEmptyMessage(event);

DhcpHandler会发送EVENT_DHCP_START消息启动DHCP去获取IP地址,当DHCP拿到IP地址之后,会发送EVENT_INTERFACE_CONFIGURATION_SUCCEEDED的消息,然后WifiStateTacker中的handleMessage会处理这样的消息 

case EVENT_INTERFACE_CONFIGURATION_SUCCEEDED:
     sendNetworkStateChangeBroadcast(mWifiInfo.getBSSID());
            ->  Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
            -> mContext.sendStickyBroadcast(intent);

这次带上完整的IP地址信息。WifiLayer中注册了此Intent的接受者,会调用handleNetworkStateChanged进行处理。最后就可以自由的上网了
Android wifi探究一:初步认识wpa_supplicant与wifi框架梳理 平时和wifi打交道还算比较多吧,wifi出了问题就只能找大神解决,这是件很令人伤感的事情。所以就想自己分析下android源码中wifi的框架,以后wifi出了问题,自己也能尝试的解一解。分析过程必定会有很多理解不到位或者错误的地方,欢迎大家不吝啬恶毒之词,使劲拍砖。 阅读详情

相关推荐

wpa_supplicant的控制接口简单说明

目录 1 说明 2 参考 2.1 函数基本说明 2.2 逻辑说明 3 应用程序的处理 3.1 事件通知消息说明 3.2 代码示例 1 说明 本文旨在用wpa_supplicant提供的API控制wifi模块以STA工作模式连接热点。wpa_supplicant程序一般运行在后台(./wpa_supplicant -B -cwpa_0_8.conf -iwlan0),用户通过它提供的接口让它做各种连接操作。 2 参考 http://w1.fi/wpa_supplicant/devel/w

li_huaqingfeng的博客 4083

android系统启动及wifi框架分析

android系统启动:http://blog.youkuaiyun.com/yicao821/article/details/6893752 最近在分析Android WIIF框架,顺便就把Android系统启动过程做了个流程分析,在这分享下我的学习经验。部分有修正网络文章。欢迎拍砖! Android系统从Linux内核启动后分为4个基本步骤: (1) init进程启动 (2) Native服务启动

Dybinx的专栏 6894

基于极限学习机的定位仿真,基于极限学习机的wifi定位,基于极限学习机的室内定位

极限学习机原理,基于极限学习机的定位仿真,基于极限学习机的wifi定位,基于极限学习机的室内定位。

abc991835105的博客 1769

wifi连接流程分析

Wifi 连接部分http://blog.youkuaiyun.com/typename/article/details/5879121当用户选择一个AP时会弹出一个AP参数配置对话框,此对话框会显示当前选择的AP信号强度,若此AP设置了密码则需要用户输入密码才能登录。WifiSettings中的 onPreferenceTreeClick会被调用 @Override publi...

weixin_34117522的博客 571

科研笔记(八) 深度学习及其在 WiFi 人体感知中的应用(下)

科研笔记(八) 深度学习及其在 WiFi 人体感知中的应用(下)

NoteBook 3568

蓝牙和WiFi技术的测试:从基础到高级的学习资源

测试是确保蓝牙和WiFi设备正常运行的关键环节,涉及到设备的功能、性能、兼容性、稳定性等多个方面。通过使用专业的工具和框架、学习相关书籍与在线课程,你可以逐步掌握如何测试蓝牙和WiFi设备,并提高测试的效率和准确性。无论是功能性测试、性能测试还是压力测试,深入学习这些测试方法将为你在无线通信领域的工作打下坚实基础。希望通过这篇博客,你能找到适合自己的学习路径,提升自己的测试能力,成为蓝牙和WiFi技术测试领域的专家!

效率工具,软件测试,实用干货,资源分享,这里全是黑科技。 1621

学习WiFi,怎么入手?

搞了一两年WiFi,但感觉还是一头雾水,啥都没掌握,怎么办?

ChaserDtao的博客 2640

Android 9.0 Framwork Wifi源码学习目录

Android 9.0 WifiService启动 WifiService的启动简单时序图表示: 1.1、启动WifiService 在SystemServer.java的 startOtherServices() 方法中,启动了WifiService,代码如下frameworks/base/services/java/com/android/server/SystemServer.java frameworks/base/services/core/java/com/android..

不冬眠的熊的博客 1616

WiFi学习Notes

WiFi学习NotesWiFi学习记录的一些资料,欢迎讨论: Wi-Fi载波侦听 Protocol Stack in Wifi Chips 11n Block Acknowledgement 4步握手过程 CWNA学习笔记

山庄来客的专栏 1249

学习STM32的WiFi模块通信

引脚配置和初始化: 首先,我们需要配置和初始化STM32的引脚,以便将其连接到WiFi模块。具体的引脚配置取决于您使用的STM32型号和WiFi模块型号。引言: 本篇文章将为您详细介绍如何使用STM32微控制器和WiFi模块进行通信。我们将通过一系列代码案例来展示WiFi模块的基本配置和连接,以及发送和接收数据的过程。学习STM32的WiFi模块通信。WiFi模块连接设置。

2401_85258012的博客 461

变压器耦合放大器(低频应用+高频应用)

变压器耦合放大器(低频应用+高频应用)

m0_54943120的博客 2274

WiFi技术学习路线图:从基础到精通的全面指南

从基础到精通。从理解WLAN(无线局域网)的基本定义与架构开始,深入学习802.11系列标准及其演进。随后,掌握路由器、交换机与AP的选型与使用,以及网络协议的运作机制。最终,精通WiFi技术的部署、优化与安全,成为该领域的专家。

byte轻骑兵的技术小窝 7185

GIS小白也能看懂的实战:5步教你将ArcGIS里的等高线和水系完美导入CAD做规划图

本文详细介绍了如何将ArcGIS中的等高线和水系数据高效导入CAD,制作专业规划底图的5个关键步骤。从数据准备、ArcGIS处理到CAD优化,涵盖坐标系设置、数据裁剪、格式转换等实用技巧,特别适合设计规划领域的新手快速掌握GIS与CAD协同工作流程。

weixin_27966471的博客 425

WiFi 学习集合

http://www.docin.com/d-470563.html

qq_17334155的专栏 474

Windows Server远程桌面断开后,PyWinAuto/按键精灵脚本失效?试试这个‘会话保持’的终极配置

本文深入解析Windows Server远程桌面断开后导致PyWinAuto/按键精灵脚本失效的问题,提供会话保持的终极配置方案。通过转换到控制台会话(console模式)和调整组策略,确保自动化程序在断开连接后持续稳定运行,适用于Windows Server各版本。

weixin_28738165的博客 227

【软件介绍】RVC本地部署使用方法

【摘要】RVC是一款功能强大的开源语音转换工具,具有实时处理、多音效选择、高质量音频处理等特点。文章详细介绍了RVC的安装与使用方法:1)配置Python环境;2)根据电脑系统选择对应安装包解压;3)启动程序进入浏览器操作界面。重点讲解了声音克隆的关键步骤:建议使用短音频素材,选择合适训练方法(推荐pm或rmvpe),设置100次训练轮数,生成的模型文件存入weights文件夹。最后通过上传音频即可实现声音克隆。操作过程需注意保持程序运行状态,并提供了相关资源下载地址。

心动的那一刻,记忆便盛开了花 2976

wifi 基础学习

看到一篇写的很好的文章。记录。 https://www.cnblogs.com/zhoading/p/8891206.html 这里对wifi的802.11协议中比较常见的知识做一个基本的总结和整理,便于后续的学习。因为无线网络中涉及术语很多,并且许多协议都是用英文描述,所以有些地方翻译出来会有歧义,这种情况就直接英文来描述了。   主要内容: 一、基本概述 二、实践基础 三、一些原...

badagougou的博客 2249

31、贝叶斯认知建模与隐马尔可夫模型:理论与应用

本文探讨了贝叶斯认知建模与隐马尔可夫模型(HMM)的理论基础及其在认知科学和神经科学中的应用。重点介绍了贝叶斯定理和HMM的基本原理,并结合实际案例,如情绪识别系统和脑机接口(BCI),展示了它们在处理复杂认知任务中的强大能力。文章还讨论了贝叶斯-HMM模型的技术细节、优势与局限性,以及未来的发展前景。

meat5的博客 141

【原】WiFi 学习整理

WiFi 学习整理 WiFi 学习 https://github.com/fzxy002763/Wi-Fi_Study_Public ...

Weixin20210210 640

利用Dify构建文档内容的分析对比

本次主要做了一些workflow和Agent的应用实现,供大家参考。主要目的是为了进行两个内部报告文件的内容对比,特别是报告中的各类审批表、申请表、推荐表和流程对比,本地数据通过知识库方式分别加载到两个知识库中,编制工作流针对同一个问题进行知识库检索,之后将查询结果进行合并,再一起提交给LLM进行对比,最终将对比分析结果以markdown方式返回显示。主要包括如何构建知识库,如何设计workflow、如何将工作流发布为工具、如何设计提示词、如何在agent中引入前面发布的工具,最终通过agent实现与用户交

hhue2007的专栏 2522

PCL 直通滤波

内容抄自优快云点云侠:[【2024最新版】PCL点云处理算法汇总(C++长期更新版)](https://blog.youkuaiyun.com/qq_36686437/article/details/114160640)。质量无忧,永久免费,可放心复制粘贴。

m0_51204289的博客 902

科研笔记(八) 深度学习及其在 WiFi 人体感知中的应用(上)

近年来,WiFi感知技术发展迅速。通过传播模型和深度学习方法的支持,实现了许多具有挑战性的应用,如基于WiFi的人类活动识别和姿势识别。然而,同用于视觉识别和自然语言处理的深度学习技术相比,目前还没有足够全面的用于WiFi感知的公共benchmark。.........

NoteBook 4777

Spring Boot集成ShardingSphere实现数据加密及数据脱敏 | Spring Cloud 48

利用ShardingSphere实现: - 数据加密 - 数据脱敏

gmHappy 1万+

嵌入式学习之WIFI模组

3.5的发送太别扭了,每次发送要提前输入指令,还有长度限制,并不高效和方便,可以不可以有一种设置,只要设置好了,我们就可以让串口助手直接和服务器进行通信,ESP8266只作一个转发者的身份存在,当发送指定字符时才退出通信。这就是透传,让ESP8266透明化的一种数据传输方式。也就是,开启透传模式后,ESP8266接收到的任何数据他都不会将其看做命令,而是看做是要传输出去的数据,此时ESP8266就只是一个数据中转站,也就是实现了其透明化,数据好像直接从发送方到了接收方。

学习过程记录,欢迎大家交流互动,互相学习 1183

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

WiFi协议学习笔记

direct-sequence spread spectrum,DSSS),简称直扩(DS),把’0’ '1’字符扩展成11Bit位的01字符串,提升抗干扰能力。用于同步,信号检测和均衡化。它的基本思想是,在发送数据之前,设备会先检测信道是否空闲(Carrier Sense),如果信道忙碌,设备将等待一段随机时间后再次尝试发送。其中,向上的箭头表示该子载波的相位或符号为正(通常表示为 +1 或类似的正值),向下的箭头表示该子载波的相位或符号为负(通常表示为 -1 或类似的负值)。这个分发策略是不常用的。

weixin_44737922的博客 1158

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

学习wifi打卡第一天

学习wifi打卡第一天

power_comba的博客 62

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

上一篇: WIFI连接原理
下一篇: Android 系统启动
karry_vcent
博客等级 码龄15年 93粉丝 45原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值