driver-peripherals-external-des.md 38.3 KB
Newer Older
A
Annie_wang 已提交
1 2 3 4 5
# WLAN


## Overview

A
Annie_wang 已提交
6
### Function
A
Annie_wang 已提交
7

A
Annie_wang 已提交
8
A 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.
A
Annie_wang 已提交
9

A
Annie_wang 已提交
10
### Basic Concepts
A
Annie_wang 已提交
11

A
Annie_wang 已提交
12
Before development, you need to understand the following basic concepts related to WLAN:
A
Annie_wang 已提交
13

A
Annie_wang 已提交
14 15 16
- AP
  
  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.
A
Annie_wang 已提交
17

A
Annie_wang 已提交
18 19 20
- STA
  
  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.
A
Annie_wang 已提交
21

A
Annie_wang 已提交
22 23 24
- SSID
  
  A service set identifier (SSID) identifies a wireless network. Each WLAN has its SSID.
A
Annie_wang 已提交
25

A
Annie_wang 已提交
26 27 28 29 30
- bssid
  
  A basic service set identifier (BSSID) is a 48-bit MAC address that uniquely identifies a basic service set on a WLAN.
  
- Scan
A
Annie_wang 已提交
31

A
Annie_wang 已提交
32
  A terminal device scans the wireless network to obtain visible wireless network information, including the hotspot SSID, operating frequency band, and signal strength.
A
Annie_wang 已提交
33

A
Annie_wang 已提交
34
- Associate
A
Annie_wang 已提交
35

A
Annie_wang 已提交
36
  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.
A
Annie_wang 已提交
37

A
Annie_wang 已提交
38
### Working Principles
A
Annie_wang 已提交
39

A
Annie_wang 已提交
40
This document describes how to develop WLAN functions based on the HDF. The following figure shows the WLAN framework.
A
Annie_wang 已提交
41

A
Annie_wang 已提交
42
![image](figures/WLAN-driver-framework.png "WLAN Framework")
A
Annie_wang 已提交
43

A
Annie_wang 已提交
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
1. 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.
   
2. The Message module distributes user-mode messages to modules, such as the AP and STA, by component.
   
3. 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.
   
4. 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.
   
5. 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.
   
6. 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.
   
7. NetBuf encapsulates the unified data structure of the Linux or LiteOS native network data buffer and the operation interfaces for network data.
   
8. The protocol stack works with the NetDevice and NetBuf modules to exchange data flows.
A
Annie_wang 已提交
59

A
Annie_wang 已提交
60
### Constraints
A
Annie_wang 已提交
61

A
Annie_wang 已提交
62
The 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.
A
Annie_wang 已提交
63

A
Annie_wang 已提交
64
## Development Guidelines
A
Annie_wang 已提交
65

A
Annie_wang 已提交
66
### When to Use
A
Annie_wang 已提交
67

A
Annie_wang 已提交
68
The 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.
A
Annie_wang 已提交
69 70 71

### Available APIs

A
Annie_wang 已提交
72
The WLAN module provides the following APIs:
A
Annie_wang 已提交
73

A
Annie_wang 已提交
74
1. HDI and HAL APIs for upper-layer services
A
Annie_wang 已提交
75

A
Annie_wang 已提交
76
2. APIs for vendors
A
Annie_wang 已提交
77

A
Annie_wang 已提交
78
3. WLAN APIs directly called by drivers
A
Annie_wang 已提交
79

