The WLAN module is developed based on the Hardware Driver Foundation \(HDF\). It supports cross-OS migration, component adaptation, and modular assembly and compilation. Based on the unified APIs provided by the WLAN module, driver developers of WLAN vendors can adapt their driver code and are capable of creating, disabling, scanning, and connecting to WLAN hotspots. The WLAN driver provides the Hardware Device Interface \(HDI\) layer with the capabilities of setting and obtaining the device MAC address and setting the transmit power. The following figure shows the framework of the WLAN module:
The Wireless Local Area Network (WLAN) Driver module in OpenHarmony is developed based on the Hardware Driver Foundation (HDF). It features cross-OS porting, self-adaptation to component differences, and modular assembly and build.
### WLAN Driver API Architecture<a name="section178022416377"></a>
### Working Principles
The WLAN module provides the following three types of APIs:
You can adapt your driver code based on the unified interfaces provided by the WLAN module. The WLAN module provides:
1. Capability APIs for the HDI layer
- A unified underlying interface to implement capabilities, such as setting up or closing a WLAN hotspot, scanning hotspots, and connecting to or disconnecting from a hotspot.
- A unified interface to the Hardware Device Interface (HDI) layer to implement capabilities, such as setting or obtaining the device Media Access Control (MAC) address and setting the transmit power.
2. Capability APIs directly invoked by drivers
The figure below shows the WLAN architecture. The WLAN Driver module implements startup loading, parses configuration files, and provides bus abstraction APIs. The WLAN Chip Driver module provides the MAC Sublayer Management Entity (MLME).
3. Capability APIs for vendors
**Figure 1** WLAN architecture
**Figure 2** Available APIs of the WLAN module<aname="fig1492411431166"></a>
## Available APIs<a name="section7331102018815"></a>
The figure below shows the WLAN driver architecture.
The WLAN driver module provides APIs that can be directly called by driver developers, such as creating/releasing a **WifiModule**, connecting to/disconnecting from a WLAN hotspot, applying for/releasing a **NetBuf**, and converting between the **pbuf** structure of Lightweight IP \(lwIP\) and a **NetBuf**. [Table 1](#table1521573319472) describes some APIs.
**Figure 2** WLAN driver architecture
**Table 1** APIs that can be directly called by driver developers
1. WLAN Message: provides an independent interface for each service or a composite service interface for multiple dependent services. It can run in the user mode, kernel mode, and MCU to implement complete decoupling between components.
6. Bus: provides a unified bus abstract interface for the upper layer. It shields the differences between different kernels by calling the Secure Digital Input Output (SDIO) interfaces provided by the platform layer and encapsulating the adapted USB and PCIe interfaces. It also encapsulates different types of bus operations in a unified manner to shield differences between different chipsets. The complete bus driving capabilities provided by the bus module help simplify and streamline the development of different chip vendors.
</td>
<tdclass="cellrowborder"valign="top"width="24.59%"headers="mcps1.2.4.1.3 "><pid="p1363012387393"><aname="p1363012387393"></a><aname="p1363012387393"></a>Creates a <strongid="b17218103820131"><aname="b17218103820131"></a><aname="b17218103820131"></a>WifiModule</strong>.</p>
7. NetDevice: creates dedicated network devices to shield differences between OSs, provides unified interfaces for Wi-Fi drivers, unified HDF NetDevice data structure, and unified management, registration, and deregistration capabilities, and connects to the Linux network device layer on mini-, small-, standard, and large-system devices.
</td>
</tr>
8. NetBuf: encapsulates the unified data structure of the Linux or LiteOS native network data buffer and the operation interfaces for network data.
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p2627638173917"><aname="p2627638173917"></a><aname="p2627638173917"></a>Deletes a <strongid="b17674114211319"><aname="b17674114211319"></a><aname="b17674114211319"></a>WifiModule</strong> and releases its data.</p>
</td>
10. HCC-CFG: configures WLAN parameters, including the board configuration, driver configuration, and module configuration.
The relationships between the main modules are as follows:
</td>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1162543816393"><aname="p1162543816393"></a><aname="p1162543816393"></a>Deletes a feature from a <strongid="b12747104710136"><aname="b12747104710136"></a><aname="b12747104710136"></a>WifiModule</strong>.</p>
1. The WLAN driver works with HCC-CFG and WLAN Configuration Core to parse and load configuration files.
</td>
</tr>
2. The WLAN Message module distributes user-mode messages to the AP and STA by component.
3. Commands are delivered to mac80211, and then forwarded by the Bus module to the WLAN chip firmware.
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p186235383393"><aname="p186235383393"></a><aname="p186235383393"></a>Adds a feature to a <strongid="b61351114111410"><aname="b61351114111410"></a><aname="b61351114111410"></a>WifiModule</strong>.</p>
</td>
4. The protocol stack works with the NetDevice, NetBuf, and FlowCtl modules to exchange data flows.
<tdclass="cellrowborder"valign="top"width="24.59%"headers="mcps1.2.4.1.3 "><pid="p195182610507"><aname="p195182610507"></a><aname="p195182610507"></a>Starts an AP.</p>
The WLAN module provides the following types of APIs:
</td>
</tr>
- WLAN APIs that can be directly called by drivers
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1151815635014"><aname="p1151815635014"></a><aname="p1151815635014"></a>Stops an AP.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p14519469509"><aname="p14519469509"></a><aname="p14519469509"></a>Connects to a hotspot.</p>
- The WLAN Driver module provides APIs that you can directly use to create or release a **WifiModule**, connect to or disconnect from a WLAN hotspot, request or release a **NetBuf**, and convert between the **pbuf** structure of Lightweight IP (lwIP) and a **NetBuf**.
</td>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p175191863503"><aname="p175191863503"></a><aname="p175191863503"></a>Disconnects from a hotspot.</p>
<tdclass="cellrowborder"valign="top"width="24.59%"headers="mcps1.2.4.1.3 "><pid="p364254211507"><aname="p364254211507"></a><aname="p364254211507"></a>Initializes a <strongid="b8331245144114"><aname="b8331245144114"></a><aname="b8331245144114"></a>NetBuf</strong> queue.</p>
| void WifiModuleDelete(struct WifiModule \*module) | Deletes a **WifiModule** and releases its data.|
</td>
| int32_t DelFeature(struct WifiModule \*module, uint16_t featureType) | Deletes a feature from a **WifiModule**.|
</tr>
| int32_t AddFeature(struct WifiModule \*module, uint16_t featureType, struct WifiFeature \*featureData) | Adds a feature to a **WifiModule**.|
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p3642164215501"><aname="p3642164215501"></a><aname="p3642164215501"></a>Applies for a <strongid="b15893135016416"><aname="b15893135016416"></a><aname="b15893135016416"></a>NetBuf</strong>.</p>
| int32_t (\*startAp)(NetDevice \*netDev) | Starts an AP.|
</td>
| int32_t (\*stopAp)(NetDevice \*netDev) | Stops an AP.|
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1464312427503"><aname="p1464312427503"></a><aname="p1464312427503"></a>Releases a <strongid="b87021256204112"><aname="b87021256204112"></a><aname="b87021256204112"></a>NetBuf</strong>.</p>
| int32_t (\*connect)(NetDevice \*netDev, WifiConnectParams \*param) | Connects to a hotspot.|
</td>
| int32_t (\*disconnect)(NetDevice \*netDev, uint16_t reasonCode) | Disconnects from a hotspot.|
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p186437429509"><aname="p186437429509"></a><aname="p186437429509"></a>Converts the <strongid="b108101241316"><aname="b108101241316"></a><aname="b108101241316"></a>pbuf</strong> structure of <strongid="b148154412318"><aname="b148154412318"></a><aname="b148154412318"></a>lwIP</strong> to a <strongid="b8994115217371"><aname="b8994115217371"></a><aname="b8994115217371"></a>NetBuf</strong>.</p>
| struct NetBuf \*NetBufAlloc(uint32_t size) | Allocates a **NetBuf**.|
</td>
| void NetBufFree(struct NetBuf \*nb) | Releases a **NetBuf**.|
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1965702312510"><aname="p1965702312510"></a><aname="p1965702312510"></a>Converts a <strongid="b92856616388"><aname="b92856616388"></a><aname="b92856616388"></a>NetBuf</strong> to the <strongid="b993215663110"><aname="b993215663110"></a><aname="b993215663110"></a>pbuf</strong> structure of <strongid="b10933563310"><aname="b10933563310"></a><aname="b10933563310"></a>lwIP</strong>.</p>
| struct NetBuf \*Pbuf2NetBuf(const struct NetDevice \*netdev, struct pbuf \*lwipBuf) | Converts the **pbuf** structure of lwIP to a **NetBuf**.|
</td>
| struct pbuf \*NetBuf2Pbuf(const struct NetBuf \*nb) | Converts a **NetBuf** to the **pbuf** structure of lwIP.|
</tr>
</tbody>
- The WLAN Driver module also provides APIs that you need to fill in the implementation. This type of APIs can be used to initialize/deinitialize a **NetDevice**, opening/stopping a **NetDevice**, and obtaining the **NetDevice** status. Table 4 describes some of these APIs.
</table>
**Table 4** net_device.h
The WLAN driver module provides APIs for driver developers, such as initializing/deregistering, opening/stopping a **NetDevice**, and obtaining the state of a **NetDevice**. [Table 2](#table74613501475) describes some APIs.
| API| Description|
**Table 2** APIs for driver developers of WLAN vendors to implement
| -------- | -------- |
| int32_t (\*init)(struct NetDevice \*netDev) | Initializes a **NetDevice**.|
<aname="table74613501475"></a>
| struct NetDevStats \*(\*getStats)(struct NetDevice \*netDev) | Obtains the state of a **NetDevice**.|
- The WLAN Driver module also provides APIs to the HDI layer for creating and destroying an **IWiFi** object and setting the MAC address. Tables 5 and 6 describe some of the APIs.
| int32_t WifiConstruct(struct IWiFi \*\*wifiInstance) | Creates an **IWiFi** object with basic capabilities.|
<tdclass="cellrowborder"valign="top"width="26.5%"headers="mcps1.2.4.1.3 "><pid="p18822442135411"><aname="p18822442135411"></a><aname="p18822442135411"></a>Initializes a <strongid="b1947112374310"><aname="b1947112374310"></a><aname="b1947112374310"></a>NetDevice</strong>.</p>
| int32_t WifiDestruct(struct IWiFi \*\*wifiInstance) | Destroys an **IWiFi** object.|
</td>
| int32_t (\*start)(struct IWiFi \*) | Creates a channel between the HAL and the driver and obtains the NICs supported by the driver.|
</tr>
| int32_t (\*stop)(struct IWiFi \*) | Stops the channel between the HAL and the driver.|
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p5900163115564"><aname="p5900163115564"></a><aname="p5900163115564"></a>Obtains the state of a <strongid="b4952125574216"><aname="b4952125574216"></a><aname="b4952125574216"></a>NetDevice</strong>.</p>
| int32_t (\*setMacAddress)(const struct IWiFiBaseFeature \*, unsigned char \*, uint8_t) | Sets the MAC address.|
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p122001431115713"><aname="p122001431115713"></a><aname="p122001431115713"></a>Sets the MAC address.</p>
| int32_t (\*getDeviceMacAddress)(const struct IWiFiBaseFeature \*, unsigned char \*, uint8_t) | Obtains the device MAC address.|
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p14845675719"><aname="p14845675719"></a><aname="p14845675719"></a>Deinitializes a <strongid="b18383143517427"><aname="b18383143517427"></a><aname="b18383143517427"></a>NetDevice</strong>.</p>
</td>
The WLAN driver module developed based on the HDF and Platform frameworks provides a unified driver model for WLAN modules of different vendors regardless of the OS and system on a chip (SoC).
1. Configure hardware (such as modules and chips) parameters in the **wifi_config.hcs** file. This configuration file is parsed by the corresponding API in the HDF to generate a structure object for full configuration.
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p164825613576"><aname="p164825613576"></a><aname="p164825613576"></a>Opens a <strongid="b226313919425"><aname="b226313919425"></a><aname="b226313919425"></a>NetDevice</strong>.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1982212428542"><aname="p1982212428542"></a><aname="p1982212428542"></a>Stops a <strongid="b81039430429"><aname="b81039430429"></a><aname="b81039430429"></a>NetDevice</strong>.</p>
4. Implement the upper-layer Wi-Fi Protected Access (WPA) service.
</td>
</tr>
### Development Example
</tbody>
</table>
The WLAN driver provides the HDI layer with the APIs for creating and destroying an **IWiFi** object and setting the MAC address. [Table 3](#table141076311618) describes some APIs.
<tdclass="cellrowborder"valign="top"width="24.59%"headers="mcps1.2.4.1.3 "><pid="p12108133112115"><aname="p12108133112115"></a><aname="p12108133112115"></a>Creates an <strongid="b218481014265"><aname="b218481014265"></a><aname="b218481014265"></a>IWiFi</strong> object with basic capabilities.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1010810315118"><aname="p1010810315118"></a><aname="p1010810315118"></a>Destroys an <strongid="b1269381514265"><aname="b1269381514265"></a><aname="b1269381514265"></a>IWiFi</strong> object.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p9108113116119"><aname="p9108113116119"></a><aname="p9108113116119"></a>Creates a channel between the HAL and the driver and obtains the NIC supported by the driver.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p12108183112110"><aname="p12108183112110"></a><aname="p12108183112110"></a>Stops the channel between the HAL and the driver.</p>
<tdclass="cellrowborder"valign="top"width="24.59%"headers="mcps1.2.4.1.3 "><pid="p910843113113"><aname="p910843113113"></a><aname="p910843113113"></a>Obtains the feature type.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p101081031818"><aname="p101081031818"></a><aname="p101081031818"></a>Sets the MAC address.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p1110810312012"><aname="p1110810312012"></a><aname="p1110810312012"></a>Obtains the device MAC address.</p>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p410817311911"><aname="p410817311911"></a><aname="p410817311911"></a>Sets the transmit power.</p>
</td>
</tr>
</tbody>
</table>
## How to Develop<a name="section15957746172412"></a>
The WLAN driver is developed based on the HDF and PLATFORM. It provides a unified driver model for WLAN modules of different vendors regardless of the operating system \(OS\) and system on a chip \(SoC\).
1. Set hardware parameters such as **module**\(different features\) and **chip** in the **wifi\_config.hcs** file.
2. Parse the **wifi\_config.hcs** file and generate a structure with the configured parameters.
>Some of the above adaptation steps have been provided. For details, see [Development Example](#section1395253612512). The steps waiting to be performed by developers include setting configuration parameters based on hardware attributes, adapting and mounting a chip, and performing tests and verification.
## Development Example<a name="section1395253612512"></a>
This example describes how to initialize a WLAN module. The following uses the Hi3881 WLAN chip as an example:
This example describes how to initialize a WLAN module. The following uses the Hi3881 WLAN chip as an example:
1. Set parameters for the WLAN module based on hardware attributes.
1. Set parameters for the WLAN module based on hardware attributes.
```
```
/* Set parameters in the wlan_platform.hcs file based on hardware attributes. The following is an example of the WLAN platform configuration. */
/* Set parameters in the wlan_platform.hcs file based on hardware attributes. The following is an example of the WLAN platform configuration. */
...
@@ -246,29 +167,29 @@ hisi :& deviceList {
...
@@ -246,29 +167,29 @@ hisi :& deviceList {
deviceInstId = 0;
deviceInstId = 0;
powers {
powers {
power0 {
power0 {
powerSeqDelay = 0; /* Power supply sequencing delay */
powerSeqDelay = 0; /* Power sequence delay. */
powerType = 1; /* Power supply type. Value 0 indicates that the power supply is always on, and value 1 indicates power supply through general-purpose input/output (GPIO). */
powerType = 1; /* Power supply type. The value 0 indicates that the device is always powered on, and 1 indicates power supply through general-purpose input/output (GPIO). */
gpioId = 1; /* GPIO pin ID */
gpioId = 1; /* GPIO pin number. */
activeLevel=1; /* Active level. Value 0 indicates a low level, and value 1 indicates a high level. */
activeLevel=1; /* Active level. The value 0 indicates low level, and 1 indicates high level. */
}
}
power1 {
power1 {
powerSeqDelay = 0; /* Power supply sequencing delay */
powerSeqDelay = 0; /* Power sequence delay. */
powerType = 0; /* Power supply type. Value 0 indicates that the power supply is always on, and value 1 indicates power supply through GPIO. */
powerType = 0; /* The value 0 indicates that the device is always powered on, and 1 indicates power supply through GPIO. */
}
}
}
}
reset {
reset {
resetType = 0; /* Reset type. Value 0 indicates that reset is not supported, and value 1 indicates reset through GPIO. */
resetType = 0; /* Reset type. The value 0 indicates that reset is dynamically determined, and value 1 indicates reset through GPIO. */
gpioId = 2; /* GPIO pin ID */
gpioId = 2; /* GPIO pin number. */
activeLevel=1; /* Active level. Value 0 indicates a low level, and value 1 indicates a high level. */
activeLevel=1; /* Active level. The value 0 indicates low level, and 1 indicates high level. */
resetHoldTime = 30; /* Hold time (ms) for a reset */
resetHoldTime = 30; /* Hold time (ms) after a reset. */
3. During the chip initialization, call the **NetDeviceInit\(\)** function to initialize a network device, call the **NetDeviceAdd\(\)** function to add the network device to a protocol stack, and implement some function pointers of **netdev**.
3. During the chip initialization process, call **NetDeviceInit()** to initialize a network device, call **NetDeviceAdd()** to add the network device to a protocol stack, and hook function pointers of **netdev**.