1e41f4b71Sopenharmony_ci# WLAN
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci
4e41f4b71Sopenharmony_ci## Overview
5e41f4b71Sopenharmony_ci
6e41f4b71Sopenharmony_ci### Function
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ciA wireless LAN (WLAN) allows users to easily connect to a wireless network to transmit and share data and move around within the area and remain connected to the network. The WLAN driver developed based on the Hardware Driver Foundation (HDF) shields hardware component differences and provides stable basic capability interfaces for upper-layer WLAN services, including starting a scan, associating with or disassociating from a hotspot, obtaining or setting MAC addresses, and obtaining link information.
9e41f4b71Sopenharmony_ci
10e41f4b71Sopenharmony_ci### Basic Concepts
11e41f4b71Sopenharmony_ci
12e41f4b71Sopenharmony_ciBefore development, you need to understand the following basic concepts related to WLAN:
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ci- AP
15e41f4b71Sopenharmony_ci  
16e41f4b71Sopenharmony_ci  A wireless access point (AP) is a central node of a network that provides the wireless access service. Once connecting to the wireless network, the device can access data.
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ci- STA
19e41f4b71Sopenharmony_ci  
20e41f4b71Sopenharmony_ci  A station (STA) is a basic component of a WLAN. Each terminal connected to a WLAN, such as a notebook and a personal digital assistant (PDA), is an STA.
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci- SSID
23e41f4b71Sopenharmony_ci  
24e41f4b71Sopenharmony_ci  A service set identifier (SSID) identifies a wireless network. Each WLAN has its SSID.
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci- bssid
27e41f4b71Sopenharmony_ci  
28e41f4b71Sopenharmony_ci  A basic service set identifier (BSSID) is a 48-bit MAC address that uniquely identifies a basic service set on a WLAN.
29e41f4b71Sopenharmony_ci  
30e41f4b71Sopenharmony_ci- Scan
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ci  A terminal device scans the wireless network to obtain visible wireless network information, including the hotspot SSID, operating frequency band, and signal strength.
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ci- Associate
35e41f4b71Sopenharmony_ci
36e41f4b71Sopenharmony_ci  When a terminal device is associated with a valid hotspot, it can communicate with the AP. A device (STA) can set up a connection with only one AP at a time.
37e41f4b71Sopenharmony_ci
38e41f4b71Sopenharmony_ci### Working Principles
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ciThis document describes how to develop WLAN functions based on the HDF. The following figure shows the WLAN framework.
41e41f4b71Sopenharmony_ci
42e41f4b71Sopenharmony_ci![image](figures/WLAN-driver-framework.png "WLAN Framework")
43e41f4b71Sopenharmony_ci
44e41f4b71Sopenharmony_ci1. The upper-layer service calls a hardware device interface (HDI) based on service requirements to deliver user-mode messages to the client through the Wi-Fi Protected Access (WPA) layer or hardware abstraction layer (HAL). The WPA layer provides interfaces for setting the encryption mode, associating with a hotspot, setting a channel, and hiding the hotspot. As a supplement to the WPA layer, the HAL provides APIs for setting the country code or MAC address and obtaining channel information.
45e41f4b71Sopenharmony_ci   
46e41f4b71Sopenharmony_ci2. The Message module distributes user-mode messages to modules, such as the AP and STA, by component.
47e41f4b71Sopenharmony_ci   
48e41f4b71Sopenharmony_ci3. Hdf_Mac80211 defines MAC-layer interfaces for underlying drivers. The command field is delivered to Hdf_Mac80211 and then sent to the WLAN chip firmware through the Bus module.
49e41f4b71Sopenharmony_ci   
50e41f4b71Sopenharmony_ci4. The Bus module provides unified bus abstraction interfaces for the upper layer. It shields the differences between kernels by calling the Secure Digital Input Output (SDIO) interfaces provided by the platform layer and encapsulating the USB and PCIe interfaces. The Bus module also encapsulates different types of bus operations in a unified manner to shield differences between chipsets. The interfaces provided by the Bus module simplify and streamline the development of different chip vendors.
51e41f4b71Sopenharmony_ci   
52e41f4b71Sopenharmony_ci5. Extensible Authentication Protocol (EAP) over LAN (EAPOL) is a LAN-based extended authentication protocol. It is used to transmit EAP packets between a client and a device (access device or server) so that EAP packets can be transmitted on a LAN to complete the authentication process and enable the device to go online.
53e41f4b71Sopenharmony_ci   
54e41f4b71Sopenharmony_ci6. NetDevice creates dedicated network devices to shield differences between OSs. It provides unified interfaces for Wi-Fi drivers, unified HDF NetDevice data structs, and unified management, registration, and deregistration capabilities, and connects to the Linux network device layer on OpenHarmony devices.
55e41f4b71Sopenharmony_ci   
56e41f4b71Sopenharmony_ci7. NetBuf encapsulates the unified data structure of the Linux or LiteOS native network data buffer and the operation interfaces for network data.
57e41f4b71Sopenharmony_ci   
58e41f4b71Sopenharmony_ci8. The protocol stack works with the NetDevice and NetBuf modules to exchange data flows.
59e41f4b71Sopenharmony_ci
60e41f4b71Sopenharmony_ci### Constraints
61e41f4b71Sopenharmony_ci
62e41f4b71Sopenharmony_ciThe WLAN driver provides basic capability interfaces for upper-layer WLAN services. The HDI interfaces apply to the standard system, and the HAL interfaces apply to mini and small systems.
63e41f4b71Sopenharmony_ci
64e41f4b71Sopenharmony_ci## Development Guidelines
65e41f4b71Sopenharmony_ci
66e41f4b71Sopenharmony_ci### When to Use
67e41f4b71Sopenharmony_ci
68e41f4b71Sopenharmony_ciThe WLAN driver provides basic capability interfaces for upper-layer WLAN services to ensure that users can easily access the wireless network and transmit and share data. Refer to the following when you adapt your WLAN module to OpenHarmony.
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ci### Available APIs
71e41f4b71Sopenharmony_ci
72e41f4b71Sopenharmony_ciThe WLAN module provides the following APIs:
73e41f4b71Sopenharmony_ci
74e41f4b71Sopenharmony_ci1. HDI and HAL APIs for upper-layer services
75e41f4b71Sopenharmony_ci
76e41f4b71Sopenharmony_ci2. APIs for vendors
77e41f4b71Sopenharmony_ci
78e41f4b71Sopenharmony_ci3. WLAN APIs directly called by drivers
79e41f4b71Sopenharmony_ci
80e41f4b71Sopenharmony_ci- This interfaces provided by the WLAN Driver module for upper-layer services can be used to create or destroy an IWiFi object, and set MAC addresses or transmit power. Table 1 and Table 2 list the C function interfaces generated based on the IDL interface description. For details about the interface declaration, see the IDL files (**/drivers/interface/wlan/v1_1/**).
81e41f4b71Sopenharmony_ci
82e41f4b71Sopenharmony_ci    **Table 1** wifi_hal.h
83e41f4b71Sopenharmony_ci
84e41f4b71Sopenharmony_ci  | API| Description|
85e41f4b71Sopenharmony_ci  | -------- | -------- |
86e41f4b71Sopenharmony_ci  | int32_t WifiConstruct(struct IWiFi \*\*wifiInstance) | Creates an **IWiFi** instance with basic capabilities.|
87e41f4b71Sopenharmony_ci  | int32_t WifiDestruct(struct IWiFi \*\*wifiInstance) | Destroys an **IWiFi** instance.|
88e41f4b71Sopenharmony_ci  | int32_t (\*start)(struct IWiFi \*) | Creates a channel between the HAL and the driver and obtains the NICs supported by the driver.|
89e41f4b71Sopenharmony_ci  | int32_t (\*stop)(struct IWiFi \*) | Stops the channel between the HAL and the driver.|
90e41f4b71Sopenharmony_ci
91e41f4b71Sopenharmony_ci    **Table 2** wifi_hal_base_feature.h
92e41f4b71Sopenharmony_ci
93e41f4b71Sopenharmony_ci  | API| Description|
94e41f4b71Sopenharmony_ci  | -------- | -------- |
95e41f4b71Sopenharmony_ci  | int32_t (\*getFeatureType)(const struct IWiFiBaseFeature \*) | Obtains the feature type.|
96e41f4b71Sopenharmony_ci  | int32_t (\*setMacAddress)(const struct IWiFiBaseFeature \*, unsigned char \*, uint8_t) | Sets the MAC address.|
97e41f4b71Sopenharmony_ci  | int32_t (\*getDeviceMacAddress)(const struct IWiFiBaseFeature \*, unsigned char \*, uint8_t) | Obtains the device MAC address.|
98e41f4b71Sopenharmony_ci  | int32_t (\*setTxPower)(const struct IWiFiBaseFeature \*, int32_t) | Sets the transmit power.|
99e41f4b71Sopenharmony_ci
100e41f4b71Sopenharmony_ci- The WLAN Driver module also provides APIs that you need to fill in the implementation. These APIs can be used to initialize or deregister a network device, open or stop a network device, and obtain network device status. Table 3 describes some APIs.
101e41f4b71Sopenharmony_ci
102e41f4b71Sopenharmony_ci    **Table 3** net_device.h
103e41f4b71Sopenharmony_ci
104e41f4b71Sopenharmony_ci  | API| Description|
105e41f4b71Sopenharmony_ci  | -------- | -------- |
106e41f4b71Sopenharmony_ci  | int32_t (\*init)(struct NetDevice \*netDev) | Initializes a network device.|
107e41f4b71Sopenharmony_ci  | struct NetDevStats \*(\*getStats)(struct NetDevice \*netDev) | Obtains the state of a network device.|
108e41f4b71Sopenharmony_ci  | int32_t (\*setMacAddr)(struct NetDevice \*netDev, void \*addr) | Sets the MAC address.|
109e41f4b71Sopenharmony_ci  | void (\*deInit)(struct NetDevice \*netDev) | Deinitializes a network device.|
110e41f4b71Sopenharmony_ci  | int32_t (\*open)(struct NetDevice \*netDev) | Opens a network device.|
111e41f4b71Sopenharmony_ci  | int32_t (\*stop)(struct NetDevice \*netDev) | Stops a network device.|
112e41f4b71Sopenharmony_ci
113e41f4b71Sopenharmony_ci- 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** struct of Lightweight IP (lwIP) and a **NetBuf**.
114e41f4b71Sopenharmony_ci
115e41f4b71Sopenharmony_ci  Tables 4 to 6 list the APIs that can be directly called.
116e41f4b71Sopenharmony_ci
117e41f4b71Sopenharmony_ci  **Table 4** wifi_module.h
118e41f4b71Sopenharmony_ci
119e41f4b71Sopenharmony_ci  | API| Description|
120e41f4b71Sopenharmony_ci  | -------- | -------- |
121e41f4b71Sopenharmony_ci  | struct WifiModule \*WifiModuleCreate(const struct HdfConfigWifiModuleConfig \*config) | Creates a **WifiModule**.|
122e41f4b71Sopenharmony_ci  | void WifiModuleDelete(struct WifiModule \*module) | Deletes a **WifiModule** and releases its data.|
123e41f4b71Sopenharmony_ci  | int32_t DelFeature(struct WifiModule \*module, uint16_t featureType) | Deletes a feature from a **WifiModule**.|
124e41f4b71Sopenharmony_ci  | int32_t&nbsp;AddFeature(struct&nbsp;WifiModule&nbsp;\*module,&nbsp;uint16_t&nbsp;featureType,<br>&nbsp;struct&nbsp;WifiFeature&nbsp;\*featureData) | Adds a feature to a **WifiModule**.|
125e41f4b71Sopenharmony_ci
126e41f4b71Sopenharmony_ci  **Table 5** wifi_mac80211_ops.h
127e41f4b71Sopenharmony_ci
128e41f4b71Sopenharmony_ci  | API| Description|
129e41f4b71Sopenharmony_ci  | -------- | -------- |
130e41f4b71Sopenharmony_ci  | int32_t&nbsp;(\*startAp)(NetDevice&nbsp;\*netDev) | Starts an AP.|
131e41f4b71Sopenharmony_ci  | int32_t&nbsp;(\*stopAp)(NetDevice&nbsp;\*netDev) | Stops an AP.|
132e41f4b71Sopenharmony_ci  | int32_t&nbsp;(\*connect)(NetDevice&nbsp;\*netDev,&nbsp;WifiConnectParams&nbsp;\*param) | Connects to a hotspot.|
133e41f4b71Sopenharmony_ci  | int32_t&nbsp;(\*disconnect)(NetDevice&nbsp;\*netDev,&nbsp;uint16_t&nbsp;reasonCode) | Disconnects from a hotspot.|
134e41f4b71Sopenharmony_ci
135e41f4b71Sopenharmony_ci  **Table 6** hdf_netbuf.h
136e41f4b71Sopenharmony_ci
137e41f4b71Sopenharmony_ci  | API| Description|
138e41f4b71Sopenharmony_ci  | -------- | -------- |
139e41f4b71Sopenharmony_ci  | static&nbsp;inline&nbsp;void&nbsp;NetBufQueueInit(struct&nbsp;NetBufQueue&nbsp;\*q) | Initializes a **NetBuf** queue.|
140e41f4b71Sopenharmony_ci  | struct&nbsp;NetBuf&nbsp;\*NetBufAlloc(uint32_t&nbsp;size) | Allocates a **NetBuf**.|
141e41f4b71Sopenharmony_ci  | void&nbsp;NetBufFree(struct&nbsp;NetBuf&nbsp;\*nb) | Releases a **NetBuf**.|
142e41f4b71Sopenharmony_ci  | struct&nbsp;NetBuf&nbsp;\*Pbuf2NetBuf(const&nbsp;struct&nbsp;NetDevice&nbsp;\*netdev,&nbsp;struct&nbsp;pbuf&nbsp;\*lwipBuf) | Converts the **pbuf** structure of lwIP to a **NetBuf**.|
143e41f4b71Sopenharmony_ci  | struct&nbsp;pbuf&nbsp;\*NetBuf2Pbuf(const&nbsp;struct&nbsp;NetBuf&nbsp;\*nb) | Converts a **NetBuf** to the **pbuf** structure of lwIP.|
144e41f4b71Sopenharmony_ci
145e41f4b71Sopenharmony_ci### How to Develop
146e41f4b71Sopenharmony_ci
147e41f4b71Sopenharmony_ciThe WLAN driver framework developed based on the HDF and Platform framework provides a unified driver model for vendors regardless of the OS and system on a chip (SoC). When developing your WLAN driver based on the WLAN driver framework, you need to make adaptation. The following uses the Hi3881 WLAN chip as an example.
148e41f4b71Sopenharmony_ci
149e41f4b71Sopenharmony_ci#### Configuring the HCS for the Driver
150e41f4b71Sopenharmony_ci
151e41f4b71Sopenharmony_ci   The HDF configuration source (HCS) includes device configuration and component configuration.
152e41f4b71Sopenharmony_ci
153e41f4b71Sopenharmony_ci   - Device configuration
154e41f4b71Sopenharmony_ci
155e41f4b71Sopenharmony_ci     The configuration file contains the power supply, reset, and bus configuration.
156e41f4b71Sopenharmony_ci
157e41f4b71Sopenharmony_ci     Configuration file path: **vendor/<vendor name>/<device name >/hdf_config/khdf/wifi**
158e41f4b71Sopenharmony_ci
159e41f4b71Sopenharmony_ci     Configure device parameters in **wlan_platform.hcs** based on the device you use. The following is an example of WLAN platform configuration.
160e41f4b71Sopenharmony_ci        ```text
161e41f4b71Sopenharmony_ci        hisi :& deviceList {
162e41f4b71Sopenharmony_ci            device0 :: deviceInst {
163e41f4b71Sopenharmony_ci                deviceInstId = 0;
164e41f4b71Sopenharmony_ci                powers {
165e41f4b71Sopenharmony_ci                    power0 {
166e41f4b71Sopenharmony_ci                        powerSeqDelay = 0;  /* Power sequence delay. */
167e41f4b71Sopenharmony_ci                        powerType = 1;      /* Power supply type. The value 0 indicates that the device is always on. The value 1 indicates power supply through GPIO. */
168e41f4b71Sopenharmony_ci                        gpioId = 1;         /* GPIO pin number. */
169e41f4b71Sopenharmony_ci                        activeLevel=1;      /* Active level. The value 0 indicates low level, and 1 indicates high level. */
170e41f4b71Sopenharmony_ci                    }
171e41f4b71Sopenharmony_ci                    power1 {
172e41f4b71Sopenharmony_ci                        powerSeqDelay = 0;  /* Power sequence delay. */
173e41f4b71Sopenharmony_ci                        powerType = 0;      /* Power supply type. The value 0 indicates that the device is always on. The value 1 indicates power supply through GPIO. */
174e41f4b71Sopenharmony_ci                    }
175e41f4b71Sopenharmony_ci                }
176e41f4b71Sopenharmony_ci                reset {
177e41f4b71Sopenharmony_ci                    resetType = 0;          /* Reset type. The value 0 indicates that reset is dynamically determined, and 1 indicates reset through GPIO. */
178e41f4b71Sopenharmony_ci                    gpioId = 2;             /* GPIO pin number. */
179e41f4b71Sopenharmony_ci                    activeLevel=1;          /* Active level. The value 0 indicates low level, and 1 indicates high level. */
180e41f4b71Sopenharmony_ci                    resetHoldTime = 30;     /* Hold time (ms) after a reset. */
181e41f4b71Sopenharmony_ci                }
182e41f4b71Sopenharmony_ci                bootUpTimeout = 30;         /* Boot timeout duration (ms). */
183e41f4b71Sopenharmony_ci                bus {
184e41f4b71Sopenharmony_ci                    busEnable = 1;          /* Whether to initialize the bus. The value 1 means to initialize the bus; the value 0 means the opposite. */
185e41f4b71Sopenharmony_ci                    busType = 0;            /* Bus type. The value 0 indicates SDIO. */
186e41f4b71Sopenharmony_ci                    busId = 2;              /* Bus number. */
187e41f4b71Sopenharmony_ci                    funcNum = [1];          /* SDIO function number. */
188e41f4b71Sopenharmony_ci                    timeout = 1000;         /* Timeout duration for data read/write. */
189e41f4b71Sopenharmony_ci                    blockSize = 512;        /* Size of the data block to read or write. */
190e41f4b71Sopenharmony_ci                }
191e41f4b71Sopenharmony_ci            }
192e41f4b71Sopenharmony_ci        }
193e41f4b71Sopenharmony_ci        ```
194e41f4b71Sopenharmony_ci   - Component configuration
195e41f4b71Sopenharmony_ci
196e41f4b71Sopenharmony_ci     Add a configuration file **wlan_chip_.hcs** for each chip, for example, **wlan_chip_hi3881.hcs**, and configure related parameters. The following is a configuration example of hi3881.
197e41f4b71Sopenharmony_ci        ```text
198e41f4b71Sopenharmony_ci        root {
199e41f4b71Sopenharmony_ci            wlan_config {
200e41f4b71Sopenharmony_ci                hi3881 :& chipList {
201e41f4b71Sopenharmony_ci                    chipHi3881 :: chipInst {
202e41f4b71Sopenharmony_ci                        match_attr = "hdf_wlan_chips_hi3881"; /* Attribute used to match the chip. */
203e41f4b71Sopenharmony_ci                        chipName = "hi3881";                  /* WLAN chip name. */
204e41f4b71Sopenharmony_ci                        bus {
205e41f4b71Sopenharmony_ci                            vendorId = 0x0296;                /* Vendor ID. */
206e41f4b71Sopenharmony_ci                            deviceId = [0x5347];              /* Device ID. */
207e41f4b71Sopenharmony_ci                        }
208e41f4b71Sopenharmony_ci                    }
209e41f4b71Sopenharmony_ci                }
210e41f4b71Sopenharmony_ci            }
211e41f4b71Sopenharmony_ci        }
212e41f4b71Sopenharmony_ci        ```
213e41f4b71Sopenharmony_ci
214e41f4b71Sopenharmony_ci#### Initializing and deinitializing the WLAN Chip and WLAN Chip Driver
215e41f4b71Sopenharmony_ci
216e41f4b71Sopenharmony_ci   - Implement the driver adaptation entry function
217e41f4b71Sopenharmony_ci
218e41f4b71Sopenharmony_ci     Define a variable of the HdfDriverEntry type based on the chip to hook functions of **Bind()**, **Init()**, and **Release()**. Call **HDF_INIT** to register the driver entry with the HDF. During driver loading, the HDF calls the **Bind** function and then the **Init** function to load the driver. If **Init()** fails to be called, the HDF calls **Release()** to release driver resources.
219e41f4b71Sopenharmony_ci     ```c
220e41f4b71Sopenharmony_ci     struct HdfDriverEntry g_hdfHisiChipEntry = {
221e41f4b71Sopenharmony_ci        .moduleVersion = 1,
222e41f4b71Sopenharmony_ci        .Bind = HdfWlanHisiDriverBind,
223e41f4b71Sopenharmony_ci        .Init = HdfWlanHisiChipDriverInit,
224e41f4b71Sopenharmony_ci        .Release = HdfWlanHisiChipRelease,
225e41f4b71Sopenharmony_ci        .moduleName = "HDF_WLAN_CHIPS"
226e41f4b71Sopenharmony_ci     };
227e41f4b71Sopenharmony_ci
228e41f4b71Sopenharmony_ci     HDF_INIT(g_hdfHisiChipEntry);
229e41f4b71Sopenharmony_ci     ```
230e41f4b71Sopenharmony_ci
231e41f4b71Sopenharmony_ci   - Register the functions for initializing the chip and chip driver
232e41f4b71Sopenharmony_ci     
233e41f4b71Sopenharmony_ci     Hook the chip initialization function to **InitChip()** and the chip deinitialization function to **DeinitChip()**.
234e41f4b71Sopenharmony_ci
235e41f4b71Sopenharmony_ci     Hook the chip driver initialization function to **Build()** and the chip driver deinitialization function to **Release()**.
236e41f4b71Sopenharmony_ci
237e41f4b71Sopenharmony_ci     ```c
238e41f4b71Sopenharmony_ci     /* Register WLAN chip functions. */
239e41f4b71Sopenharmony_ci     static int32_t HDFWlanRegHisiDriverFactory(void)
240e41f4b71Sopenharmony_ci     {
241e41f4b71Sopenharmony_ci         static struct HdfChipDriverFactory tmpFactory = { 0 };
242e41f4b71Sopenharmony_ci         struct HdfChipDriverManager *driverMgr = NULL;
243e41f4b71Sopenharmony_ci         driverMgr = HdfWlanGetChipDriverMgr();
244e41f4b71Sopenharmony_ci         if (driverMgr == NULL) {
245e41f4b71Sopenharmony_ci             HDF_LOGE("%s fail: driverMgr is NULL!", __func__);
246e41f4b71Sopenharmony_ci             return HDF_FAILURE;
247e41f4b71Sopenharmony_ci         }
248e41f4b71Sopenharmony_ci         tmpFactory.driverName = HI3881_DRIVER_NAME;
249e41f4b71Sopenharmony_ci         tmpFactory.GetMaxIFCount = GetHi3881GetMaxIFCount;
250e41f4b71Sopenharmony_ci         tmpFactory.InitChip = InitHi3881Chip;
251e41f4b71Sopenharmony_ci         tmpFactory.DeinitChip = DeinitHi3881Chip;
252e41f4b71Sopenharmony_ci         tmpFactory.Build = BuildHi3881Driver;
253e41f4b71Sopenharmony_ci         tmpFactory.Release = ReleaseHi3881Driver;
254e41f4b71Sopenharmony_ci         tmpFactory.ReleaseFactory = NULL;
255e41f4b71Sopenharmony_ci         if (driverMgr->RegChipDriver(&tmpFactory) != HDF_SUCCESS) {
256e41f4b71Sopenharmony_ci             HDF_LOGE("%s fail: driverMgr is NULL!", __func__);
257e41f4b71Sopenharmony_ci             return HDF_FAILURE;
258e41f4b71Sopenharmony_ci         }
259e41f4b71Sopenharmony_ci
260e41f4b71Sopenharmony_ci         return HDF_SUCCESS;
261e41f4b71Sopenharmony_ci     }
262e41f4b71Sopenharmony_ci
263e41f4b71Sopenharmony_ci     static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device)
264e41f4b71Sopenharmony_ci     {
265e41f4b71Sopenharmony_ci         (void)device;
266e41f4b71Sopenharmony_ci         return HDFWlanRegHisiDriverFactory();
267e41f4b71Sopenharmony_ci     }
268e41f4b71Sopenharmony_ci     ```
269e41f4b71Sopenharmony_ci
270e41f4b71Sopenharmony_ci     1. Initialize and deinitialize the chip.
271e41f4b71Sopenharmony_ci
272e41f4b71Sopenharmony_ci      ```c
273e41f4b71Sopenharmony_ci      /* Function for initializing the WLAN chip. */
274e41f4b71Sopenharmony_ci      int32_t InitHi3881Chip(struct HdfWlanDevice *device)
275e41f4b71Sopenharmony_ci      {
276e41f4b71Sopenharmony_ci          uint8_t maxPortCount = 3;
277e41f4b71Sopenharmony_ci          int32_t ret = HI_SUCCESS;
278e41f4b71Sopenharmony_ci          uint8_t maxRetryCount = 3;
279e41f4b71Sopenharmony_ci          if (device == NULL || device->bus == NULL) {
280e41f4b71Sopenharmony_ci              HDF_LOGE("%s:NULL ptr!", __func__);
281e41f4b71Sopenharmony_ci              return HI_FAIL;
282e41f4b71Sopenharmony_ci          }
283e41f4b71Sopenharmony_ci
284e41f4b71Sopenharmony_ci          do {
285e41f4b71Sopenharmony_ci              if (ret != HI_SUCCESS) {
286e41f4b71Sopenharmony_ci                  if (device->reset != NULL && device->reset->Reset != NULL) {
287e41f4b71Sopenharmony_ci                      device->reset->Reset(device->reset);
288e41f4b71Sopenharmony_ci                  }
289e41f4b71Sopenharmony_ci                  HDF_LOGE("%s:Retry init hi3881!last ret=%d", __func__, ret);
290e41f4b71Sopenharmony_ci              }
291e41f4b71Sopenharmony_ci              ret = hi_wifi_init(maxPortCount, device->bus);
292e41f4b71Sopenharmony_ci          } while (ret != 0 && --maxRetryCount > 0);
293e41f4b71Sopenharmony_ci
294e41f4b71Sopenharmony_ci          if (ret != 0) {
295e41f4b71Sopenharmony_ci              HDF_LOGE("%s:Init hi3881 driver failed!", __func__);
296e41f4b71Sopenharmony_ci              return ret;
297e41f4b71Sopenharmony_ci          }
298e41f4b71Sopenharmony_ci          return HI_SUCCESS;
299e41f4b71Sopenharmony_ci      }
300e41f4b71Sopenharmony_ci
301e41f4b71Sopenharmony_ci      /* Function for deinitializing the WLAN chip. */
302e41f4b71Sopenharmony_ci      int32_t DeinitHi3881Chip(struct HdfWlanDevice *device)
303e41f4b71Sopenharmony_ci      {
304e41f4b71Sopenharmony_ci          (void)device;
305e41f4b71Sopenharmony_ci          int32_t ret = hi_wifi_deinit();
306e41f4b71Sopenharmony_ci          if (ret != 0) {
307e41f4b71Sopenharmony_ci              HDF_LOGE("%s:Deinit failed!ret=%d", __func__, ret);
308e41f4b71Sopenharmony_ci          }
309e41f4b71Sopenharmony_ci          return ret;
310e41f4b71Sopenharmony_ci      }
311e41f4b71Sopenharmony_ci      ```
312e41f4b71Sopenharmony_ci
313e41f4b71Sopenharmony_ci     2. Initialize and deinitialize the chip driver.
314e41f4b71Sopenharmony_ci      
315e41f4b71Sopenharmony_ci      ```c
316e41f4b71Sopenharmony_ci      /* Hook the functions of the WLAN chip driver, mac80211, and chip. */
317e41f4b71Sopenharmony_ci      static struct HdfChipDriver *BuildHi3881Driver(struct HdfWlanDevice *device, uint8_t ifIndex)
318e41f4b71Sopenharmony_ci      {
319e41f4b71Sopenharmony_ci          struct HdfChipDriver *specificDriver = NULL;
320e41f4b71Sopenharmony_ci          if (device == NULL) {
321e41f4b71Sopenharmony_ci              HDF_LOGE("%s fail: channel is NULL!", __func__);
322e41f4b71Sopenharmony_ci              return NULL;
323e41f4b71Sopenharmony_ci          }
324e41f4b71Sopenharmony_ci          (void)ifIndex;
325e41f4b71Sopenharmony_ci          specificDriver = (struct HdfChipDriver *)OsalMemCalloc(sizeof(struct HdfChipDriver));
326e41f4b71Sopenharmony_ci          if (specificDriver == NULL) {
327e41f4b71Sopenharmony_ci              HDF_LOGE("%s fail: OsalMemCalloc fail!", __func__);
328e41f4b71Sopenharmony_ci              return NULL;
329e41f4b71Sopenharmony_ci          }
330e41f4b71Sopenharmony_ci          if (memset_s(specificDriver, sizeof(struct HdfChipDriver), 0, sizeof(struct HdfChipDriver)) != EOK) {
331e41f4b71Sopenharmony_ci              HDF_LOGE("%s fail: memset_s fail!", __func__);
332e41f4b71Sopenharmony_ci              OsalMemFree(specificDriver);
333e41f4b71Sopenharmony_ci              return NULL;
334e41f4b71Sopenharmony_ci          }
335e41f4b71Sopenharmony_ci
336e41f4b71Sopenharmony_ci          if (strcpy_s(specificDriver->name, MAX_WIFI_COMPONENT_NAME_LEN, HI3881_DRIVER_NAME) != EOK) {
337e41f4b71Sopenharmony_ci              HDF_LOGE("%s fail: strcpy_s fail!", __func__);
338e41f4b71Sopenharmony_ci              OsalMemFree(specificDriver);
339e41f4b71Sopenharmony_ci              return NULL;
340e41f4b71Sopenharmony_ci          }
341e41f4b71Sopenharmony_ci          specificDriver->init = Hi3881Init;
342e41f4b71Sopenharmony_ci          specificDriver->deinit = Hi3881Deinit;
343e41f4b71Sopenharmony_ci
344e41f4b71Sopenharmony_ci          HiMac80211Init(specificDriver);
345e41f4b71Sopenharmony_ci
346e41f4b71Sopenharmony_ci          return specificDriver;
347e41f4b71Sopenharmony_ci      }
348e41f4b71Sopenharmony_ci
349e41f4b71Sopenharmony_ci      /* Release the WLAN chip driver. */
350e41f4b71Sopenharmony_ci      static void ReleaseHi3881Driver(struct HdfChipDriver *chipDriver)
351e41f4b71Sopenharmony_ci      {
352e41f4b71Sopenharmony_ci          if (chipDriver == NULL) {
353e41f4b71Sopenharmony_ci              return;
354e41f4b71Sopenharmony_ci          }
355e41f4b71Sopenharmony_ci          if (strcmp(chipDriver->name, HI3881_DRIVER_NAME) != 0) {
356e41f4b71Sopenharmony_ci              HDF_LOGE("%s:Not my driver!", __func__);
357e41f4b71Sopenharmony_ci              return;
358e41f4b71Sopenharmony_ci          }
359e41f4b71Sopenharmony_ci          OsalMemFree(chipDriver);
360e41f4b71Sopenharmony_ci      }
361e41f4b71Sopenharmony_ci
362e41f4b71Sopenharmony_ci      /* Function for initializing the WLAN chip driver. */
363e41f4b71Sopenharmony_ci      int32_t Hi3881Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice)
364e41f4b71Sopenharmony_ci      {
365e41f4b71Sopenharmony_ci          hi_u16 mode;
366e41f4b71Sopenharmony_ci          int32_t ret;
367e41f4b71Sopenharmony_ci          nl80211_iftype_uint8 type;
368e41f4b71Sopenharmony_ci          (void)chipDriver;
369e41f4b71Sopenharmony_ci          HDF_LOGI("%s: start...", __func__);
370e41f4b71Sopenharmony_ci          mode = wal_get_vap_mode();
371e41f4b71Sopenharmony_ci          if (mode >= WAL_WIFI_MODE_BUTT) {
372e41f4b71Sopenharmony_ci              oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode);
373e41f4b71Sopenharmony_ci              return HI_FAIL;
374e41f4b71Sopenharmony_ci          }
375e41f4b71Sopenharmony_ci          if (mode == WAL_WIFI_MODE_STA) {
376e41f4b71Sopenharmony_ci              type = NL80211_IFTYPE_STATION;
377e41f4b71Sopenharmony_ci      #ifdef _PRE_WLAN_FEATURE_P2P
378e41f4b71Sopenharmony_ci               if (InitNetdev(netDevice, NL80211_IFTYPE_P2P_DEVICE) != HI_SUCCESS) {
379e41f4b71Sopenharmony_ci                  return HI_FAIL;
380e41f4b71Sopenharmony_ci              }
381e41f4b71Sopenharmony_ci      #endif
382e41f4b71Sopenharmony_ci          } else if (mode == WAL_WIFI_MODE_AP) {
383e41f4b71Sopenharmony_ci              type = NL80211_IFTYPE_AP;
384e41f4b71Sopenharmony_ci          } else {
385e41f4b71Sopenharmony_ci              oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode);
386e41f4b71Sopenharmony_ci              return HI_FAIL;
387e41f4b71Sopenharmony_ci          }
388e41f4b71Sopenharmony_ci          ret = wal_init_drv_wlan_netdev(type, WAL_PHY_MODE_11N, netDevice);
389e41f4b71Sopenharmony_ci          if (ret != HI_SUCCESS) {
390e41f4b71Sopenharmony_ci              oam_error_log2(0, OAM_SF_ANY, "wal_init_drv_netdev %s failed.l_return:%d\n", netDevice->name, ret);
391e41f4b71Sopenharmony_ci          }
392e41f4b71Sopenharmony_ci          return ret;
393e41f4b71Sopenharmony_ci      }
394e41f4b71Sopenharmony_ci
395e41f4b71Sopenharmony_ci      /* Function for deinitializing the WLAN chip driver. */
396e41f4b71Sopenharmony_ci      int32_t Hi3881Deinit(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice)
397e41f4b71Sopenharmony_ci      {
398e41f4b71Sopenharmony_ci          int32_t ret;
399e41f4b71Sopenharmony_ci          (void)chipDriver;
400e41f4b71Sopenharmony_ci          ret = DeinitNetdev(NL80211_IFTYPE_P2P_DEVICE);
401e41f4b71Sopenharmony_ci          if (ret != HI_SUCCESS) {
402e41f4b71Sopenharmony_ci              oam_error_log1(0, OAM_SF_ANY, "Hi3881Deinit: DeinitNetdev p2p device fail, ret = %d\n",  ret);
403e41f4b71Sopenharmony_ci              return ret;
404e41f4b71Sopenharmony_ci          }
405e41f4b71Sopenharmony_ci          return wal_deinit_drv_wlan_netdev(netDevice);
406e41f4b71Sopenharmony_ci      }
407e41f4b71Sopenharmony_ci
408e41f4b71Sopenharmony_ci      ```
409e41f4b71Sopenharmony_ci
410e41f4b71Sopenharmony_ci      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**.
411e41f4b71Sopenharmony_ci
412e41f4b71Sopenharmony_ci      ```c
413e41f4b71Sopenharmony_ci      hi_s32 wal_init_drv_wlan_netdev(nl80211_iftype_uint8 type, wal_phy_mode mode, oal_net_device_stru *netdev)
414e41f4b71Sopenharmony_ci      {
415e41f4b71Sopenharmony_ci          hi_char *ac_mode_str = NULL;
416e41f4b71Sopenharmony_ci          hi_s32 ret;
417e41f4b71Sopenharmony_ci          if (oal_unlikely(netdev == HI_NULL)) {
418e41f4b71Sopenharmony_ci              oam_error_log0(0, OAM_SF_ANY, "{netdev is null!}");
419e41f4b71Sopenharmony_ci              return HI_ERR_CODE_PTR_NULL;
420e41f4b71Sopenharmony_ci          }
421e41f4b71Sopenharmony_ci
422e41f4b71Sopenharmony_ci          do {
423e41f4b71Sopenharmony_ci              /* Initialize the network device. */
424e41f4b71Sopenharmony_ci              ret = wal_init_netdev(type, netdev);
425e41f4b71Sopenharmony_ci              if (ret != HI_SUCCESS) {
426e41f4b71Sopenharmony_ci                  break;
427e41f4b71Sopenharmony_ci              }
428e41f4b71Sopenharmony_ci
429e41f4b71Sopenharmony_ci              ret = wal_init_netif(type, netdev);
430e41f4b71Sopenharmony_ci              if (ret != HI_SUCCESS) {
431e41f4b71Sopenharmony_ci                  break;
432e41f4b71Sopenharmony_ci              }
433e41f4b71Sopenharmony_ci              ac_mode_str = "11bgn";
434e41f4b71Sopenharmony_ci              if (mode == WAL_PHY_MODE_11G) {
435e41f4b71Sopenharmony_ci                  ac_mode_str = "11bg";
436e41f4b71Sopenharmony_ci              } else if (mode == WAL_PHY_MODE_11B) {
437e41f4b71Sopenharmony_ci                  ac_mode_str = "11b";
438e41f4b71Sopenharmony_ci              }
439e41f4b71Sopenharmony_ci
440e41f4b71Sopenharmony_ci              ret = wal_ioctl_set_mode(netdev, ac_mode_str);
441e41f4b71Sopenharmony_ci          } while (false);
442e41f4b71Sopenharmony_ci
443e41f4b71Sopenharmony_ci          if (ret != HI_SUCCESS) {
444e41f4b71Sopenharmony_ci              wal_deinit_wlan_vap(netdev);
445e41f4b71Sopenharmony_ci              oal_net_unregister_netdev(netdev);
446e41f4b71Sopenharmony_ci              oal_net_clear_netdev(netdev);
447e41f4b71Sopenharmony_ci              return HI_FAIL;
448e41f4b71Sopenharmony_ci          }
449e41f4b71Sopenharmony_ci
450e41f4b71Sopenharmony_ci          return HI_SUCCESS;
451e41f4b71Sopenharmony_ci      }
452e41f4b71Sopenharmony_ci
453e41f4b71Sopenharmony_ci      /* Hook function pointers of netdev. For details, see NetDeviceInterFace. */
454e41f4b71Sopenharmony_ci      oal_net_device_ops_stru g_wal_net_dev_ops =
455e41f4b71Sopenharmony_ci      {
456e41f4b71Sopenharmony_ci         .getStats          = wal_netdev_get_stats,
457e41f4b71Sopenharmony_ci         .open               = wal_netdev_open,
458e41f4b71Sopenharmony_ci         .stop               = wal_netdev_stop,
459e41f4b71Sopenharmony_ci         .xmit         = hmac_bridge_vap_xmit,
460e41f4b71Sopenharmony_ci         .ioctl           = wal_net_device_ioctl,
461e41f4b71Sopenharmony_ci         .changeMtu         = oal_net_device_change_mtu,
462e41f4b71Sopenharmony_ci         .init              = oal_net_device_init,
463e41f4b71Sopenharmony_ci         .deInit            = oal_net_free_netdev,
464e41f4b71Sopenharmony_ci        
465e41f4b71Sopenharmony_ci         ......
466e41f4b71Sopenharmony_ci
467e41f4b71Sopenharmony_ci      };
468e41f4b71Sopenharmony_ci
469e41f4b71Sopenharmony_ci      hi_s32 wal_init_netif(nl80211_iftype_uint8 type, oal_net_device_stru *netdev, const oal_wireless_dev *wdev)
470e41f4b71Sopenharmony_ci      {
471e41f4b71Sopenharmony_ci          /* Add the network device to the protocol stack. */
472e41f4b71Sopenharmony_ci          hi_u32 ret = NetDeviceAdd(netdev, (Protocol80211IfType)type);
473e41f4b71Sopenharmony_ci
474e41f4b71Sopenharmony_ci          ...
475e41f4b71Sopenharmony_ci
476e41f4b71Sopenharmony_ci          return HI_SUCCESS;
477e41f4b71Sopenharmony_ci      }
478e41f4b71Sopenharmony_ci      ```
479e41f4b71Sopenharmony_ci
480e41f4b71Sopenharmony_ci#### Modifying the MAC Layer Interfaces
481e41f4b71Sopenharmony_ci
482e41f4b71Sopenharmony_ciAfter the user-mode message is delivered to the driver, the driver calls the corresponding MAC-layer capability interfaces.
483e41f4b71Sopenharmony_ci
484e41f4b71Sopenharmony_ci   ```c
485e41f4b71Sopenharmony_ci   /* Define the functions for implementing the basic capabilities in the MAC layer for the driver. */
486e41f4b71Sopenharmony_ci   static struct HdfMac80211BaseOps g_baseOps = {
487e41f4b71Sopenharmony_ci       .SetMode = WalSetMode,
488e41f4b71Sopenharmony_ci       .AddKey = WalAddKey,
489e41f4b71Sopenharmony_ci       .DelKey = WalDelKey,
490e41f4b71Sopenharmony_ci       .SetDefaultKey = WalSetDefaultKey,
491e41f4b71Sopenharmony_ci       .GetDeviceMacAddr = WalGetDeviceMacAddr,
492e41f4b71Sopenharmony_ci       .SetMacAddr = WalSetMacAddr,
493e41f4b71Sopenharmony_ci       .SetTxPower = WalSetTxPower,
494e41f4b71Sopenharmony_ci       .GetValidFreqsWithBand = WalGetValidFreqsWithBand,
495e41f4b71Sopenharmony_ci       .GetHwCapability = WalGetHwCapability
496e41f4b71Sopenharmony_ci   };
497e41f4b71Sopenharmony_ci
498e41f4b71Sopenharmony_ci   /* Define the functions for implementing the STA capabilities in the MAC layer for the driver. */
499e41f4b71Sopenharmony_ci   static struct HdfMac80211STAOps g_staOps = {
500e41f4b71Sopenharmony_ci       .Connect = WalConnect,
501e41f4b71Sopenharmony_ci       .Disconnect = WalDisconnect,
502e41f4b71Sopenharmony_ci       .StartScan = WalStartScan,
503e41f4b71Sopenharmony_ci       .AbortScan = WalAbortScan,
504e41f4b71Sopenharmony_ci       .SetScanningMacAddress = WalSetScanningMacAddress,
505e41f4b71Sopenharmony_ci   };
506e41f4b71Sopenharmony_ci
507e41f4b71Sopenharmony_ci   /* Define the functions for implementing the AP capabilities in the MAC layer for the driver. */
508e41f4b71Sopenharmony_ci   static struct HdfMac80211APOps g_apOps = {
509e41f4b71Sopenharmony_ci       .ConfigAp = WalConfigAp,
510e41f4b71Sopenharmony_ci       .StartAp = WalStartAp,
511e41f4b71Sopenharmony_ci       .StopAp = WalStopAp,
512e41f4b71Sopenharmony_ci       .ConfigBeacon = WalChangeBeacon,
513e41f4b71Sopenharmony_ci       .DelStation = WalDelStation,
514e41f4b71Sopenharmony_ci       .SetCountryCode = WalSetCountryCode,
515e41f4b71Sopenharmony_ci       .GetAssociatedStasCount = WalGetAssociatedStasCount,
516e41f4b71Sopenharmony_ci       .GetAssociatedStasInfo = WalGetAssociatedStasInfo
517e41f4b71Sopenharmony_ci   };
518e41f4b71Sopenharmony_ci
519e41f4b71Sopenharmony_ci   static struct HdfMac80211P2POps g_p2pOps = {
520e41f4b71Sopenharmony_ci       .RemainOnChannel = WalRemainOnChannel,
521e41f4b71Sopenharmony_ci       .CancelRemainOnChannel = WalCancelRemainOnChannel,
522e41f4b71Sopenharmony_ci       .ProbeReqReport = WalProbeReqReport,
523e41f4b71Sopenharmony_ci       .AddIf = WalAddIf,
524e41f4b71Sopenharmony_ci       .RemoveIf = WalRemoveIf,
525e41f4b71Sopenharmony_ci       .SetApWpsP2pIe = WalSetApWpsP2pIe,
526e41f4b71Sopenharmony_ci       .GetDriverFlag = WalGetDriverFlag
527e41f4b71Sopenharmony_ci   };
528e41f4b71Sopenharmony_ci
529e41f4b71Sopenharmony_ci   /* Initialize mac80211 and hook functions of the chip. */
530e41f4b71Sopenharmony_ci   void HiMac80211Init(struct HdfChipDriver *chipDriver)
531e41f4b71Sopenharmony_ci   {
532e41f4b71Sopenharmony_ci       if (chipDriver == NULL) {
533e41f4b71Sopenharmony_ci           HDF_LOGE("%s:input is NULL!", __func__);
534e41f4b71Sopenharmony_ci           return;
535e41f4b71Sopenharmony_ci       }
536e41f4b71Sopenharmony_ci       chipDriver->ops = &g_baseOps;
537e41f4b71Sopenharmony_ci       chipDriver->staOps = &g_staOps;
538e41f4b71Sopenharmony_ci       chipDriver->apOps = &g_apOps;
539e41f4b71Sopenharmony_ci       chipDriver->p2pOps = &g_p2pOps;
540e41f4b71Sopenharmony_ci   }
541e41f4b71Sopenharmony_ci   ```
542e41f4b71Sopenharmony_ci
543e41f4b71Sopenharmony_ci#### Configuring Event Reporting
544e41f4b71Sopenharmony_ci
545e41f4b71Sopenharmony_ciThe WLAN framework provides interfaces for event reporting. For details, see **hdf_wifi_event.c**. 
546e41f4b71Sopenharmony_ci
547e41f4b71Sopenharmony_ciThe following presents how to use **HdfWiFiEventNewSta()** to report information about a newly associated STA.
548e41f4b71Sopenharmony_ci
549e41f4b71Sopenharmony_ci   ```c
550e41f4b71Sopenharmony_ci   hi_u32 oal_cfg80211_new_sta(oal_net_device_stru *net_device, const hi_u8 *mac_addr, hi_u8 addr_len,
551e41f4b71Sopenharmony_ci       oal_station_info_stru *station_info, oal_gfp_enum_uint8 en_gfp)
552e41f4b71Sopenharmony_ci   {
553e41f4b71Sopenharmony_ci   #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION) && !defined(_PRE_HDF_LINUX)
554e41f4b71Sopenharmony_ci       cfg80211_new_sta(net_device, mac_addr, station_info, en_gfp);
555e41f4b71Sopenharmony_ci       hi_unref_param(addr_len);
556e41f4b71Sopenharmony_ci   #elif (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) || defined(_PRE_HDF_LINUX)
557e41f4b71Sopenharmony_ci       struct StationInfo info = { 0 };
558e41f4b71Sopenharmony_ci       info.assocReqIes = station_info->assoc_req_ies;
559e41f4b71Sopenharmony_ci       info.assocReqIesLen = station_info->assoc_req_ies_len;
560e41f4b71Sopenharmony_ci       HdfWifiEventNewSta(net_device, mac_addr, WLAN_MAC_ADDR_LEN, &info);
561e41f4b71Sopenharmony_ci       hi_unref_param(en_gfp);
562e41f4b71Sopenharmony_ci       hi_unref_param(addr_len);
563e41f4b71Sopenharmony_ci   #endif
564e41f4b71Sopenharmony_ci
565e41f4b71Sopenharmony_ci       return HI_SUCCESS;
566e41f4b71Sopenharmony_ci   }
567e41f4b71Sopenharmony_ci   ```
568e41f4b71Sopenharmony_ci
569e41f4b71Sopenharmony_ci### Debugging and Verification
570e41f4b71Sopenharmony_ci
571e41f4b71Sopenharmony_ci#### Driver Adaptation Verification
572e41f4b71Sopenharmony_ci
573e41f4b71Sopenharmony_ciDevelop test cases in the WLAN module unit test to verify the basic features of the WLAN module. The following uses Hi3516D V300 standard system as an example.
574e41f4b71Sopenharmony_ci
575e41f4b71Sopenharmony_ci1. Set up the test environment.
576e41f4b71Sopenharmony_ci
577e41f4b71Sopenharmony_ci   - Create a **hostapd.conf** file (used to start the AP) and copy the following content to the file:
578e41f4b71Sopenharmony_ci
579e41f4b71Sopenharmony_ci        ```text
580e41f4b71Sopenharmony_ci        interface=wlan0
581e41f4b71Sopenharmony_ci        driver=hdf wifi
582e41f4b71Sopenharmony_ci        ctrl_interface=udp
583e41f4b71Sopenharmony_ci        #Wi-Fi name
584e41f4b71Sopenharmony_ci        ssid=test
585e41f4b71Sopenharmony_ci        hw_mode=g
586e41f4b71Sopenharmony_ci        channel=1
587e41f4b71Sopenharmony_ci        ignore_broadcast_ssid=0
588e41f4b71Sopenharmony_ci        wpa=2
589e41f4b71Sopenharmony_ci        rsn_pairwise=CCMP
590e41f4b71Sopenharmony_ci        # Wi-Fi password.
591e41f4b71Sopenharmony_ci        wpa_passphrase=12345678
592e41f4b71Sopenharmony_ci        ```
593e41f4b71Sopenharmony_ci
594e41f4b71Sopenharmony_ci    - Create a **wpa_supplicant.conf** file (used to start the STA) and copy the following content to the file:
595e41f4b71Sopenharmony_ci
596e41f4b71Sopenharmony_ci        ```text
597e41f4b71Sopenharmony_ci        country=GB
598e41f4b71Sopenharmony_ci
599e41f4b71Sopenharmony_ci        network={
600e41f4b71Sopenharmony_ci            #Hotspot name
601e41f4b71Sopenharmony_ci            ssid="test"
602e41f4b71Sopenharmony_ci            #Hotspot password
603e41f4b71Sopenharmony_ci            psk="12345678" 
604e41f4b71Sopenharmony_ci        }
605e41f4b71Sopenharmony_ci        ```
606e41f4b71Sopenharmony_ci
607e41f4b71Sopenharmony_ci    - Create a **dhcpc.sh** file (used to write the IP address allocated by the udhcpc to the device) and copy the following content to the file:
608e41f4b71Sopenharmony_ci
609e41f4b71Sopenharmony_ci        ```shell
610e41f4b71Sopenharmony_ci        #!/system/bin/sh
611e41f4b71Sopenharmony_ci        [ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1
612e41f4b71Sopenharmony_ci
613e41f4b71Sopenharmony_ci        RESOLV_CONF="/etc/resolv.conf"
614e41f4b71Sopenharmony_ci        [ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
615e41f4b71Sopenharmony_ci        [ -n "$subnet" ] && NETMASK="netmask $subnet"
616e41f4b71Sopenharmony_ci
617e41f4b71Sopenharmony_ci        case "$1" in
618e41f4b71Sopenharmony_ci            deconfig)
619e41f4b71Sopenharmony_ci            /system/bin/ifconfig $interface 0.0.0.0
620e41f4b71Sopenharmony_ci            ;;
621e41f4b71Sopenharmony_ci
622e41f4b71Sopenharmony_ci            renew|bound)
623e41f4b71Sopenharmony_ci            /system/bin/ifconfig $interface $ip $BROADCAST $NETMASK
624e41f4b71Sopenharmony_ci
625e41f4b71Sopenharmony_ci            if [ -n "$router" ] ; then
626e41f4b71Sopenharmony_ci                echo "deleting routers"
627e41f4b71Sopenharmony_ci                while busybox route del default gw 0.0.0.0 dev $interface ; do
628e41f4b71Sopenharmony_ci                :
629e41f4b71Sopenharmony_ci                done
630e41f4b71Sopenharmony_ci
631e41f4b71Sopenharmony_ci                for i in $router ; do
632e41f4b71Sopenharmony_ci                busybox route add default gw $i dev $interface
633e41f4b71Sopenharmony_ci                done
634e41f4b71Sopenharmony_ci            fi
635e41f4b71Sopenharmony_ci
636e41f4b71Sopenharmony_ci            echo -n > $RESOLV_CONF
637e41f4b71Sopenharmony_ci            [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF
638e41f4b71Sopenharmony_ci            for i in $dns ; do
639e41f4b71Sopenharmony_ci                echo adding dns $i
640e41f4b71Sopenharmony_ci                echo nameserver $i >> $RESOLV_CONF
641e41f4b71Sopenharmony_ci            done
642e41f4b71Sopenharmony_ci            ;;
643e41f4b71Sopenharmony_ci        esac
644e41f4b71Sopenharmony_ci
645e41f4b71Sopenharmony_ci        exit 0
646e41f4b71Sopenharmony_ci        ```
647e41f4b71Sopenharmony_ci
648e41f4b71Sopenharmony_ci    - Create the **udhcpd.conf** file and copy the following content to the file. 
649e41f4b71Sopenharmony_ci
650e41f4b71Sopenharmony_ci        In the following example, "opt dns x.x.x.x x.x.x.x" indicates two DNS servers configured. You can configure DNS servers as required.
651e41f4b71Sopenharmony_ci
652e41f4b71Sopenharmony_ci        ```text
653e41f4b71Sopenharmony_ci        start 192.168.12.2
654e41f4b71Sopenharmony_ci        end 192.168.12.100
655e41f4b71Sopenharmony_ci        interface wlan0 #default: eth0
656e41f4b71Sopenharmony_ci        max_leases 20 #default: 254
657e41f4b71Sopenharmony_ci        remaining yes #default: yes
658e41f4b71Sopenharmony_ci        auto_time 7200 #default: 7200 (2 hours)
659e41f4b71Sopenharmony_ci        decline_time 3600 #default: 3600 (1 hour)
660e41f4b71Sopenharmony_ci        conflict_time 3600 #default: 3600 (1 hour)
661e41f4b71Sopenharmony_ci        offer_time 60 #default: 60 (1 minute)
662e41f4b71Sopenharmony_ci        min_lease 60 #defult: 60
663e41f4b71Sopenharmony_ci        lease_file /vendor/etc/udhcpd.leases
664e41f4b71Sopenharmony_ci        opt dns x.x.x.x x.x.x.x
665e41f4b71Sopenharmony_ci        option subnet 255.255.255.0
666e41f4b71Sopenharmony_ci        opt router 192.168.12.1
667e41f4b71Sopenharmony_ci        ```
668e41f4b71Sopenharmony_ci
669e41f4b71Sopenharmony_ci    - Run the following commands to push the files required for the test to the development board:
670e41f4b71Sopenharmony_ci
671e41f4b71Sopenharmony_ci        ```shell
672e41f4b71Sopenharmony_ci        hdc shell "mount -o rw,remount /"
673e41f4b71Sopenharmony_ci        timeout /T 1
674e41f4b71Sopenharmony_ci        hdc file send dhcpc.sh /system/lib/
675e41f4b71Sopenharmony_ci        hdc shell "chmod 777 /system/lib/dhcpc.sh"
676e41f4b71Sopenharmony_ci        hdc file send wpa_supplicant.conf /
677e41f4b71Sopenharmony_ci        hdc shell "mount -o rw,remount /vendor"
678e41f4b71Sopenharmony_ci        hdc file send hostapd.conf /
679e41f4b71Sopenharmony_ci        hdc file send udhcpd.conf /vendor/etc
680e41f4b71Sopenharmony_ci        hdc shell "touch /vendor/etc/udhcpd.leases"
681e41f4b71Sopenharmony_ci        hdc shell "chmod 777 /vendor/etc/udhcpd.leases"
682e41f4b71Sopenharmony_ci        ```
683e41f4b71Sopenharmony_ci
684e41f4b71Sopenharmony_ci2. Verify basic Wi-Fi features.
685e41f4b71Sopenharmony_ci
686e41f4b71Sopenharmony_ci   - Verify basic AP features.
687e41f4b71Sopenharmony_ci
688e41f4b71Sopenharmony_ci     1. Start the AP on the development board and enable Wi-Fi on the test terminal. For example, choose **Settings** > **WLAN** and turn on Wi-Fi on a mobile phone.
689e41f4b71Sopenharmony_ci
690e41f4b71Sopenharmony_ci     2. Run the following command in the **cmd** window:
691e41f4b71Sopenharmony_ci        ```shell
692e41f4b71Sopenharmony_ci        hdc shell
693e41f4b71Sopenharmony_ci        hostapd ./hostapd.conf
694e41f4b71Sopenharmony_ci        ```
695e41f4b71Sopenharmony_ci
696e41f4b71Sopenharmony_ci     3. Run the following commands in another **cmd** window:
697e41f4b71Sopenharmony_ci
698e41f4b71Sopenharmony_ci        ```shell
699e41f4b71Sopenharmony_ci        hdc shell
700e41f4b71Sopenharmony_ci        ifconfig wlan0 192.168.12.1 netmask 255.255.255.0
701e41f4b71Sopenharmony_ci        busybox udhcpd /vendor/etc/udhcpd.conf
702e41f4b71Sopenharmony_ci        ```
703e41f4b71Sopenharmony_ci
704e41f4b71Sopenharmony_ci     4. On the mobile phone, select the network named **test** in the available Wi-Fi list and enter the password. (The network name and password are configured in the **hostapd.conf** file.) You can see that network name in the connected Wi-Fi list if the connection is successful.
705e41f4b71Sopenharmony_ci
706e41f4b71Sopenharmony_ci     5. Ping the test terminal from the development board.
707e41f4b71Sopenharmony_ci
708e41f4b71Sopenharmony_ci        ```shell
709e41f4b71Sopenharmony_ci        busybox ping xxx.xxx.xxx.xxx
710e41f4b71Sopenharmony_ci        ```
711e41f4b71Sopenharmony_ci
712e41f4b71Sopenharmony_ci        In the command, xxx.xxx.xxx.xxx indicates the IP address of the test terminal. If the test terminal can be pinged, the WLAN driver provides basic features normally.
713e41f4b71Sopenharmony_ci
714e41f4b71Sopenharmony_ci   - Verify basic STA functions
715e41f4b71Sopenharmony_ci
716e41f4b71Sopenharmony_ci     1. Start the STA on the development board, and enable the hotspot on the test terminal. (The hotspot name and password are configured in the **hostapd.conf** file. The hotspot name is **test**, and the password is **12345678**.)
717e41f4b71Sopenharmony_ci
718e41f4b71Sopenharmony_ci     2. Run the following command in the **cmd** window:
719e41f4b71Sopenharmony_ci
720e41f4b71Sopenharmony_ci        ```shell
721e41f4b71Sopenharmony_ci        hdc shell
722e41f4b71Sopenharmony_ci        wpa_supplicant -i wlan0 -d -c wpa_supplicant.conf
723e41f4b71Sopenharmony_ci        ```
724e41f4b71Sopenharmony_ci
725e41f4b71Sopenharmony_ci     3. Run the following commands in another **cmd** window:
726e41f4b71Sopenharmony_ci
727e41f4b71Sopenharmony_ci        ```shell
728e41f4b71Sopenharmony_ci        hdc shell
729e41f4b71Sopenharmony_ci        mount -o rw,remount /
730e41f4b71Sopenharmony_ci        mount -o rw,remount /vendor
731e41f4b71Sopenharmony_ci        busybox udhcpc -i wlan0 -s system/lib/dhcpc.sh
732e41f4b71Sopenharmony_ci        ```
733e41f4b71Sopenharmony_ci        The IP addresses of the board and test terminal are displayed if the command is successful.
734e41f4b71Sopenharmony_ci
735e41f4b71Sopenharmony_ci     4. Ping the test terminal from the development board.
736e41f4b71Sopenharmony_ci
737e41f4b71Sopenharmony_ci        ```shell
738e41f4b71Sopenharmony_ci        busybox ping xxx.xxx.xxx.xxx
739e41f4b71Sopenharmony_ci        ```
740e41f4b71Sopenharmony_ci
741e41f4b71Sopenharmony_ci        In the command, xxx.xxx.xxx.xxx indicates the IP address of the test terminal. If the test terminal can be pinged, the WLAN driver provides basic features normally.
742e41f4b71Sopenharmony_ci
743e41f4b71Sopenharmony_ci#### API Usage Example
744e41f4b71Sopenharmony_ci
745e41f4b71Sopenharmony_ciThe WLAN Driver module provides two types of capability interfaces for the upper layer: HDI APIs and HAL APIs.
746e41f4b71Sopenharmony_ci- HDI API invocation
747e41f4b71Sopenharmony_ci
748e41f4b71Sopenharmony_ci   The following uses **GetSupportFeature** as an example to describe the development procedure:
749e41f4b71Sopenharmony_ci
750e41f4b71Sopenharmony_ci   1. Call **WlanInterfaceGetInstance()** to obtain a WLAN service instance.
751e41f4b71Sopenharmony_ci
752e41f4b71Sopenharmony_ci   2. Call **Start()** to create a channel between the HAL and the driver and obtain information about the driver network interface card (NIC).
753e41f4b71Sopenharmony_ci
754e41f4b71Sopenharmony_ci   3. Call **GetSupportFeature()** to obtain the WLAN features supported by the device.
755e41f4b71Sopenharmony_ci
756e41f4b71Sopenharmony_ci   4. Call **Stop()** to destroy the channel between the HAL and the driver
757e41f4b71Sopenharmony_ci
758e41f4b71Sopenharmony_ci   5. Call **WlanInterfaceRelease()** to destroy the WLAN service instance.
759e41f4b71Sopenharmony_ci
760e41f4b71Sopenharmony_ci   Example:
761e41f4b71Sopenharmony_ci   ```c
762e41f4b71Sopenharmony_ci   #include "v1_0/iwlan_interface.h"
763e41f4b71Sopenharmony_ci   #include "wlan_callback_impl.h"
764e41f4b71Sopenharmony_ci   #include "wlan_impl.h"
765e41f4b71Sopenharmony_ci   
766e41f4b71Sopenharmony_ci   #define PROTOCOL_80211_IFTYPE_NUM 11
767e41f4b71Sopenharmony_ci   #define HDF_SUCCESS 0
768e41f4b71Sopenharmony_ci   #define HDF_FAILURE (-1)
769e41f4b71Sopenharmony_ci
770e41f4b71Sopenharmony_ci   static int32_t hdi_main()
771e41f4b71Sopenharmony_ci   {
772e41f4b71Sopenharmony_ci       int32_t rc;
773e41f4b71Sopenharmony_ci       const char *WLAN_SERVICE_NAME = "wlan_hal_c_service";
774e41f4b71Sopenharmony_ci       static struct IWlanInterface *g_wlanObj = NULL;
775e41f4b71Sopenharmony_ci       uint8_t supType[PROTOCOL_80211_IFTYPE_NUM + 1] = {0};
776e41f4b71Sopenharmony_ci       uint32_t supTypeLen = PROTOCOL_80211_IFTYPE_NUM + 1;
777e41f4b71Sopenharmony_ci   
778e41f4b71Sopenharmony_ci        /* Obtain the WLAN service instance. */
779e41f4b71Sopenharmony_ci        g_wlanObj = WlanInterfaceGetInstance(WLAN_SERVICE_NAME);
780e41f4b71Sopenharmony_ci        if (g_wlanObj == NULL)
781e41f4b71Sopenharmony_ci        {
782e41f4b71Sopenharmony_ci            return HDF_FAILURE;
783e41f4b71Sopenharmony_ci        }
784e41f4b71Sopenharmony_ci   
785e41f4b71Sopenharmony_ci        /* Create a channel between the HAL and the driver and obtain the driver NIC information. */
786e41f4b71Sopenharmony_ci        rc = g_wlanObj->Start(g_wlanObj);
787e41f4b71Sopenharmony_ci        if (rc != HDF_SUCCESS)
788e41f4b71Sopenharmony_ci        {
789e41f4b71Sopenharmony_ci            return HDF_FAILURE;
790e41f4b71Sopenharmony_ci        }
791e41f4b71Sopenharmony_ci   
792e41f4b71Sopenharmony_ci        /* Obtain the WLAN features supported by the device irrespective of the device status (AP, STA, or P2P).
793e41f4b71Sopenharmony_ci        rc = g_wlanObj->GetSupportFeature(g_wlanObj, supType, &supTypeLen);
794e41f4b71Sopenharmony_ci        if (rc != HDF_SUCCESS)
795e41f4b71Sopenharmony_ci        {
796e41f4b71Sopenharmony_ci            return HDF_FAILURE;
797e41f4b71Sopenharmony_ci        }
798e41f4b71Sopenharmony_ci   
799e41f4b71Sopenharmony_ci        /* Destroy the channel between the HAL and the driver. */
800e41f4b71Sopenharmony_ci        rc = g_wlanObj->Stop(g_wlanObj);
801e41f4b71Sopenharmony_ci        if (rc != HDF_SUCCESS)
802e41f4b71Sopenharmony_ci        {
803e41f4b71Sopenharmony_ci            return HDF_FAILURE;
804e41f4b71Sopenharmony_ci        }
805e41f4b71Sopenharmony_ci   
806e41f4b71Sopenharmony_ci        /* Destroy the WLAN service instance. */
807e41f4b71Sopenharmony_ci        rc = WlanInterfaceRelease(g_wlanObj);
808e41f4b71Sopenharmony_ci        if (rc != HDF_SUCCESS)
809e41f4b71Sopenharmony_ci        {
810e41f4b71Sopenharmony_ci            return HDF_FAILURE;
811e41f4b71Sopenharmony_ci        }
812e41f4b71Sopenharmony_ci        return rc;
813e41f4b71Sopenharmony_ci    }
814e41f4b71Sopenharmony_ci   
815e41f4b71Sopenharmony_ci   ```
816e41f4b71Sopenharmony_ci   
817e41f4b71Sopenharmony_ci   Building:
818e41f4b71Sopenharmony_ci
819e41f4b71Sopenharmony_ci   1. Add the dependent library file to the build script.
820e41f4b71Sopenharmony_ci      
821e41f4b71Sopenharmony_ci      ```text
822e41f4b71Sopenharmony_ci      deps = [
823e41f4b71Sopenharmony_ci        "//drivers/peripheral/wlan/hdi_service:hdi_wlan_service",
824e41f4b71Sopenharmony_ci      ]
825e41f4b71Sopenharmony_ci      ```
826e41f4b71Sopenharmony_ci   2. Add the dependent header files to the build script.
827e41f4b71Sopenharmony_ci      ```text
828e41f4b71Sopenharmony_ci      include_dirs = [
829e41f4b71Sopenharmony_ci        "//drivers/peripheral/wlan/interfaces/include",
830e41f4b71Sopenharmony_ci        "//drivers/peripheral/wlan/hdi_service",
831e41f4b71Sopenharmony_ci        "//drivers/peripheral/wlan/client/include",
832e41f4b71Sopenharmony_ci        "//drivers/peripheral/wlan/hal/include",
833e41f4b71Sopenharmony_ci      ]
834e41f4b71Sopenharmony_ci      ```
835e41f4b71Sopenharmony_ci   3. Run the build script and check whether the build is successful.
836e41f4b71Sopenharmony_ci
837e41f4b71Sopenharmony_ci- HAL API invocation
838e41f4b71Sopenharmony_ci
839e41f4b71Sopenharmony_ci   To test a specified interface of the HAL module, perform the following steps:
840e41f4b71Sopenharmony_ci
841e41f4b71Sopenharmony_ci   1. Call **WifiConstruct()** to create an **IWiFi** instance.
842e41f4b71Sopenharmony_ci
843e41f4b71Sopenharmony_ci   2. Use the created **IWiFi** instance to call **start()** to create a channel between the HAL and the driver and obtain the driver NIC information.
844e41f4b71Sopenharmony_ci
845e41f4b71Sopenharmony_ci   3. Call **createFeature()** to create an **apFeature** or **staFeature**. These features can be used to invoke specific APIs. The following uses the **apFeature** instance as an example.
846e41f4b71Sopenharmony_ci
847e41f4b71Sopenharmony_ci   4. Call related APIs, for example, call **setMacAddress()** to set the MAC address and call **getDeviceMacAddress()** to obtain the device MAC address.
848e41f4b71Sopenharmony_ci
849e41f4b71Sopenharmony_ci   5. Call **destroyFeature()** to destroy the **apFeature** instance.
850e41f4b71Sopenharmony_ci
851e41f4b71Sopenharmony_ci   6. Call **Stop()** to destroy the channel between the HAL and the driver.
852e41f4b71Sopenharmony_ci
853e41f4b71Sopenharmony_ci   7. Call **WifiDestruct()** to destroy the **IWiFi** instance.
854e41f4b71Sopenharmony_ci
855e41f4b71Sopenharmony_ci   Example:
856e41f4b71Sopenharmony_ci
857e41f4b71Sopenharmony_ci   ```c
858e41f4b71Sopenharmony_ci    #include "wifi_hal.h"
859e41f4b71Sopenharmony_ci    #include "wifi_hal_sta_feature.h"
860e41f4b71Sopenharmony_ci    #include "wifi_hal_ap_feature.h"
861e41f4b71Sopenharmony_ci    #include "wifi_hal_cmd.h"
862e41f4b71Sopenharmony_ci   
863e41f4b71Sopenharmony_ci    #define MAC_LEN 6
864e41f4b71Sopenharmony_ci    #define HDF_SUCCESS 0
865e41f4b71Sopenharmony_ci    #define HDF_FAILURE (-1)
866e41f4b71Sopenharmony_ci
867e41f4b71Sopenharmony_ci    static int32_t hal_main()
868e41f4b71Sopenharmony_ci    {
869e41f4b71Sopenharmony_ci        int32_t ret;
870e41f4b71Sopenharmony_ci        struct IWiFi *wifi;
871e41f4b71Sopenharmony_ci        struct IWiFiAp *apFeature;
872e41f4b71Sopenharmony_ci    
873e41f4b71Sopenharmony_ci        /* Create an IWiFi instance. */
874e41f4b71Sopenharmony_ci        ret = WifiConstruct(&wifi);
875e41f4b71Sopenharmony_ci        if (ret != HDF_SUCCESS || wifi == NULL) {
876e41f4b71Sopenharmony_ci            return HDF_FAILURE;
877e41f4b71Sopenharmony_ci        }
878e41f4b71Sopenharmony_ci
879e41f4b71Sopenharmony_ci        /* Create a channel between the HAL and the driver and obtain the driver NIC information. */
880e41f4b71Sopenharmony_ci        ret = wifi->start(wifi);
881e41f4b71Sopenharmony_ci        if (ret != HDF_SUCCESS) {
882e41f4b71Sopenharmony_ci            return HDF_FAILURE;
883e41f4b71Sopenharmony_ci        }
884e41f4b71Sopenharmony_ci
885e41f4b71Sopenharmony_ci        /* Create an apFeature instance. */
886e41f4b71Sopenharmony_ci        ret = wifi->createFeature(PROTOCOL_80211_IFTYPE_AP, (struct IWiFiBaseFeature **)&apFeature);
887e41f4b71Sopenharmony_ci        if (ret != HDF_SUCCESS) {
888e41f4b71Sopenharmony_ci            return HDF_FAILURE;
889e41f4b71Sopenharmony_ci        }
890e41f4b71Sopenharmony_ci
891e41f4b71Sopenharmony_ci        /* Obtain the MAC address of the device. */
892e41f4b71Sopenharmony_ci        unsigned char mac[MAC_LEN] = {0};
893e41f4b71Sopenharmony_ci        ret = apFeature->baseFeature.getDeviceMacAddress((struct IWiFiBaseFeature *)apFeature, mac, MAC_LEN);
894e41f4b71Sopenharmony_ci        if (ret != HDF_SUCCESS) {
895e41f4b71Sopenharmony_ci            return HDF_FAILURE;
896e41f4b71Sopenharmony_ci        }
897e41f4b71Sopenharmony_ci
898e41f4b71Sopenharmony_ci        /* Destroy the apFeature instance. */
899e41f4b71Sopenharmony_ci        ret = wifi->destroyFeature((struct IWiFiBaseFeature *)apFeature);
900e41f4b71Sopenharmony_ci        if (ret != HDF_SUCCESS) {
901e41f4b71Sopenharmony_ci            return HDF_FAILURE;
902e41f4b71Sopenharmony_ci        }
903e41f4b71Sopenharmony_ci
904e41f4b71Sopenharmony_ci        /* Destroy the channel between the HAL and the driver. */
905e41f4b71Sopenharmony_ci        ret = wifi->stop(wifi);
906e41f4b71Sopenharmony_ci        if (ret != HDF_SUCCESS) {
907e41f4b71Sopenharmony_ci            return HDF_FAILURE;
908e41f4b71Sopenharmony_ci        }
909e41f4b71Sopenharmony_ci
910e41f4b71Sopenharmony_ci        /* Destroy the IWiFi instance. */
911e41f4b71Sopenharmony_ci        ret = WifiDestruct(&wifi);
912e41f4b71Sopenharmony_ci        if (ret != HDF_SUCCESS) {
913e41f4b71Sopenharmony_ci            return HDF_FAILURE;
914e41f4b71Sopenharmony_ci        }
915e41f4b71Sopenharmony_ci        return ret;
916e41f4b71Sopenharmony_ci    }
917e41f4b71Sopenharmony_ci   ```
918e41f4b71Sopenharmony_ci   Building:
919e41f4b71Sopenharmony_ci   1. Add the dependent library file to the build script.
920e41f4b71Sopenharmony_ci          
921e41f4b71Sopenharmony_ci      ```text
922e41f4b71Sopenharmony_ci      deps = [
923e41f4b71Sopenharmony_ci        "//drivers/peripheral/wlan/client:wifi_driver_client",
924e41f4b71Sopenharmony_ci        "//drivers/peripheral/wlan/hal:wifi_hal",
925e41f4b71Sopenharmony_ci      ]
926e41f4b71Sopenharmony_ci      ```
927e41f4b71Sopenharmony_ci
928e41f4b71Sopenharmony_ci   2. Add the dependent header files to the build script.
929e41f4b71Sopenharmony_ci      ```text
930e41f4b71Sopenharmony_ci      include_dirs = [
931e41f4b71Sopenharmony_ci        "//drivers/peripheral/wlan/interfaces/include",
932e41f4b71Sopenharmony_ci        "//drivers/peripheral/wlan/hdi_service",
933e41f4b71Sopenharmony_ci        "//drivers/peripheral/wlan/client/include",
934e41f4b71Sopenharmony_ci        "//drivers/peripheral/wlan/hal/include",
935e41f4b71Sopenharmony_ci      ]
936e41f4b71Sopenharmony_ci      ```
937e41f4b71Sopenharmony_ci   3. Run the build script and check whether the build is successful.
938e41f4b71Sopenharmony_ci      
939e41f4b71Sopenharmony_ci   
940e41f4b71Sopenharmony_ci
941e41f4b71Sopenharmony_ci
942e41f4b71Sopenharmony_ci## Reference
943e41f4b71Sopenharmony_ci
944e41f4b71Sopenharmony_ci- Code repositories:
945e41f4b71Sopenharmony_ci
946e41f4b71Sopenharmony_ci  **[drivers\_hdf\_core](https://gitee.com/openharmony/drivers_hdf_core)**
947e41f4b71Sopenharmony_ci
948e41f4b71Sopenharmony_ci  [drivers\_peripheral](https://gitee.com/openharmony/drivers_peripheral)
949e41f4b71Sopenharmony_ci
950e41f4b71Sopenharmony_ci  [drivers\_interface](https://gitee.com/openharmony/drivers_interface)
951e41f4b71Sopenharmony_ci
952e41f4b71Sopenharmony_ci- Code paths:
953e41f4b71Sopenharmony_ci
954e41f4b71Sopenharmony_ci  - Adaptation of WLAN FlowCtl component on LiteOS: **//drivers/hdf_core/adapter/khdf/liteos/model/network/wifi**
955e41f4b71Sopenharmony_ci
956e41f4b71Sopenharmony_ci  - Adaptation of HDF network model on LiteOS: **//drivers/hdf_core/adapter/khdf/liteos/model/network**
957e41f4b71Sopenharmony_ci
958e41f4b71Sopenharmony_ci  - Adaptation of WLAN FlowCtl component on Linux, build of the HDF WLAN model, and build of the vendor's WLAN driver: **//drivers/hdf_core/adapter/khdf/linux/model/network/wifi**
959e41f4b71Sopenharmony_ci
960e41f4b71Sopenharmony_ci  - Core code for implementing the WLAN module: **//drivers/hdf_core/framework/model/network/wifi**
961e41f4b71Sopenharmony_ci
962e41f4b71Sopenharmony_ci  - External APIs of the WLAN module: **//drivers/hdf_core/framework/include/wifi**
963e41f4b71Sopenharmony_ci
964e41f4b71Sopenharmony_ci  - HDF network model APIs: **//drivers/hdf_core/framework/include/net**
965e41f4b71Sopenharmony_ci
966e41f4b71Sopenharmony_ci  - WLAN HDI server implementation: **//drivers/peripheral/wlan**
967