自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

OpenHarmony 資源調(diào)度之智能感知調(diào)度源碼分析

系統(tǒng) OpenHarmony
本文主要介紹了WPA_supplicant基礎(chǔ)及其在分布式軟總線(xiàn)子系統(tǒng)WIFI模塊的應(yīng)用 ,著重分析了HAL層與WPA_supplicant之間的Unix socket通信機(jī)制并貼出主要入口代碼,為開(kāi)發(fā)人員維護(hù)和擴(kuò)展功能提供參考。

想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):

51CTO 開(kāi)源基礎(chǔ)軟件社區(qū)

https://ost.51cto.com

1、WPA_supplicant簡(jiǎn)介

WPA是WiFi Protected Access的縮寫(xiě),中文含義為“WiFi網(wǎng)絡(luò)安全存取”。WPA是一種基于標(biāo)準(zhǔn)的可互操作的WLAN安全性增強(qiáng)解決方案,可大大增強(qiáng)現(xiàn)有以及未來(lái)無(wú)線(xiàn)局域網(wǎng)絡(luò)的數(shù)據(jù)保護(hù)和訪(fǎng)問(wèn)控制水平。

wpa_supplicant是開(kāi)源項(xiàng)目源碼,支持Linux,Windows以及很多嵌入式系統(tǒng)。它是WPA的應(yīng)用層認(rèn)證客戶(hù)端,負(fù)責(zé)完成認(rèn)證相關(guān)的登錄、加密等工作。wpa_supplicant是一個(gè) 獨(dú)立運(yùn)行的 守護(hù)進(jìn)程,其核心是一個(gè)消息循環(huán),在消息循環(huán)中處理WPA狀態(tài)機(jī)、控制命令、驅(qū)動(dòng)事件、配置信息等。

經(jīng)過(guò)編譯后 的 wpa_supplicant源程序可以看到兩個(gè)主要的可執(zhí)行工具:wpa_supplicant 和 wpa_cli。wpa_supplicant是核心程序,它和wpa_cli的關(guān)系就是服務(wù)和客戶(hù)端的關(guān)系:后臺(tái)運(yùn)行wpa_supplicant,使用 wpa_cli來(lái)搜索、設(shè)置、和連接網(wǎng)絡(luò)。wpa_supplicant與上層還是wpa_supplicant與驅(qū)動(dòng)都采用socket通訊, 與驅(qū)動(dòng)交互上報(bào)數(shù)據(jù)給用戶(hù),而用戶(hù)可以通過(guò)socket發(fā)送命令給wpa_supplicant調(diào)動(dòng)驅(qū)動(dòng)來(lái)對(duì)WiFi芯片操作,如圖1所示:

OpenHarmony 資源調(diào)度之智能感知調(diào)度源碼分析-開(kāi)源基礎(chǔ)軟件社區(qū)

圖 1 wpa_supplicant框架

2、AF_INET與AF_UNIX socket

Wpa_supplicant支持AF_INET和AF_UNIX socket兩種通信方式:AF_INET socket、AF_UNIX socket。

AF_INET socket通信方式類(lèi)似于網(wǎng)絡(luò)socket通信,發(fā)送方、接收方依賴(lài)IP:Port來(lái)標(biāo)識(shí),即將本地的socket綁定到對(duì)應(yīng)的IP端口上,發(fā)送數(shù)據(jù)時(shí),指定對(duì)方的IP端口,經(jīng)過(guò)Internet,可以根據(jù)此IP端口最終找到接收方;接收數(shù)據(jù)時(shí),可以從數(shù)據(jù)包中獲取到發(fā)送方的IP端口。發(fā)送方通過(guò)系統(tǒng)調(diào)用send()將原始數(shù)據(jù)發(fā)送到操作系統(tǒng)內(nèi)核緩沖區(qū)中。內(nèi)核緩沖區(qū)從上到下依次經(jīng)過(guò)TCP層、IP層、鏈路層的編碼,分別添加對(duì)應(yīng)的頭部信息,經(jīng)過(guò)網(wǎng)卡將一個(gè)數(shù)據(jù)包發(fā)送到網(wǎng)絡(luò)中。經(jīng)過(guò)網(wǎng)絡(luò)路由到接收方的網(wǎng)卡。網(wǎng)卡通過(guò)系統(tǒng)中斷將數(shù)據(jù)包通知到接收方的操作系統(tǒng),再沿著發(fā)送方編碼的反方向進(jìn)行解碼,即依次經(jīng)過(guò)鏈路層、IP層、TCP層去除頭部、檢查校驗(yàn)等,最終將原始數(shù)據(jù)上報(bào)到接收方進(jìn)程,通信過(guò)程如下圖所示:

OpenHarmony 資源調(diào)度之智能感知調(diào)度源碼分析-開(kāi)源基礎(chǔ)軟件社區(qū)

圖 2 AF_INET socket通信過(guò)程

AF_UNIX socket通信是典型的本地IPC,類(lèi)似于管道,依賴(lài)路徑名標(biāo)識(shí)發(fā)送方和接收方。即發(fā)送數(shù)據(jù)時(shí),指定接收方綁定的路徑名,操作系統(tǒng)根據(jù)該路徑名可以直接找到對(duì)應(yīng)的接收方,并將原始數(shù)據(jù)直接拷貝到接收方的內(nèi)核緩沖區(qū)中,并上報(bào)給接收方進(jìn)程進(jìn)行處理。同樣的接收方可以從收到的數(shù)據(jù)包中獲取到發(fā)送方的路徑名,并通過(guò)此路徑名向其發(fā)送數(shù)據(jù)。

OpenHarmony 資源調(diào)度之智能感知調(diào)度源碼分析-開(kāi)源基礎(chǔ)軟件社區(qū)

圖 3 AF_UNIX socket通信過(guò)程

他們的相同點(diǎn):操作系統(tǒng)提供的接口socket(),bind(),connect(),accept(),send(),recv(),以及用來(lái)對(duì)其進(jìn)行多路復(fù)用事件檢測(cè)的select(),poll(),epoll()都是完全相同的。收發(fā)數(shù)據(jù)的過(guò)程中,上層應(yīng)用感知不到底層的差別。

不同點(diǎn):

  • 建立socket傳遞的地址域,及bind()的地址結(jié)構(gòu)稍有區(qū)別:socket() 分別傳遞不同的域AF_INET和AF_UNIX bind()的地址結(jié)構(gòu)分別為sockaddr_in(制定IP端口)和sockaddr_un(指定路徑名)
  • AF_INET需經(jīng)過(guò)多個(gè)協(xié)議層的編解碼,消耗系統(tǒng)cpu,并且數(shù)據(jù)傳輸需要經(jīng)過(guò)網(wǎng)卡,受到網(wǎng)卡帶寬的限制。AF_UNIX數(shù)據(jù)到達(dá)內(nèi)核緩沖區(qū)后,由內(nèi)核根據(jù)指定路徑名找到接收方socket對(duì)應(yīng)的內(nèi)核緩沖區(qū),直接將數(shù)據(jù)拷貝過(guò)去,不經(jīng)過(guò)協(xié)議層編解碼,節(jié)省系統(tǒng)cpu,并且不經(jīng)過(guò)網(wǎng)卡,因此不受網(wǎng)卡帶寬的限制。
  • AF_UNIX的傳輸速率遠(yuǎn)遠(yuǎn)大于AF_INET
  • AF_INET不僅可以用作本機(jī)的跨進(jìn)程通信,同樣的可以用于不同機(jī)器之間的通信,其就是為了在不同機(jī)器之間進(jìn)行網(wǎng)絡(luò)互聯(lián)傳遞數(shù)據(jù)而生。而AF_UNIX則只能用于本機(jī)內(nèi)進(jìn)程之間的通信。

3、WPA_supplicant在OpenHarmony中的應(yīng)用

(1)WPA_supplicant的位置

OpenHarmony的WIFI子系統(tǒng)使用WPA_supplicant實(shí)現(xiàn)調(diào)動(dòng)驅(qū)動(dòng)操作WIFI芯片,驅(qū)動(dòng)數(shù)據(jù)上報(bào)給框架層的功能,WPA_supplicant在WIFI子系統(tǒng)的位置如下圖的WIFI架構(gòu)圖所示:

OpenHarmony 資源調(diào)度之智能感知調(diào)度源碼分析-開(kāi)源基礎(chǔ)軟件社區(qū)

圖 4 WIFI子系統(tǒng)架構(gòu)圖