A
Annie_wang 已提交
80
- 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/**).
A
Annie_wang 已提交
81

A
Annie_wang 已提交
82
    **Table 1** wifi_hal.h
A
Annie_wang 已提交
83 84 85

  | API| Description|
  | -------- | -------- |
A
Annie_wang 已提交
86 87 88 89
  | int32_t WifiConstruct(struct IWiFi \*\*wifiInstance) | Creates an **IWiFi** instance with basic capabilities.|
  | int32_t WifiDestruct(struct IWiFi \*\*wifiInstance) | Destroys an **IWiFi** instance.|
  | int32_t (\*start)(struct IWiFi \*) | Creates a channel between the HAL and the driver and obtains the NICs supported by the driver.|
  | int32_t (\*stop)(struct IWiFi \*) | Stops the channel between the HAL and the driver.|
A
Annie_wang 已提交
90

A
Annie_wang 已提交
91
    **Table 2** wifi_hal_base_feature.h
A
Annie_wang 已提交
92 93 94

  | API| Description|
  | -------- | -------- |
A
Annie_wang 已提交
95 96 97 98
  | int32_t (\*getFeatureType)(const struct IWiFiBaseFeature \*) | Obtains the feature type.|
  | int32_t (\*setMacAddress)(const struct IWiFiBaseFeature \*, unsigned char \*, uint8_t) | Sets the MAC address.|
  | int32_t (\*getDeviceMacAddress)(const struct IWiFiBaseFeature \*, unsigned char \*, uint8_t) | Obtains the device MAC address.|
  | int32_t (\*setTxPower)(const struct IWiFiBaseFeature \*, int32_t) | Sets the transmit power.|
A
Annie_wang 已提交
99

A
Annie_wang 已提交
100
- 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.
A
Annie_wang 已提交
101

A
Annie_wang 已提交
102
    **Table 3** net_device.h
A
Annie_wang 已提交
103 104 105

  | API| Description|
  | -------- | -------- |
A
Annie_wang 已提交
106 107 108 109 110 111
  | int32_t (\*init)(struct NetDevice \*netDev) | Initializes a network device.|
  | struct NetDevStats \*(\*getStats)(struct NetDevice \*netDev) | Obtains the state of a network device.|
  | int32_t (\*setMacAddr)(struct NetDevice \*netDev, void \*addr) | Sets the MAC address.|
  | void (\*deInit)(struct NetDevice \*netDev) | Deinitializes a network device.|
  | int32_t (\*open)(struct NetDevice \*netDev) | Opens a network device.|
  | int32_t (\*stop)(struct NetDevice \*netDev) | Stops a network device.|
A
Annie_wang 已提交
112

A
Annie_wang 已提交
113
- 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**.
A
Annie_wang 已提交
114

A
Annie_wang 已提交
115
  Tables 4 to 6 list the APIs that can be directly called.
A
Annie_wang 已提交
116

A
Annie_wang 已提交
117
  **Table 4** wifi_module.h
A
Annie_wang 已提交
118 119 120

  | API| Description|
  | -------- | -------- |
A
Annie_wang 已提交
121 122 123 124
  | struct WifiModule \*WifiModuleCreate(const struct HdfConfigWifiModuleConfig \*config) | Creates a **WifiModule**.|
  | void WifiModuleDelete(struct WifiModule \*module) | Deletes a **WifiModule** and releases its data.|
  | int32_t DelFeature(struct WifiModule \*module, uint16_t featureType) | Deletes a feature from a **WifiModule**.|
  | 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**.|
A
Annie_wang 已提交
125

A
Annie_wang 已提交
126
  **Table 5** wifi_mac80211_ops.h
A
Annie_wang 已提交
127 128 129

  | API| Description|
  | -------- | -------- |
A
Annie_wang 已提交
130 131 132 133
  | int32_t&nbsp;(\*startAp)(NetDevice&nbsp;\*netDev) | Starts an AP.|
  | int32_t&nbsp;(\*stopAp)(NetDevice&nbsp;\*netDev) | Stops an AP.|
  | int32_t&nbsp;(\*connect)(NetDevice&nbsp;\*netDev,&nbsp;WifiConnectParams&nbsp;\*param) | Connects to a hotspot.|
  | int32_t&nbsp;(\*disconnect)(NetDevice&nbsp;\*netDev,&nbsp;uint16_t&nbsp;reasonCode) | Disconnects from a hotspot.|
A
Annie_wang 已提交
134

A
Annie_wang 已提交
135
  **Table 6** hdf_netbuf.h
A
Annie_wang 已提交
136 137 138

  | API| Description|
  | -------- | -------- |
A
Annie_wang 已提交
139 140 141 142 143
  | static&nbsp;inline&nbsp;void&nbsp;NetBufQueueInit(struct&nbsp;NetBufQueue&nbsp;\*q) | Initializes a **NetBuf** queue.|
  | struct&nbsp;NetBuf&nbsp;\*NetBufAlloc(uint32_t&nbsp;size) | Allocates a **NetBuf**.|
  | void&nbsp;NetBufFree(struct&nbsp;NetBuf&nbsp;\*nb) | Releases a **NetBuf**.|
  | 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**.|
  | struct&nbsp;pbuf&nbsp;\*NetBuf2Pbuf(const&nbsp;struct&nbsp;NetBuf&nbsp;\*nb) | Converts a **NetBuf** to the **pbuf** structure of lwIP.|
A
Annie_wang 已提交
144

A
Annie_wang 已提交
145
### How to Develop
A
Annie_wang 已提交
146

A
Annie_wang 已提交
147
The 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.
A
Annie_wang 已提交
148

A
Annie_wang 已提交
149
#### Configuring the HCS for the Driver
D
duangavin123 已提交
150

A
Annie_wang 已提交
151
   The HDF configuration source (HCS) includes device configuration and component configuration.
A
Annie_wang 已提交
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174

   - Device configuration

     The configuration file contains the power supply, reset, and bus configuration.

     Configuration file path: **vendor/<vendor name>/<device name >/hdf_config/khdf/wifi**

     Configure device parameters in **wlan_platform.hcs** based on the device you use. The following is an example of WLAN platform configuration.
        ```text
        hisi :& deviceList {
            device0 :: deviceInst {
                deviceInstId = 0;
                powers {
                    power0 {
                        powerSeqDelay = 0;  /* Power sequence delay. */
                        powerType = 1;      /* Power supply type. The value 0 indicates that the device is always on. The value 1 indicates power supply through GPIO. */
                        gpioId = 1;         /* GPIO pin number. */
                        activeLevel=1;      /* Active level. The value 0 indicates low level, and 1 indicates high level. */
                    }
                    power1 {
                        powerSeqDelay = 0;  /* Power sequence delay. */
                        powerType = 0;      /* Power supply type. The value 0 indicates that the device is always on. The value 1 indicates power supply through GPIO. */
                    }
A
Annie_wang 已提交
175
                }
A
Annie_wang 已提交
176
                reset {
A
Annie_wang 已提交
177 178 179 180
                    resetType = 0;          /* Reset type. The value 0 indicates that reset is dynamically determined, and 1 indicates reset through GPIO. */
                    gpioId = 2;             /* GPIO pin number. */
                    activeLevel=1;          /* Active level. The value 0 indicates low level, and 1 indicates high level. */
                    resetHoldTime = 30;     /* Hold time (ms) after a reset. */
A
Annie_wang 已提交
181
                }
