鴻蒙適配wifi驅動 1

2021-10-12 16:37:35 字數 3872 閱讀 7484

本文首發於: lhm』s notes歡迎關注我的新部落格

一入wifi深似海~

使用者態(wpas)適配

首先找到如下目錄,是開源wpas**,由於之前看了點wpas的具體實現**,知道在linux系統中wpas與核心打交道是通過兩種標準介面,要麼是nl80211介面,要麼是wext(wireless extensions無線拓展介面); 由於當前核心系統更換,那麼nl80211和wext自然是不適用了。因此猜想鴻蒙在wpas上有做適配,先到wpas原始碼上瞧了瞧,果然發現有新增檔案。

下面這個是鴻蒙框架下的wpa_driver_ops結構體,是繼nl80211和wext之後的又一套新標準。由於上層只是呼叫指定的方法,如get_ssid 、scan2等等,而對其具體實現不會關注,因此在整個鴻蒙適配wpas**的過程中,只需要將這個g_wifidriverops物件的方法通過hdf框架實現即可,說實話,我對nl80211裡面又臭又長的**已經忍了很久了,希望這個不要讓我失望:)

如上圖所示,左邊是wpas使用nl80211標準介面,右邊是wpas使用鴻蒙wifi 介面;兩者在上層業務面的改動基本不大,只是和核心互動的介面區域需要適配鴻蒙liteos。如下是介面部分的**:

接下來我們以掃瞄業務為例子,分析鴻蒙wifi介面與核心態的互動過程。

掃瞄流程分析

首先看wifiwpascan2內部實現

static int32_t wifiwpascan2(void *priv, struct wpa_driver_scan_params *params)

drv = (wifidriverdata *)priv;

scan = (wifiscan *)os_zalloc(sizeof(wifiscan));

if (scan == null)

// 以下四個函式都是引數賦值,將param中的引數賦值到scan結構體中

if ((wifiwpascanprocessssid(params, scan) != succ) || (wifiwpascanprocessbssid(params, scan) != succ) ||

(wifiwpascanproces***traies(params, scan) != succ) || (wifiwpascanprocessfreq(params, scan) != succ))

// scan結構體繼續被填充

scan->fastconnectflag = wpa_flag_off;

scan->prefixssidscanflag = wpa_flag_off;

// 將填充好的scan 訊息結構體傳送給核心

ret = wifiwpacmdscan(drv->iface, scan);

wifiwpascanfree(&scan);

timeout = scan_time_out;

//在事件排程中註冊超時處理機制

eloop_cancel_timeout(wifiwpascantimeout, drv, drv->ctx);

eloop_register_timeout(timeout, 0, wifiwpascantimeout, drv, drv->ctx);

return ret;

}

可以看到wifiwpascan2只是乙個結構體的填充並將該訊息通過wifiwpacmdscan去傳送,具體傳送流程進入看下:

int32_t wifiwpacmdscan(const char *ifname, wifiscan *scan)

struct hdfsbuf *data = hdfsbufobtaindefaultsize();

if (data == null)

bool isserializefailed = false;

isserializefailed = isserializefailed || !hdfsbufwritestring(data, ifname);

if (scan->bssid == null) else

isserializefailed =

isserializefailed || !hdfsbufwritebuffer(data, scan->ssids, sizeof(scan->ssids[0]) * scan->numssids);

isserializefailed = isserializefailed || !hdfsbufwritebuffer(data, scan->extraies, scan->extraieslen);

isserializefailed =

isserializefailed || !hdfsbufwritebuffer(data, scan->freqs, sizeof(scan->freqs[0]) * scan->numfreqs);

isserializefailed = isserializefailed || !hdfsbufwriteuint8(data, scan->prefixssidscanflag);

isserializefailed = isserializefailed || !hdfsbufwriteuint8(data, scan->fastconnectflag);

if (isserializefailed) else

hdfsbufrecycle(data);

return ret;

}

看過鴻蒙驅動開發實戰那章的對這個**一定不會陌生,由於鴻蒙dispatch服務的引數型別是固定的,是struct hdfsbuf *型別,因此這裡將傳送資料通過hdfsbufwritebuffer重新又拷貝到了struct hdfsbuf *指標裡面, 並通過wifiwpacmdblocksyncsend進行傳送,開啟進入

int32_t wifiwpacmdblocksyncsend(const uint32_t cmd, struct hdfsbuf *reqdata, struct hdfsbuf *respdata)

if (g_wifiservice == null || g_wifiservice->dispatcher == null || g_wifiservice->dispatcher->dispatch == null)

int32_t ret = g_wifiservice->dispatcher->dispatch(&g_wifiservice->object, cmd, reqdata, respdata);

hdf_logi("%s: cmd=%d, ret=%d", __func__, cmd, ret);

return ret;

}

可以看到通訊手法正是上面兩章講到的hdf service機制。

總結:除了掃瞄流程、還有認證流程、關聯流程,這些都是接下來去看的內容。目前對核心通訊的機制基本有了了解,下面需要關注的有兩點。

1、業務:訊息中填充的每個資料,代表了什麼含義;各個業務之間又是如何關聯起來的。

wifi驅動的理解(1) 驅動架構

在分析wifi驅動前,分享一下個人對linux驅動的一些了解,其實縱觀linux眾多的裝置驅動,幾乎都是以匯流排為載體,所有的資料傳輸都是基於匯流排形式的,即使裝置沒有所謂的匯流排介面,但是linux還是會給它新增一條虛擬匯流排,如platform匯流排等 介於wifi的驅動實在是太龐大了,同時又是...

鴻蒙系統 OLED螢幕驅動

hi3861 oled驅動 hispark wifi開發套件又提供乙個oled螢幕,但是鴻蒙原始碼中沒有這個螢幕的驅動,我們需要自己去移植。2 設定i2c引腳復用 確定i2c引腳,檢視原理圖,可以看到oled螢幕使用到的是i2c0,引腳是gpio13 gpio14 i2c io復用也可以選擇3 4 ...

linux列印驅動適配

國產作業系統適配 cups除錯和可能產生的問題 linux作業系統列印驅動適配。cups即common unix printing system,即通用unix列印系統,所有linux作業系統,均採用cups進行列印。cups提供了列印任務所需要的介面和工具。cups將上層的資料,通過其自帶的轉換工...