1e41f4b71Sopenharmony_ci# Third-Party SDK Integration<a name="EN-US_TOPIC_0000001051612018"></a>
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ciTo build a more open and complete Internet of Things \(IoT\) ecosystem, OpenHarmony has opened up a group of directories to integrate SDKs provided by different vendors. This guide describes how to integrate SDKs into OpenHarmony based on the Hi3861 board.
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci## Planning a Directory Structure<a name="section1736472718351"></a>
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciA third-party SDK consists of a static library and the adaption code. The SDK service logic is compiled to obtain the static library  **libs**  through the hardware module tool chain. Each module has its corresponding  **libs**. The southbound APIs of the SDK are different from the APIs of OpenHarmony. The difference can be shielded by using the adaptation code  **adapter**. Different modules can share the same  **adapter**.
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ciBased on the preceding features, third-party SDK directories can be divided as follows in the OpenHarmony directory structure:
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ci-   domains/iot/link/: The  **adapter**  is stored in this directory and is decoupled from the module.
12e41f4b71Sopenharmony_ci-   device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/: The service library  **libs**  is stored in this directory and is bound to the module.
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ciYou must perform the following steps before adaptation. The following uses the demolink SDK as an example.
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ci1.  Create vendor directories,  **domains/iot/link/demolink/**  and  **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/**, to isolate different vendors.
17e41f4b71Sopenharmony_ci2.  Create the  **domains/iot/link/demolink/BUILD.gn**  file to build the adaptation code.
18e41f4b71Sopenharmony_ci3.  Create the  **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/**  directory to store the service library  **libs**.
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ci```
21e41f4b71Sopenharmony_ci.
22e41f4b71Sopenharmony_ci├── domains
23e41f4b71Sopenharmony_ci│   └── iot
24e41f4b71Sopenharmony_ci│       └── link
25e41f4b71Sopenharmony_ci│           ├── demolink
26e41f4b71Sopenharmony_ci│           │   └── BUILD.gn
27e41f4b71Sopenharmony_ci│           ├── libbuild
28e41f4b71Sopenharmony_ci│           │   └── BUILD.gn
29e41f4b71Sopenharmony_ci│           └── BUILD.gn
30e41f4b71Sopenharmony_ci└── device
31e41f4b71Sopenharmony_ci     └── hisilicon
32e41f4b71Sopenharmony_ci         └── hispark_pegasus
33e41f4b71Sopenharmony_ci             └── sdk_liteos
34e41f4b71Sopenharmony_ci                 └── 3rd_sdk
35e41f4b71Sopenharmony_ci                     └── demolink
36e41f4b71Sopenharmony_ci                         └── libs
37e41f4b71Sopenharmony_ci```
38e41f4b71Sopenharmony_ci
39e41f4b71Sopenharmony_ci## Building the Service  **libs**<a name="section442815485351"></a>
40e41f4b71Sopenharmony_ci
41e41f4b71Sopenharmony_ciGenerally, the platform SDK service is provided as a static library. After obtaining the OpenHarmony code, the platform vendor needs to compile the service library  **libs**  based on the corresponding hardware module vendor and save the compilation result to the  **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/**  directory. The following describes how to build the service library  **libs**.
42e41f4b71Sopenharmony_ci
43e41f4b71Sopenharmony_ciOpenHarmony has planned the  **domains/iot/link/libbuild/**  directory for compiling the service library  **libs**. This directory contains the  **domains/iot/link/libbuild/BUILD.gn**  and  **domains/iot/link/BUILD.gn**  files. The directory structure is as follows:
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ci```
46e41f4b71Sopenharmony_ci.
47e41f4b71Sopenharmony_ci└── domains
48e41f4b71Sopenharmony_ci    └── iot
49e41f4b71Sopenharmony_ci        └── link
50e41f4b71Sopenharmony_ci            ├── demolink
51e41f4b71Sopenharmony_ci            │   └── BUILD.gn
52e41f4b71Sopenharmony_ci            ├── libbuild
53e41f4b71Sopenharmony_ci            │   └── BUILD.gn
54e41f4b71Sopenharmony_ci            └── BUILD.gn
55e41f4b71Sopenharmony_ci```
56e41f4b71Sopenharmony_ci
57e41f4b71Sopenharmony_ciBefore building  **libs**, you must perform the following steps:
58e41f4b71Sopenharmony_ci
59e41f4b71Sopenharmony_ci1.  Place the service source code files \(including  **.c**  and  **.h**  files\) in the  **domains/iot/link/libbuild/**  directory.
60e41f4b71Sopenharmony_ci
61e41f4b71Sopenharmony_ci    ```
62e41f4b71Sopenharmony_ci    .
63e41f4b71Sopenharmony_ci    └── domains
64e41f4b71Sopenharmony_ci        └── iot
65e41f4b71Sopenharmony_ci            └── link
66e41f4b71Sopenharmony_ci                ├── demolink
67e41f4b71Sopenharmony_ci                │   ├── demosdk_adapter.c
68e41f4b71Sopenharmony_ci                │   ├── demosdk_adapter.h
69e41f4b71Sopenharmony_ci                │   └── BUILD.gn
70e41f4b71Sopenharmony_ci                ├── libbuild
71e41f4b71Sopenharmony_ci                │   ├── demosdk.c
72e41f4b71Sopenharmony_ci                │   ├── demosdk.h
73e41f4b71Sopenharmony_ci                │   └── BUILD.gn
74e41f4b71Sopenharmony_ci                └── BUILD.gn
75e41f4b71Sopenharmony_ci    ```
76e41f4b71Sopenharmony_ci
77e41f4b71Sopenharmony_ci2.  Adapt to the  **domains/iot/link/libbuild/BUILD.gn**  file and restore the file after the compilation is complete.
78e41f4b71Sopenharmony_ci
79e41f4b71Sopenharmony_ci    In the  **BUILD.gn**  file,  **sources**  specifies the source file to build and  **include\_dirs**  specifies the path of the dependent header file so that the target build result is the static library  **libdemosdk.a**.
80e41f4b71Sopenharmony_ci
81e41f4b71Sopenharmony_ci    ```
82e41f4b71Sopenharmony_ci    static_library("demosdk") {
83e41f4b71Sopenharmony_ci        sources = [
84e41f4b71Sopenharmony_ci            "demosdk.c"
85e41f4b71Sopenharmony_ci        ]
86e41f4b71Sopenharmony_ci        include_dirs = [
87e41f4b71Sopenharmony_ci            "//domains/iot/link/libbuild",
88e41f4b71Sopenharmony_ci            "//domains/iot/link/demolink"
89e41f4b71Sopenharmony_ci        ]
90e41f4b71Sopenharmony_ci    }
91e41f4b71Sopenharmony_ci    ```
92e41f4b71Sopenharmony_ci
93e41f4b71Sopenharmony_ci3.  Adapt to the  **domains/iot/link/BUILD.gn**  file and restore the file after the compilation is complete.
94e41f4b71Sopenharmony_ci
95e41f4b71Sopenharmony_ci    The  **BUILD.gn**  file is used to specify build entries. You need to enter all static library entries to be compiled in  **features**  so that the  **domains/iot/link/libbuild/BUILD.gn**  file is used in the build.
96e41f4b71Sopenharmony_ci
97e41f4b71Sopenharmony_ci    ```
98e41f4b71Sopenharmony_ci    import("//build/lite/config/subsystem/lite_subsystem.gni")
99e41f4b71Sopenharmony_ci    import("//build/lite/config/component/lite_component.gni")
100e41f4b71Sopenharmony_ci    lite_subsystem("iot") {
101e41f4b71Sopenharmony_ci        subsystem_components = [
102e41f4b71Sopenharmony_ci            ":link"
103e41f4b71Sopenharmony_ci        ]
104e41f4b71Sopenharmony_ci    }
105e41f4b71Sopenharmony_ci    lite_component("link") {
106e41f4b71Sopenharmony_ci        features = [
107e41f4b71Sopenharmony_ci            "libbuild:demosdk"
108e41f4b71Sopenharmony_ci        ]
109e41f4b71Sopenharmony_ci    }
110e41f4b71Sopenharmony_ci    ```
111e41f4b71Sopenharmony_ci
112e41f4b71Sopenharmony_ci
113e41f4b71Sopenharmony_ciAfter the preceding operations are complete, run the  **hb build -T //domains/iot/link:iot**  command in the root directory of the code and then check whether the target library file is generated in the  **out/hispark\_pegasus/wifiiot\_hispark\_pegasus/libs/**  directory.
114e41f4b71Sopenharmony_ci
115e41f4b71Sopenharmony_ci![](figures/device-wlan-sdk-files.png)
116e41f4b71Sopenharmony_ci
117e41f4b71Sopenharmony_ciCopy the library file to the  **device/hisilicon/hispark\_pegasus/sdk\_liteos/3rd\_sdk/demolink/libs/**  directory and delete the  **.c**  and  **.h**  files from the  **domains/iot/link/libbuild/**  directory.
118e41f4b71Sopenharmony_ci
119e41f4b71Sopenharmony_ci## Compiling Adaptation Code<a name="section3984721113613"></a>
120e41f4b71Sopenharmony_ci
121e41f4b71Sopenharmony_ci## Compiling Code<a name="section830417531286"></a>
122e41f4b71Sopenharmony_ci
123e41f4b71Sopenharmony_ciThe APIs used in the platform SDK are different from the OpenHarmony APIs and cannot be directly used. Therefore, the adaptation code  **adapter**  is required for intermediate conversion. This section uses  **DemoSdkCreateTask**  in  **domains/iot/link/demolink/demosdk\_adapter.c**  as an example to describe how to compile adaptation code on OpenHarmony.
124e41f4b71Sopenharmony_ci
125e41f4b71Sopenharmony_ci1.  Check the description, parameters, and return values of the  **DemoSdkCreateTask**  API to adapt.
126e41f4b71Sopenharmony_ci
127e41f4b71Sopenharmony_ci    ```
128e41f4b71Sopenharmony_ci    struct TaskPara {
129e41f4b71Sopenharmony_ci        char *name;
130e41f4b71Sopenharmony_ci        void *(*func)(char* arg);
131e41f4b71Sopenharmony_ci        void *arg;
132e41f4b71Sopenharmony_ci        unsigned char prio;
133e41f4b71Sopenharmony_ci        unsigned int size;
134e41f4b71Sopenharmony_ci    };
135e41f4b71Sopenharmony_ci    
136e41f4b71Sopenharmony_ci    /*
137e41f4b71Sopenharmony_ci     * Create a thread for the IoT OS.
138e41f4b71Sopenharmony_ci     * Returns 0 if the operation is successful; returns a non-zero value otherwise.
139e41f4b71Sopenharmony_ci     */
140e41f4b71Sopenharmony_ci    int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para);
141e41f4b71Sopenharmony_ci    ```
142e41f4b71Sopenharmony_ci
143e41f4b71Sopenharmony_ci2.  Check the OpenHarmony API document, select an API with similar features, and compare the parameters and usage. This guide uses  **osThreadNew**  as an example. By comparing this API with  **DemoSdkCreateTask**, you can find that the parameters on which the two APIs depend are basically the same, but the structures to which the parameters belong are different.
144e41f4b71Sopenharmony_ci
145e41f4b71Sopenharmony_ci    ```
146e41f4b71Sopenharmony_ci    typedef struct {
147e41f4b71Sopenharmony_ci        const char                   *name;   ///< name of the thread
148e41f4b71Sopenharmony_ci        uint32_t                 attr_bits;   ///< attribute bits
149e41f4b71Sopenharmony_ci        void                      *cb_mem;    ///< memory for control block
150e41f4b71Sopenharmony_ci        uint32_t                   cb_size;   ///< size of provided memory for control block
151e41f4b71Sopenharmony_ci        void                   *stack_mem;    ///< memory for stack
152e41f4b71Sopenharmony_ci        uint32_t                stack_size;   ///< size of stack
153e41f4b71Sopenharmony_ci        osPriority_t              priority;   ///< initial thread priority (default: osPriorityNormal)
154e41f4b71Sopenharmony_ci        TZ_ModuleId_t            tz_module;   ///< TrustZone module identifier
155e41f4b71Sopenharmony_ci        uint32_t                  reserved;   ///< reserved (must be 0)
156e41f4b71Sopenharmony_ci    } osThreadAttr_t;
157e41f4b71Sopenharmony_ci    
158e41f4b71Sopenharmony_ci    /// Create a thread and add it to Active Threads.
159e41f4b71Sopenharmony_ci    /// \param[in]     func          thread function.
160e41f4b71Sopenharmony_ci    /// \param[in]     argument      pointer that is passed to the thread function as start argument.
161e41f4b71Sopenharmony_ci    /// \param[in]     attr          thread attributes; NULL: default values.
162e41f4b71Sopenharmony_ci    /// \return thread ID for reference by other functions or NULL in case of error.
163e41f4b71Sopenharmony_ci    osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr);
164e41f4b71Sopenharmony_ci    ```
165e41f4b71Sopenharmony_ci
166e41f4b71Sopenharmony_ci3.  Perform code adaptation to shield the difference.
167e41f4b71Sopenharmony_ci
168e41f4b71Sopenharmony_ci    ```
169e41f4b71Sopenharmony_ci    int DemoSdkCreateTask(unsigned int *handle, const struct TaskPara *para)
170e41f4b71Sopenharmony_ci    {
171e41f4b71Sopenharmony_ci        osThreadAttr_t attr = {0};
172e41f4b71Sopenharmony_ci        osThreadId_t threadId;
173e41f4b71Sopenharmony_ci        if (handle == 0 || para == 0) {
174e41f4b71Sopenharmony_ci            return DEMOSDK_ERR;
175e41f4b71Sopenharmony_ci        }
176e41f4b71Sopenharmony_ci        if (para->func == 0) {
177e41f4b71Sopenharmony_ci            return DEMOSDK_ERR;
178e41f4b71Sopenharmony_ci        }
179e41f4b71Sopenharmony_ci        if (para->name == 0) {
180e41f4b71Sopenharmony_ci            return DEMOSDK_ERR;
181e41f4b71Sopenharmony_ci        }
182e41f4b71Sopenharmony_ci        attr.name = para->name;
183e41f4b71Sopenharmony_ci        attr.priority = para->prio;
184e41f4b71Sopenharmony_ci        attr.stack_size = para->size;
185e41f4b71Sopenharmony_ci        threadId = osThreadNew((osThreadFunc_t)para->func, para->arg, &attr);
186e41f4b71Sopenharmony_ci        if (threadId == 0) {
187e41f4b71Sopenharmony_ci            printf("osThreadNew fail\n");
188e41f4b71Sopenharmony_ci            return DEMOSDK_ERR;
189e41f4b71Sopenharmony_ci        }
190e41f4b71Sopenharmony_ci        *(unsigned int *)handle = (unsigned int)threadId;
191e41f4b71Sopenharmony_ci        return DEMOSDK_OK;
192e41f4b71Sopenharmony_ci    }
193e41f4b71Sopenharmony_ci    ```
194e41f4b71Sopenharmony_ci
195e41f4b71Sopenharmony_ci
196e41f4b71Sopenharmony_ci## Compiling a Script<a name="section13500201173710"></a>
197e41f4b71Sopenharmony_ci
198e41f4b71Sopenharmony_ciAfter completing code adaptation, create the  **BUILD.gn**  file in the directory where the  **adapter**  is located. This file can be used to compile the adaptation code into a static library and link the static library to the  **bin**  package during the entire package build. In the  **domains/iot/link/demolink/BUILD.gn**  file,  **sources**  specifies the source files to be used in the build and  **include\_dirs**  specifies the path of the dependent header file so that the target build result is the static library  **libdemolinkadapter.a**.
199e41f4b71Sopenharmony_ci
200e41f4b71Sopenharmony_ci```
201e41f4b71Sopenharmony_ciimport("//build/lite/config/component/lite_component.gni")
202e41f4b71Sopenharmony_cistatic_library("demolinkadapter") {
203e41f4b71Sopenharmony_ci    sources = [
204e41f4b71Sopenharmony_ci        "demosdk_adapter.c"
205e41f4b71Sopenharmony_ci    ]
206e41f4b71Sopenharmony_ci    include_dirs = [
207e41f4b71Sopenharmony_ci        "//kernel/liteos-m/kal/cmsis",
208e41f4b71Sopenharmony_ci        "//domains/iot/link/demolink"
209e41f4b71Sopenharmony_ci    ]
210e41f4b71Sopenharmony_ci}
211e41f4b71Sopenharmony_ci```
212e41f4b71Sopenharmony_ci
213e41f4b71Sopenharmony_ciModify the  **domains/iot/link/BUILD.gn**  file so that the  **domain/iot/hilink/BUILD.gn**  file is used in the build.
214e41f4b71Sopenharmony_ci
215e41f4b71Sopenharmony_ci```
216e41f4b71Sopenharmony_ciimport("//build/lite/config/subsystem/lite_subsystem.gni")
217e41f4b71Sopenharmony_ciimport("//build/lite/config/component/lite_component.gni")
218e41f4b71Sopenharmony_cilite_subsystem("iot") {
219e41f4b71Sopenharmony_ci    subsystem_components = [
220e41f4b71Sopenharmony_ci        ":link"
221e41f4b71Sopenharmony_ci    ]
222e41f4b71Sopenharmony_ci}
223e41f4b71Sopenharmony_cilite_component("link") {
224e41f4b71Sopenharmony_ci    features = [
225e41f4b71Sopenharmony_ci        "demolink:demolinkadapter"
226e41f4b71Sopenharmony_ci    ]
227e41f4b71Sopenharmony_ci}
228e41f4b71Sopenharmony_ci```
229e41f4b71Sopenharmony_ci
230e41f4b71Sopenharmony_ci## Compiling Service Code<a name="section8754114803918"></a>
231e41f4b71Sopenharmony_ci
232e41f4b71Sopenharmony_ciAfter the service library  **libs**  and adaptation code are ready, compile the service entry function to call the service entry of the third-party SDK.
233e41f4b71Sopenharmony_ci
234e41f4b71Sopenharmony_ciThe following uses  **demolink**  as an example to describe how to compile code in  **applications/sample/wifi-iot/app/**  to call the  **demosdk**  entry function.
235e41f4b71Sopenharmony_ci
236e41f4b71Sopenharmony_ci1.  Create a directory.
237e41f4b71Sopenharmony_ci
238e41f4b71Sopenharmony_ci    Before compiling a service, you must create a directory \(or a directory structure\) in  **applications/sample/wifi-iot/app/**  to store service source code files.
239e41f4b71Sopenharmony_ci
240e41f4b71Sopenharmony_ci    For example, add the service directory  **demolink**  to the app, and create the service entry code  **helloworld.c**  and compile the  **BUILD.gn**  file.
241e41f4b71Sopenharmony_ci
242e41f4b71Sopenharmony_ci    ```
243e41f4b71Sopenharmony_ci    .
244e41f4b71Sopenharmony_ci    └── applications
245e41f4b71Sopenharmony_ci        └── sample
246e41f4b71Sopenharmony_ci            └── wifi-iot
247e41f4b71Sopenharmony_ci                └── app
248e41f4b71Sopenharmony_ci                    │── demolink
249e41f4b71Sopenharmony_ci                    │    │── helloworld.c
250e41f4b71Sopenharmony_ci                    │    └── BUILD.gn
251e41f4b71Sopenharmony_ci                    └── BUILD.gn
252e41f4b71Sopenharmony_ci    ```
253e41f4b71Sopenharmony_ci
254e41f4b71Sopenharmony_ci2.  Compile service code.
255e41f4b71Sopenharmony_ci
256e41f4b71Sopenharmony_ci    Compile the service entry function  **DemoSdkMain**  in the  **helloworld.c**  file, call the service entry  **DemoSdkEntry**  of  **demolink**, and call the entry function through  **SYS\_RUN\(\)**  to start the service.
257e41f4b71Sopenharmony_ci
258e41f4b71Sopenharmony_ci    ```
259e41f4b71Sopenharmony_ci    #include "hos_init.h"
260e41f4b71Sopenharmony_ci    #include "demosdk.h"
261e41f4b71Sopenharmony_ci    
262e41f4b71Sopenharmony_ci    void DemoSdkMain(void)
263e41f4b71Sopenharmony_ci    {
264e41f4b71Sopenharmony_ci        DemoSdkEntry();
265e41f4b71Sopenharmony_ci    }
266e41f4b71Sopenharmony_ci    
267e41f4b71Sopenharmony_ci    SYS_RUN(DemoSdkMain);
268e41f4b71Sopenharmony_ci    ```
269e41f4b71Sopenharmony_ci
270e41f4b71Sopenharmony_ci3.  Compile build scripts.
271e41f4b71Sopenharmony_ci
272e41f4b71Sopenharmony_ci    Add the  **applications/sample/wifi-iot/app/demolink/BUILD.gn**  file, specify the paths of the source code and header file, and compile the static library file  **libexample\_demolink.a**.
273e41f4b71Sopenharmony_ci
274e41f4b71Sopenharmony_ci    ```
275e41f4b71Sopenharmony_ci    static_library("example_demolink") {
276e41f4b71Sopenharmony_ci        sources = [
277e41f4b71Sopenharmony_ci            "helloworld.c"
278e41f4b71Sopenharmony_ci        ]
279e41f4b71Sopenharmony_ci        include_dirs = [
280e41f4b71Sopenharmony_ci            "//utils/native/lite/include",
281e41f4b71Sopenharmony_ci            "//domains/iot/link/libbuild"
282e41f4b71Sopenharmony_ci        ]
283e41f4b71Sopenharmony_ci    }
284e41f4b71Sopenharmony_ci    ```
285e41f4b71Sopenharmony_ci
286e41f4b71Sopenharmony_ci    Modify the  **applications/sample/wifi-iot/app/BUILD.gn**  file so that  **demolink**  is used in compilation.
287e41f4b71Sopenharmony_ci
288e41f4b71Sopenharmony_ci    ```
289e41f4b71Sopenharmony_ci    import("//build/lite/config/component/lite_component.gni")
290e41f4b71Sopenharmony_ci    lite_component("app") {
291e41f4b71Sopenharmony_ci        features = [
292e41f4b71Sopenharmony_ci            "demolink:example_demolink"
293e41f4b71Sopenharmony_ci        ]
294e41f4b71Sopenharmony_ci    }
295e41f4b71Sopenharmony_ci    ```
296e41f4b71Sopenharmony_ci
297e41f4b71Sopenharmony_ci
298e41f4b71Sopenharmony_ci## Runtime<a name="section7737749184012"></a>
299e41f4b71Sopenharmony_ci
300e41f4b71Sopenharmony_ciRun the  **hb build**  command in the root directory of the code to compile and output the version package. Start  **demolink**. The following shows the running result, which is consistent with the expected result of  **demolink**.
301e41f4b71Sopenharmony_ci
302e41f4b71Sopenharmony_ci```
303e41f4b71Sopenharmony_ciready to OS start
304e41f4b71Sopenharmony_cisdk ver:Hi3861V100R001C00SPC024 2020-08-05 16:30:00
305e41f4b71Sopenharmony_ciformatting spiffs...
306e41f4b71Sopenharmony_ciFileSystem mount ok.
307e41f4b71Sopenharmony_ciwifi init success!
308e41f4b71Sopenharmony_ciit is demosdk entry.
309e41f4b71Sopenharmony_ciit is demo biz: hello world.
310e41f4b71Sopenharmony_ciit is demo biz: hello world.
311e41f4b71Sopenharmony_ci```
312e41f4b71Sopenharmony_ci
313e41f4b71Sopenharmony_ci## End<a name="section153301392411"></a>
314e41f4b71Sopenharmony_ci
315e41f4b71Sopenharmony_ciThe third-party SDK integration is complete.
316e41f4b71Sopenharmony_ci
317