A
Annie_wang 已提交
182
                bootUpTimeout = 30;         /* Boot timeout duration (ms). */
A
Annie_wang 已提交
183
                bus {
A
Annie_wang 已提交
184 185 186 187 188 189
                    busEnable = 1;          /* Whether to initialize the bus. The value 1 means to initialize the bus; the value 0 means the opposite. */
                    busType = 0;            /* Bus type. The value 0 indicates SDIO. */
                    busId = 2;              /* Bus number. */
                    funcNum = [1];          /* SDIO function number. */
                    timeout = 1000;         /* Timeout duration for data read/write. */
                    blockSize = 512;        /* Size of the data block to read or write. */
A
Annie_wang 已提交
190
                }
D
duangavin123 已提交
191 192
            }
        }
A
Annie_wang 已提交
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
        ```
   - Component configuration

     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.
        ```text
        root {
            wlan_config {
                hi3881 :& chipList {
                    chipHi3881 :: chipInst {
                        match_attr = "hdf_wlan_chips_hi3881"; /* Attribute used to match the chip. */
                        chipName = "hi3881";                  /* WLAN chip name. */
                        bus {
                            vendorId = 0x0296;                /* Vendor ID. */
                            deviceId = [0x5347];              /* Device ID. */
                        }
A
Annie_wang 已提交
208
                    }
D
duangavin123 已提交
209 210 211
                }
            }
        }
A
Annie_wang 已提交
212
        ```
A
Annie_wang 已提交
213

A
Annie_wang 已提交
214 215 216
#### Initializing and deinitializing the WLAN Chip and WLAN Chip Driver

   - Implement the driver adaptation entry function
A
Annie_wang 已提交
217

A
Annie_wang 已提交
218 219 220
     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.
     ```c
     struct HdfDriverEntry g_hdfHisiChipEntry = {
A
Annie_wang 已提交
221 222 223 224 225
        .moduleVersion = 1,
        .Bind = HdfWlanHisiDriverBind,
        .Init = HdfWlanHisiChipDriverInit,
        .Release = HdfWlanHisiChipRelease,
        .moduleName = "HDF_WLAN_CHIPS"
A
Annie_wang 已提交
226
     };
A
Annie_wang 已提交
227