WPA Supplicant包含libwpa、libwpa_client庫(kù)和wpa_cli、wpa_supplicant、hostapd可執(zhí)行程序。

  • libwpa是一個(gè)包含了wpa_suppliant和hostapd具體實(shí)現(xiàn)的庫(kù)。
  • wpa_supplicant是wpa的認(rèn)證客戶(hù)端,負(fù)責(zé)完成認(rèn)證相關(guān)的登錄、加密等工作。
  • hostapd包含了IEEE802.11接入點(diǎn)管理、IEEE802.1X/WPA/WPA2認(rèn)證、EAP服務(wù)器以及Radius鑒權(quán)服務(wù)器功能。
  • libwpa_client是一個(gè)給客戶(hù)端連接和調(diào)用的庫(kù),提供創(chuàng)建與wpa_supplicant或hostapd通信控制接口的能力。
  • wpa_cli和wpa_supplicant是客戶(hù)端和服務(wù)器的關(guān)系,通過(guò)wpa_cli可以向wpa_supplicant發(fā)送命令,進(jìn)行掃描、連接等做操作,可用來(lái)進(jìn)行Wifi功能的驗(yàn)證。

Wifi HAL層作為硬件適配層,承上啟下,對(duì)上層框架屏蔽底層硬件差別,為上層提供一致的接口。對(duì)下則負(fù)責(zé)拉起WPAS,即fork進(jìn)程wifi_hal_service的子進(jìn)程,在子進(jìn)程中加載libwpa庫(kù),執(zhí)行wpa_supplicant或hostapd的入口函數(shù), 作為unix socket通信的服務(wù)端. Wifi HAL的wifi_hal_service進(jìn)程是unix socket通信的客戶(hù)端,通過(guò)命令消息下發(fā)給wpa_supplicant或hostapd。

(2)Wifi HAL與wpa_supplicant的unix socket機(jī)制

Wifi HAL拉起wpa_supplicant或hostapd并建立unix socket連接過(guò)程如下圖所示:

OpenHarmony 資源調(diào)度之智能感知調(diào)度源碼分析-開(kāi)源基礎(chǔ)軟件社區(qū)

圖 5 Wifi HAL與wpa_supplicant unix socket建立過(guò)程

其中HAL拉起wpas的主要實(shí)現(xiàn)函數(shù)為StartModuleInternal,代碼主干如下

int StartModuleInternal(const char *moduleName, const char *startCmd, pid_t *pProcessId)
{
    ...
    pid_t pid = fork();  // fork子進(jìn)程
    if (pid < 0) {
        LOGE("Create wpa process failed!");
        return HAL_FAILURE;
    }
    if (pid == 0) { /* sub process */
        prctl(PR_SET_PDEATHSIG, SIGKILL);
        pthread_t tid;
        int ret = pthread_create(&tid, NULL, WpaThreadMain, (void *)startCmd); // 子進(jìn)程中創(chuàng)建主線(xiàn)程,線(xiàn)程入口函數(shù)WpaThreadMain 
        ...
    } else {
        ...
    }
    return HAL_SUCCESS;
}

子進(jìn)程的主線(xiàn)程入口函數(shù)WpaThreadMain中,加載libwpa動(dòng)態(tài)庫(kù),執(zhí)行主函數(shù)wpa_main或ap_main,參數(shù)由創(chuàng)建線(xiàn)程時(shí)傳入的startcmd解析而來(lái)。對(duì)于Sta和P2p業(yè)務(wù),有兩個(gè)參數(shù)分別是配置文件路徑、全局控制路徑;對(duì)于hostapd業(yè)務(wù),傳入一個(gè)參數(shù),即hostapd配置文件路徑。

static void *WpaThreadMain(void *p)
{
   ...
// 加載動(dòng)態(tài)庫(kù)libwpa
#ifdef OHOS_ARCH_LITE
    void *handleLibWpa = dlopen("libwpa.so", RTLD_NOW | RTLD_LOCAL);
#else
#ifdef __aarch64__
    void *handleLibWpa = dlopen("/system/lib64/libwpa.z.so", RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE);
#else
    void *handleLibWpa = dlopen("/system/lib/libwpa.z.so", RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE);
#endif
#endif
    ...
    if (strcmp(param.argv[0], "wpa_supplicant") == 0) {
        func = (int (*)(int, char **))dlsym(handleLibWpa, "wpa_main");
    } else {
        func = (int (*)(int, char **))dlsym(handleLibWpa, "ap_main");
    }
...
// 執(zhí)行主函數(shù)
    int ret = func(param.argc, tmpArgv);
    LOGD("run wpa_main ret:%{public}d.\n", ret);
    if (dlclose(handleLibWpa) != 0) {
        LOGE("dlclose libwpa failed.");
        return NULL;
    }
    return NULL;
}