A
Annie_wang 已提交
228 229
     HDF_INIT(g_hdfHisiChipEntry);
     ```
A
Annie_wang 已提交
230

A
Annie_wang 已提交
231
   - Register the functions for initializing the chip and chip driver
A
Annie_wang 已提交
232
     
A
Annie_wang 已提交
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
     Hook the chip initialization function to **InitChip()** and the chip deinitialization function to **DeinitChip()**.

     Hook the chip driver initialization function to **Build()** and the chip driver deinitialization function to **Release()**.

     ```c
     /* Register WLAN chip functions. */
     static int32_t HDFWlanRegHisiDriverFactory(void)
     {
         static struct HdfChipDriverFactory tmpFactory = { 0 };
         struct HdfChipDriverManager *driverMgr = NULL;
         driverMgr = HdfWlanGetChipDriverMgr();
         if (driverMgr == NULL) {
             HDF_LOGE("%s fail: driverMgr is NULL!", __func__);
             return HDF_FAILURE;
         }
         tmpFactory.driverName = HI3881_DRIVER_NAME;
         tmpFactory.GetMaxIFCount = GetHi3881GetMaxIFCount;
         tmpFactory.InitChip = InitHi3881Chip;
         tmpFactory.DeinitChip = DeinitHi3881Chip;
         tmpFactory.Build = BuildHi3881Driver;
         tmpFactory.Release = ReleaseHi3881Driver;
         tmpFactory.ReleaseFactory = NULL;
         if (driverMgr->RegChipDriver(&tmpFactory) != HDF_SUCCESS) {
             HDF_LOGE("%s fail: driverMgr is NULL!", __func__);
             return HDF_FAILURE;
         }

         return HDF_SUCCESS;
     }

     static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device)
     {
         (void)device;
         return HDFWlanRegHisiDriverFactory();
     }
     ```

A
Annie_wang 已提交
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
     1. Initialize and deinitialize the chip.

      ```c
      /* Function for initializing the WLAN chip. */
      int32_t InitHi3881Chip(struct HdfWlanDevice *device)
      {
          uint8_t maxPortCount = 3;
          int32_t ret = HI_SUCCESS;
          uint8_t maxRetryCount = 3;
          if (device == NULL || device->bus == NULL) {
              HDF_LOGE("%s:NULL ptr!", __func__);
              return HI_FAIL;
          }

          do {
              if (ret != HI_SUCCESS) {
                  if (device->reset != NULL && device->reset->Reset != NULL) {
                      device->reset->Reset(device->reset);
                  }
                  HDF_LOGE("%s:Retry init hi3881!last ret=%d", __func__, ret);
              }
              ret = hi_wifi_init(maxPortCount, device->bus);
          } while (ret != 0 && --maxRetryCount > 0);

          if (ret != 0) {
              HDF_LOGE("%s:Init hi3881 driver failed!", __func__);
              return ret;
          }
          return HI_SUCCESS;
      }

      /* Function for deinitializing the WLAN chip. */
      int32_t DeinitHi3881Chip(struct HdfWlanDevice *device)
      {
          (void)device;
          int32_t ret = hi_wifi_deinit();
          if (ret != 0) {
              HDF_LOGE("%s:Deinit failed!ret=%d", __func__, ret);
          }
          return ret;
      }
      ```
A
Annie_wang 已提交
312

A
Annie_wang 已提交
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
     2. Initialize and deinitialize the chip driver.
      
      ```c
      /* Hook the functions of the WLAN chip driver, mac80211, and chip. */
      static struct HdfChipDriver *BuildHi3881Driver(struct HdfWlanDevice *device, uint8_t ifIndex)
      {
          struct HdfChipDriver *specificDriver = NULL;
          if (device == NULL) {
              HDF_LOGE("%s fail: channel is NULL!", __func__);
              return NULL;
          }
          (void)ifIndex;
          specificDriver = (struct HdfChipDriver *)OsalMemCalloc(sizeof(struct HdfChipDriver));
          if (specificDriver == NULL) {
              HDF_LOGE("%s fail: OsalMemCalloc fail!", __func__);
              return NULL;
          }
          if (memset_s(specificDriver, sizeof(struct HdfChipDriver), 0, sizeof(struct HdfChipDriver)) != EOK) {
              HDF_LOGE("%s fail: memset_s fail!", __func__);
              OsalMemFree(specificDriver);
              return NULL;
          }

          if (strcpy_s(specificDriver->name, MAX_WIFI_COMPONENT_NAME_LEN, HI3881_DRIVER_NAME) != EOK) {
              HDF_LOGE("%s fail: strcpy_s fail!", __func__);
              OsalMemFree(specificDriver);
              return NULL;
          }
          specificDriver->init = Hi3881Init;
          specificDriver->deinit = Hi3881Deinit;

          HiMac80211Init(specificDriver);

          return specificDriver;
      }

      /* Release the WLAN chip driver. */
      static void ReleaseHi3881Driver(struct HdfChipDriver *chipDriver)
      {
          if (chipDriver == NULL) {
              return;
          }
          if (strcmp(chipDriver->name, HI3881_DRIVER_NAME) != 0) {
              HDF_LOGE("%s:Not my driver!", __func__);
              return;
          }
          OsalMemFree(chipDriver);
      }

      /* Function for initializing the WLAN chip driver. */
      int32_t Hi3881Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice)
      {
          hi_u16 mode;
          int32_t ret;
          nl80211_iftype_uint8 type;
          (void)chipDriver;
          HDF_LOGI("%s: start...", __func__);
          mode = wal_get_vap_mode();
          if (mode >= WAL_WIFI_MODE_BUTT) {
              oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode);
              return HI_FAIL;
          }
          if (mode == WAL_WIFI_MODE_STA) {
              type = NL80211_IFTYPE_STATION;
      #ifdef _PRE_WLAN_FEATURE_P2P
               if (InitNetdev(netDevice, NL80211_IFTYPE_P2P_DEVICE) != HI_SUCCESS) {
                  return HI_FAIL;
              }
      #endif
          } else if (mode == WAL_WIFI_MODE_AP) {
              type = NL80211_IFTYPE_AP;
          } else {
              oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode);
              return HI_FAIL;
          }
          ret = wal_init_drv_wlan_netdev(type, WAL_PHY_MODE_11N, netDevice);
          if (ret != HI_SUCCESS) {
              oam_error_log2(0, OAM_SF_ANY, "wal_init_drv_netdev %s failed.l_return:%d\n", netDevice->name, ret);
          }
          return ret;
      }

      /* Function for deinitializing the WLAN chip driver. */
      int32_t Hi3881Deinit(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice)
      {
          int32_t ret;
          (void)chipDriver;
          ret = DeinitNetdev(NL80211_IFTYPE_P2P_DEVICE);
          if (ret != HI_SUCCESS) {
              oam_error_log1(0, OAM_SF_ANY, "Hi3881Deinit: DeinitNetdev p2p device fail, ret = %d\n",  ret);
              return ret;
          }
          return wal_deinit_drv_wlan_netdev(netDevice);
      }
A
Annie_wang 已提交
407