Wifi HAL作為客戶(hù)端建立unix socket連接的主要實(shí)現(xiàn)函數(shù)WpaCliConnect,通過(guò)調(diào)用wpa client的函數(shù)wpa_ctrl_open建立socket連接,其參數(shù)ifname為“/data/service/el1/public/wifi/sockets/wpa/wlan0”。

static int WpaCliConnect(WifiWpaInterface *p)
{
    ...
    int count = WPA_TRY_CONNECT_TIMES;
    while (count-- > 0) {
        int ret = InitWpaCtrl(&p->wpaCtrl, WPA_CTRL_OPEN_IFNAME);
        if (ret == 0) {
            LOGI("Global wpa interface connect successfully!");
            break;
        } else {
            LOGE("Init wpaCtrl failed: %{public}d", ret);
        }
        usleep(WPA_TRY_CONNECT_SLEEP_TIME);
    }
    if (count <= 0) {
        return -1;
    }
    p->threadRunFlag = 1;
    if (pthread_create(&p->tid, NULL, WpaReceiveCallback, p) != 0) {
        p->threadRunFlag = 0;
        ReleaseWpaCtrl(&p->wpaCtrl);
        LOGE("Create monitor thread failed!");
        return -1;
    }
    LOGI("Wpa connect finish.");
    return 0;
}

int InitWpaCtrl(WpaCtrl *pCtrl, const char *ifname)
{
    ...
    do {
#ifdef WPA_CTRL_IFACE_UNIX
        pCtrl->pRecv = wpa_ctrl_open(ifname);
#else
        pCtrl->pRecv = wpa_ctrl_open("global");
#endif
        if (pCtrl->pRecv == NULL) {
            LOGE("open wpa control recv interface failed!");
            break;
        }
        if (wpa_ctrl_attach(pCtrl->pRecv) != 0) {
            LOGE("attach monitor interface failed!");
            break;
        }
#ifdef WPA_CTRL_IFACE_UNIX
        pCtrl->pSend = wpa_ctrl_open(ifname);
#else
        pCtrl->pSend = wpa_ctrl_open("global");
#endif
        if (pCtrl->pSend == NULL) {
            LOGE("open wpa control send interface failed!");
            break;
        }
        flag += 1;
    } while (0);
    ...
    return 0;
}

總結(jié)

本文主要介紹了WPA_supplicant基礎(chǔ)及其在分布式軟總線(xiàn)子系統(tǒng)WIFI模塊的應(yīng)用 ,著重分析了HAL層與WPA_supplicant之間的unix socket通信機(jī)制并貼出主要入口代碼,為開(kāi)發(fā)人員維護(hù)和擴(kuò)展功能提供參考。

想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):

51CTO 開(kāi)源基礎(chǔ)軟件社區(qū)

https://ost.51cto.com

責(zé)任編輯:jianghua 來(lái)源: 51CTO 開(kāi)源基礎(chǔ)軟件社區(qū)
相關(guān)推薦

2022-06-13 14:31:02

資源調(diào)度鴻蒙

2022-06-27 10:25:55

Kubernetes調(diào)度CPU

2024-10-21 09:18:47

2021-12-15 15:03:51

Linux內(nèi)核調(diào)度

2021-11-10 16:10:18

鴻蒙HarmonyOS應(yīng)用

2009-12-11 09:42:54

Linux內(nèi)核源碼進(jìn)程調(diào)度

2009-12-11 09:47:23

Linux內(nèi)核源碼進(jìn)程調(diào)度

2021-05-20 09:50:20

鴻蒙HarmonyOS應(yīng)用

2016-06-15 10:35:59

云計(jì)算

2015-05-05 09:37:29

OpenStackNova資源統(tǒng)計(jì)

2022-12-16 08:31:37

調(diào)度線(xiàn)程池源碼

2020-10-13 08:34:53

全球流量調(diào)度

2010-08-12 15:38:39

IT運(yùn)維網(wǎng)管軟件摩卡軟件

2022-07-31 23:46:57

人工智能語(yǔ)言模型感知力

2024-05-23 08:40:46

Kubernetes預(yù)過(guò)濾調(diào)度

2022-06-20 15:32:55

Stage模型分布式開(kāi)發(fā)

2024-12-16 07:41:35

2022-07-19 20:04:31

NAPI模塊鴻蒙
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)