A
Annie_wang 已提交
408
      ```
A
Annie_wang 已提交
409

A
Annie_wang 已提交
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
      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**.

      ```c
      hi_s32 wal_init_drv_wlan_netdev(nl80211_iftype_uint8 type, wal_phy_mode mode, oal_net_device_stru *netdev)
      {
          hi_char *ac_mode_str = NULL;
          hi_s32 ret;
          if (oal_unlikely(netdev == HI_NULL)) {
              oam_error_log0(0, OAM_SF_ANY, "{netdev is null!}");
              return HI_ERR_CODE_PTR_NULL;
          }

          do {
              /* Initialize the network device. */
              ret = wal_init_netdev(type, netdev);
              if (ret != HI_SUCCESS) {
                  break;
              }

              ret = wal_init_netif(type, netdev);
              if (ret != HI_SUCCESS) {
                  break;
              }
              ac_mode_str = "11bgn";
              if (mode == WAL_PHY_MODE_11G) {
                  ac_mode_str = "11bg";
              } else if (mode == WAL_PHY_MODE_11B) {
                  ac_mode_str = "11b";
              }

              ret = wal_ioctl_set_mode(netdev, ac_mode_str);
          } while (false);

          if (ret != HI_SUCCESS) {
              wal_deinit_wlan_vap(netdev);
              oal_net_unregister_netdev(netdev);
              oal_net_clear_netdev(netdev);
              return HI_FAIL;
          }

          return HI_SUCCESS;
      }

      /* Hook function pointers of netdev. For details, see NetDeviceInterFace. */
      oal_net_device_ops_stru g_wal_net_dev_ops =
      {
         .getStats          = wal_netdev_get_stats,
         .open               = wal_netdev_open,
         .stop               = wal_netdev_stop,
         .xmit         = hmac_bridge_vap_xmit,
         .ioctl           = wal_net_device_ioctl,
         .changeMtu         = oal_net_device_change_mtu,
         .init              = oal_net_device_init,
         .deInit            = oal_net_free_netdev,
        
         ......

      };

      hi_s32 wal_init_netif(nl80211_iftype_uint8 type, oal_net_device_stru *netdev, const oal_wireless_dev *wdev)
      {
          /* Add the network device to the protocol stack. */
          hi_u32 ret = NetDeviceAdd(netdev, (Protocol80211IfType)type);

          ...

          return HI_SUCCESS;
      }
      ```
A
Annie_wang 已提交
479

A
Annie_wang 已提交
480
#### Modifying the MAC Layer Interfaces
A
Annie_wang 已提交
481

A
Annie_wang 已提交
482
After the user-mode message is delivered to the driver, the driver calls the corresponding MAC-layer capability interfaces.
A
Annie_wang 已提交
483

A
Annie_wang 已提交
484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541
   ```c
   /* Define the functions for implementing the basic capabilities in the MAC layer for the driver. */
   static struct HdfMac80211BaseOps g_baseOps = {
       .SetMode = WalSetMode,
       .AddKey = WalAddKey,
       .DelKey = WalDelKey,
       .SetDefaultKey = WalSetDefaultKey,
       .GetDeviceMacAddr = WalGetDeviceMacAddr,
       .SetMacAddr = WalSetMacAddr,
       .SetTxPower = WalSetTxPower,
       .GetValidFreqsWithBand = WalGetValidFreqsWithBand,
       .GetHwCapability = WalGetHwCapability
   };

   /* Define the functions for implementing the STA capabilities in the MAC layer for the driver. */
   static struct HdfMac80211STAOps g_staOps = {
       .Connect = WalConnect,
       .Disconnect = WalDisconnect,
       .StartScan = WalStartScan,
       .AbortScan = WalAbortScan,
       .SetScanningMacAddress = WalSetScanningMacAddress,
   };

   /* Define the functions for implementing the AP capabilities in the MAC layer for the driver. */
   static struct HdfMac80211APOps g_apOps = {
       .ConfigAp = WalConfigAp,
       .StartAp = WalStartAp,
       .StopAp = WalStopAp,
       .ConfigBeacon = WalChangeBeacon,
       .DelStation = WalDelStation,
       .SetCountryCode = WalSetCountryCode,
       .GetAssociatedStasCount = WalGetAssociatedStasCount,
       .GetAssociatedStasInfo = WalGetAssociatedStasInfo
   };

   static struct HdfMac80211P2POps g_p2pOps = {
       .RemainOnChannel = WalRemainOnChannel,
       .CancelRemainOnChannel = WalCancelRemainOnChannel,
       .ProbeReqReport = WalProbeReqReport,
       .AddIf = WalAddIf,
       .RemoveIf = WalRemoveIf,
       .SetApWpsP2pIe = WalSetApWpsP2pIe,
       .GetDriverFlag = WalGetDriverFlag
   };

   /* Initialize mac80211 and hook functions of the chip. */
   void HiMac80211Init(struct HdfChipDriver *chipDriver)
   {
       if (chipDriver == NULL) {
           HDF_LOGE("%s:input is NULL!", __func__);
           return;
       }
       chipDriver->ops = &g_baseOps;
       chipDriver->staOps = &g_staOps;
       chipDriver->apOps = &g_apOps;
       chipDriver->p2pOps = &g_p2pOps;
   }
   ```
A
Annie_wang 已提交
542

A
Annie_wang 已提交
543
#### Configuring Event Reporting
A
Annie_wang 已提交
544

A
Annie_wang 已提交
545
The WLAN framework provides interfaces for event reporting. For details, see **hdf_wifi_event.c**. 
A
Annie_wang 已提交
546

A
Annie_wang 已提交
547
The following presents how to use **HdfWiFiEventNewSta()** to report information about a newly associated STA.
A
Annie_wang 已提交
548

A
Annie_wang 已提交
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567
   ```c
   hi_u32 oal_cfg80211_new_sta(oal_net_device_stru *net_device, const hi_u8 *mac_addr, hi_u8 addr_len,
       oal_station_info_stru *station_info, oal_gfp_enum_uint8 en_gfp)
   {
   #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION) && !defined(_PRE_HDF_LINUX)
       cfg80211_new_sta(net_device, mac_addr, station_info, en_gfp);
       hi_unref_param(addr_len);
   #elif (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) || defined(_PRE_HDF_LINUX)
       struct StationInfo info = { 0 };
       info.assocReqIes = station_info->assoc_req_ies;
       info.assocReqIesLen = station_info->assoc_req_ies_len;
       HdfWifiEventNewSta(net_device, mac_addr, WLAN_MAC_ADDR_LEN, &info);
       hi_unref_param(en_gfp);
       hi_unref_param(addr_len);
   #endif

       return HI_SUCCESS;
   }
   ```
A
Annie_wang 已提交
568

A
Annie_wang 已提交
569
### Debugging and Verification
A
Annie_wang 已提交
570

A
Annie_wang 已提交
571
#### Driver Adaptation Verification
A
Annie_wang 已提交
572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643

Develop 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.

1. Set up the test environment.

   - Create a **hostapd.conf** file (used to start the AP) and copy the following content to the file:

        ```text
        interface=wlan0
        driver=hdf wifi
        ctrl_interface=udp
        #Wi-Fi name
        ssid=test
        hw_mode=g
        channel=1
        ignore_broadcast_ssid=0
        wpa=2
        rsn_pairwise=CCMP
        # Wi-Fi password.
        wpa_passphrase=12345678
        ```

    - Create a **wpa_supplicant.conf** file (used to start the STA) and copy the following content to the file:

        ```text
        country=GB

        network={
            #Hotspot name
            ssid="test"
            #Hotspot password
            psk="12345678" 
        }
        ```

    - 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:

        ```shell
        #!/system/bin/sh
        [ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1

        RESOLV_CONF="/etc/resolv.conf"
        [ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
        [ -n "$subnet" ] && NETMASK="netmask $subnet"

        case "$1" in
            deconfig)
            /system/bin/ifconfig $interface 0.0.0.0
            ;;

            renew|bound)
            /system/bin/ifconfig $interface $ip $BROADCAST $NETMASK

            if [ -n "$router" ] ; then
                echo "deleting routers"
                while busybox route del default gw 0.0.0.0 dev $interface ; do
                :
                done

                for i in $router ; do
                busybox route add default gw $i dev $interface
                done
            fi

            echo -n > $RESOLV_CONF
            [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF
            for i in $dns ; do
                echo adding dns $i
                echo nameserver $i >> $RESOLV_CONF
            done
            ;;
        esac
D
duangavin123 已提交
644

A
Annie_wang 已提交
645 646
        exit 0
        ```
D
duangavin123 已提交
647

A
Annie_wang 已提交
648 649 650
    - Create the **udhcpd.conf** file and copy the following content to the file. 

        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.
D
duangavin123 已提交
651

A
Annie_wang 已提交
652 653 654 655 656 657 658 659 660 661 662 663
        ```text
        start 192.168.12.2
        end 192.168.12.100
        interface wlan0 #default: eth0
        max_leases 20 #default: 254
        remaining yes #default: yes
        auto_time 7200 #default: 7200 (2 hours)
        decline_time 3600 #default: 3600 (1 hour)
        conflict_time 3600 #default: 3600 (1 hour)
        offer_time 60 #default: 60 (1 minute)
        min_lease 60 #defult: 60
        lease_file /vendor/etc/udhcpd.leases
A
Annie_wang 已提交
664
        opt dns x.x.x.x x.x.x.x
A
Annie_wang 已提交
665 666 667
        option subnet 255.255.255.0
        opt router 192.168.12.1
        ```
D
duangavin123 已提交
668

A
Annie_wang 已提交
669
    - Run the following commands to push the files required for the test to the development board:
D
duangavin123 已提交
670

A
Annie_wang 已提交
671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703
        ```shell
        hdc shell "mount -o rw,remount /"
        timeout /T 1
        hdc file send dhcpc.sh /system/lib/
        hdc shell "chmod 777 /system/lib/dhcpc.sh"
        hdc file send wpa_supplicant.conf /
        hdc shell "mount -o rw,remount /vendor"
        hdc file send hostapd.conf /
        hdc file send udhcpd.conf /vendor/etc
        hdc shell "touch /vendor/etc/udhcpd.leases"
        hdc shell "chmod 777 /vendor/etc/udhcpd.leases"
        ```

2. Verify basic Wi-Fi features.

   - Verify basic AP features.

     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.

     2. Run the following command in the **cmd** window:
        ```shell
        hdc shell
        hostapd ./hostapd.conf
        ```

     3. Run the following commands in another **cmd** window:

        ```shell
        hdc shell
        ifconfig wlan0 192.168.12.1 netmask 255.255.255.0
        busybox udhcpd /vendor/etc/udhcpd.conf
        ```

A
Annie_wang 已提交
704
     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.
A
Annie_wang 已提交
705 706

     5. Ping the test terminal from the development board.
A
Annie_wang 已提交
707

A
Annie_wang 已提交
708 709 710 711
        ```shell
        busybox ping xxx.xxx.xxx.xxx
        ```

A
Annie_wang 已提交
712
        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.
A
Annie_wang 已提交
713

A
Annie_wang 已提交
714
   - Verify basic STA functions
A
Annie_wang 已提交
715

A
Annie_wang 已提交
716
     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**.)
A
Annie_wang 已提交
717

A
Annie_wang 已提交
718
     2. Run the following command in the **cmd** window:
A
Annie_wang 已提交
719

A
Annie_wang 已提交
720 721 722 723
        ```shell
        hdc shell
        wpa_supplicant -i wlan0 -d -c wpa_supplicant.conf
        ```
A
Annie_wang 已提交
724

A
Annie_wang 已提交
725
     3. Run the following commands in another **cmd** window:
A
Annie_wang 已提交
726

A
Annie_wang 已提交
727 728 729 730 731 732 733
        ```shell
        hdc shell
        mount -o rw,remount /
        mount -o rw,remount /vendor
        busybox udhcpc -i wlan0 -s system/lib/dhcpc.sh
        ```
        The IP addresses of the board and test terminal are displayed if the command is successful.
A
Annie_wang 已提交
734

A
Annie_wang 已提交
735
     4. Ping the test terminal from the development board.
A
Annie_wang 已提交
736

A
Annie_wang 已提交
737 738 739
        ```shell
        busybox ping xxx.xxx.xxx.xxx
        ```
A
Annie_wang 已提交
740 741

        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.
A
Annie_wang 已提交
742

A
Annie_wang 已提交
743 744 745
#### API Usage Example

The WLAN Driver module provides two types of capability interfaces for the upper layer: HDI APIs and HAL APIs.
A
Annie_wang 已提交
746
- HDI API invocation
A
Annie_wang 已提交
747

A
Annie_wang 已提交
748
   The following uses **GetSupportFeature** as an example to describe the development procedure:
A
Annie_wang 已提交
749 750 751 752 753 754 755 756 757 758 759

   1. Call **WlanInterfaceGetInstance()** to obtain a WLAN service instance.

   2. Call **Start()** to create a channel between the HAL and the driver and obtain information about the driver network interface card (NIC).

   3. Call **GetSupportFeature()** to obtain the WLAN features supported by the device.

   4. Call **Stop()** to destroy the channel between the HAL and the driver

   5. Call **WlanInterfaceRelease()** to destroy the WLAN service instance.

A
Annie_wang 已提交
760
   Example:
A
Annie_wang 已提交
761 762 763 764
   ```c
   #include "v1_0/iwlan_interface.h"
   #include "wlan_callback_impl.h"
   #include "wlan_impl.h"
A
Annie_wang 已提交
765
   
A
Annie_wang 已提交
766 767 768 769 770 771 772 773 774 775 776
   #define PROTOCOL_80211_IFTYPE_NUM 11
   #define HDF_SUCCESS 0
   #define HDF_FAILURE (-1)

   static int32_t hdi_main()
   {
       int32_t rc;
       const char *WLAN_SERVICE_NAME = "wlan_hal_c_service";
       static struct IWlanInterface *g_wlanObj = NULL;
       uint8_t supType[PROTOCOL_80211_IFTYPE_NUM + 1] = {0};
       uint32_t supTypeLen = PROTOCOL_80211_IFTYPE_NUM + 1;
A
Annie_wang 已提交
777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812
   
        /* Obtain the WLAN service instance. */
        g_wlanObj = WlanInterfaceGetInstance(WLAN_SERVICE_NAME);
        if (g_wlanObj == NULL)
        {
            return HDF_FAILURE;
        }
   
        /* Create a channel between the HAL and the driver and obtain the driver NIC information. */
        rc = g_wlanObj->Start(g_wlanObj);
        if (rc != HDF_SUCCESS)
        {
            return HDF_FAILURE;
        }
   
        /* Obtain the WLAN features supported by the device irrespective of the device status (AP, STA, or P2P).
        rc = g_wlanObj->GetSupportFeature(g_wlanObj, supType, &supTypeLen);
        if (rc != HDF_SUCCESS)
        {
            return HDF_FAILURE;
        }
   
        /* Destroy the channel between the HAL and the driver. */
        rc = g_wlanObj->Stop(g_wlanObj);
        if (rc != HDF_SUCCESS)
        {
            return HDF_FAILURE;
        }
   
        /* Destroy the WLAN service instance. */
        rc = WlanInterfaceRelease(g_wlanObj);
        if (rc != HDF_SUCCESS)
        {
            return HDF_FAILURE;
        }
        return rc;
D
duangavin123 已提交
813
    }
A
Annie_wang 已提交
814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837
   
   ```
   
   Building:

   1. Add the dependent library file to the build script.
      
      ```text
      deps = [
        "//drivers/peripheral/wlan/hdi_service:hdi_wlan_service",
      ]
      ```
   2. Add the dependent header files to the build script.
      ```text
      include_dirs = [
        "//drivers/peripheral/wlan/interfaces/include",
        "//drivers/peripheral/wlan/hdi_service",
        "//drivers/peripheral/wlan/client/include",
        "//drivers/peripheral/wlan/hal/include",
      ]
      ```
   3. Run the build script and check whether the build is successful.

- HAL API invocation
A
Annie_wang 已提交
838 839 840 841 842 843 844 845 846 847 848 849 850

   To test a specified interface of the HAL module, perform the following steps:

   1. Call **WifiConstruct()** to create an **IWiFi** instance.

   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.

   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.

   4. Call related APIs, for example, call **setMacAddress()** to set the MAC address and call **getDeviceMacAddress()** to obtain the device MAC address.

   5. Call **destroyFeature()** to destroy the **apFeature** instance.

A
Annie_wang 已提交
851
   6. Call **Stop()** to destroy the channel between the HAL and the driver.
A
Annie_wang 已提交
852 853 854

   7. Call **WifiDestruct()** to destroy the **IWiFi** instance.

A
Annie_wang 已提交
855
   Example:
A
Annie_wang 已提交
856

A
Annie_wang 已提交
857
   ```c
A
Annie_wang 已提交
858 859 860 861
    #include "wifi_hal.h"
    #include "wifi_hal_sta_feature.h"
    #include "wifi_hal_ap_feature.h"
    #include "wifi_hal_cmd.h"
A
Annie_wang 已提交
862
   
A
Annie_wang 已提交
863 864 865 866 867 868 869 870
    #define MAC_LEN 6
    #define HDF_SUCCESS 0
    #define HDF_FAILURE (-1)

    static int32_t hal_main()
    {
        int32_t ret;
        struct IWiFi *wifi;
A
Annie_wang 已提交
871
        struct IWiFiAp *apFeature;
A
Annie_wang 已提交
872
    
A
Annie_wang 已提交
873 874 875 876 877
        /* Create an IWiFi instance. */
        ret = WifiConstruct(&wifi);
        if (ret != HDF_SUCCESS || wifi == NULL) {
            return HDF_FAILURE;
        }
A
Annie_wang 已提交
878

A
Annie_wang 已提交
879 880 881 882 883
        /* Create a channel between the HAL and the driver and obtain the driver NIC information. */
        ret = wifi->start(wifi);
        if (ret != HDF_SUCCESS) {
            return HDF_FAILURE;
        }
A
Annie_wang 已提交
884

A
Annie_wang 已提交
885 886 887 888 889
        /* Create an apFeature instance. */
        ret = wifi->createFeature(PROTOCOL_80211_IFTYPE_AP, (struct IWiFiBaseFeature **)&apFeature);
        if (ret != HDF_SUCCESS) {
            return HDF_FAILURE;
        }
A
Annie_wang 已提交
890

A
Annie_wang 已提交
891 892 893 894 895 896
        /* Obtain the MAC address of the device. */
        unsigned char mac[MAC_LEN] = {0};
        ret = apFeature->baseFeature.getDeviceMacAddress((struct IWiFiBaseFeature *)apFeature, mac, MAC_LEN);
        if (ret != HDF_SUCCESS) {
            return HDF_FAILURE;
        }
A
Annie_wang 已提交
897

A
Annie_wang 已提交
898 899 900 901 902
        /* Destroy the apFeature instance. */
        ret = wifi->destroyFeature((struct IWiFiBaseFeature *)apFeature);
        if (ret != HDF_SUCCESS) {
            return HDF_FAILURE;
        }
A
Annie_wang 已提交
903

A
Annie_wang 已提交
904 905 906 907 908
        /* Destroy the channel between the HAL and the driver. */
        ret = wifi->stop(wifi);
        if (ret != HDF_SUCCESS) {
            return HDF_FAILURE;
        }
A
Annie_wang 已提交
909

A
Annie_wang 已提交
910 911 912 913 914 915 916
        /* Destroy the IWiFi instance. */
        ret = WifiDestruct(&wifi);
        if (ret != HDF_SUCCESS) {
            return HDF_FAILURE;
        }
        return ret;
    }
A
Annie_wang 已提交
917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939
   ```
   Building:
   1. Add the dependent library file to the build script.
          
      ```text
      deps = [
        "//drivers/peripheral/wlan/client:wifi_driver_client",
        "//drivers/peripheral/wlan/hal:wifi_hal",
      ]
      ```

   2. Add the dependent header files to the build script.
      ```text
      include_dirs = [
        "//drivers/peripheral/wlan/interfaces/include",
        "//drivers/peripheral/wlan/hdi_service",
        "//drivers/peripheral/wlan/client/include",
        "//drivers/peripheral/wlan/hal/include",
      ]
      ```
   3. Run the build script and check whether the build is successful.
      
   
A
Annie_wang 已提交
940 941


A
Annie_wang 已提交
942 943 944 945
## Reference

- Code repositories:

A
Annie_wang 已提交
946
  **[drivers\_hdf\_core](https://gitee.com/openharmony/drivers_hdf_core)**
A
Annie_wang 已提交
947 948 949

  [drivers\_peripheral](https://gitee.com/openharmony/drivers_peripheral)

A
Annie_wang 已提交
950 951
  [drivers\_interface](https://gitee.com/openharmony/drivers_interface)

A
Annie_wang 已提交
952 953
- Code paths:

A
Annie_wang 已提交
954
  - Adaptation of WLAN FlowCtl component on LiteOS: **//drivers/hdf_core/adapter/khdf/liteos/model/network/wifi**
A
Annie_wang 已提交
955

A
Annie_wang 已提交
956
  - Adaptation of HDF network model on LiteOS: **//drivers/hdf_core/adapter/khdf/liteos/model/network**
A
Annie_wang 已提交
957

A
Annie_wang 已提交
958
  - 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**
A
Annie_wang 已提交
959

A
Annie_wang 已提交
960
  - Core code for implementing the WLAN module: **//drivers/hdf_core/framework/model/network/wifi**
A
Annie_wang 已提交
961

A
Annie_wang 已提交
962
  - External APIs of the WLAN module: **//drivers/hdf_core/framework/include/wifi**
A
Annie_wang 已提交
963

A
Annie_wang 已提交
964
  - HDF network model APIs: **//drivers/hdf_core/framework/include/net**
A
Annie_wang 已提交
965

A
Annie_wang 已提交
966
  - WLAN HDI server implementation: **//drivers/peripheral/wlan**