update OpenHarmony 2.0 Canary

This commit is contained in:
mamingshuai 2021-06-02 00:05:35 +08:00
parent 8ff21ed04d
commit 21fef0fee0
359 changed files with 56149 additions and 61 deletions

15
.gitattributes vendored Normal file
View File

@ -0,0 +1,15 @@
*.tgz filter=lfs diff=lfs merge=lfs -text
*.trp filter=lfs diff=lfs merge=lfs -text
*.apk filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.asm filter=lfs diff=lfs merge=lfs -text
*.8svn filter=lfs diff=lfs merge=lfs -text
*.9svn filter=lfs diff=lfs merge=lfs -text
*.dylib filter=lfs diff=lfs merge=lfs -text
*.exe filter=lfs diff=lfs merge=lfs -text
*.a filter=lfs diff=lfs merge=lfs -text
*.so filter=lfs diff=lfs merge=lfs -text
*.bin filter=lfs diff=lfs merge=lfs -text
*.dll filter=lfs diff=lfs merge=lfs -text

22
BUILD.gn Executable file
View File

@ -0,0 +1,22 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/config/component/lite_component.gni")
import("//foundation/communication/dsoftbus/dsoftbus.gni")
lite_component("dsoftbus") {
features = [
"core:softbus_server",
"sdk:softbus_client",
]
}

177
LICENSE Normal file
View File

@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

63
OAT.xml Executable file
View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (c) 2021 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- OAT(OSS Audit Tool) configuration guide:
basedir: Root dir, the basedir + project path is the real source file location.
licensefile:
1.If the project don't have "LICENSE" in root dir, please define all the license files in this project in , OAT will check license files according to this rule.
tasklist(only for batch mode):
1. task: Define oat check thread, each task will start a new thread.
2. task name: Only an name, no practical effect.
3. task policy: Default policy for projects under this task, this field is required and the specified policy must defined in policylist.
4. task filter: Default filefilter for projects under this task, this field is required and the specified filefilter must defined in filefilterlist.
5. task project: Projects to be checked, the path field define the source root dir of the project.
policyList:
1. policy: All policyitems will be merged to default OAT.xml rules, the name of policy doesn't affect OAT check process.
2. policyitem: The fields type, name, path, desc is required, and the fields rule, group, filefilter is optional,the default value is:
<policyitem type="" name="" path="" desc="" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
3. policyitem type:
"compatibility" is used to check license compatibility in the specified path;
"license" is used to check source license header in the specified path;
"copyright" is used to check source copyright header in the specified path;
"import" is used to check source dependency in the specified path, such as import ... ,include ...
"filetype" is used to check file type in the specified path, supported file types: archive, binary
"filename" is used to check whether the specified file exists in the specified path(support projectroot in default OAT.xml), supported file names: LICENSE, README, README.OpenSource
4. policyitem name: This field is used for define the license, copyright, "*" means match all, the "!" prefix means could not match this value. For example, "!GPL" means can not use GPL license.
5. policyitem path: This field is used for define the source file scope to apply this policyitem, the "!" prefix means exclude the files. For example, "!.*/lib/.*" means files in lib dir will be exclude while process this policyitem.
6. policyitem rule and group: These two fields are used together to merge policy results. "may" policyitems in the same group means any one in this group passed, the result will be passed.
7. policyitem filefilter: Used to bind filefilter which define filter rules.
8. filefilter: Filter rules, the type filename is used to filter file name, the type filepath is used to filter file path.
Note:If the text contains special characters, please escape them according to the following rules:
" == &gt;
& == &gt;
' == &gt;
< == &gt;
> == &gt;
-->
<configuration>
<oatconfig>
<licensefile></licensefile>
<filefilterlist>
<filefilter name="licenseFileNamePolicyFilter" desc="Filters for LICENSE file policies" >
<filteritem type="filepath" name="core/adapter/.*" desc="Not contains 3rd code, license file is not required in this subdirectory."/>
</filefilter>
</filefilterlist>
</oatconfig>
</configuration>

View File

@ -1,36 +0,0 @@
# communication_dsoftbus
#### Description
DSoftBus capabilities, including discovery, networking, and transmission | 软总线发现、组网、传输功能实现
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

270
README.md Normal file → Executable file
View File

@ -1,37 +1,257 @@
# communication_dsoftbus
# communication\_dsoftbus<a name="EN-US_TOPIC_0000001103650648"></a>
#### 介绍
DSoftBus capabilities, including discovery, networking, and transmission | 软总线发现、组网、传输功能实现
- [Introduction](#section13587125816351)
- [Architecture](#section13587185873516)
- [Directory Structure](#section161941989596)
- [Constraints](#section119744591305)
- [Usage](#section1312121216216)
- [Usage Guidelines](#section1698318421816)
#### 软件架构
软件架构说明
- [Repositories Involved](#section1371113476307)
## Introduction<a name="section13587125816351"></a>
There are various communication modes \(such as Wi-Fi and Bluetooth\), and the usage of different communication modes varies greatly and often leads to problems. In addition, the convergence, sharing, and conflict of communication links cannot be handled. DSoftBus manages unified distributed communications between near-field devices and provides APIs for device discovery, connection, networking, and data transmission, regardless of the link type. It mainly provides the following capabilities:
- Device discovery and connection in various communication modes, such as WLAN and Bluetooth
- Unified device networking and topology management, and device information provisioning for data transmission
- Channel setup for transmitting messages and bytes
You can use the APIs provided by DSoftBus to implement fast communications between devices without caring about the communication details, thereby deploying and running services across platforms.
## Architecture<a name="section13587185873516"></a>
**Figure 1** DSoftBus architecture<a name="fig4460722185514"></a>
#### 安装教程
![](figures/dsoftbus-architecture.png)
1. xxxx
2. xxxx
3. xxxx
## Directory Structure<a name="section161941989596"></a>
#### 使用说明
The main code directory structure of DSoftBus is as follows:
1. xxxx
2. xxxx
3. xxxx
```
/foundation/communication/dsoftbus
├── interfaces # APIs
├── core # Core code
│ ├── common # Common code
│ ├── adapter # Adaptation code
│ ├── authentication # Authentication code
│ ├── bus_center # Networking code
│ ├── connection # Connection code
│ ├── discovery # Discovery code
│ ├── transmission # Transmission code
│ └── frame # Framework code
├── sdk # Service process code
│ ├── bus_center # Networking code
│ ├── discovery # Discovery code
│ ├── transmission # Transmission code
│ └── frame # Framework code
└── components # Dependent component code
```
#### 参与贡献
## Constraints<a name="section119744591305"></a>
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
- The devices between which you want to set up a connection must be in the same LAN.
- Before setting up a connection between two devices, you must bind the devices. For details about the binding process, see relevant descriptions in the Security subsystem readme file.
- A device can only be connected to another one device.
## Usage<a name="section1312121216216"></a>
### Usage Guidelines<a name="section1698318421816"></a>
>**NOTICE:**
>To use RPC across devices, you must have the **ohos.permission.DISTRIBUTED\_DATASYNC** permission \(which is a dangerous one\).
**1. Discovery**
- **Publishing process**
1. Publish a service of your application.
```
// Callbacks for service publishing
typedef struct {
void (*OnPublishSuccess)(int publishId); // Called when the service is published successfully.
void (*OnPublishFail)(int publishId, PublishFailReason reason);// Called when the service fails to be published.
} IPublishCallback;
// Publish the service.
int PublishService(const char *pkgName, const PublishInfo *info, const IPublishCallback *cb);
```
2. Unpublish a service of your application.
```
// Unpublish a service.
int UnPublishService(const char *pkgName, int publishId);
```
#### 特技
- **Discovery process**
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
1. Discovery a specified device.
```
// Callbacks for device discovery
typedef struct {
void (*OnDeviceFound)(const DeviceInfo *device); // Called when a device is found.
void (*OnDiscoverFailed)(int subscribeId, DiscoveryFailReason failReason); // Called when the discovery fails to start.
void (*OnDiscoverySuccess)(int subscribeId); // Called when the discovery starts successfully.
} IDiscoveryCallback;
// Start a device discovery.
int StartDiscovery(const char *pkgName, const SubscribeInfo *info, const IDiscoveryCallback *cb);
```
2. The DSoftBus notifies you of the device information via the callback once a device is found.
3. Stop the discovery as you need.
```
// Stop the discovery.
int StopDiscovery(const char *pkgName, int subscribeId);
```
**2. Networking**
1. Initiate a connection request with the address of the target device and the connection callback.
```
// Address to connect to
typedef struct {
ConnectionAddrType type;
union {
struct BrAddr {
char brMac[BT_MAC_LEN];
} br;
struct BleAddr {
char bleMac[BT_MAC_LEN];
} ble;
struct IpAddr {
char ip[IP_STR_MAX_LEN];
int port;
} ip;
} info;
} ConnectionAddr;
// Address types
typedef enum {
CONNECTION_ADDR_WLAN = 0,
CONNECTION_ADDR_BR,
CONNECTION_ADDR_BLE,
CONNECTION_ADDR_ETH,
CONNECTION_ADDR_MAX
} ConnectionAddrType;
// Callback for the connection result
typedef void (*OnJoinLNNResult)(ConnectionAddr *addr, const char *networkId, int32_t retCode);
// Initiate a connection request.
int32_t JoinLNN(ConnectionAddr *target, OnJoinLNNResult cb);
```
2. Wait for the connection result. If **JoinLNN\(\)** returns success, the DSoftBus accepts the connection request and notifies you of the connection result through the callback. The **addr** parameter in the callback matches the **target** parameter in **JoinLNN\(\)**. If **retCode** in the callback is **0**, the connection is successful. In this case, the value of **networkId** is valid and will be used in the data transmission and disconnection APIs. If the value of **retCode** is not **0**, the connection fails, and the value of **networkId** is invalid.
3. Transmit data using transmission APIs.
4. Initiate a disconnection request with the **networkId** and the callback.
```
// Callback for the disconnection result
typedef void (*OnLeaveLNNResult)(const char *networkId, int32_t retCode);
// Initiate a disconnection request.
int32_t LeaveLNN(const char *networkId, OnLeaveLNNResult cb);
```
5. Wait until the disconnection is complete. The **networkId** parameter in **OnLeaveLNNResult\(\)** matches **networkId** in **LeaveLNN\(\)**. If **retCode** in the callback is **0**, the disconnection is successful; otherwise, the disconnection fails. If the disconnection is successful, **networkId** becomes invalid and can no longer be used.
6. Register and unregister callbacks for device state changes.
```
// Device state events
#define EVENT_NODE_STATE_ONLINE 0x1
#define EVENT_NODE_STATE_OFFLINE 0x02
#define EVENT_NODE_STATE_INFO_CHANGED 0x04
#define EVENT_NODE_STATE_MASK 0x07
// Device information
typedef struct {
char networkId[NETWORK_ID_BUF_LEN];
char deviceName[DEVICE_NAME_BUF_LEN];
uint8_t deviceTypeId;
} NodeBasicInfo;
// Device state event callbacks
typedef struct {
uint32_t events; // Networking event mask
void (*onNodeOnline)(NodeBasicInfo *info); // Called when the device gets online.
void (*onNodeOffline)(NodeBasicInfo *info); // Called when the device gets offline.
void (*onNodeBasicInfoChanged)(NodeBasicInfoType type, NodeBasicInfo *info); // Called when the device information changes.
} INodeStateCb;
// Register the callback for device state events.
int32_t RegNodeDeviceStateCb(INodeStateCb *callback);
// Unregister the callback for device state events.
int32_t UnregNodeDeviceStateCb(INodeStateCb *callback);
```
**3. Transmission**
1. Create a session server with a listener. You can use the listener to monitor events such as opening and closing a session, and receiving messages or bytes.
```
// Callbacks for session management
typedef struct {
int (*OnSessionOpened)(int sessionId, int result);
void (*OnSessionClosed)(int sessionId);
void (*OnBytesReceived)(int sessionId, const void *data, unsigned int dataLen);
void (*OnMessageReceived)(int sessionId, const void *data, unsigned int dataLen);
} ISessionListener;
// Create a session server.
int CreateSessionServer(const char *pkgName, const char *sessionName, const ISessionListener* listener);
```
2. Open a session for sending and receiving data.
```
// Open a session.
int OpenSession(const char *mySessionName, const char *peerSessionName, const char *peerDeviceId, const char *groupId, const SessionAttribute* attr);
```
3. Send data to the peer device based on the session ID.
```
// Send bytes.
int SendBytes(int sessionId, const void *data, unsigned int len);
// Send messages.
int SendMessage(int sessionId, const void *data, unsigned int len);
```
4. Close a session with a specified ID.
```
// Close a session.
void CloseSession(int sessionId);
```
5. Remove the session server.
```
// Remove the session server.
int RemoveSessionServer(const char *pkgName, const char *sessionName);
```
## Repositories Involved<a name="section1371113476307"></a>
DSoftBus subsystem
**communication_dsoftbus**
communication_bluetooth
communication_ipc
communication_wifi

257
README_zh.md Executable file
View File

@ -0,0 +1,257 @@
# 分布式软总线组件<a name="ZH-CN_TOPIC_0000001103650648"></a>
- [简介](#section13587125816351)
- [系统架构](#section13587185873516)
- [目录](#section161941989596)
- [约束](#section119744591305)
- [说明](#section1312121216216)
- [使用说明](#section1698318421816)
- [相关仓](#section1371113476307)
## 简介<a name="section13587125816351"></a>
由于设备通信方式多种多样\(WIFI、蓝牙等\),不同通信方式使用差异大,问题多。同时通信链路的融合共享和冲突无法处理。分布式软总线实现近场设备间统一的分布式通信能力管理,提供不区分链路的设备发现连接、组网和传输能力,主要包括如下:
- 发现连接提供基于Wifi、蓝牙等通信方式的设备发现连接能力。
- 设备组网:提供统一的设备组网和拓扑管理能力,为数据传输提供已组网设备信息。
- 数据传输:提供数据传输通道,支持消息、字节数据传输等能力。
业务方通过使用分布式软总线提供的API实现设备间高速通信不用关心通信细节进而实现业务平台部署与运行能力。
## 系统架构<a name="section13587185873516"></a>
**图 1** 分布式软总线组件架构图<a name="fig4460722185514"></a>
![](figures/dsoftbus-architecture_zh.png)
## 目录<a name="section161941989596"></a>
分布式软总线组件主要代码目录结构如下:
```
/foundation/communication/dsoftbus
├── interfaces # 接口代码
├── core # 核心代码
│ ├── common # 通用代码
│ ├── adapter # 适配层代码
│ ├── authentication # 认证代码
│ ├── bus_center # 组网代码
│ ├── connection # 连接代码
│ ├── discovery # 发现代码
│ ├── transmission # 传输代码
│ └── frame # 框架代码
├── sdk # 运行业务进程代码
│ ├── bus_center # 组网代码
│ ├── discovery # 发现代码
│ ├── transmission # 传输代码
│ └── frame # 框架代码
└── components # 依赖组件代码
```
## 约束<a name="section119744591305"></a>
- 组网设备需在同一局域网中。
- 组网之前,需先完成设备绑定,绑定流程参见安全子系统中说明。
- 只能和一个设备进行组网。
## 说明<a name="section1312121216216"></a>
### 使用说明<a name="section1698318421816"></a>
>**须知:**
>使用跨设备通信时必须添加权限ohos.permission.DISTRIBUTED\_DATASYNC该权限类型为dangerous。
**1、发现**
- **发布流程**
1. 上层应用需要对外发布自身能力时,调用服务发布接口发布自身能力。
```
// 发布回调
typedef struct {
void (*OnPublishSuccess)(int publishId); //发布成功时回调
void (*OnPublishFail)(int publishId, PublishFailReason reason);//发布失败时回调
} IPublishCallback;
// 发布服务
int PublishService(const char *pkgName, const PublishInfo *info, const IPublishCallback *cb);
```
2. 上层应用不再需要对外发布自身能力时调用UnpublishService接口注销服务。
```
// 注销服务
int UnPublishService(const char *pkgName, int publishId);
```
- **发现流程**
1. 上层应用需要发现特定能力设备时,调用发现接口启动发现。
```
// 发现回调
typedef struct {
void (*OnDeviceFound)(const DeviceInfo *device); //发现设备回调
void (*OnDiscoverFailed)(int subscribeId, DiscoveryFailReason failReason); //启动发现失败回调
void (*OnDiscoverySuccess)(int subscribeId); //启动发现成功回调
} IDiscoveryCallback;
// 发现服务
int StartDiscovery(const char *pkgName, const SubscribeInfo *info, const IDiscoveryCallback *cb);
```
2. 软总线发现到设备时,通过回调接口通知业务发现的设备信息。
3. 上层应用不再需要发现时调用StopDiscovery接口停止设备发现。
```
// 停止服务
int StopDiscovery(const char *pkgName, int subscribeId);
```
**2、组网**
1. 发起组网请求,携带组网连接地址信息,并且提供组网执行结果回调函数。
```
// 组网连接地址
typedef struct {
ConnectionAddrType type;
union {
struct BrAddr {
char brMac[BT_MAC_LEN];
} br;
struct BleAddr {
char bleMac[BT_MAC_LEN];
} ble;
struct IpAddr {
char ip[IP_STR_MAX_LEN];
int port;
} ip;
} info;
} ConnectionAddr;
// 组网连接地址类型
typedef enum {
CONNECTION_ADDR_WLAN = 0,
CONNECTION_ADDR_BR,
CONNECTION_ADDR_BLE,
CONNECTION_ADDR_ETH,
CONNECTION_ADDR_MAX
} ConnectionAddrType;
// 组网请求执行结果回调
typedef void (*OnJoinLNNResult)(ConnectionAddr *addr, const char *networkId, int32_t retCode);
// 发起组网请求
int32_t JoinLNN(ConnectionAddr *target, OnJoinLNNResult cb);
```
2. 等待组网结果JoinLNN\(\)返回成功表示软总线接受了组网请求组网结果通过回调函数通知业务组网回调函数中addr参数内容和JoinLNN\(\)的入参互相匹配retCode如果为0表示组网成功此时networkId为有效值后续传输、退网等接口均需使用该参数retCode如果不为0表示组网失败此时networkId为无效值。
3. 使用传输相关接口进行数据传输。
4. 发送退网请求携带组网成功后返回的networkId并且提供退网执行结果回调。
```
// 退网执行结果回调
typedef void (*OnLeaveLNNResult)(const char *networkId, int32_t retCode);
// 退网请求
int32_t LeaveLNN(const char *networkId, OnLeaveLNNResult cb);
```
5. 等待退网完成OnLeaveLNNResult\(\)的networkId和退网请求接口中的networkId互相匹配retCode为0表示退网成功否则退网失败。退网成功后networkId变为无效值后续不应该被继续使用。
6. 使用节点(即设备)注册和注销接口,监听网络中节点状态变化等事件。
```
// 事件掩码
#define EVENT_NODE_STATE_ONLINE 0x1
#define EVENT_NODE_STATE_OFFLINE 0x02
#define EVENT_NODE_STATE_INFO_CHANGED 0x04
#define EVENT_NODE_STATE_MASK 0x07
// 节点信息
typedef struct {
char networkId[NETWORK_ID_BUF_LEN];
char deviceName[DEVICE_NAME_BUF_LEN];
uint8_t deviceTypeId;
} NodeBasicInfo;
// 节点状态事件回调
typedef struct {
uint32_t events; // 组网事件掩码
void (*onNodeOnline)(NodeBasicInfo *info); // 节点上线事件回调
void (*onNodeOffline)(NodeBasicInfo *info); // 节点下线事件回调
void (*onNodeBasicInfoChanged)(NodeBasicInfoType type, NodeBasicInfo *info); // 节点信息变化事件回调
} INodeStateCb;
// 注册节点状态事件回调
int32_t RegNodeDeviceStateCb(INodeStateCb *callback);
// 注销节点状态事件回调
int32_t UnregNodeDeviceStateCb(INodeStateCb *callback);
```
**3、传输**
1. 创建会话服务,并设置会话相关回调,用户可在回调中处理打开/关闭和消息接收事件。
```
// 会话管理回调
typedef struct {
int (*OnSessionOpened)(int sessionId, int result);
void (*OnSessionClosed)(int sessionId);
void (*OnBytesReceived)(int sessionId, const void *data, unsigned int dataLen);
void (*OnMessageReceived)(int sessionId, const void *data, unsigned int dataLen);
} ISessionListener;
// 创建会话服务
int CreateSessionServer(const char *pkgName, const char *sessionName, const ISessionListener* listener);
```
2. 创建会话 ,用于收发数据。
```
// 创建会话
int OpenSession(const char *mySessionName, const char *peerSessionName, const char *peerDeviceId, const char *groupId, const SessionAttribute* attr);
```
3. 通过sessionId向对端设备发送数据。
```
// 发送字节数据
int SendBytes(int sessionId, const void *data, unsigned int len);
// 发送消息数据
int SendMessage(int sessionId, const void *data, unsigned int len);
```
4. 通过sessionId关闭会话。
```
// 关闭会话
void CloseSession(int sessionId);
```
5. 删除会话服务。
```
// 删除会话服务
int RemoveSessionServer(const char *pkgName, const char *sessionName);
```
## 相关仓<a name="section1371113476307"></a>
分布式软总线子系统
**communication_dsoftbus**
communication_bluetooth
communication_ipc
communication_wifi

114
components/mbedtls/BUILD.gn Executable file
View File

@ -0,0 +1,114 @@
#
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import("//build/ohos.gni")
library = "//third_party/mbedtls/library"
mbedtls_sources = []
mbedtls_sources += [
"$library/aes.c",
"$library/aesni.c",
"$library/arc4.c",
"$library/aria.c",
"$library/asn1parse.c",
"$library/asn1write.c",
"$library/base64.c",
"$library/bignum.c",
"$library/blowfish.c",
"$library/camellia.c",
"$library/ccm.c",
"$library/chacha20.c",
"$library/chachapoly.c",
"$library/cipher.c",
"$library/cipher_wrap.c",
"$library/cmac.c",
"$library/ctr_drbg.c",
"$library/des.c",
"$library/dhm.c",
"$library/ecdh.c",
"$library/ecdsa.c",
"$library/ecjpake.c",
"$library/ecp.c",
"$library/ecp_curves.c",
"$library/entropy.c",
"$library/entropy_poll.c",
"$library/error.c",
"$library/gcm.c",
"$library/havege.c",
"$library/hkdf.c",
"$library/hmac_drbg.c",
"$library/md.c",
"$library/md2.c",
"$library/md4.c",
"$library/md5.c",
"$library/md_wrap.c",
"$library/memory_buffer_alloc.c",
"$library/net_sockets.c",
"$library/nist_kw.c",
"$library/oid.c",
"$library/padlock.c",
"$library/pem.c",
"$library/pk.c",
"$library/pk_wrap.c",
"$library/pkcs12.c",
"$library/pkcs5.c",
"$library/pkparse.c",
"$library/pkwrite.c",
"$library/platform.c",
"$library/platform_util.c",
"$library/poly1305.c",
"$library/ripemd160.c",
"$library/rsa.c",
"$library/rsa_internal.c",
"$library/sha1.c",
"$library/sha256.c",
"$library/sha512.c",
"$library/ssl_ciphersuites.c",
"$library/ssl_cli.c",
"$library/ssl_tls.c",
"$library/threading.c",
"$library/timing.c",
"$library/version.c",
"$library/version_features.c",
"$library/x509.c",
"$library/x509_crl.c",
"$library/x509_crt.c",
"$library/xtea.c",
]
config("mbedtls_config") {
include_dirs = [ "//third_party/mbedtls/include" ]
cflags = [ "-Wno-error" ]
}
ohos_shared_library("mbedtls_shared") {
sources = mbedtls_sources
output_name = "mbedtls"
public_configs = [ ":mbedtls_config" ]
part_name = "dsoftbus_standard"
subsystem_name = "communication"
}
static_library("mbedtls_static") {
sources = mbedtls_sources
output_name = "mbedtls"
public_configs = [ ":mbedtls_config" ]
}
group("mbedtls") {
deps = [ ":mbedtls_shared" ]
}

View File

@ -0,0 +1,55 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//foundation/communication/dsoftbus/dsoftbus.gni")
if (defined(ohos_lite)) {
import("//build/lite/config/component/lite_component.gni")
} else {
import("//build/ohos.gni")
config("dfinder_interface") {
include_dirs = [ "interface" ]
}
ohos_shared_library("nstackx_ctrl") {
sources = [
"core/coap_discover/coap_app.c",
"core/coap_discover/coap_client.c",
"core/coap_discover/coap_discover.c",
"core/coap_discover/json_payload.c",
"core/nstackx_common.c",
"core/nstackx_database.c",
"core/nstackx_device.c",
"core/nstackx_smartgenius.c",
]
include_dirs = [
"//third_party/libcoap/include/coap2",
"//third_party/cJSON",
"//third_party/bounds_checking_function/include",
"include",
"include/coap_discover",
"../nstackx_util/interface",
"../nstackx_util/platform/unix",
]
public_configs = [ ":dfinder_interface" ]
deps = [
"../nstackx_util:nstackx_util",
"//third_party/bounds_checking_function:libsec_static",
"//third_party/cJSON:cjson_static",
"//third_party/libcoap:libcoap",
]
defines = [ "SUPPORT_SMARTGENIUS" ]
subsystem_name = "communication"
part_name = "dsoftbus_standard"
}
}

View File

@ -0,0 +1,469 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "coap_app.h"
#include <errno.h>
#include <net.h>
#include <netdb.h>
#include <pthread.h>
#include <securec.h>
#include <string.h>
#include <unistd.h>
#include "coap.h"
#include "coap_client.h"
#include "coap_discover.h"
#include "nstackx_util.h"
#include "nstackx_device.h"
#include "nstackx_epoll.h"
#include "nstackx_error.h"
#include "nstackx_log.h"
#define TAG "nStackXCoAP"
#define DEFAULT_COAP_TIMEOUT (COAP_RESOURCE_CHECK_TIME * COAP_TICKS_PER_SECOND)
#define MAX_COAP_SOCKET_NUM 64
static coap_context_t *g_ctx = NULL;
static EpollTask g_taskList[MAX_COAP_SOCKET_NUM] = {0};
static uint32_t g_socketNum = 0;
static uint8_t g_ctxSocketErrFlag = NSTACKX_FALSE;
static coap_context_t *g_p2pCtx = NULL;
static EpollTask g_p2pTaskList[MAX_COAP_SOCKET_NUM] = {0};
static uint32_t g_p2pSocketNum = 0;
static uint8_t g_p2pCtxSocketErrFlag = NSTACKX_FALSE;
static coap_context_t *g_usbCtx = NULL;
static EpollTask g_usbTaskList[MAX_COAP_SOCKET_NUM] = {0};
static uint32_t g_usbSocketNum = 0;
static uint8_t g_usbCtxSocketErrFlag = NSTACKX_FALSE;
typedef enum {
SOCKET_READ_EVENT = 0,
SOCKET_WRITE_EVENT,
SOCKET_ERROR_EVENT,
SOCKET_END_EVENT
} SocketEventType;
static uint64_t g_socketEventNum[SOCKET_END_EVENT];
static void CoAPEpollReadHandle(void *data)
{
if (data == NULL) {
return;
}
EpollTask *task = (EpollTask*)data;
if (task->taskfd < 0) {
return;
}
coap_socket_t *socket = task->ptr;
if (socket->flags & COAP_SOCKET_WANT_READ) {
socket->flags |= COAP_SOCKET_CAN_READ;
}
if (socket->flags & COAP_SOCKET_WANT_ACCEPT) {
socket->flags |= COAP_SOCKET_CAN_ACCEPT;
}
g_socketEventNum[SOCKET_READ_EVENT]++;
}
static void CoAPEpollWriteHandle(void *data)
{
if (data == NULL) {
return;
}
EpollTask *task = data;
if (task->taskfd < 0) {
return;
}
coap_socket_t *socket = task->ptr;
if (socket->flags & COAP_SOCKET_WANT_WRITE) {
socket->flags |= COAP_SOCKET_CAN_WRITE;
}
if (socket->flags & COAP_SOCKET_WANT_CONNECT) {
socket->flags |= COAP_SOCKET_CAN_CONNECT;
}
g_socketEventNum[SOCKET_WRITE_EVENT]++;
}
static void CoAPEpollErrorHandle(void *data)
{
if (data == NULL) {
return;
}
EpollTask *task = data;
if (task->taskfd < 0) {
return;
}
coap_socket_t *socket = task->ptr;
g_socketEventNum[SOCKET_ERROR_EVENT]++;
if (IsCoapCtxEndpointSocket(g_ctx, socket->fd)) {
LOGE(TAG, "error of g_ctx's socket occurred");
g_ctxSocketErrFlag = NSTACKX_TRUE;
return;
}
if (IsCoapCtxEndpointSocket(g_p2pCtx, socket->fd)) {
LOGE(TAG, "error of g_p2pCtx's socket occurred");
g_p2pCtxSocketErrFlag = NSTACKX_TRUE;
return;
}
if (IsCoapCtxEndpointSocket(g_usbCtx, socket->fd)) {
LOGE(TAG, "error of g_usbCtx's socket occurred");
g_usbCtxSocketErrFlag = NSTACKX_TRUE;
return;
}
LOGE(TAG, "coap session socket error occurred and close it");
DeRegisterEpollTask(task);
CloseDesc(socket->fd);
socket->fd = -1;
task->taskfd = -1;
}
uint32_t RegisterCoAPEpollTask(EpollDesc epollfd)
{
uint32_t timeoutWlan, timeoutP2p, timeoutUsb, minTimeout;
if ((g_ctx == NULL) && (g_p2pCtx == NULL) && (g_usbCtx == NULL)) {
return DEFAULT_COAP_TIMEOUT;
}
timeoutWlan = GetTimeout(g_ctx, &g_socketNum, g_taskList, epollfd);
timeoutP2p = GetTimeout(g_p2pCtx, &g_p2pSocketNum, g_p2pTaskList, epollfd);
timeoutUsb = GetTimeout(g_usbCtx, &g_usbSocketNum, g_usbTaskList, epollfd);
if (timeoutWlan == DEFAULT_COAP_TIMEOUT &&
timeoutP2p == DEFAULT_COAP_TIMEOUT &&
timeoutUsb == DEFAULT_COAP_TIMEOUT) {
return DEFAULT_COAP_TIMEOUT;
} else {
minTimeout = (timeoutWlan < timeoutP2p) ? timeoutWlan : timeoutP2p;
return (minTimeout < timeoutUsb) ? minTimeout : timeoutUsb;
}
}
uint32_t GetTimeout(struct coap_context_t *ctx, uint32_t *socketNum, EpollTask *taskList, EpollDesc epollfd)
{
uint32_t events;
coap_tick_t now;
uint32_t i;
uint32_t timeout;
coap_socket_t *sockets[MAX_COAP_SOCKET_NUM] = {0};
if (ctx == NULL) {
return DEFAULT_COAP_TIMEOUT;
}
coap_ticks(&now);
timeout = coap_write(ctx, sockets,
(uint32_t)(sizeof(sockets) / sizeof(sockets[0])), socketNum, now);
if (timeout == 0 || timeout > DEFAULT_COAP_TIMEOUT) {
timeout = DEFAULT_COAP_TIMEOUT;
}
if (*socketNum > MAX_COAP_SOCKET_NUM) {
*socketNum = MAX_COAP_SOCKET_NUM;
LOGI(TAG, "socketNum exccedd MAX_COAP_SOCKET_NUM, and set it to MAX_COAP_SOCKET_NUM");
}
for (i = 0; i < *socketNum; i++) {
events = 0;
if ((sockets[i]->flags & COAP_SOCKET_WANT_READ) || (sockets[i]->flags & COAP_SOCKET_WANT_ACCEPT)) {
events = EPOLLIN;
}
if ((sockets[i]->flags & COAP_SOCKET_WANT_WRITE) || (sockets[i]->flags & COAP_SOCKET_WANT_CONNECT)) {
events = events | EPOLLOUT;
}
if (sockets[i]->flags & COAP_SOCKET_WANT_CONNECT) {
events = events | EPOLLHUP | EPOLLERR;
}
taskList[i].taskfd = sockets[i]->fd;
taskList[i].epollfd = epollfd;
taskList[i].readHandle = CoAPEpollReadHandle;
taskList[i].writeHandle = CoAPEpollWriteHandle;
taskList[i].errorHandle = CoAPEpollErrorHandle;
taskList[i].ptr = sockets[i];
if (taskList[i].taskfd < 0) {
continue;
}
RegisterEpollTask(&taskList[i], events);
}
return timeout;
}
void DeRegisterCoAPEpollTask(void)
{
if (g_ctxSocketErrFlag) {
LOGI(TAG, "error of g_ctx's socket occurred and destroy g_ctx");
g_ctxSocketErrFlag = NSTACKX_FALSE;
NotifyDFinderMsgRecver(DFINDER_ON_INNER_ERROR);
} else {
DeRegisteCoAPEpollTaskCtx(g_ctx, &g_socketNum, g_taskList);
}
if (g_p2pCtxSocketErrFlag) {
LOGI(TAG, "error of g_p2pctx's socket occurred and destroy g_ctx");
CoapP2pServerDestroy();
} else {
DeRegisteCoAPEpollTaskCtx(g_p2pCtx, &g_p2pSocketNum, g_p2pTaskList);
}
if (g_usbCtxSocketErrFlag) {
LOGI(TAG, "error of g_usbCtx's socket occurred and destroy g_ctx");
CoapUsbServerDestroy();
} else {
DeRegisteCoAPEpollTaskCtx(g_usbCtx, &g_usbSocketNum, g_usbTaskList);
}
}
void DeRegisteCoAPEpollTaskCtx(struct coap_context_t *ctx, uint32_t *socketNum, EpollTask *taskList)
{
coap_tick_t now;
uint32_t i;
if (ctx == NULL) {
return;
}
if (*socketNum > MAX_COAP_SOCKET_NUM) {
*socketNum = MAX_COAP_SOCKET_NUM;
LOGI(TAG, "socketNum exccedd MAX_COAP_SOCKET_NUM, and set it to MAX_COAP_SOCKET_NUM");
}
for (i = 0; i < *socketNum; i++) {
if (taskList[i].taskfd < 0) {
continue;
}
DeRegisterEpollTask(&taskList[i]);
}
*socketNum = 0;
coap_ticks(&now);
coap_read(ctx, now);
}
int32_t CoapServerInit(const struct in_addr *ip)
{
LOGD(TAG, "CoapServerInit is called");
char addrStr[NI_MAXHOST] = COAP_SRV_DEFAULT_ADDR;
char portStr[NI_MAXSERV] = COAP_SRV_DEFAULT_PORT;
if (!IsWifiApConnected()) {
LOGD(TAG, "wifi not connected");
return NSTACKX_EOK;
}
if (g_ctx != NULL) {
LOGI(TAG, "coap server need to change");
CoapServerDestroy();
}
coap_startup();
g_ctx = CoapGetContext(addrStr, portStr, NSTACKX_TRUE, ip);
if (g_ctx == NULL) {
LOGE(TAG, "coap init get context failed");
return NSTACKX_EFAILED;
}
CoapInitResources(g_ctx, SERVER_TYPE_WLANORETH);
coap_register_response_handler(g_ctx, CoapMessageHandler);
return NSTACKX_EOK;
}
int32_t CoapP2pServerInit(const struct in_addr *ip)
{
LOGD(TAG, "CoapP2pServerInit is called");
char addrStr[NI_MAXHOST] = {0};
char portStr[NI_MAXSERV] = COAP_SRV_DEFAULT_PORT;
if (g_p2pCtx != NULL) {
LOGI(TAG, "coap p2p server init has finished");
return NSTACKX_EOK;
}
if (ip == NULL) {
return NSTACKX_EFAILED;
}
if (inet_ntop(AF_INET, ip, addrStr, NI_MAXHOST) == NULL) {
LOGE(TAG, "inet_ntop failed");
return NSTACKX_EFAILED;
}
coap_startup();
g_p2pCtx = CoapGetContext(addrStr, portStr, NSTACKX_TRUE, ip);
if (g_p2pCtx == NULL) {
LOGE(TAG, "coap p2p init get context failed");
return NSTACKX_EFAILED;
}
/* if g_p2pCtx has been created, update the g_p2pIp */
SetP2pIp(ip);
CoapInitResources(g_p2pCtx, SERVER_TYPE_P2P);
coap_register_response_handler(g_p2pCtx, CoapMessageHandler);
return NSTACKX_EOK;
}
int32_t CoapUsbServerInit(const struct in_addr *ip)
{
LOGD(TAG, "CoapUsbServerInit is called");
char addrStr[NI_MAXHOST] = {0};
char portStr[NI_MAXSERV] = COAP_SRV_DEFAULT_PORT;
if (g_usbCtx != NULL) {
LOGI(TAG, "coap usb server init has finished");
return NSTACKX_EOK;
}
if (ip == NULL) {
return NSTACKX_EFAILED;
}
if (inet_ntop(AF_INET, ip, addrStr, NI_MAXHOST) == NULL) {
LOGE(TAG, "inet_ntop failed");
return NSTACKX_EFAILED;
}
coap_startup();
g_usbCtx = CoapGetContext(addrStr, portStr, NSTACKX_TRUE, ip);
if (g_usbCtx == NULL) {
LOGE(TAG, "coap usb init get context failed");
return NSTACKX_EFAILED;
}
SetUsbIp(ip);
CoapInitResources(g_usbCtx, SERVER_TYPE_USB);
coap_register_response_handler(g_usbCtx, CoapMessageHandler);
return NSTACKX_EOK;
}
void CoapServerDestroy(void)
{
LOGD(TAG, "CoapServerDestroy is called");
uint32_t i;
g_ctxSocketErrFlag = NSTACKX_FALSE;
if (g_ctx == NULL) {
return;
}
for (i = 0; i < g_socketNum && i < MAX_COAP_SOCKET_NUM; i++) {
if (g_taskList[i].taskfd < 0) {
continue;
}
DeRegisterEpollTask(&g_taskList[i]);
}
g_socketNum = 0;
coap_free_context(g_ctx);
g_ctx = NULL;
CoapDestroyCtx(SERVER_TYPE_WLANORETH);
}
void CoapP2pServerDestroy(void)
{
LOGD(TAG, "CoapP2pServerDestroy is called");
uint32_t i;
g_p2pCtxSocketErrFlag = NSTACKX_FALSE;
if (g_p2pCtx == NULL) {
return;
}
if (g_p2pSocketNum > MAX_COAP_SOCKET_NUM) {
g_p2pSocketNum = MAX_COAP_SOCKET_NUM;
LOGI(TAG, "socketNum exccedd MAX_COAP_SOCKET_NUM, and set it to MAX_COAP_SOCKET_NUM");
}
for (i = 0; i < g_p2pSocketNum; i++) {
if (g_p2pTaskList[i].taskfd < 0) {
continue;
}
DeRegisterEpollTask(&g_p2pTaskList[i]);
}
g_p2pSocketNum = 0;
coap_free_context(g_p2pCtx);
g_p2pCtx = NULL;
CoapDestroyCtx(SERVER_TYPE_P2P);
}
void CoapUsbServerDestroy(void)
{
LOGD(TAG, "CoapUsbServerDestroy is called");
uint32_t i;
g_usbCtxSocketErrFlag = NSTACKX_FALSE;
if (g_usbCtx == NULL) {
return;
}
if (g_usbSocketNum > MAX_COAP_SOCKET_NUM) {
g_usbSocketNum = MAX_COAP_SOCKET_NUM;
LOGI(TAG, "socketNum exccedd MAX_COAP_SOCKET_NUM, and set it to MAX_COAP_SOCKET_NUM");
}
for (i = 0; i < g_usbSocketNum; i++) {
if (g_usbTaskList[i].taskfd < 0) {
continue;
}
DeRegisterEpollTask(&g_usbTaskList[i]);
}
g_usbSocketNum = 0;
coap_free_context(g_usbCtx);
g_usbCtx = NULL;
CoapDestroyCtx(SERVER_TYPE_USB);
}
void ResetCoapSocketTaskCount(uint8_t isBusy)
{
uint64_t totalTaskCount = 0;
uint64_t totalP2pTaskCount = 0;
uint64_t totalUsbTaskCount = 0;
for (uint32_t i = 0; i < g_socketNum && i < MAX_COAP_SOCKET_NUM; i++) {
if (totalTaskCount < UINT64_MAX && g_taskList[i].count <= UINT64_MAX - totalTaskCount) {
totalTaskCount += g_taskList[i].count;
}
g_taskList[i].count = 0;
}
for (uint32_t i = 0; i < g_p2pSocketNum && i < MAX_COAP_SOCKET_NUM; i++) {
if (totalP2pTaskCount < UINT64_MAX && g_p2pTaskList[i].count <= UINT64_MAX - totalP2pTaskCount) {
totalP2pTaskCount += g_p2pTaskList[i].count;
}
g_p2pTaskList[i].count = 0;
}
for (uint32_t i = 0; i < g_usbSocketNum && i < MAX_COAP_SOCKET_NUM; i++) {
if (totalUsbTaskCount < UINT64_MAX && g_usbTaskList[i].count <= UINT64_MAX - totalUsbTaskCount) {
totalUsbTaskCount += g_usbTaskList[i].count;
}
g_usbTaskList[i].count = 0;
}
if (isBusy) {
LOGI(TAG, "in this busy interval, socket task count: wifi %llu, p2p %llu, usb %llu,"
"read %llu, write %llu, error %llu",
totalTaskCount, totalP2pTaskCount, totalUsbTaskCount,
g_socketEventNum[SOCKET_READ_EVENT],
g_socketEventNum[SOCKET_WRITE_EVENT], g_socketEventNum[SOCKET_ERROR_EVENT]);
}
(void)memset_s(g_socketEventNum, sizeof(g_socketEventNum), 0, sizeof(g_socketEventNum));
}

View File

@ -0,0 +1,306 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "coap_client.h"
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <netdb.h>
#include <securec.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "coap_session_internal.h"
#include "nstackx_device.h"
#include "nstackx_error.h"
#include "nstackx_log.h"
#include "nstackx_util.h"
#include "utlist.h"
#define TAG "nStackXCoAP"
#define FLAGS_BLOCK 0x01
#define DEFAULT_COAP_BUFFER_LENGTH 256
#define COAP_CODE_RIGHT_PART_LENGTH 5
#define COAP_CERT_CHAIN_DEPTH 2
/*
* the initial timeout will be set to a random duration between COAP_ACK_TIMEOUT and
* (COAP_ACK_TIMEOUT * COAP_ACK_RANDOM_FACTOR).
*/
#define COAP_ACK_TIMEOUT ((coap_fixed_point_t){1, 0}) // 1 seconds
#define COAP_ACK_RANDOM_FACTOR ((coap_fixed_point_t){1, 200}) // 1.2
/* Request URI.
* associate the resources with transaction id and make it expireable
*/
coap_uri_t g_uri;
int32_t CoapResolveAddress(const coap_str_const_t *server, struct sockaddr *dst)
{
struct addrinfo *res = NULL;
struct addrinfo *ainfo = NULL;
struct addrinfo hints;
char addrstr[DEFAULT_COAP_BUFFER_LENGTH]; /* Get a char array with length 256 to save host name. */
int error;
int32_t len = -1;
(void)memset_s(addrstr, sizeof(addrstr), 0, sizeof(addrstr));
if (server->length) {
if (memcpy_s(addrstr, sizeof(addrstr), server->s, server->length) != EOK) {
LOGD(TAG, "addrstr copy error");
return len;
}
} else {
if (memcpy_s(addrstr, sizeof(addrstr), "localhost", strlen("localhost")) != EOK) {
LOGD(TAG, "addrstr copy error");
return len;
}
}
(void)memset_s((char *)&hints, sizeof(hints), 0, sizeof(hints));
hints.ai_socktype = SOCK_DGRAM;
hints.ai_family = AF_UNSPEC;
error = getaddrinfo(addrstr, NULL, &hints, &res);
if (error != 0) {
LOGE(TAG, "getaddrinfo error");
return error;
}
for (ainfo = res; ainfo != NULL; ainfo = ainfo->ai_next) {
switch (ainfo->ai_family) {
case AF_INET6:
/* fall-through */
case AF_INET:
len = ainfo->ai_addrlen;
if (memcpy_s(dst, sizeof(struct sockaddr), ainfo->ai_addr, len) != EOK) {
LOGE(TAG, "ai_addr copy error");
len = -1;
break;
}
goto finish;
default:
break;
}
}
finish:
freeaddrinfo(res);
return len;
}
void CoapMessageHandler(struct coap_context_t *ctx,
coap_session_t *session,
coap_pdu_t *sent,
coap_pdu_t *received,
const coap_tid_t id)
{
if (received == NULL) {
LOGE(TAG, "received error");
return;
}
(void)ctx;
(void)session;
(void)sent;
(void)id;
coap_opt_t *blockOpt1 = NULL;
coap_opt_t *blockOpt2 = NULL;
coap_opt_iterator_t optIter;
(void)memset_s(&optIter, sizeof(optIter), 0, sizeof(optIter));
if (received->type == COAP_MESSAGE_RST) {
LOGD(TAG, "got RST");
return;
}
if (coap_check_option(received, COAP_OPTION_OBSERVE, &optIter)) {
LOGE(TAG, "observe not support.");
return;
}
blockOpt2 = coap_check_option(received, COAP_OPTION_BLOCK2, &optIter);
blockOpt1 = coap_check_option(received, COAP_OPTION_BLOCK1, &optIter);
if ((blockOpt1 != NULL) || (blockOpt2 != NULL)) {
LOGE(TAG, "block not support.");
return;
}
LOGD(TAG, "%u.%02u", (received->code >> COAP_CODE_RIGHT_PART_LENGTH), received->code & 0x1F);
}
static void InitAddrinfo(struct addrinfo *hints)
{
if (hints == NULL) {
return;
}
(void)memset_s(hints, sizeof(struct addrinfo), 0, sizeof(struct addrinfo));
hints->ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints->ai_socktype = SOCK_DGRAM; /* Coap uses UDP */
hints->ai_flags = AI_PASSIVE | AI_NUMERICHOST;
}
coap_context_t *CoapGetContext(const char *node, const char *port, uint8_t needBind, const struct in_addr *ip)
{
struct addrinfo hints;
struct addrinfo *result = NULL;
struct addrinfo *rp = NULL;
coap_endpoint_t *ep = NULL;
coap_context_t *ctx = coap_new_context(NULL);
if (ctx == NULL) {
return NULL;
}
InitAddrinfo(&hints);
if (getaddrinfo(node, port, &hints, &result) != 0) {
coap_free_context(ctx);
return NULL;
}
coap_address_t addr;
/* iterate through results until success */
for (rp = result; rp != NULL; rp = rp->ai_next) {
if (rp->ai_addrlen > (socklen_t)sizeof(addr.addr)) {
continue;
}
coap_address_init(&addr);
addr.size = rp->ai_addrlen;
if (memcpy_s(&addr.addr, sizeof(addr.addr), rp->ai_addr, rp->ai_addrlen) != EOK ||
(addr.addr.sa.sa_family != AF_INET && addr.addr.sa.sa_family != AF_INET6)) {
continue;
}
ep = coap_new_endpoint(ctx, &addr, COAP_PROTO_UDP);
if (ep != NULL) {
struct sockaddr_in sockIp;
struct sockaddr_in *sockIpPtr = NULL;
(void)memset_s(&sockIp, sizeof(struct sockaddr_in), 0, sizeof(struct sockaddr_in));
if (ip != NULL && needBind) {
(void)memcpy_s(&sockIp.sin_addr, sizeof(struct in_addr), ip, sizeof(struct in_addr));
sockIpPtr = &sockIp;
}
if (needBind && BindToDevice(ep->sock.fd, sockIpPtr) != NSTACKX_EOK) {
LOGE(TAG, "bind to device fail");
}
} else {
LOGE(TAG, "coap_new_endpoint get null");
coap_free_context(ctx);
ctx = NULL;
}
break;
}
freeaddrinfo(result);
return ctx;
}
static coap_session_t *CoapGetSessionInner(struct addrinfo *result, coap_context_t *ctx,
const CoapServerParameter *coapServerParameter)
{
coap_session_t *session = NULL;
struct addrinfo *rp = NULL;
coap_proto_t proto = coapServerParameter->proto;
const coap_address_t *dst = coapServerParameter->dst;
if (proto != COAP_PROTO_UDP) {
LOGE(TAG, "unsupported proto");
return NULL;
}
for (rp = result; rp != NULL; rp = rp->ai_next) {
coap_address_t bindAddr;
if (rp->ai_addrlen > (socklen_t)sizeof(bindAddr.addr)) {
continue;
}
coap_address_init(&bindAddr);
bindAddr.size = rp->ai_addrlen;
if (memcpy_s(&bindAddr.addr, sizeof(bindAddr.addr), rp->ai_addr, rp->ai_addrlen) != EOK) {
LOGE(TAG, "ai_addr copy error");
continue;
}
session = coap_new_client_session(ctx, &bindAddr, dst, proto);
if (session != NULL) {
break;
}
}
return session;
}
static void CoapSetAckTimeOut(coap_session_t *session)
{
if (session == NULL) {
return;
}
coap_session_set_ack_timeout(session, COAP_ACK_TIMEOUT);
coap_session_set_ack_random_factor(session, COAP_ACK_RANDOM_FACTOR);
}
coap_session_t *CoapGetSession(coap_context_t *ctx, const char *localAddr, const char *localPort,
const CoapServerParameter *coapServerParameter)
{
coap_session_t *session = NULL;
coap_proto_t proto;
const coap_address_t *dst = NULL;
if (coapServerParameter == NULL) {
return NULL;
}
proto = coapServerParameter->proto;
dst = coapServerParameter->dst;
if (proto != COAP_PROTO_UDP) {
LOGE(TAG, "unsupported proto");
return NULL;
}
if (localAddr != NULL) {
int s;
struct addrinfo hints;
struct addrinfo *result = NULL;
(void)memset_s(&hints, sizeof(struct addrinfo), 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = COAP_PROTO_RELIABLE(proto) ? SOCK_STREAM : SOCK_DGRAM; /* Coap uses UDP */
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
s = getaddrinfo(localAddr, localPort, &hints, &result);
if (s != 0) {
LOGE(TAG, "getaddrinfo error");
return NULL;
}
session = CoapGetSessionInner(result, ctx, coapServerParameter);
freeaddrinfo(result);
} else {
session = coap_new_client_session(ctx, NULL, dst, proto);
}
CoapSetAckTimeOut(session);
return session;
}
uint8_t IsCoapCtxEndpointSocket(const coap_context_t *ctx, int fd)
{
coap_endpoint_t *ep = NULL;
coap_endpoint_t *tmp = NULL;
if (ctx == NULL || ctx->endpoint == NULL) {
return NSTACKX_FALSE;
}
LL_FOREACH_SAFE(ctx->endpoint, ep, tmp) {
if (ep->sock.fd == fd) {
return NSTACKX_TRUE;
}
}
return NSTACKX_FALSE;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,370 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "json_payload.h"
#include <securec.h>
#include "cJSON.h"
#include "coap_client.h"
#include "nstackx_log.h"
#include "nstackx_error.h"
#include "nstackx_device.h"
#define TAG "nStackXCoAP"
#define JSON_COAP_URI "coapUri"
#define JSON_CAPABILITY_BITMAP "capabilityBitmap"
#define JSON_DEVICE_ID "deviceId"
#define JSON_DEVICE_NAME "devicename"
#define JSON_DEVICE_WLAN_IP "wlanIp"
#define JSON_DEVICE_TYPE "type"
#define JSON_HICOM_VERSION "hicomversion"
#define JSON_REQUEST_MODE "mode"
#define JSON_DEVICE_HASH "deviceHash"
#define JSON_SERVICE_DATA "serviceData"
#define NSTACKX_MAX_URI_BUFFER_LENGTH 64
static int32_t AddDeviceJsonData(cJSON *data, const DeviceInfo *deviceInfo)
{
cJSON *item;
item = cJSON_CreateString(deviceInfo->deviceId);
if (item == NULL || !cJSON_AddItemToObject(data, JSON_DEVICE_ID, item)) {
cJSON_Delete(item);
return NSTACKX_EFAILED;
}
item = cJSON_CreateString(deviceInfo->deviceName);
if (item == NULL || !cJSON_AddItemToObject(data, JSON_DEVICE_NAME, item)) {
cJSON_Delete(item);
return NSTACKX_EFAILED;
}
item = cJSON_CreateNumber(deviceInfo->deviceType);
if (item == NULL || !cJSON_AddItemToObject(data, JSON_DEVICE_TYPE, item)) {
cJSON_Delete(item);
return NSTACKX_EFAILED;
}
item = cJSON_CreateString(deviceInfo->version);
if (item == NULL || !cJSON_AddItemToObject(data, JSON_HICOM_VERSION, item)) {
cJSON_Delete(item);
return NSTACKX_EFAILED;
}
item = cJSON_CreateNumber(deviceInfo->mode);
if (item == NULL || !cJSON_AddItemToObject(data, JSON_REQUEST_MODE, item)) {
cJSON_Delete(item);
return NSTACKX_EFAILED;
}
item = cJSON_CreateString(deviceInfo->deviceHash);
if (item == NULL || !cJSON_AddItemToObject(data, JSON_DEVICE_HASH, item)) {
cJSON_Delete(item);
return NSTACKX_EFAILED;
}
item = cJSON_CreateString(deviceInfo->serviceData);
if (item == NULL || !cJSON_AddItemToObject(data, JSON_SERVICE_DATA, item)) {
cJSON_Delete(item);
LOGE(TAG, "cJSON_CreateString for serviceData failed");
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
static int32_t AddWifiApJsonData(cJSON *data)
{
cJSON *item = NULL;
char ipString[INET_ADDRSTRLEN] = {0};
if (GetLocalIpString(ipString, sizeof(ipString)) != NSTACKX_EOK) {
return NSTACKX_EFAILED;
}
item = cJSON_CreateString(ipString);
if (item == NULL || !cJSON_AddItemToObject(data, JSON_DEVICE_WLAN_IP, item)) {
cJSON_Delete(item);
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
static int32_t AddCapabilityBitmap(cJSON *data, const DeviceInfo *deviceInfo)
{
cJSON *capabilityArray = NULL;
cJSON *capability = NULL;
uint32_t i;
if (deviceInfo->capabilityBitmapNum == 0) {
return NSTACKX_EOK;
}
capabilityArray = cJSON_CreateArray();
if (capabilityArray == NULL) {
goto L_END_JSON;
}
for (i = 0; i < deviceInfo->capabilityBitmapNum; i++) {
capability = cJSON_CreateNumber(deviceInfo->capabilityBitmap[i]);
if (capability == NULL || !cJSON_AddItemToArray(capabilityArray, capability)) {
cJSON_Delete(capability);
goto L_END_JSON;
}
}
if (!cJSON_AddItemToObject(data, JSON_CAPABILITY_BITMAP, capabilityArray)) {
goto L_END_JSON;
}
return NSTACKX_EOK;
L_END_JSON:
cJSON_Delete(capabilityArray);
return NSTACKX_EFAILED;
}
static int32_t ParseDeviceJsonData(const cJSON *data, DeviceInfo *dev)
{
cJSON *item = NULL;
item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_ID);
if (!cJSON_IsString(item) || !strlen(item->valuestring)) {
LOGE(TAG, "Cannot find device ID or invalid device ID");
return NSTACKX_EINVAL;
}
if (strcpy_s(dev->deviceId, sizeof(dev->deviceId), item->valuestring) != EOK) {
return NSTACKX_EFAILED;
}
item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_NAME);
if (!cJSON_IsString(item) || !strlen(item->valuestring)) {
LOGE(TAG, "Cannot find device name or invalid device name");
return NSTACKX_EINVAL;
}
if (strcpy_s(dev->deviceName, sizeof(dev->deviceName), item->valuestring) != EOK) {
return NSTACKX_EFAILED;
}
item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_TYPE);
if (!cJSON_IsNumber(item) || (item->valuedouble < 0) || (item->valuedouble > 0xFF)) {
LOGE(TAG, "Cannot find device type or invalid device type");
return NSTACKX_EINVAL;
}
dev->deviceType = (uint8_t)item->valuedouble;
item = cJSON_GetObjectItemCaseSensitive(data, JSON_HICOM_VERSION);
if (!cJSON_IsString(item) || !strlen(item->valuestring)) {
LOGW(TAG, "Can't find hicom version");
return NSTACKX_EOK;
}
if (strcpy_s(dev->version, sizeof(dev->version), item->valuestring) != EOK) {
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
static void ParseWifiApJsonData(const cJSON *data, DeviceInfo *dev)
{
cJSON *item = NULL;
item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_WLAN_IP);
if (cJSON_IsString(item)) {
if (inet_pton(AF_INET, item->valuestring, &(dev->netChannelInfo.wifiApInfo.ip)) != 1) {
LOGW(TAG, "Invalid ip address");
} else {
dev->netChannelInfo.wifiApInfo.state = NET_CHANNEL_STATE_CONNETED;
}
}
}
static void ParseModeJsonData(const cJSON *data, DeviceInfo *dev)
{
cJSON *item = NULL;
item = cJSON_GetObjectItemCaseSensitive(data, JSON_REQUEST_MODE);
if (item == NULL) {
LOGE(TAG, "Cannot get mode json");
return;
}
if (!cJSON_IsNumber(item) || (item->valuedouble < 0)) {
LOGE(TAG, "Cannot find mode or invalid mode");
} else {
if (dev == NULL) {
LOGE(TAG, "device info is null");
return;
}
dev->mode = (uint8_t)item->valuedouble;
}
}
static void ParseDeviceHashData(const cJSON *data, DeviceInfo *dev)
{
cJSON *item = NULL;
item = cJSON_GetObjectItemCaseSensitive(data, JSON_DEVICE_HASH);
if (item == NULL) {
LOGD(TAG, "Cannot get hash json");
return;
}
if (!cJSON_IsString(item) || !strlen(item->valuestring)) {
LOGD(TAG, "Cannot find device hash or invalid hash");
return;
}
if (strcpy_s(dev->deviceHash, sizeof(dev->deviceHash), item->valuestring) != EOK) {
LOGE(TAG, "parse device hash data error");
return;
}
}
static void ParseServiceDataJsonData(const cJSON *data, DeviceInfo *dev)
{
cJSON *item = NULL;
item = cJSON_GetObjectItemCaseSensitive(data, JSON_SERVICE_DATA);
if (item == NULL) {
LOGE(TAG, "Cannot get service data");
return;
}
if (!cJSON_IsString(item)) {
LOGE(TAG, "Cannot find serviceData");
return;
}
if (strcpy_s(dev->serviceData, sizeof(dev->serviceData), item->valuestring)) {
LOGE(TAG, "parse device serviceData error");
return;
}
}
static void ParseCapabilityBitmap(const cJSON *data, DeviceInfo *deviceInfo)
{
cJSON *capability = NULL;
cJSON *item = NULL;
uint32_t capabilityBitmapNum = 0;
item = cJSON_GetObjectItemCaseSensitive(data, JSON_CAPABILITY_BITMAP);
if (cJSON_IsArray(item)) {
cJSON_ArrayForEach(capability, item) {
if (capabilityBitmapNum >= NSTACKX_MAX_CAPABILITY_NUM) {
break;
}
if (!cJSON_IsNumber(capability) ||
capability->valuedouble < 0 ||
capability->valuedouble > 0xFFFFFFFF) {
/* skip invalid capability */
continue;
}
deviceInfo->capabilityBitmap[capabilityBitmapNum++] = (uint32_t)capability->valuedouble;
}
}
deviceInfo->capabilityBitmapNum = capabilityBitmapNum;
}
/*
* Service Discover JSON format
* {
* "deviceId":[device ID, string],
* "deviceName":[device name, string],
* "type": [device type, number],
* "version":[hicom version, string],
* "wlanIp":[WLAN IP address, string],
* "capabilityBitmap":[bitmap, bitmap, bitmap, ...]
* "coapUri":[coap uri for discover, string] <-- optional. When present, means it's broadcast request.
* }
*/
char *PrepareServiceDiscover(uint8_t isBroadcast)
{
char coapUriBuffer[NSTACKX_MAX_URI_BUFFER_LENGTH] = {0};
char host[NSTACKX_MAX_IP_STRING_LEN] = {0};
char *formatString = NULL;
const DeviceInfo *deviceInfo = GetLocalDeviceInfoPtr();
cJSON *data = NULL;
cJSON *localCoapString = NULL;
data = cJSON_CreateObject();
if (data == NULL) {
goto L_END_JSON;
}
/* Prepare local device info */
if ((AddDeviceJsonData(data, deviceInfo) != NSTACKX_EOK) ||
(AddWifiApJsonData(data) != NSTACKX_EOK) ||
(AddCapabilityBitmap(data, deviceInfo) != NSTACKX_EOK)) {
goto L_END_JSON;
}
if (isBroadcast) {
if (GetLocalIpString(host, sizeof(host)) != NSTACKX_EOK) {
goto L_END_JSON;
}
if (sprintf_s(coapUriBuffer, sizeof(coapUriBuffer), "coap://%s/" COAP_DEVICE_DISCOVER_URI, host) < 0) {
goto L_END_JSON;
}
localCoapString = cJSON_CreateString(coapUriBuffer);
if (localCoapString == NULL || !cJSON_AddItemToObject(data, JSON_COAP_URI, localCoapString)) {
cJSON_Delete(localCoapString);
goto L_END_JSON;
}
}
formatString = cJSON_PrintUnformatted(data);
if (formatString == NULL) {
LOGE(TAG, "cJSON_PrintUnformatted failed");
}
L_END_JSON:
cJSON_Delete(data);
return formatString;
}
int32_t ParseServiceDiscover(const uint8_t *buf, DeviceInfo *deviceInfo, char **remoteUrlPtr)
{
char *remoteUrl = NULL;
cJSON *data = NULL;
cJSON *item = NULL;
if (buf == NULL || deviceInfo == NULL || remoteUrlPtr == NULL) {
return NSTACKX_EINVAL;
}
data = cJSON_Parse((char *)buf);
if (data == NULL) {
return NSTACKX_EINVAL;
}
if (ParseDeviceJsonData(data, deviceInfo) != NSTACKX_EOK) {
cJSON_Delete(data);
return NSTACKX_EINVAL;
}
ParseWifiApJsonData(data, deviceInfo);
ParseCapabilityBitmap(data, deviceInfo);
ParseModeJsonData(data, deviceInfo);
ParseDeviceHashData(data, deviceInfo);
ParseServiceDataJsonData(data, deviceInfo);
item = cJSON_GetObjectItemCaseSensitive(data, JSON_COAP_URI);
if (item != NULL) {
if (cJSON_IsString(item)) {
remoteUrl = strdup(item->valuestring);
LOGD(TAG, "new device join");
}
}
*remoteUrlPtr = remoteUrl;
cJSON_Delete(data);
return NSTACKX_EOK;
}

View File

@ -0,0 +1,815 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nstackx_common.h"
#include <pthread.h>
#include <securec.h>
#include <semaphore.h>
#include <unistd.h>
#include "cJSON.h"
#include "coap_discover/coap_app.h"
#include "coap_discover/coap_discover.h"
#include "nstackx.h"
#include "nstackx_device.h"
#include "nstackx_epoll.h"
#include "nstackx_error.h"
#include "nstackx_event.h"
#include "nstackx_log.h"
#include "nstackx_smartgenius.h"
#include "nstackx_timer.h"
#include "nstackx_util.h"
#define TAG "nStackXDFinder"
enum {
NSTACKX_INIT_STATE_START = 0,
NSTACKX_INIT_STATE_ONGOING,
NSTACKX_INIT_STATE_DONE,
};
static EpollDesc g_epollfd = INVALID_EPOLL_DESC;
static List g_eventNodeChain = {&(g_eventNodeChain), &(g_eventNodeChain)};
static pthread_t g_tid;
static uint8_t g_validTidFlag = NSTACKX_FALSE;
static uint8_t g_terminateFlag = NSTACKX_FALSE;
static NSTACKX_Parameter g_parameter;
static uint8_t g_nstackInitState;
#define EVENT_COUNT_RATE_INTERVAL 2000 /* 2 SECONDS */
#define MAX_EVENT_PROCESS_NUM_PER_INTERVAL 700
#define MAX_CONTINUOUS_BUSY_INTERVAL_NUM 20
typedef struct {
uint32_t epollWaitTimeoutCount;
uint32_t epollWaitEventCount;
struct timespec measureBefore;
} EventProcessRatePara;
static EventProcessRatePara g_processRatePara;
static uint32_t g_continuousBusyIntervals;
void NotifyDFinderMsgRecver(DFinderMsgType msgType)
{
if (g_parameter.onDFinderMsgReceived != NULL) {
g_parameter.onDFinderMsgReceived(msgType);
}
}
static void ResetMainEpollTaskCount(uint8_t isBusy)
{
EpollTask *task = GetEpollTask(&g_eventNodeChain, g_epollfd);
if (task == NULL) {
return;
}
if (isBusy) {
LOGI(TAG, "in this busy interval: main epoll task count %llu", task->count);
}
task->count = 0;
}
uint8_t IsBusyInterval(uint32_t eventCount, uint32_t timeMs)
{
uint8_t retFlag;
if ((uint64_t)eventCount * EVENT_COUNT_RATE_INTERVAL <
MAX_EVENT_PROCESS_NUM_PER_INTERVAL * (uint64_t)timeMs) {
retFlag = NSTACKX_FALSE;
} else {
retFlag = NSTACKX_TRUE;
}
ResetMainEpollTaskCount(retFlag);
ResetCoapSocketTaskCount(retFlag);
ResetCoapDiscoverTaskCount(retFlag);
ResetDeviceTaskCount(retFlag);
ResetSmartGeniusTaskCount(retFlag);
return retFlag;
}
static void CalculateEventProcessRate(void)
{
struct timespec now;
ClockGetTime(CLOCK_MONOTONIC, &now);
uint32_t measureElapse = GetTimeDiffMs(&now, &g_processRatePara.measureBefore);
if (measureElapse > EVENT_COUNT_RATE_INTERVAL) {
uint32_t totalCount = g_processRatePara.epollWaitEventCount + g_processRatePara.epollWaitTimeoutCount;
if (!IsBusyInterval(totalCount, measureElapse)) {
g_continuousBusyIntervals = 0;
} else {
LOGI(TAG, "main loop seems to be busy in the past interval. Timeout count %u, event count %u",
g_processRatePara.epollWaitTimeoutCount, g_processRatePara.epollWaitEventCount);
g_continuousBusyIntervals++;
if (g_continuousBusyIntervals >= MAX_CONTINUOUS_BUSY_INTERVAL_NUM) {
LOGE(TAG, "main loop seems to be busy in the past %u intervals. notify user to restart",
g_continuousBusyIntervals);
NotifyDFinderMsgRecver(DFINDER_ON_TOO_BUSY);
g_continuousBusyIntervals = 0;
}
}
g_processRatePara.epollWaitTimeoutCount = 0;
g_processRatePara.epollWaitEventCount = 0;
ClockGetTime(CLOCK_MONOTONIC, &g_processRatePara.measureBefore);
}
}
static void *NstackMainLoop(void *arg)
{
uint32_t timeout;
int32_t ret;
(void)arg;
(void)memset_s(&g_processRatePara, sizeof(g_processRatePara), 0, sizeof(g_processRatePara));
g_continuousBusyIntervals = 0;
ClockGetTime(CLOCK_MONOTONIC, &g_processRatePara.measureBefore);
while (g_terminateFlag == NSTACKX_FALSE) {
timeout = RegisterCoAPEpollTask(g_epollfd);
ret = EpollLoop(g_epollfd, timeout);
if (ret == NSTACKX_EFAILED) {
LOGE(TAG, "epoll loop failed");
DeRegisterCoAPEpollTask();
break;
} else if (ret == NSTACKX_ETIMEOUT) {
g_processRatePara.epollWaitTimeoutCount++;
} else if (ret > 0) {
g_processRatePara.epollWaitEventCount++;
}
CalculateEventProcessRate();
DeRegisterCoAPEpollTask();
}
return NULL;
}
EpollDesc GetMainLoopEpollFd(void)
{
return g_epollfd;
}
List *GetMainLoopEvendChain(void)
{
return &g_eventNodeChain;
}
static int32_t InternalInit(EpollDesc epollfd)
{
int32_t ret = EventModuleInit(&g_eventNodeChain, g_epollfd);
if (ret != NSTACKX_EOK) {
return ret;
}
ret = DeviceModuleInit(epollfd);
if (ret != NSTACKX_EOK) {
return ret;
}
ret = P2pUsbTimerInit(epollfd);
if (ret != NSTACKX_EOK) {
return ret;
}
ret = CoapServerInit(NULL);
if (ret != NSTACKX_EOK) {
return ret;
}
ret = CoapDiscoverInit(epollfd);
if (ret != NSTACKX_EOK) {
return ret;
}
return SmartGeniusInit(epollfd);
}
int32_t NSTACKX_Init(const NSTACKX_Parameter *parameter)
{
int32_t ret;
if (g_nstackInitState != NSTACKX_INIT_STATE_START) {
return NSTACKX_EOK;
}
g_nstackInitState = NSTACKX_INIT_STATE_ONGOING;
cJSON_InitHooks(NULL);
SetLogLevel(NSTACKX_LOG_LEVEL_DEBUG);
g_epollfd = CreateEpollDesc();
if (!IsEpollDescValid(g_epollfd)) {
LOGE(TAG, "epoll create fail! errno: %d", errno);
g_nstackInitState = NSTACKX_INIT_STATE_START;
return NSTACKX_EFAILED;
}
LOGD(TAG, "nstack ctrl create epollfd %d", REPRESENT_EPOLL_DESC(g_epollfd));
g_terminateFlag = NSTACKX_FALSE;
g_validTidFlag = NSTACKX_FALSE;
ret = PthreadCreate(&g_tid, NULL, NstackMainLoop, NULL);
if (ret != 0) {
LOGE(TAG, "thread create failed");
goto L_ERR_INIT;
}
g_validTidFlag = NSTACKX_TRUE;
ret = InternalInit(g_epollfd);
if (ret != NSTACKX_EOK) {
goto L_ERR_INIT;
}
(void)memset_s(&g_parameter, sizeof(g_parameter), 0, sizeof(g_parameter));
if (parameter != NULL) {
(void)memcpy_s(&g_parameter, sizeof(g_parameter), parameter, sizeof(NSTACKX_Parameter));
}
CoapInitSubscribeModuleInner(); /* initialize subscribe module number */
g_nstackInitState = NSTACKX_INIT_STATE_DONE;
LOGI(TAG, "DFinder init successfully");
return NSTACKX_EOK;
L_ERR_INIT:
NSTACKX_Deinit();
return ret;
}
void NSTACKX_Deinit(void)
{
if (g_nstackInitState == NSTACKX_INIT_STATE_START) {
return;
}
if (g_validTidFlag) {
g_terminateFlag = NSTACKX_TRUE;
PthreadJoin(g_tid, NULL);
g_validTidFlag = NSTACKX_FALSE;
}
SmartGeniusClean();
CoapDiscoverDeinit();
DestroyP2pUsbServerInitRetryTimer();
CoapServerDestroy();
CoapP2pServerDestroy();
CoapUsbServerDestroy();
DeviceModuleClean();
EventNodeChainClean(&g_eventNodeChain);
if (IsEpollDescValid(g_epollfd)) {
CloseEpollDesc(g_epollfd);
g_epollfd = INVALID_EPOLL_DESC;
}
g_nstackInitState = NSTACKX_INIT_STATE_START;
LOGI(TAG, "deinit successfully");
}
static void DeviceDiscoverInner(void *argument)
{
(void)argument;
CoapServiceDiscoverInner(INNER_DISCOVERY);
/* If both Wifi AP and BLE are disabled, we should also notify user, with empty list. */
if (!IsWifiApConnected()) {
NotifyDeviceFound(NULL, 0);
}
}
static void DeviceDiscoverInnerAn(void *argument)
{
(void)argument;
CoapServiceDiscoverInnerAn(INNER_DISCOVERY);
}
static void DeviceDiscoverStopInner(void *argument)
{
(void)argument;
CoapServiceDiscoverStopInner();
}
int32_t NSTACKX_StartDeviceFind(void)
{
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
return NSTACKX_EFAILED;
}
if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverInner, NULL) != NSTACKX_EOK) {
LOGE(TAG, "Failed to start device discover!");
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
int32_t NSTACKX_StartDeviceFindAn(uint8_t mode)
{
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
return NSTACKX_EFAILED;
}
SetModeInfo(mode);
if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverInnerAn, NULL) != NSTACKX_EOK) {
LOGE(TAG, "Failed to start device discover!");
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
int32_t NSTACKX_StopDeviceFind(void)
{
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
return NSTACKX_EFAILED;
}
if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverStopInner, NULL) != NSTACKX_EOK) {
LOGE(TAG, "Failed to stop device discover!");
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
static void SubscribeModuleInner(void *argument)
{
(void)argument;
CoapSubscribeModuleInner(INNER_DISCOVERY);
}
int32_t NSTACKX_SubscribeModule(void)
{
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
return NSTACKX_EFAILED;
}
if (PostEvent(&g_eventNodeChain, g_epollfd, SubscribeModuleInner, NULL) != NSTACKX_EOK) {
LOGE(TAG, "Failed to subscribe module!");
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
static void UnsubscribeModuleInner(void *argument)
{
(void)argument;
CoapUnsubscribeModuleInner(INNER_DISCOVERY);
}
int32_t NSTACKX_UnsubscribeModule(void)
{
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
return NSTACKX_EFAILED;
}
if (PostEvent(&g_eventNodeChain, g_epollfd, UnsubscribeModuleInner, NULL) != NSTACKX_EOK) {
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
static void ConfigureLocalDeviceInfoInner(void *argument)
{
NSTACKX_LocalDeviceInfo *localDeviceInfo = argument;
ConfigureLocalDeviceInfo(localDeviceInfo);
free(localDeviceInfo);
}
int32_t NSTACKX_RegisterDevice(const NSTACKX_LocalDeviceInfo *localDeviceInfo)
{
NSTACKX_LocalDeviceInfo *dupLocalDeviceInfo = NULL;
LOGE(TAG, "begin to NSTACKX_RegisterDevice!");
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
return NSTACKX_EFAILED;
}
if (localDeviceInfo == NULL) {
LOGE(TAG, "Invalid local device info");
return NSTACKX_EINVAL;
}
dupLocalDeviceInfo = malloc(sizeof(NSTACKX_LocalDeviceInfo));
if (dupLocalDeviceInfo == NULL) {
LOGE(TAG, "malloc failed");
return NSTACKX_ENOMEM;
}
if (memcpy_s(dupLocalDeviceInfo, sizeof(NSTACKX_LocalDeviceInfo),
localDeviceInfo, sizeof(NSTACKX_LocalDeviceInfo)) != EOK) {
LOGE(TAG, "cp failed");
free(dupLocalDeviceInfo);
return NSTACKX_EFAILED;
}
if (PostEvent(&g_eventNodeChain, g_epollfd, ConfigureLocalDeviceInfoInner, dupLocalDeviceInfo) != NSTACKX_EOK) {
LOGE(TAG, "Failed to configure local device info!");
free(dupLocalDeviceInfo);
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
int32_t NSTACKX_RegisterDeviceAn(const NSTACKX_LocalDeviceInfo *localDeviceInfo, uint64_t deviceHash)
{
NSTACKX_LocalDeviceInfo *dupLocalDeviceInfo = NULL;
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
return NSTACKX_EFAILED;
}
if (localDeviceInfo == NULL) {
LOGE(TAG, "Invalid local device info");
return NSTACKX_EINVAL;
}
dupLocalDeviceInfo = malloc(sizeof(NSTACKX_LocalDeviceInfo));
if (dupLocalDeviceInfo == NULL) {
return NSTACKX_ENOMEM;
}
if (memcpy_s(dupLocalDeviceInfo, sizeof(NSTACKX_LocalDeviceInfo),
localDeviceInfo, sizeof(NSTACKX_LocalDeviceInfo)) != EOK) {
free(dupLocalDeviceInfo);
return NSTACKX_EFAILED;
}
if (PostEvent(&g_eventNodeChain, g_epollfd, ConfigureLocalDeviceInfoInner, dupLocalDeviceInfo) != NSTACKX_EOK) {
LOGE(TAG, "Failed to configure local device info!");
free(dupLocalDeviceInfo);
return NSTACKX_EFAILED;
}
SetDeviceHash(deviceHash);
return NSTACKX_EOK;
}
typedef struct {
uint32_t capabilityBitmapNum;
uint32_t capabilityBitmap[NSTACKX_MAX_CAPABILITY_NUM];
} CapabilityProcessData;
static void RegisterCapabilityInner(void *argument)
{
CapabilityProcessData *capabilityData = argument;
RegisterCapability(capabilityData->capabilityBitmapNum, capabilityData->capabilityBitmap);
free(capabilityData);
}
static void SetFilterCapabilityInner(void *argument)
{
CapabilityProcessData *capabilityData = argument;
SetFilterCapability(capabilityData->capabilityBitmapNum, capabilityData->capabilityBitmap);
free(capabilityData);
}
static int32_t NSTACKX_CapabilityHandle(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[], EventHandle handle)
{
CapabilityProcessData *capabilityData = NULL;
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
return NSTACKX_EFAILED;
}
if (capabilityBitmapNum > NSTACKX_MAX_CAPABILITY_NUM) {
LOGE(TAG, "capabilityBitmapNum (%u) exceed max number", capabilityBitmapNum);
return NSTACKX_EINVAL;
}
capabilityData = calloc(1U, sizeof(CapabilityProcessData));
if (capabilityData == NULL) {
return NSTACKX_ENOMEM;
}
if ((capabilityBitmapNum != 0) && memcpy_s(capabilityData->capabilityBitmap,
sizeof(capabilityData->capabilityBitmap), capabilityBitmap, capabilityBitmapNum * sizeof(uint32_t)) != EOK) {
free(capabilityData);
return NSTACKX_EINVAL;
}
capabilityData->capabilityBitmapNum = capabilityBitmapNum;
if (PostEvent(&g_eventNodeChain, g_epollfd, handle, capabilityData) != NSTACKX_EOK) {
LOGE(TAG, "Failed to register capability!");
free(capabilityData);
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
int32_t NSTACKX_RegisterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[])
{
LOGI(TAG, "Register Capability");
return NSTACKX_CapabilityHandle(capabilityBitmapNum, capabilityBitmap, RegisterCapabilityInner);
}
int32_t NSTACKX_SetFilterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[])
{
LOGI(TAG, "Set Filter Capability");
return NSTACKX_CapabilityHandle(capabilityBitmapNum, capabilityBitmap, SetFilterCapabilityInner);
}
static void RegisterServiceDataInner(void *argument)
{
char *serviceData = argument;
if (RegisterServiceData(serviceData) != NSTACKX_EOK) {
LOGE(TAG, "RegisterServiceData failed");
}
free(serviceData);
}
int32_t NSTACKX_RegisterServiceData(const char *serviceData)
{
char *serviceDataTmp = NULL;
if (serviceData == NULL) {
LOGE(TAG, "serviceData is null");
return NSTACKX_EINVAL;
}
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
return NSTACKX_EFAILED;
}
if (strlen(serviceData) >= NSTACKX_MAX_SERVICE_DATA_LEN) {
LOGE(TAG, "serviceData (%u) exceed max number", strlen(serviceData));
return NSTACKX_EINVAL;
}
serviceDataTmp = calloc(1U, NSTACKX_MAX_SERVICE_DATA_LEN);
if (serviceDataTmp == NULL) {
return NSTACKX_ENOMEM;
}
if (strncpy_s(serviceDataTmp, NSTACKX_MAX_SERVICE_DATA_LEN, serviceData, strlen(serviceData)) != EOK) {
LOGE(TAG, "Failed to copy serviceData");
free(serviceDataTmp);
return NSTACKX_EINVAL;
}
if (PostEvent(&g_eventNodeChain, g_epollfd, RegisterServiceDataInner, serviceDataTmp) != NSTACKX_EOK) {
LOGE(TAG, "Failed to register serviceData!");
free(serviceDataTmp);
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
static void SendMsgInner(void *arg)
{
MsgCtx *msg = arg;
DeviceInfo *deviceInfo = NULL;
if (msg == NULL) {
LOGE(TAG, "SendMsgInner: msg is NULL");
return;
}
if (strlen(msg->p2pAddr) != 0) {
LOGD(TAG, "Enter WifiDirect send");
CoapSendServiceMsgWithDefiniteTargetIp(msg, deviceInfo);
} else {
deviceInfo = GetDeviceInfoById(msg->deviceId, GetDeviceDB());
if (deviceInfo == NULL) {
LOGW(TAG, "no device found in device list, try to find in backup");
deviceInfo = GetDeviceInfoById(msg->deviceId, GetDeviceDBBackup());
if (deviceInfo == NULL) {
LOGE(TAG, "no device found in device list backup yet");
goto FINISH;
}
}
CoapSendServiceMsg(msg, deviceInfo);
}
FINISH:
free(msg->data);
free(msg);
}
int32_t NSTACKX_SendMsgParamCheck(const char *moduleName, const char *deviceId, const uint8_t *data,
uint32_t len)
{
if (moduleName == NULL || strlen(moduleName) > NSTACKX_MAX_MODULE_NAME_LEN) {
LOGE(TAG, "Invalid module name");
return NSTACKX_EINVAL;
}
if (deviceId == NULL || strlen(deviceId) > NSTACKX_MAX_DEVICE_ID_LEN) {
LOGE(TAG, "Invalid device id");
return NSTACKX_EINVAL;
}
if (data == NULL || len == 0 || len > NSTACKX_MAX_SENDMSG_DATA_LEN) {
LOGE(TAG, "Null data to send");
return NSTACKX_EINVAL;
}
return NSTACKX_EOK;
}
int32_t NSTACKX_SendMsgDirect(const char *moduleName, const char *deviceId, const uint8_t *data,
uint32_t len, const char *ipaddr, uint8_t type)
{
MsgCtx *msg = NULL;
LOGD(TAG, "NSTACKX_SendMsgDirect");
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
return NSTACKX_EFAILED;
}
if (NSTACKX_SendMsgParamCheck(moduleName, deviceId, data, len) != NSTACKX_EOK) {
return NSTACKX_EINVAL;
}
msg = calloc(1U, sizeof(MsgCtx));
if (msg == NULL) {
LOGE(TAG, "MsgCtx malloc fail");
return NSTACKX_ENOMEM;
}
if ((strcpy_s(msg->deviceId, sizeof(msg->deviceId), deviceId) != EOK) ||
(strcpy_s(msg->moduleName, sizeof(msg->moduleName), moduleName) != EOK)) {
LOGE(TAG, "Cpy deviceId fail");
free(msg);
return NSTACKX_EFAILED;
}
if (strcpy_s(msg->p2pAddr, sizeof(msg->p2pAddr), ipaddr) != EOK) {
LOGE(TAG, "Cpy p2pAddr fail.");
free(msg);
return NSTACKX_EFAILED;
}
msg->data = malloc(len);
if (msg->data == NULL) {
LOGE(TAG, "Msg data malloc fail");
free(msg);
return NSTACKX_ENOMEM;
}
if (memcpy_s(msg->data, len, data, len) != EOK) {
LOGE(TAG, "Msg data memcpy error");
free(msg->data);
free(msg);
return NSTACKX_EFAILED;
}
msg->len = len;
msg->type = type;
if (PostEvent(&g_eventNodeChain, g_epollfd, SendMsgInner, msg) != NSTACKX_EOK) {
LOGE(TAG, "Failed to send msg");
free(msg->data);
free(msg);
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
int32_t NSTACKX_SendMsg(const char *moduleName, const char *deviceId, const uint8_t *data, uint32_t len)
{
MsgCtx *msg = NULL;
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
return NSTACKX_EFAILED;
}
if (NSTACKX_SendMsgParamCheck(moduleName, deviceId, data, len) != NSTACKX_EOK) {
return NSTACKX_EINVAL;
}
msg = calloc(1U, sizeof(MsgCtx));
if (msg == NULL) {
LOGE(TAG, "MsgCtx malloc fail");
return NSTACKX_ENOMEM;
}
if ((strcpy_s(msg->deviceId, sizeof(msg->deviceId), deviceId) != EOK) ||
(strcpy_s(msg->moduleName, sizeof(msg->moduleName), moduleName) != EOK)) {
free(msg);
return NSTACKX_EFAILED;
}
msg->data = malloc(len);
if (msg->data == NULL) {
LOGE(TAG, "msg data malloc fail");
free(msg);
return NSTACKX_ENOMEM;
}
if (memcpy_s(msg->data, len, data, len) != EOK) {
LOGE(TAG, "msg data memcpy error");
free(msg->data);
free(msg);
return NSTACKX_EFAILED;
}
msg->len = len;
msg->type = SERVER_TYPE_WLANORETH;
if (PostEvent(&g_eventNodeChain, g_epollfd, SendMsgInner, msg) != NSTACKX_EOK) {
LOGE(TAG, "failed to send msg");
free(msg->data);
free(msg);
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
typedef struct {
NSTACKX_DeviceInfo *deviceList;
uint32_t *deviceCountPtr;
sem_t wait;
} GetDeviceListMessage;
static void GetDeviceListInner(void *argument)
{
GetDeviceListMessage *message = argument;
GetDeviceList(message->deviceList, message->deviceCountPtr, true);
SemPost(&message->wait);
}
int32_t NSTACKX_GetDeviceList(NSTACKX_DeviceInfo *deviceList, uint32_t *deviceCountPtr)
{
GetDeviceListMessage message = {
.deviceList = deviceList,
.deviceCountPtr = deviceCountPtr,
};
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
return NSTACKX_EFAILED;
}
if (deviceList == NULL || deviceCountPtr == NULL) {
LOGE(TAG, "Device list or count pointer is NULL");
return NSTACKX_EINVAL;
}
if (SemInit(&message.wait, 0, 0)) {
return NSTACKX_EFAILED;
}
if (PostEvent(&g_eventNodeChain, g_epollfd, GetDeviceListInner, &message) != NSTACKX_EOK) {
LOGE(TAG, "Failed to get device list");
SemDestroy(&message.wait);
return NSTACKX_EFAILED;
}
SemWait(&message.wait);
SemDestroy(&message.wait);
return NSTACKX_EOK;
}
void NotifyDeviceListChanged(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount)
{
if (g_parameter.onDeviceListChanged != NULL) {
LOGI(TAG, "notify callback: device list changed");
g_parameter.onDeviceListChanged(deviceList, deviceCount);
LOGI(TAG, "finish to notify device list changed");
} else {
LOGI(TAG, "notify callback: device list changed callback is null");
}
}
void NotifyDeviceFound(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount)
{
if (g_parameter.onDeviceFound != NULL) {
LOGI(TAG, "notify callback: device found");
g_parameter.onDeviceFound(deviceList, deviceCount);
LOGI(TAG, "finish to notify device found");
} else {
LOGI(TAG, "notify callback: device found callback is null");
}
}
void NotifyMsgReceived(const char *moduleName, const char *deviceId, const uint8_t *data, uint32_t len)
{
if (g_parameter.onMsgReceived != NULL) {
LOGI(TAG, "notify callback: message received, data length %u", len);
g_parameter.onMsgReceived(moduleName, deviceId, data, len);
LOGI(TAG, "finish to notify msg received");
} else {
LOGI(TAG, "notify callback: message received callback is null");
}
}
int32_t NSTACKX_InitRestart(const NSTACKX_Parameter *parameter)
{
LOGI(TAG, "NSTACKX_InitRestart");
int32_t ret = NSTACKX_Init(parameter);
if (ret == NSTACKX_EOK) {
if (PostEvent(&g_eventNodeChain, g_epollfd, GetLocalNetworkInterface, NULL) != NSTACKX_EOK) {
LOGE(TAG, "Failed to GetLocalNetworkInterface");
}
}
return ret;
}
static void DeviceDiscoverInnerRestart(void *argument)
{
(void)argument;
CoapServiceDiscoverInner(NSTACKX_FALSE);
}
void NSTACKX_StartDeviceFindRestart(void)
{
if (g_nstackInitState != NSTACKX_INIT_STATE_DONE) {
LOGE(TAG, "NSTACKX_Ctrl is not initiated yet");
return;
}
LOGI(TAG, "start device find for restart");
if (PostEvent(&g_eventNodeChain, g_epollfd, DeviceDiscoverInnerRestart, NULL) != NSTACKX_EOK) {
LOGE(TAG, "Failed to start device discover!");
return;
}
return;
}

View File

@ -0,0 +1,241 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nstackx_database.h"
#include <stdint.h>
#include <malloc.h>
#include <string.h>
#include <securec.h>
#include "nstackx_log.h"
#include "nstackx_error.h"
#define TAG "nStackXDFinder"
#define NSTACKX_USEDMAP_ROW_SIZE 32U /* Row size suit for uint32_t */
typedef struct {
uint8_t *blk;
uint32_t *usedMap;
uint32_t mapSize;
uint32_t useCount;
uint32_t maxCount;
size_t recSize;
RecCompareCallback cb;
} DatabaseInfo;
static inline int64_t GetRecordIndex(const DatabaseInfo *db, const void *rec)
{
if (db->recSize == 0) {
return -1;
}
return ((uint8_t *)rec - db->blk) / db->recSize;
}
/* Make sure that recNum is valid */
static uint8_t IsRecordOccupied(const DatabaseInfo *db, uint32_t recNum, uint32_t *iptr, uint32_t *offptr)
{
uint32_t i;
uint32_t off;
i = recNum / NSTACKX_USEDMAP_ROW_SIZE;
off = recNum % NSTACKX_USEDMAP_ROW_SIZE;
if (iptr != NULL) {
*iptr = i;
}
if (offptr != NULL) {
*offptr = off;
}
if (db->usedMap[i] & (1U << off)) {
return NSTACKX_TRUE;
}
return NSTACKX_FALSE;
}
static inline void *GetRecord(const DatabaseInfo *db, uint32_t index)
{
return db->blk + (index * db->recSize);
}
void *DatabaseSearchRecord(const void *dbptr, void *ptr)
{
const DatabaseInfo *db = dbptr;
void *rec = NULL;
uint32_t i, j;
if (dbptr == NULL || ptr == NULL || db->cb == NULL) {
return NULL;
}
for (i = 0; i < db->mapSize; i++) {
if (!db->usedMap[i]) {
continue;
}
for (j = 0; j < NSTACKX_USEDMAP_ROW_SIZE; j++) {
if (!(db->usedMap[i] & (1U << j))) {
continue;
}
rec = GetRecord(db, i * NSTACKX_USEDMAP_ROW_SIZE + j);
if (db->cb(rec, ptr)) {
return rec;
}
}
}
return NULL;
}
uint32_t GetDatabaseUseCount(const void *dbptr)
{
if (dbptr == NULL) {
return 0;
}
return ((const DatabaseInfo *)dbptr)->useCount;
}
void *DatabaseGetNextRecord(void *dbptr, int64_t *idx)
{
DatabaseInfo *db = dbptr;
void *rec = NULL;
uint32_t i;
if (dbptr == NULL || idx == NULL || *idx >= UINT32_MAX) {
return NULL;
}
if (*idx >= 0) {
*idx = *idx + 1;
} else {
*idx = 0;
}
for (i = (uint32_t)(*idx); i < db->maxCount; i++) {
if (IsRecordOccupied(db, i, NULL, NULL)) {
rec = GetRecord(db, i);
*idx = (int64_t)i;
return rec;
}
}
return NULL;
}
void *DatabaseAllocRecord(void *dbptr)
{
DatabaseInfo *db = dbptr;
void *rec = NULL;
uint32_t i, j;
if (dbptr == NULL) {
return NULL;
}
if (db->useCount >= db->maxCount) {
LOGE(TAG, "DB max limit exceeded maxcnt:%u, usecnt:%u", db->maxCount, db->useCount);
return NULL;
}
for (i = 0; i < db->mapSize; i++) {
if (db->usedMap[i] == ~(uint32_t)0) {
continue;
}
for (j = 0; j < NSTACKX_USEDMAP_ROW_SIZE; j++) {
if (db->usedMap[i] & (1U << j)) {
continue;
}
rec = GetRecord(db, i * NSTACKX_USEDMAP_ROW_SIZE + j);
if (memset_s(rec, db->recSize, 0, db->recSize) != EOK) {
return NULL;
} else {
db->usedMap[i] |= (1U << j);
db->useCount++;
return rec;
}
}
}
return NULL;
}
void DatabaseFreeRecord(void *dbptr, const void *ptr)
{
DatabaseInfo *db = dbptr;
uint32_t i, off;
int64_t recNum;
if (dbptr == NULL || ptr == NULL || db->useCount == 0) {
LOGE(TAG, "Sanity chk failed");
return;
}
recNum = GetRecordIndex(db, ptr);
if (recNum < 0 || recNum >= db->maxCount) {
LOGE(TAG, "Invalid record");
return;
}
if (!IsRecordOccupied(db, (uint32_t)recNum, &i, &off)) {
LOGE(TAG, "Unused record");
return;
}
db->usedMap[i] &= ~(1U << off);
db->useCount--;
}
void DatabaseClean(void *ptr)
{
DatabaseInfo *db = ptr;
if (db == NULL) {
return;
}
free(db->blk);
free(db->usedMap);
free(db);
}
void *DatabaseInit(uint32_t recNumber, size_t recSize, RecCompareCallback cb)
{
DatabaseInfo *db = NULL;
if (recNumber == 0 || recSize == 0) {
return NULL;
}
db = (DatabaseInfo *)calloc(1U, sizeof(DatabaseInfo));
if (db == NULL) {
LOGE(TAG, "calloc dbinfo failed");
return NULL;
}
db->mapSize = recNumber / NSTACKX_USEDMAP_ROW_SIZE + 1;
db->usedMap = calloc(db->mapSize, sizeof(uint32_t));
if (db->usedMap == NULL) {
LOGE(TAG, "calloc usedmap failed");
free(db);
return NULL;
}
db->blk = (uint8_t *)malloc(recNumber * recSize);
if (db->blk == NULL) {
LOGE(TAG, "malloc %u %zu failed", recNumber, recSize);
free(db->usedMap);
free(db);
return NULL;
}
db->maxCount = recNumber;
db->useCount = 0;
db->recSize = recSize;
db->cb = cb;
return db;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,255 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nstackx_smartgenius.h"
#include <errno.h>
#include <string.h>
#include <securec.h>
#include <sys/types.h>
#ifdef SUPPORT_SMARTGENIUS
#include <sys/socket.h>
#include <unistd.h>
#include <linux/rtnetlink.h>
#include <arpa/inet.h>
#endif /* SUPPORT_SMARTGENIUS */
#include "nstackx_log.h"
#include "nstackx_error.h"
#include "nstackx_util.h"
#include "nstackx_epoll.h"
#include "nstackx_device.h"
#include "nstackx_timer.h"
#include "coap_discover/coap_discover.h"
#define TAG "nStackXDFinder"
#ifdef SUPPORT_SMARTGENIUS
#define BUFLEN 256
#define NSTACKX_POSTPONE_DELAY_MS 500
static EpollTask g_netlinkTask;
static Timer *g_postponeTimer;
static uint8_t g_smartGeniusInit = NSTACKX_FALSE;
static void ParseRTattr(struct rtattr **tb, uint32_t max, struct rtattr *attr, uint32_t len)
{
/*
* Use macro RTA_OK() and RTA_NEXT() to iterate attribute list, and fill table "tb" with attribute whose type is not
* greater than "max".
*/
for (; RTA_OK(attr, len); attr = RTA_NEXT(attr, len)) {
if (attr->rta_type <= max) {
tb[attr->rta_type] = attr;
}
}
}
static void IfAddrMsgHandle(struct nlmsghdr *msgHdr)
{
struct rtattr *tb[IFA_MAX + 1] = {0}; /* Table to store rtnetlink attribute pointers */
struct ifaddrmsg *ifAddr = NLMSG_DATA(msgHdr); /* Get IP address information from message */
if (msgHdr->nlmsg_len < NLMSG_SPACE(sizeof(struct ifaddrmsg))) {
return;
}
uint32_t len = msgHdr->nlmsg_len - NLMSG_SPACE(sizeof(struct ifaddrmsg));
NetworkInterfaceInfo interfaceInfo;
(void)memset_s(&interfaceInfo, sizeof(interfaceInfo), 0, sizeof(interfaceInfo));
/* Parse attribute in "ifAddr", and store attribute pointers in "tb" */
ParseRTattr(tb, IFA_MAX, IFA_RTA(ifAddr), len);
if (tb[IFA_LABEL] == NULL || tb[IFA_ADDRESS] == NULL) {
return;
}
/* Use macro RTA_DATA() to get network insterface name from attribute "IFA_LABEL". */
if (!FilterNetworkInterface((char *)RTA_DATA(tb[IFA_LABEL]))) {
return;
}
if (ifAddr->ifa_family != AF_INET) {
return;
}
if (strcpy_s(interfaceInfo.name, sizeof(interfaceInfo.name), (char *)RTA_DATA(tb[IFA_LABEL])) != EOK) {
return;
}
if (msgHdr->nlmsg_type == RTM_NEWADDR) {
if (memcpy_s(&interfaceInfo.ip, sizeof(interfaceInfo.ip),
RTA_DATA(tb[IFA_ADDRESS]), sizeof(interfaceInfo.ip)) != EOK) {
return;
}
/* delay 500 ms after WiFi connection avoid "Network Unreachable" error, only activate when wlan/eth online */
if (!(IsUsbIpAddr((char *)RTA_DATA(tb[IFA_LABEL])) || IsP2pIpAddr((char *)RTA_DATA(tb[IFA_LABEL])))) {
TimerSetTimeout(g_postponeTimer, NSTACKX_POSTPONE_DELAY_MS, NSTACKX_FALSE);
}
LOGD(TAG, "Interface %s got new address.", interfaceInfo.name);
} else {
LOGD(TAG, "Interface %s delete address.", interfaceInfo.name);
}
if (IsP2pIpAddr((char *)RTA_DATA(tb[IFA_LABEL]))) {
UpdateLocalNetworkInterfaceP2pMode(&interfaceInfo, msgHdr->nlmsg_type);
} else if (IsUsbIpAddr((char *)RTA_DATA(tb[IFA_LABEL]))) {
UpdateLocalNetworkInterfaceUsbMode(&interfaceInfo, msgHdr->nlmsg_type);
} else {
UpdateLocalNetworkInterface(&interfaceInfo);
}
}
static void SmartGeniusCallback(void *arg)
{
struct nlmsghdr *innerNlmsghdr = NULL;
struct nlmsgerr *nlmErr = NULL;
char innerBuf[BUFLEN] = {0};
struct sockaddr_nl peer = {AF_NETLINK, 0, 0, 0};
int len;
socklen_t socklen;
EpollTask *task = arg;
socklen = sizeof(struct sockaddr_nl);
len = recvfrom(task->taskfd, innerBuf, BUFLEN, 0, (struct sockaddr *)&peer, &socklen);
if (len <= 0) {
LOGE(TAG, "recvfrom error %d", errno);
return;
}
innerNlmsghdr = (struct nlmsghdr *)innerBuf;
switch (innerNlmsghdr->nlmsg_type) {
case RTM_NEWADDR:
case RTM_DELADDR: {
IfAddrMsgHandle(innerNlmsghdr);
break;
}
case NLMSG_ERROR: {
nlmErr = NLMSG_DATA(innerNlmsghdr);
if (nlmErr->error == 0) {
LOGD(TAG, "NLMSG_ACK");
} else {
LOGE(TAG, "NLMSG_ERROR");
}
break;
}
default:
break;
}
return;
}
static void PostponeTimerHandle(void *data)
{
(void)data;
CoapServiceDiscoverInner(0);
}
int32_t SmartGeniusInit(EpollDesc epollfd)
{
socklen_t len;
struct sockaddr_nl local = {0};
int fd = -1;
if (g_smartGeniusInit) {
return NSTACKX_EOK;
}
local.nl_family = AF_NETLINK;
local.nl_groups = RTMGRP_NOTIFY | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE | RTMGRP_LINK;
local.nl_pid = getpid();
len = sizeof(local);
fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (fd < 0) {
LOGE(TAG, "unable to create netlink socket: %d", errno);
return NSTACKX_EFAILED;
}
if (bind(fd, (struct sockaddr *)&local, sizeof(local)) < 0) {
LOGE(TAG, "bind for netlink socket failed: %d", errno);
close(fd);
return NSTACKX_EFAILED;
}
if (getsockname(fd, (struct sockaddr *)&local, &len) < 0) {
LOGE(TAG, "getsockname failed: %d", errno);
close(fd);
return NSTACKX_EFAILED;
}
g_netlinkTask.taskfd = fd;
g_netlinkTask.epollfd = epollfd;
g_netlinkTask.readHandle = SmartGeniusCallback;
g_netlinkTask.writeHandle = NULL;
g_netlinkTask.errorHandle = NULL;
g_netlinkTask.endHandle = NULL;
g_netlinkTask.count = 0;
if (RegisterEpollTask(&g_netlinkTask, EPOLLIN) != NSTACKX_EOK) {
close(fd);
LOGE(TAG, "RegisterEpollTask fail");
return NSTACKX_EFAILED;
}
g_postponeTimer = TimerStart(epollfd, 0, NSTACKX_FALSE, PostponeTimerHandle, NULL);
if (g_postponeTimer == NULL) {
DeRegisterEpollTask(&g_netlinkTask);
close(g_netlinkTask.taskfd);
LOGE(TAG, "Create timer fail");
return NSTACKX_EFAILED;
}
g_smartGeniusInit = NSTACKX_TRUE;
return NSTACKX_EOK;
}
void SmartGeniusClean(void)
{
if (!g_smartGeniusInit) {
return;
}
TimerDelete(g_postponeTimer);
g_postponeTimer = NULL;
DeRegisterEpollTask(&g_netlinkTask);
close(g_netlinkTask.taskfd);
g_smartGeniusInit = NSTACKX_FALSE;
}
void ResetSmartGeniusTaskCount(uint8_t isBusy)
{
if (isBusy) {
LOGI(TAG, "in this busy interval: g_netlinkTask count %llu", g_netlinkTask.count);
}
g_netlinkTask.count = 0;
if (g_postponeTimer != NULL) {
if (isBusy) {
LOGI(TAG, "in this busy interval: g_postponeTimer task count %llu", g_postponeTimer->task.count);
}
g_postponeTimer->task.count = 0;
}
}
#else
int32_t SmartGeniusInit(EpollDesc epollfd)
{
(void)epollfd;
return NSTACKX_EOK;
}
void SmartGeniusClean(void)
{
}
void ResetSmartGeniusTaskCount(uint8_t isBusy)
{
(void)isBusy;
}
#endif /* SUPPORT_SMARTGENIUS */

View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef COAP_APP_H
#define COAP_APP_H
#include <net.h>
#include "nstackx_epoll.h"
#ifdef __cplusplus
extern "C" {
#endif
#define COAP_SRV_DEFAULT_PORT "5684"
#define COAP_SRV_DEFAULT_ADDR "0.0.0.0"
int32_t CoapServerInit(const struct in_addr *ip);
void CoapServerDestroy(void);
int32_t CoapP2pServerInit(const struct in_addr *ip);
void CoapP2pServerDestroy(void);
int32_t CoapUsbServerInit(const struct in_addr *ip);
void CoapUsbServerDestroy(void);
uint32_t RegisterCoAPEpollTask(EpollDesc epollfd);
uint32_t GetTimeout(struct coap_context_t *ctx, uint32_t *socketNum, EpollTask *taskList, EpollDesc epollfd);
void DeRegisterCoAPEpollTask(void);
void DeRegisteCoAPEpollTaskCtx(struct coap_context_t *ctx, uint32_t *socketNum, EpollTask *taskList);
void ResetCoapSocketTaskCount(uint8_t isBusy);
#ifdef __cplusplus
}
#endif
#endif /* COAP_APP_H */

View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef COAP_CLIENT_H
#define COAP_CLIENT_H
#include <net.h>
#ifdef __cplusplus
extern "C" {
#endif
#define COAP_DEVICE_DISCOVER_URI "device_discover"
#define COAP_SERVICE_DISCOVER_URI "service_discover"
#define COAP_SERVICE_MSG_URI "service_msg"
typedef struct {
coap_proto_t proto;
const coap_address_t *dst;
} CoapServerParameter;
coap_context_t *CoapGetContext(const char *node, const char *port, uint8_t needBind, const struct in_addr *ip);
coap_session_t *CoapGetSession(coap_context_t *ctx, const char *localAddr, const char *localPort,
const CoapServerParameter *coapServerParameter);
int32_t CoapResolveAddress(const coap_str_const_t *server, struct sockaddr *dst);
void CoapMessageHandler(struct coap_context_t *ctx, coap_session_t *session,
coap_pdu_t *sent, coap_pdu_t *received, const coap_tid_t id);
uint8_t IsCoapCtxEndpointSocket(const coap_context_t *ctx, int fd);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef COAP_CLIENT_H */

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef COAP_DISCOVER_H
#define COAP_DISCOVER_H
#include <net.h>
#include "nstackx_common.h"
#define COAP_MODULE_NAME_TYPE 0x01
#define COAP_DEVICE_ID_TYPE 0x02
#define COAP_MSG_TYPE 0x03
#define SERVER_TYPE_WLANORETH 0
#define SERVER_TYPE_P2P 1
#define SERVER_TYPE_USB 2
#define INVALID_TYPE 255
typedef struct {
uint8_t type;
uint16_t len; /* must be a positive integer */
uint8_t value[0];
} __attribute__((packed)) CoapMsgUnit;
struct coap_session_t;
struct DeviceInfo;
typedef struct {
char deviceId[NSTACKX_MAX_DEVICE_ID_LEN];
char moduleName[NSTACKX_MAX_MODULE_NAME_LEN];
char p2pAddr[NSTACKX_MAX_IP_STRING_LEN];
uint8_t *data;
uint32_t len;
uint8_t type;
} MsgCtx;
void CoapServiceDiscoverInner(uint8_t userRequest);
void CoapServiceDiscoverInnerAn(uint8_t userRequest);
void CoapServiceDiscoverStopInner(void);
uint8_t CoapDiscoverRequestOngoing(void);
void CoapInitResources(coap_context_t *ctx, uint8_t isNeedInitCtx);
int32_t CoapDiscoverInit(EpollDesc epollfd);
void CoapDiscoverDeinit(void);
void CoapDestroyCtx(uint8_t serverType);
int32_t CoapSendServiceMsg(MsgCtx *msgCtx, struct DeviceInfo *deviceInfo);
int32_t CoapSendServiceMsgWithDefiniteTargetIp(MsgCtx *msgCtx, struct DeviceInfo *deviceInfo);
coap_context_t *GetContext(uint8_t serverType);
void CoapSubscribeModuleInner(uint8_t isSubscribe);
void CoapUnsubscribeModuleInner(uint8_t isUnsubscribe);
void CoapInitSubscribeModuleInner(void);
void ResetCoapDiscoverTaskCount(uint8_t isBusy);
uint8_t GetActualType(const uint8_t type, const char *dstIp);
#endif /* #ifndef COAP_DISCOVER_H */

View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef JSON_PAYLOAD_H
#define JSON_PAYLOAD_H
#include <stdint.h>
#include "nstackx.h"
#ifdef __cplusplus
extern "C" {
#endif
struct DeviceInfo;
char *PrepareServiceDiscover(uint8_t isBroadcast);
int32_t ParseServiceDiscover(const uint8_t *buf, struct DeviceInfo *deviceInfo, char **remoteUrlPtr);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef JSON_PAYLOAD_H */

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NSTACK_COMMON_H
#define NSTACK_COMMON_H
#include "nstackx.h"
#include "nstackx_list.h"
#include "nstackx_epoll.h"
#ifdef __cplusplus
extern "C"{
#endif
void NotifyDeviceListChanged(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount);
void NotifyDeviceFound(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount);
void NotifyMsgReceived(const char *moduleName, const char *deviceId, const uint8_t *data, uint32_t len);
void NotifyDFinderMsgRecver(DFinderMsgType msgType);
EpollDesc GetMainLoopEpollFd(void);
List *GetMainLoopEvendChain(void);
#ifdef __cplusplus
};
#endif
#endif /* #ifndef NSTACK_COMMON_H */

View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NSTACKX_DATABASE_H
#define NSTACKX_DATABASE_H
#include <stdio.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef uint8_t (*RecCompareCallback)(void *, void *);
void *DatabaseInit(uint32_t recnum, size_t recsz, RecCompareCallback cb);
void DatabaseClean(void *ptr);
uint32_t GetDatabaseUseCount(const void *dbptr);
void *DatabaseAllocRecord(void *dbptr);
void DatabaseFreeRecord(void *dbptr, const void *ptr);
void *DatabaseSearchRecord(const void *dbptr, void *ptr);
void *DatabaseGetNextRecord(void *dbptr, int64_t *state);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef NSTACKX_DATABASE_H */

View File

@ -0,0 +1,128 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NSTACKX_DEVICE_H
#define NSTACKX_DEVICE_H
#include <arpa/inet.h>
#include <stdbool.h>
#include "nstackx.h"
#include "coap_discover.h"
#define MAX_ADDRESS_LEN 64
#define MAX_MAC_ADDRESS_LENGTH 6
#define MAX_IPV4_ADDRESS_LEN 4
enum DeviceState {
IDEL,
ACTIVE,
LEAVE
};
typedef enum {
NSTACKX_EVENT_JOIN,
NSTACKX_EVENT_UPDATE,
NSTACKX_EVENT_LEAVE,
} NSTACKX_Event;
enum NetChannelState {
NET_CHANNEL_STATE_START,
NET_CHANNEL_STATE_DISABLED,
NET_CHANNEL_STATE_DISCONNECT,
NET_CHANNEL_STATE_CONNETING,
NET_CHANNEL_STATE_CONNETED,
NET_CHANNEL_STATE_END,
};
typedef struct {
char name[NSTACKX_MAX_INTERFACE_NAME_LEN];
char alias[NSTACKX_MAX_INTERFACE_NAME_LEN];
struct in_addr ip;
} NetworkInterfaceInfo;
typedef struct {
struct in_addr ip;
uint8_t state;
/* AP information? */
} WifiApChannelInfo;
typedef struct {
WifiApChannelInfo wifiApInfo;
} NetChannelInfo;
typedef struct DeviceInfo {
char deviceName[NSTACKX_MAX_DEVICE_NAME_LEN];
char deviceId[NSTACKX_MAX_DEVICE_ID_LEN];
uint8_t update : 1;
uint8_t reserved : 7;
uint8_t deviceType;
uint16_t portNumber;
NetChannelInfo netChannelInfo;
/* Capability data */
uint32_t capabilityBitmapNum;
uint32_t capabilityBitmap[NSTACKX_MAX_CAPABILITY_NUM];
char version[NSTACKX_MAX_HICOM_VERSION];
uint8_t mode;
char deviceHash[DEVICE_HASH_LEN];
char serviceData[NSTACKX_MAX_SERVICE_DATA_LEN];
} DeviceInfo;
int32_t DeviceModuleInit(EpollDesc epollfd);
int32_t P2pUsbTimerInit(EpollDesc epollfd);
void DestroyP2pUsbServerInitRetryTimer(void);
void DeviceModuleClean(void);
void PushPublishInfo(DeviceInfo *deviceInfo, NSTACKX_DeviceInfo *deviceList, uint32_t deviceNum);
int32_t UpdateDeviceDb(const DeviceInfo *deviceInfo, uint8_t forceUpdate);
uint8_t ClearDevices(void *deviceList);
int32_t BackupDeviceDB(void);
void *GetDeviceDB(void);
void *GetDeviceDBBackup(void);
DeviceInfo *GetDeviceInfoById(const char *deviceId, const void *db);
void GetDeviceList(NSTACKX_DeviceInfo *deviceList, uint32_t *deviceCountPtr, bool doFilter);
int8_t SetReservedInfoFromDeviceInfo(NSTACKX_DeviceInfo *deviceList, uint32_t count, DeviceInfo *deviceInfo);
void SetModeInfo(uint8_t mode);
uint8_t GetModeInfo(void);
void SetDeviceHash(uint64_t deviceHash);
int32_t ConfigureLocalDeviceInfo(const NSTACKX_LocalDeviceInfo *localDeviceInfo);
int32_t UpdateLocalNetworkInterface(const NetworkInterfaceInfo *interfaceInfo);
int32_t UpdateLocalNetworkInterfaceP2pMode(const NetworkInterfaceInfo *interfaceInfo, uint16_t nlmsgType);
int32_t UpdateLocalNetworkInterfaceUsbMode(const NetworkInterfaceInfo *interfaceInfo, uint16_t nlmsgType);
uint8_t FilterNetworkInterface(const char *ifName);
uint8_t IsWlanIpAddr(const char *ifName);
uint8_t IsEthIpAddr(const char *ifName);
uint8_t IsP2pIpAddr(const char *ifName);
uint8_t IsUsbIpAddr(const char *ifName);
const DeviceInfo *GetLocalDeviceInfoPtr(void);
uint8_t IsWifiApConnected(void);
int32_t GetLocalIpString(char *ipString, size_t length);
int32_t GetLocalInterfaceName(char *ifName, size_t ifNameLength);
int32_t RegisterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]);
int32_t SetFilterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]);
int32_t RegisterServiceData(const char *serviceData);
void GetLocalNetworkInterface(void *arg);
void ResetDeviceTaskCount(uint8_t isBusy);
void SetP2pIp(const struct in_addr *ip);
void SetUsbIp(const struct in_addr *ip);
int32_t GetP2pIpString(char *ipString, size_t length);
int32_t GetUsbIpString(char *ipString, size_t length);
#endif /* #ifndef NSTACKX_DEVICE_H */

View File

@ -0,0 +1,31 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NSTACKX_SMARTGENIUS_H
#define NSTACKX_SMARTGENIUS_H
#include <stdint.h>
#include "nstackx_epoll.h"
#ifdef __cplusplus
extern "C" {
#endif
int32_t SmartGeniusInit(EpollDesc epollfd);
void SmartGeniusClean(void);
void ResetSmartGeniusTaskCount(uint8_t isBusy);
#ifdef __cplusplus
}
#endif
#endif /* #ifndef NSTACKX_SMARTGENIUS_H */

View File

@ -0,0 +1,202 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NSTACKX_H
#define NSTACKX_H
#include <stdint.h>
#ifdef __cplusplus
extern "C"{
#endif
#define NSTACKX_MAX_DEVICE_NAME_LEN 64
#define NSTACKX_MAX_MODULE_NAME_LEN 64
#define NSTACKX_MAX_DEVICE_ID_LEN 96
#define NSTACKX_MAX_SENDMSG_DATA_LEN 512
#define NSTACKX_MAX_MAC_STRING_LEN 18
#define NSTACKX_MAX_IP_STRING_LEN 16
#define NSTACKX_MAX_CAPABILITY_NUM 2
#define NSTACKX_MAX_DEVICE_NUM 20
#define NSTACKX_MAX_INTERFACE_NAME_LEN 16
#define NSTACKX_MAX_HICOM_VERSION 16
#define NSTACKX_MAX_SERVICE_DATA_LEN 64
#define NSTACKX_MAX_RESERVED_INFO_LEN 219 // expand from 131 to 219 (+88) bytes to hold service data
#define DEVICE_HASH_LEN 21
#define DEFAULT_MODE 0
#define DISCOVER_MODE 1
#define PUBLISH_MODE_UPLINE 2
#define PUBLISH_MODE_OFFLINE 3
#define PUBLISH_MODE_PROACTIVE 10
#define PUBLISH_DEVICE_NUM 1
#define INNER_DISCOVERY 1
#define PUBLISH_NUM 1
/* Remote device information */
typedef struct NSTACKX_DeviceInfo {
char deviceId[NSTACKX_MAX_DEVICE_ID_LEN];
char deviceName[NSTACKX_MAX_DEVICE_NAME_LEN];
uint32_t capabilityBitmapNum;
uint32_t capabilityBitmap[NSTACKX_MAX_CAPABILITY_NUM];
uint8_t deviceType;
uint8_t mode;
uint8_t update : 1;
uint8_t reserved : 7;
char version[NSTACKX_MAX_HICOM_VERSION];
char reservedInfo[NSTACKX_MAX_RESERVED_INFO_LEN];
} NSTACKX_DeviceInfo;
/* Local device information */
typedef struct {
char name[NSTACKX_MAX_DEVICE_NAME_LEN];
char deviceId[NSTACKX_MAX_DEVICE_ID_LEN];
char btMacAddr[NSTACKX_MAX_MAC_STRING_LEN];
char wifiMacAddr[NSTACKX_MAX_MAC_STRING_LEN];
char networkIpAddr[NSTACKX_MAX_IP_STRING_LEN];
char networkName[NSTACKX_MAX_INTERFACE_NAME_LEN];
uint8_t is5GHzBandSupported;
uint8_t deviceType;
char version[NSTACKX_MAX_HICOM_VERSION];
} NSTACKX_LocalDeviceInfo;
/* Register local device information */
int32_t NSTACKX_RegisterDevice(const NSTACKX_LocalDeviceInfo *localDeviceInfo);
/* Register local device information with deviceHash */
int32_t NSTACKX_RegisterDeviceAn(const NSTACKX_LocalDeviceInfo *localDeviceInfo, uint64_t deviceHash);
/* Device list change callback type */
typedef void (*NSTACKX_OnDeviceListChanged)(const NSTACKX_DeviceInfo *deviceList, uint32_t deviceCount);
/* Data receive callback type */
typedef void (*NSTACKX_OnMsgReceived)(const char *moduleName, const char *deviceId,
const uint8_t *data, uint32_t len);
/* DFinder message type list. */
typedef enum {
DFINDER_ON_TOO_BUSY = 1,
DFINDER_ON_INNER_ERROR,
} DFinderMsgType;
/* Data receive callback type */
typedef void (*NSTACKX_OnDFinderMsgReceived)(DFinderMsgType msgType);
/* NSTACKX parameter, which contains callback list */
typedef struct {
NSTACKX_OnDeviceListChanged onDeviceListChanged;
NSTACKX_OnDeviceListChanged onDeviceFound;
NSTACKX_OnMsgReceived onMsgReceived;
NSTACKX_OnDFinderMsgReceived onDFinderMsgReceived;
} NSTACKX_Parameter;
/*
* NSTACKX Initialization
* return 0 on success, negative value on failure
*/
int32_t NSTACKX_Init(const NSTACKX_Parameter *parameter);
/* NSTACKX Destruction */
void NSTACKX_Deinit(void);
/*
* Start device discovery
* return 0 on success, negative value on failure
*/
int32_t NSTACKX_StartDeviceFind(void);
/*
* Start device discovery by mode
* return 0 on success, negative value on failure
*/
int32_t NSTACKX_StartDeviceFindAn(uint8_t mode);
/*
* Stop device discovery
* return 0 on success, negative value on failure
*/
int32_t NSTACKX_StopDeviceFind(void);
/*
* subscribe module
* return 0 on success, negative value on failure
*/
int32_t NSTACKX_SubscribeModule(void);
/*
* unsubscribe module
* return 0 on success, negative value on failure
*/
int32_t NSTACKX_UnsubscribeModule(void);
/*
* Register the capability of local device.
* return 0 on success, negative value on failure
*/
int32_t NSTACKX_RegisterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]);
/*
* Set the capability to filter remote devices.
* return 0 on success, negative value on failure
*/
int32_t NSTACKX_SetFilterCapability(uint32_t capabilityBitmapNum, uint32_t capabilityBitmap[]);
/*
* Register the serviceData of local device.
* return 0 on success, negative value on failure
*/
int32_t NSTACKX_RegisterServiceData(const char* serviceData);
/*
* Send Msg to remote peer
* return 0 on success, negative value on failure
*/
int32_t NSTACKX_SendMsg(const char *moduleName, const char *deviceId, const uint8_t *data,
uint32_t len);
/*
* Send Msg to remote peer
* return 0 on success, negative value on failure
*/
int32_t NSTACKX_SendMsgDirect(const char *moduleName, const char *deviceId, const uint8_t *data,
uint32_t len, const char *ipaddr, uint8_t sendType);
/*
* Get device list from cache
* param: deviceList - Device list return from NSTACKX, user should prepare sufficient buffer to store
* device list.
* param: deviceCountPtr - In/Out parameter. It indicates buffer size (number of elements) in deviceList
* When returns, it indicates numbers of valid device in deviceList.
* return 0 on success, negative value on failure
*/
int32_t NSTACKX_GetDeviceList(NSTACKX_DeviceInfo *deviceList, uint32_t *deviceCountPtr);
/*
* NSTACKX Initialization, only used for restart.
* return 0 on success, negative value on failure
*/
int32_t NSTACKX_InitRestart(const NSTACKX_Parameter *parameter);
/*
* NSTACKX Initialization, only used for restart.
* return 0 on success, negative value on failure
*/
void NSTACKX_StartDeviceFindRestart(void);
#ifdef __cplusplus
}
#endif
#endif /* NSTACKX_H */

View File

@ -0,0 +1,44 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//foundation/communication/dsoftbus/dsoftbus.gni")
if (defined(ohos_lite)) {
import("//build/lite/config/component/lite_component.gni")
} else {
import("//build/ohos.gni")
ohos_shared_library("nstackx_util") {
sources = [
"core/nstackx_dev.c",
"core/nstackx_event.c",
"core/nstackx_log.c",
"core/nstackx_timer.c",
"core/nstackx_util.c",
"platform/unix/sys_dev.c",
"platform/unix/sys_epoll.c",
"platform/unix/sys_event.c",
"platform/unix/sys_log.c",
"platform/unix/sys_timer.c",
"platform/unix/sys_util.c",
]
include_dirs = [
"platform/unix",
"interface",
"//third_party/bounds_checking_function/include",
]
deps = [ "//third_party/bounds_checking_function:libsec_static" ]
subsystem_name = "communication"
part_name = "dsoftbus_standard"
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nstackx_dev.h"
#include "nstackx_util.h"
#include "nstackx_error.h"
#include "nstackx_log.h"
#include "securec.h"
#define TAG "nStackXDev"
int32_t GetConnectionTypeByDev(const uint32_t sourceIp, uint16_t *connectType);
static int32_t GetConnectionTypeByIP(const uint32_t sourceIp, const uint32_t destinationIp, uint16_t *connectType)
{
if (sourceIp == htonl(SOFTAP_ADDR_KEY) || destinationIp == htonl(SOFTAP_ADDR_KEY) ||
sourceIp == htonl(P2P_ADDR_KEY) || destinationIp == htonl(P2P_ADDR_KEY)) {
*connectType = CONNECT_TYPE_P2P;
LOGI(TAG, "connType is P2P(%hu)", *connectType);
return NSTACKX_EOK;
}
return NSTACKX_EFAILED;
}
int32_t GetConnectionType(const uint32_t sourceIp, const uint32_t destinationIp, uint16_t *connectType)
{
if (GetConnectionTypeByIP(sourceIp, destinationIp, connectType) == NSTACKX_EOK) {
return NSTACKX_EOK;
}
return GetConnectionTypeByDev(sourceIp, connectType);
}

View File

@ -0,0 +1,94 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nstackx_event.h"
#include "nstackx_log.h"
#include "securec.h"
#define TAG "nStackXEvent"
void DeleteEventNode(EventNode *node);
EventNode *SearchEventNode(const List *eventNodeChain, EpollDesc epollfd)
{
List *pos = NULL;
EventNode *node = NULL;
LIST_FOR_EACH(pos, eventNodeChain) {
node = (EventNode *)pos;
if (IsEpollDescEqual(node->epollfd, epollfd)) {
break;
}
node = NULL;
}
return node;
}
void EventModuleClean(const List *eventNodeChain, EpollDesc epollfd)
{
List *pos = NULL;
EventNode *node = NULL;
if (eventNodeChain == NULL) {
LOGE(TAG, "eventNodeChain is null");
return;
}
LIST_FOR_EACH(pos, eventNodeChain) {
node = (EventNode *)pos;
if (IsEpollDescEqual(node->epollfd, epollfd)) {
break;
}
node = NULL;
}
if (node == NULL) {
return;
}
DeleteEventNode(node);
}
void EventNodeChainClean(List *eventNodeChain)
{
List *tmp = NULL;
List *pos = NULL;
EventNode *node = NULL;
if (eventNodeChain == NULL) {
LOGE(TAG, "eventNodeChain is null");
return;
}
LIST_FOR_EACH_SAFE(pos, tmp, eventNodeChain) {
node = (EventNode *)pos;
if (node != NULL) {
DeleteEventNode(node);
}
}
}
EpollTask *GetEpollTask(List *eventNodeChain, EpollDesc epollfd)
{
if (eventNodeChain == NULL) {
LOGE(TAG, "eventNodeChain is null");
return NULL;
}
EventNode *node = SearchEventNode(eventNodeChain, epollfd);
if (node == NULL) {
LOGE(TAG, "Cannot find event node for %d", REPRESENT_EPOLL_DESC(epollfd));
return NULL;
}
return &node->task;
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nstackx_log.h"
static uint32_t g_logLevel = NSTACKX_LOG_LEVEL_INFO;
#ifdef BUILD_FOR_WINDOWS
static void DefaultLogImpl(const char *tag, uint32_t level, const char *format, va_list args)
{
SYSTEMTIME st = { 0 };
GetLocalTime(&st);
printf("%02d-%02d %02d:%02d:%02d.%03d %d %d %d %s: ", st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond,
st.wMilliseconds, GetCurrentProcessId(), GetCurrentThreadId(), level, tag);
vprintf(format, args);
}
static LogImplInternal g_logImpl = DefaultLogImpl;
#endif
uint32_t GetLogLevel(void)
{
return g_logLevel;
}
void SetLogLevel(uint32_t logLevel)
{
if (logLevel >= NSTACKX_LOG_LEVEL_END) {
return;
}
g_logLevel = logLevel;
}
void SetLogImpl(LogImplInternal fn)
{
if (fn == NULL) {
return;
}
#ifdef BUILD_FOR_WINDOWS
g_logImpl = fn;
#endif
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nstackx_timer.h"
#include "nstackx_log.h"
#include "securec.h"
#define TAG "nStackXTimer"
uint32_t GetTimeDiffMs(const struct timespec *etv, const struct timespec *stv)
{
uint64_t ms;
if (etv->tv_sec < stv->tv_sec || (etv->tv_sec == stv->tv_sec && etv->tv_nsec < stv->tv_nsec)) {
LOGE(TAG, "invalid input: etv is smaller than stv");
return 0;
}
if (etv->tv_nsec < stv->tv_nsec) {
ms = ((uint64_t)etv->tv_sec - (uint64_t)stv->tv_sec - 1) * NSTACKX_MILLI_TICKS;
ms += (NSTACKX_NANO_TICKS + (uint64_t)etv->tv_nsec - (uint64_t)stv->tv_nsec) / NSTACKX_MICRO_TICKS;
} else {
ms = ((uint64_t)etv->tv_sec - (uint64_t)stv->tv_sec) * NSTACKX_MILLI_TICKS;
ms += ((uint64_t)etv->tv_nsec - (uint64_t)stv->tv_nsec) / NSTACKX_MICRO_TICKS;
}
if (ms > UINT32_MAX) {
ms = UINT32_MAX;
}
return (uint32_t)ms;
}
uint32_t GetTimeDiffUs(const struct timespec *etv, const struct timespec *stv)
{
uint64_t us;
if (etv->tv_sec < stv->tv_sec || (etv->tv_sec == stv->tv_sec && etv->tv_nsec < stv->tv_nsec)) {
LOGE(TAG, "invalid input: etv is smaller than stv");
return 0;
}
if (etv->tv_nsec < stv->tv_nsec) {
us = ((uint64_t)etv->tv_sec - (uint64_t)stv->tv_sec - 1) * NSTACKX_MICRO_TICKS;
us += (NSTACKX_NANO_TICKS + (uint64_t)etv->tv_nsec - (uint64_t)stv->tv_nsec) / NSTACKX_NANO_SEC_PER_MICRO_SEC;
} else {
us = ((uint64_t)etv->tv_sec - (uint64_t)stv->tv_sec) * NSTACKX_MILLI_TICKS;
us += ((uint64_t)etv->tv_nsec - (uint64_t)stv->tv_nsec) / NSTACKX_NANO_SEC_PER_MICRO_SEC;
}
if (us > UINT32_MAX) {
us = UINT32_MAX;
}
return (uint32_t)us;
}

View File

@ -0,0 +1,174 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nstackx_util.h"
#include "nstackx_error.h"
#include "nstackx_log.h"
#include "securec.h"
#define TAG "nStackXUtil"
#define DEFAULT_NEW_PATH_AUTHORITY 0755
int32_t GetTargetFileSize(const char *dir, uint64_t *size)
{
struct stat statbuf;
if (dir == NULL || size == NULL) {
LOGE(TAG, "Invalid dir or size");
return NSTACKX_EINVAL;
}
if (stat(dir, &statbuf) != 0 || statbuf.st_size < 0) {
LOGE(TAG, "stat error: %d", GetErrno());
return NSTACKX_EFAILED;
}
*size = (uint64_t)statbuf.st_size;
return NSTACKX_EOK;
}
int32_t CheckPathSeprator(const char *path)
{
if (strlen(path) > 0 && path[strlen(path) - 1] == PATH_SEPARATOR) {
return NSTACKX_TRUE;
}
return NSTACKX_FALSE;
}
int32_t CheckFilenameSeprator(const char *fileName)
{
if (strlen(fileName) > 0 && fileName[0] == PATH_SEPARATOR) {
return NSTACKX_TRUE;
}
return NSTACKX_FALSE;
}
/*
* return value includes the length of terminator '\0'
* return value 0 means the input dir is null or it's last char is PATH_SEPARATOR
*/
uint32_t GetFileNameLen(const char *dir)
{
int32_t i;
if (dir == NULL || strlen(dir) < 1 || dir[strlen(dir) - 1] == PATH_SEPARATOR) {
LOGE(TAG, "Invalid input param");
return 0;
}
int32_t dirLen = (int32_t)strlen(dir);
for (i = dirLen - 1; i >= 0; i--) {
if (dir[i] == PATH_SEPARATOR) {
i++;
break;
}
if (i == 0) {
break;
}
}
return (uint32_t)(dirLen + 1 - i);
}
int32_t GetFileName(const char *dir, char *name, uint32_t nameLen)
{
uint32_t fileNameLen, startIdx;
if (dir == NULL || name == NULL) {
LOGE(TAG, "Invalid dir or name");
return NSTACKX_EINVAL;
}
fileNameLen = GetFileNameLen(dir);
if (fileNameLen == 0 || fileNameLen > nameLen) {
LOGE(TAG, "Invalid fileNameLen dir: %s", dir);
return NSTACKX_EINVAL;
}
startIdx = (uint32_t)(strlen(dir) + 1 - fileNameLen);
if (strcpy_s(name, nameLen, dir + startIdx) != EOK) {
LOGE(TAG, "strcpy_s name error");
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
uint8_t IsAccessiblePath(const char *pathName, int32_t mode, uint32_t fileType)
{
struct stat statbuf;
if (pathName == NULL) {
LOGE(TAG, "invalid input");
return NSTACKX_FALSE;
}
if (stat(pathName, &statbuf) != 0) {
LOGE(TAG, "can't get file stat.error: %d", GetErrno());
return NSTACKX_FALSE;
}
if (((statbuf.st_mode) & S_IFMT) != fileType) {
LOGE(TAG, "this path name is not target file type");
return NSTACKX_FALSE;
}
if (access(pathName, F_OK) != 0) {
return NSTACKX_FALSE;
}
if (access(pathName, mode) != 0) {
return NSTACKX_FALSE;
}
return NSTACKX_TRUE;
}
uint8_t IsExistingFile(const char *fileName)
{
if (access(fileName, F_OK) != 0) {
return NSTACKX_FALSE;
}
return NSTACKX_TRUE;
}
int32_t TestAndCreateDirectory(const char *path)
{
uint32_t len, i;
char *tmp = NULL;
int32_t ret;
if (path == NULL || strlen(path) == 0) {
return NSTACKX_EINVAL;
}
len = (uint32_t)strlen(path);
tmp = (char *)calloc(len + 1, sizeof(char));
if (tmp == NULL) {
LOGE(TAG, "tmp calloc error");
return NSTACKX_EFAILED;
}
for (i = 0; i < len; i++) {
tmp[i] = path[i];
if (tmp[i] != PATH_SEPARATOR) {
continue;
}
if (access(tmp, 0) == -1) {
ret = mkdir(tmp, DEFAULT_NEW_PATH_AUTHORITY);
if (ret == -1 && errno != EEXIST) {
LOGI(TAG, "mkdir failed(%d)", errno);
free(tmp);
return NSTACKX_EFAILED;
}
}
}
free(tmp);
return NSTACKX_EOK;
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NSTACKX_COMMON_HEADER_H
#define NSTACKX_COMMON_HEADER_H
#include "sys_common_header.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
// C standard library header files
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>
#define PIPE_OUT 0
#define PIPE_IN 1
#define PIPE_FD_NUM 2
#endif // NSTACKX_COMMON_HEADER_H

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NSTACKX_CONFIG_H
#define NSTACKX_CONFIG_H
#ifdef NSTACKX_WITH_LITEOS
/**
* Enable(1) or Disable(0) fillp support in nStackx
*/
#ifndef NSTACKX_SUPPORT_FILLP
#define NSTACKX_SUPPORT_FILLP 0
#endif
/**
* Enable(1) or Disable(0) encrypt support in nStackx
*/
#ifndef NSTACKX_SUPPORT_ENCRYPT
#define NSTACKX_SUPPORT_ENCRYPT 0
#endif
#endif /* NSTACKX_WITH_LITEOS */
#ifdef NSTACKX_WITH_HMOS_LINUX
#ifndef NSTACKX_SUPPORT_ENCRYPT
#define NSTACKX_SUPPORT_ENCRYPT 0
#endif
#endif /* NSTACKX_WITH_HMOS_LINUX */
#ifndef NSTACKX_SUPPORT_FILLP
#define NSTACKX_SUPPORT_FILLP 1
#endif
#ifndef NSTACKX_SUPPORT_ENCRYPT
#define NSTACKX_SUPPORT_ENCRYPT 1
#endif
#endif /* NSTACKX_CONFIG_H */

View File

@ -0,0 +1,59 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NSTACKX_DEV_H
#define NSTACKX_DEV_H
#include "nstackx_common_header.h"
#ifndef UNUSED
#ifdef __GNUC__
#define UNUSED __attribute__((unused))
#else /* not a GCC */
#define UNUSED
#endif /* GCC */
#endif
/* DFile connect type list. */
typedef enum {
CONNECT_TYPE_NONE = 0,
CONNECT_TYPE_P2P,
CONNECT_TYPE_WLAN,
CONNECT_TYPE_MAX,
} ConnectType;
#define P2P_DEV_NAME_PRE "p2p"
#define WLAN_DEV_NAME_PRE "wlan"
#define ETH_DEV_NAME_PRE "eth"
#define USB_DEV_NAME_PRE "rndis"
#define WIFI_DIRECT_NAME "Wi-Fi Direct"
#define INTERFCAE_NAME_MAX_LENGTH (128 + 4)
#define INTERFACE_GUID_MAX_LENGTH (256 + 4)
#define INTERFACE_NETMASK (0xffffff)
#define INTERFCAE_DES_MAX_LENGTH 128
#define INTERFCAE_ADDR_MAX_LENGTH 16
#define INTERFCAE_TYPE_MAX_LENGTH 20
#define INTERFACE_MAX 16
#define SOFTAP_ADDR_KEY (0xc0a82b01)
#define P2P_ADDR_KEY (0xc0a83101)
NSTACKX_EXPORT int32_t BindToDevice(SocketDesc sockfd, const struct sockaddr_in *localAddr);
NSTACKX_EXPORT int32_t GetIfBroadcastIp(const char *ifName, char *ipString, size_t ipStringLen);
NSTACKX_EXPORT int32_t GetConnectionType(const uint32_t sourceIp, const uint32_t destinationIp, uint16_t *connectType);
NSTACKX_EXPORT int32_t BindToTargetDev(SocketDesc sockfd, const char *targetInterfaceName);
NSTACKX_EXPORT int32_t GetInterfaceNameByIP(uint32_t sourceIp, char *interfaceName);
NSTACKX_EXPORT void BindToDevInTheSameLan(SocketDesc sockfd, const struct sockaddr_in *sockAddr);
#endif // NSTACKX_DEV_H

View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NSTACKX_EPOLL_H
#define NSTACKX_EPOLL_H
#include "sys_epoll.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef EPOLLIN
#define EPOLLIN 0x00000001U
#endif
#ifndef EPOLLOUT
#define EPOLLOUT 0x00000004U
#endif
#ifndef EPOLLERR
#define EPOLLERR 0x00000008U
#endif
#ifndef EPOLLHUP
#define EPOLLHUP 0x00000010U
#endif
typedef void (*TaskHandle)(void *arg);
typedef struct {
EpollDesc epollfd;
TaskDesc taskfd;
TaskHandle readHandle;
TaskHandle writeHandle;
TaskHandle errorHandle;
TaskHandle endHandle;
void *ptr;
uint64_t count;
} EpollTask;
NSTACKX_EXPORT int32_t RegisterEpollTask(EpollTask *task, uint32_t events);
NSTACKX_EXPORT int32_t DeRegisterEpollTask(EpollTask *task);
NSTACKX_EXPORT int32_t RefreshEpollTask(EpollTask *task, uint32_t events);
NSTACKX_EXPORT EpollDesc CreateEpollDesc(void);
NSTACKX_EXPORT int32_t EpollLoop(EpollDesc epollfd, int32_t timeout);
static inline bool IsEpollDescValid(EpollDesc epollfd);
static inline bool IsEpollDescEqual(EpollDesc epollfd1, EpollDesc epollfd2);
static inline void CloseEpollDesc(EpollDesc epollfd);
#ifdef __cplusplus
}
#endif
#endif // NSTACKX_EPOLL_H

View File

@ -0,0 +1,84 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NSTACKX_ERROR_H
#define NSTACKX_ERROR_H
#ifdef __cplusplus
extern "C" {
#endif
#define NSTACKX_EOK 0 /* OK */
#define NSTACKX_EFAILED (-1) /* Operation failed */
/*
* Description:Invalid argument.
* Solution: Verify that related input parameters are correctly set.
*/
#define NSTACKX_EINVAL (-2)
#define NSTACKX_EINPROGRESS (-3) /* Operation now in progress */
/*
* Description: Device or resource busy.
* Solution: Please retry later.
*/
#define NSTACKX_EBUSY (-4)
/*
* Description: Out of memory.
* Solution: 1. Verify that the memory usage exceeds the threshold.
* 2. Release the memory and try again
*/
#define NSTACKX_ENOMEM (-5)
#define NSTACKX_EEXIST (-6) /* Resource already exist */
/*
* Description: The resource is temporarily unavailable.
* Solution: Try again later.
*/
#define NSTACKX_EAGAIN (-7)
/*
* Description: Timeout.
* Solution: Try again.
*/
#define NSTACKX_ETIMEOUT (-8)
/*
* Description: Overflow.
* Solution: Try again.
*/
#define NSTACKX_OVERFLOW (-9)
/*
* Description: Not exist.
* Solution: Try again.
*/
#define NSTACKX_NOEXIST (-10)
/*
* Description: Interrupted system call.
* Solution: Try again.
*/
#define NSTACKX_EINTR (-11)
#define NSTACKX_TRUE 1
#define NSTACKX_FALSE 0
#ifdef __cplusplus
}
#endif
#endif // NSTACKX_ERROR_H

View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NSTACKX_EVENT_H
#define NSTACKX_EVENT_H
#include "sys_event.h"
#include "nstackx_epoll.h"
#include "nstackx_list.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*EventHandle)(void *arg);
typedef struct EventNode {
List list;
EpollDesc epollfd;
PipeDesc pipeFd[PIPE_FD_NUM];
EpollTask task;
} EventNode;
NSTACKX_EXPORT int32_t PostEvent(const List *eventNodeChain, EpollDesc epollfd, EventHandle handle, void *arg);
NSTACKX_EXPORT void ClearEvent(const List *eventNodeChain, EpollDesc epollfd);
NSTACKX_EXPORT int32_t EventModuleInit(List *eventNodeChain, EpollDesc epollfd);
NSTACKX_EXPORT void EventModuleClean(const List *eventNodeChain, EpollDesc epollfd);
NSTACKX_EXPORT void EventNodeChainClean(List *eventNodeChain);
NSTACKX_EXPORT EpollTask *GetEpollTask(List *eventNodeChain, EpollDesc epollfd);
#ifdef __cplusplus
}
#endif
#endif // NSTACKX_EVENT_H

View File

@ -0,0 +1,117 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NSTACKX_LIST_H
#define NSTACKX_LIST_H
#include <stdio.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct List {
struct List *prev;
struct List *next;
} List;
static inline void ListInitHead(List *head)
{
head->next = head;
head->prev = head;
}
static inline void ListInsertHead(List *head, List *node)
{
node->next = head->next;
node->next->prev = node;
node->prev = head;
head->next = node;
}
static inline void ListInsertTail(List *head, List *node)
{
node->prev = head->prev;
node->prev->next = node;
node->next = head;
head->prev = node;
}
static inline void ListRemoveNode(List *node)
{
if (node == NULL) {
return;
}
node->next->prev = node->prev;
node->prev->next = node->next;
node->next = NULL;
node->prev = NULL;
}
static inline uint8_t ListIsEmpty(const List *head)
{
return (head == head->next);
}
static inline List *ListGetFront(List *head)
{
return head->next;
}
static inline List *ListPopFront(List *head)
{
List *element = NULL;
if (head == NULL || ListIsEmpty(head)) {
return NULL;
}
element = head->next;
ListRemoveNode(element);
return element;
}
static inline void ListInsertNewHead(List *prevHead, List *newHead)
{
prevHead->prev->next = newHead->next;
newHead->next->prev = prevHead->prev;
newHead->prev->next = prevHead;
prevHead->prev = newHead->prev;
}
static inline void ListMove(List *from, List *to)
{
List *first = from->next;
List *last = from->prev;
to->next = first;
to->prev = last;
first->prev = to;
last->next = to;
ListInitHead(from);
}
#define LIST_FOR_EACH(curr, head) \
for ((curr) = (head)->next; (curr) != (head); (curr) = (curr)->next)
#define LIST_FOR_EACH_SAFE(pos, tmp, head) \
for ((pos) = (head)->next, (tmp) = (pos)->next; (pos) != (head); \
(pos) = (tmp), (tmp) = (pos)->next)
#ifdef __cplusplus
}
#endif
#endif // NSTACKX_LIST_H

View File

@ -0,0 +1,69 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NSTACKX_LOG_H
#define NSTACKX_LOG_H
#include "nstackx_common_header.h"
#ifdef __cplusplus
extern "C" {
#endif
enum {
NSTACKX_LOG_LEVEL_OFF = 0,
NSTACKX_LOG_LEVEL_FATAL = 1,
NSTACKX_LOG_LEVEL_ERROR = 2,
NSTACKX_LOG_LEVEL_WARNING = 3,
NSTACKX_LOG_LEVEL_INFO = 4,
NSTACKX_LOG_LEVEL_DEBUG = 5,
NSTACKX_LOG_LEVEL_END,
};
#define NSTACKX_DEFAULT_TAG "nStackX"
/* Log module initialization */
NSTACKX_EXPORT void SetLogLevel(uint32_t logLevel);
/* Get current log level */
NSTACKX_EXPORT uint32_t GetLogLevel(void);
/* Actual implementation of "print", which is platform dependent */
NSTACKX_EXPORT void PrintfImpl(const char *moduleName, uint32_t logLevel, const char *format, ...);
/* internal log implementation for windows */
typedef void (*LogImplInternal)(const char *tag, uint32_t level, const char *format, va_list args);
/* Set log implementation */
NSTACKX_EXPORT void SetLogImpl(LogImplInternal fn);
#define NSTACKX_LOG_COMMON(moduleName, logLevel, format, ...) \
do { \
if (logLevel <= GetLogLevel()) { \
PrintfImpl(moduleName, logLevel, "%s:[%d] :" format "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \
} \
} while (0)
#define LOGF(moduleName, format, ...) NSTACKX_LOG_COMMON(moduleName, NSTACKX_LOG_LEVEL_FATAL, format, ##__VA_ARGS__)
#define LOGE(moduleName, format, ...) NSTACKX_LOG_COMMON(moduleName, NSTACKX_LOG_LEVEL_ERROR, format, ##__VA_ARGS__)
#define LOGW(moduleName, format, ...) NSTACKX_LOG_COMMON(moduleName, NSTACKX_LOG_LEVEL_WARNING, format, ##__VA_ARGS__)
#define LOGI(moduleName, format, ...) NSTACKX_LOG_COMMON(moduleName, NSTACKX_LOG_LEVEL_INFO, format, ##__VA_ARGS__)
#define LOGD(moduleName, format, ...) NSTACKX_LOG_COMMON(moduleName, NSTACKX_LOG_LEVEL_DEBUG, format, ##__VA_ARGS__)
#ifdef __cplusplus
}
#endif
#endif // NSTACKX_LOG_H

View File

@ -0,0 +1,52 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NSTACKX_TIMER_H
#define NSTACKX_TIMER_H
#include "nstackx_epoll.h"
#ifdef __cplusplus
extern "C" {
#endif
#define NSTACKX_MILLI_TICKS 1000
#define NSTACKX_MICRO_TICKS 1000000
#define NSTACKX_NANO_TICKS 1000000000
#define NSTACKX_MICRO_SEC_PER_MILLI_SEC (NSTACKX_MICRO_TICKS / NSTACKX_MILLI_TICKS)
#define NSTACKX_NANO_SEC_PER_MILLI_SEC (NSTACKX_NANO_TICKS / NSTACKX_MILLI_TICKS)
#define NSTACKX_NANO_SEC_PER_MICRO_SEC (NSTACKX_NANO_TICKS / NSTACKX_MICRO_TICKS)
typedef void (*TimeoutHandle)(void *data);
typedef struct {
EpollTask task;
TimeoutHandle timeoutHandle;
void *data;
uint8_t disabled;
} Timer;
NSTACKX_EXPORT uint32_t GetTimeDiffMs(const struct timespec *etv, const struct timespec *stv);
NSTACKX_EXPORT int32_t TimerSetTimeout(Timer *timer, uint32_t timeoutMs, uint8_t repeated);
NSTACKX_EXPORT int32_t TimerGetRemainTime(Timer *timer, uint32_t *remainTimeMsPtr);
NSTACKX_EXPORT Timer *TimerStart(EpollDesc epollfd, uint32_t ms, uint8_t repeated, TimeoutHandle handle, void *data);
NSTACKX_EXPORT void TimerDelete(Timer *timer);
NSTACKX_EXPORT uint32_t GetTimeDiffUs(const struct timespec *etv, const struct timespec *stv);
#ifdef __cplusplus
}
#endif
#endif // NSTACKX_TIMER_H

View File

@ -0,0 +1,77 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NSTACKX_UTIL_H
#define NSTACKX_UTIL_H
#include "nstackx_dev.h"
#include "sys_util.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
CPU_IDX_0 = 0,
CPU_IDX_1,
CPU_IDX_2,
CPU_IDX_3,
CPU_IDX_4,
CPU_IDX_5,
CPU_IDX_6,
CPU_IDX_7,
} CpuIdx;
#define FIRST_CPU_NUM_LEVEL 8
#define SECOND_CPU_NUM_LEVEL 4
#define THIRD_CPU_NUM_LEVEL 2
#define MAX_THREAD_NAME_LEN 100
#define THREAD_MAXIMUM_PRIORITY (-20)
NSTACKX_EXPORT int32_t GetTargetFileSize(const char *dir, uint64_t *size);
NSTACKX_EXPORT int32_t CheckPathSeprator(const char *path);
NSTACKX_EXPORT int32_t CheckFilenameSeprator(const char *fileName);
NSTACKX_EXPORT uint32_t GetFileNameLen(const char *dir);
NSTACKX_EXPORT int32_t GetFileName(const char *dir, char *name, uint32_t nameLen);
NSTACKX_EXPORT uint8_t IsAccessiblePath(const char *fileName, int32_t mode, uint32_t fileType);
NSTACKX_EXPORT int32_t TestAndCreateDirectory(const char *path);
NSTACKX_EXPORT uint8_t IsFileNameLegal(const char *fileName);
NSTACKX_EXPORT uint8_t IsExistingFile(const char *fileName);
NSTACKX_EXPORT void StartThreadBindCore(int32_t cpu);
NSTACKX_EXPORT void BindThreadToTargetMask(pid_t tid, uint32_t cpuMask);
NSTACKX_EXPORT int32_t GetCpuNum(void);
NSTACKX_EXPORT void SetThreadName(const char *name);
NSTACKX_EXPORT void ClockGetTime(clockid_t id, struct timespec *tp);
NSTACKX_EXPORT void SetMaximumPriorityForThread(void);
/* pthread series */
NSTACKX_EXPORT void SemGetValue(sem_t *sem, int *sval);
NSTACKX_EXPORT void SemPost(sem_t *sem);
NSTACKX_EXPORT void SemWait(sem_t *sem);
NSTACKX_EXPORT void SemDestroy(sem_t *sem);
NSTACKX_EXPORT int32_t SemInit(sem_t *sem, int pshared, unsigned int value);
NSTACKX_EXPORT int32_t PthreadMutexInit(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
NSTACKX_EXPORT void PthreadMutexDestroy(pthread_mutex_t *mutex);
NSTACKX_EXPORT int32_t PthreadMutexLock(pthread_mutex_t *mutex);
NSTACKX_EXPORT int32_t PthreadMutexUnlock(pthread_mutex_t *mutex);
NSTACKX_EXPORT int32_t PthreadCreate(pthread_t *tid, const pthread_attr_t *attr, void *(*entry)(void *), void *arg);
NSTACKX_EXPORT void PthreadJoin(pthread_t thread, void **retval);
#ifdef __cplusplus
}
#endif
#endif // NSTACKX_UTIL_H

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SYS_COMMON_HEADER_H
#define SYS_COMMON_HEADER_H
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <sys/socket.h>
#include <sys/epoll.h>
#include <sys/timerfd.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include <sys/select.h>
#include <sys/types.h>
#include <syscall.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <ifaddrs.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#ifndef offsetof
#define offsetof(type, member) __builtin_offsetof(type, member)
#endif
#define container_of(ptr, type, member) ({ \
void *__mptr = (void *)(ptr); \
(type *)((char *)__mptr - offsetof(type, member)); \
})
#define NSTACKX_EXPORT extern
typedef int32_t SocketDesc;
#define INVALID_SOCKET (-1)
#endif // SYS_COMMON_HEADER_H

View File

@ -0,0 +1,406 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nstackx_dev.h"
#include "nstackx_util.h"
#include "nstackx_error.h"
#include "nstackx_log.h"
#include "securec.h"
#define TAG "nStackXDev"
static int32_t GetConnectionTypeByDevName(const char *devName, uint32_t devNameLen, uint16_t *connectType)
{
int32_t ret = NSTACKX_EFAILED;
uint32_t p2pNameLen = (uint32_t)strlen(P2P_DEV_NAME_PRE);
uint32_t wlanNameLen = (uint32_t)strlen(WLAN_DEV_NAME_PRE);
if (devNameLen >= p2pNameLen && memcmp(devName, P2P_DEV_NAME_PRE, p2pNameLen) == 0) {
*connectType = CONNECT_TYPE_P2P;
ret = NSTACKX_EOK;
LOGI(TAG, "connType is P2P(%u)", *connectType);
} else if (devNameLen >= wlanNameLen && memcmp(devName, WLAN_DEV_NAME_PRE, wlanNameLen) == 0) {
*connectType = CONNECT_TYPE_WLAN;
LOGI(TAG, "connType is WLAN(%u)", *connectType);
ret = NSTACKX_EOK;
}
return ret;
}
static int32_t GetInterfaceInfo(int32_t fd, int32_t option, struct ifreq *interface)
{
if (interface == NULL) {
return NSTACKX_EINVAL;
}
if (ioctl(fd, SIOCGIFFLAGS, (char*)interface) < 0) {
LOGE(TAG, "ioctl fail, errno = %d", errno);
return NSTACKX_EFAILED;
}
if (!((uint16_t)interface->ifr_flags & IFF_UP)) {
LOGE(TAG, "interface is not up");
return NSTACKX_EINVAL;
}
/* get IP of this interface */
if (ioctl(fd, option, (char*)interface) < 0) {
LOGE(TAG, "ioctl fail, errno = %d", errno);
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
int32_t GetInterfaceIP(int32_t fd, struct ifreq *interface)
{
return GetInterfaceInfo(fd, SIOCGIFADDR, interface);
}
static int32_t GetInterfaceNetMask(int32_t fd, struct ifreq *interface)
{
return GetInterfaceInfo(fd, SIOCGIFNETMASK, interface);
}
int32_t GetInterfaceList(struct ifconf *ifc, struct ifreq *buf, uint32_t size)
{
int32_t fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
return NSTACKX_EFAILED;
}
ifc->ifc_len = (int32_t)size;
ifc->ifc_buf = (char*)buf;
if (ioctl(fd, SIOCGIFCONF, (char*)ifc) < 0) {
LOGE(TAG, "ioctl fail, errno = %d", errno);
CloseSocketInner(fd);
return NSTACKX_EFAILED;
}
return fd;
}
int32_t GetConnectionTypeByDev(const uint32_t sourceIp, uint16_t *connectType)
{
struct ifreq buf[INTERFACE_MAX];
struct ifconf ifc;
uint32_t ethNameLen = (uint32_t)strlen(ETH_DEV_NAME_PRE);
uint32_t wlanNameLen = (uint32_t)strlen(WLAN_DEV_NAME_PRE);
int32_t fd = GetInterfaceList(&ifc, buf, sizeof(buf));
if (fd < 0) {
LOGE(TAG, "get interfacelist failed");
return NSTACKX_EFAILED;
}
int32_t ifreqLen = (int32_t)sizeof(struct ifreq);
int32_t interfaceNum = (int32_t)(ifc.ifc_len / ifreqLen);
for (int32_t i = 0; i < interfaceNum && i < INTERFACE_MAX; i++) {
LOGI(TAG, "ndevice name: %s", buf[i].ifr_name);
uint32_t ifrNameLen = (uint32_t)strlen(buf[i].ifr_name);
if (ifrNameLen < ethNameLen && ifrNameLen < wlanNameLen) {
continue;
}
/* get IP of this interface */
int32_t state = GetInterfaceIP(fd, &buf[i]);
if (state == NSTACKX_EFAILED) {
goto L_ERROR;
} else if (state == NSTACKX_EINVAL) {
continue;
}
if (sourceIp == ((struct sockaddr_in *)&(buf[i].ifr_addr))->sin_addr.s_addr) {
if (GetConnectionTypeByDevName(buf[i].ifr_name, ifrNameLen, connectType) == NSTACKX_EOK) {
break;
}
}
}
CloseSocketInner(fd);
return NSTACKX_EOK;
L_ERROR:
CloseSocketInner(fd);
LOGE(TAG, "get connect type failed");
return NSTACKX_EFAILED;
}
static int32_t FindDevByInterfaceIP(int32_t fd, struct ifconf ifc, struct ifreq buf[], uint32_t sourceIP)
{
int32_t i;
int32_t ifreqLen = (int32_t)sizeof(struct ifreq);
int32_t interfaceNum = (int32_t)(ifc.ifc_len / ifreqLen);
for (i = 0; i < interfaceNum && i < INTERFACE_MAX; i++) {
/* get IP of this interface */
int32_t state = GetInterfaceIP(fd, &buf[i]);
if (state == NSTACKX_EFAILED) {
return NSTACKX_EFAILED;
} else if (state == NSTACKX_EINVAL) {
continue;
}
if (sourceIP == ((struct sockaddr_in *)&(buf[i].ifr_addr))->sin_addr.s_addr) {
return i;
}
}
return NSTACKX_EFAILED;
}
int32_t GetInterfaceNameByIP(uint32_t sourceIP, char *interfaceName)
{
struct ifreq buf[INTERFACE_MAX];
struct ifconf ifc;
int32_t devIndex;
int32_t ret = NSTACKX_EOK;
int32_t fd = GetInterfaceList(&ifc, buf, sizeof(buf));
if (fd < 0) {
LOGE(TAG, "can't GetInterfaceList");
return NSTACKX_EFAILED;
}
devIndex = FindDevByInterfaceIP(fd, ifc, buf, sourceIP);
CloseSocketInner(fd);
if (devIndex >= 0) {
if (strcpy_s(interfaceName, strlen(buf[devIndex].ifr_name) + 1, buf[devIndex].ifr_name) != EOK) {
LOGE(TAG, "strcpy failed");
ret = NSTACKX_EFAILED;
}
}
return ret;
}
static int32_t BindToDeviceInner(int32_t sockfd, const struct ifreq *ifBinding)
{
struct ifreq ifr;
if (ifBinding == NULL) {
LOGE(TAG, "no right interface for binding");
return NSTACKX_EFAILED;
}
if (strncpy_s(ifr.ifr_ifrn.ifrn_name, IFNAMSIZ, ifBinding->ifr_name, strlen(ifBinding->ifr_name)) != EOK) {
LOGE(TAG, "strncpy fail");
return NSTACKX_EFAILED;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&ifr, sizeof(ifr)) < 0) {
LOGE(TAG, "setsockopt fail, errno = %d", errno);
return NSTACKX_EFAILED;
}
LOGI(TAG, "binding interface %s success", ifBinding->ifr_name);
return NSTACKX_EOK;
}
/*
* If localAddr isn't NULL, bind to interface correspond to ip,
* otherwise, bind to interface which is choosed by strategy.
*/
int32_t BindToDevice(SocketDesc sockfd, const struct sockaddr_in *localAddr)
{
struct ifreq buf[INTERFACE_MAX];
struct ifconf ifc;
struct ifreq *ifBinding = NULL;
uint32_t ethNameLen = (uint32_t)strlen(ETH_DEV_NAME_PRE);
uint32_t wlanNameLen = (uint32_t)strlen(WLAN_DEV_NAME_PRE);
int32_t fd = GetInterfaceList(&ifc, buf, sizeof(buf));
if (fd < 0) {
return NSTACKX_EFAILED;
}
int32_t ifreqLen = (int32_t)sizeof(struct ifreq);
int32_t interfaceNum = (int32_t)(ifc.ifc_len / ifreqLen);
for (int32_t i = 0; i < interfaceNum && i < INTERFACE_MAX; i++) {
LOGI(TAG, "device name: %s", buf[i].ifr_name);
if (strlen(buf[i].ifr_name) < ethNameLen && strlen(buf[i].ifr_name) < wlanNameLen) {
continue;
}
/* get IP of this interface */
int32_t state = GetInterfaceIP(fd, &buf[i]);
if (state == NSTACKX_EFAILED) {
goto L_ERROR;
} else if (state == NSTACKX_EINVAL) {
continue;
}
if (localAddr != NULL) {
/* find corresponding interface by ip */
if (localAddr->sin_addr.s_addr == ((struct sockaddr_in *)&(buf[i].ifr_addr))->sin_addr.s_addr) {
ifBinding = &buf[i];
break;
}
} else {
/* strategy: ethernet have higher priority */
if (memcmp(buf[i].ifr_name, ETH_DEV_NAME_PRE, ethNameLen) == 0) {
ifBinding = &buf[i];
break;
} else if (memcmp(buf[i].ifr_name, WLAN_DEV_NAME_PRE, wlanNameLen) == 0) {
ifBinding = &buf[i];
}
}
}
CloseSocketInner(fd);
return BindToDeviceInner(sockfd, ifBinding);
L_ERROR:
LOGE(TAG, "ioctl fail, errno = %d", errno);
CloseSocketInner(fd);
return NSTACKX_EFAILED;
}
int32_t GetIfBroadcastIp(const char *ifName, char *ipString, size_t ipStringLen)
{
struct ifreq buf[INTERFACE_MAX];
struct ifconf ifc;
uint8_t foundIp = NSTACKX_FALSE;
if (ifName == NULL) {
return NSTACKX_EFAILED;
}
int32_t fd = GetInterfaceList(&ifc, buf, sizeof(buf));
if (fd < 0) {
return NSTACKX_EFAILED;
}
int32_t ifreqLen = (int32_t)sizeof(struct ifreq);
int32_t interfaceNum = (int32_t)(ifc.ifc_len / ifreqLen);
for (int32_t i = 0; i < interfaceNum && i < INTERFACE_MAX; i++) {
if (strlen(buf[i].ifr_name) < strlen(ifName)) {
continue;
}
if (memcmp(buf[i].ifr_name, ifName, strlen(ifName)) != 0) {
continue;
}
if (GetInterfaceInfo(fd, SIOCGIFBRDADDR, &buf[i]) != NSTACKX_EOK) {
continue;
}
if (buf[i].ifr_addr.sa_family != AF_INET) {
continue;
}
if (inet_ntop(AF_INET, &(((struct sockaddr_in *)&(buf[i].ifr_addr))->sin_addr), ipString,
(socklen_t)ipStringLen) == NULL) {
continue;
}
foundIp = NSTACKX_TRUE;
break;
}
CloseSocketInner(fd);
if (!foundIp) {
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
static uint8_t IsValidInterface(const char *interfaceName)
{
if (interfaceName == NULL) {
return NSTACKX_FALSE;
}
uint32_t targetDevLen = (uint32_t)strlen(P2P_DEV_NAME_PRE);
if (strlen(interfaceName) >= targetDevLen && memcmp(interfaceName, P2P_DEV_NAME_PRE, targetDevLen) == 0) {
return NSTACKX_TRUE;
}
targetDevLen = (uint32_t)strlen(ETH_DEV_NAME_PRE);
if (strlen(interfaceName) >= targetDevLen && memcmp(interfaceName, ETH_DEV_NAME_PRE, targetDevLen) == 0) {
return NSTACKX_TRUE;
}
targetDevLen = (uint32_t)strlen(WLAN_DEV_NAME_PRE);
if (strlen(interfaceName) >= targetDevLen && memcmp(interfaceName, WLAN_DEV_NAME_PRE, targetDevLen) == 0) {
return NSTACKX_TRUE;
}
return NSTACKX_FALSE;
}
int32_t GetTargetInterface(const struct sockaddr_in *dstAddr, struct ifreq *localDev)
{
struct ifreq buf[INTERFACE_MAX];
struct ifconf ifc;
uint32_t localIp;
uint32_t netMask;
int32_t fd = GetInterfaceList(&ifc, buf, sizeof(buf));
if (fd < 0) {
return NSTACKX_EFAILED;
}
int32_t ifreqLen = (int32_t)sizeof(struct ifreq);
int32_t interfaceNum = (int32_t)(ifc.ifc_len / ifreqLen);
for (int32_t i = 0; i < interfaceNum && i < INTERFACE_MAX; i++) {
if (!IsValidInterface(buf[i].ifr_name)) {
continue;
}
/* get IP of this interface */
int32_t state = GetInterfaceIP(fd, &buf[i]);
if (state == NSTACKX_EFAILED) {
goto L_ERROR;
} else if (state == NSTACKX_EINVAL) {
continue;
}
localIp = ((struct sockaddr_in *)(&buf[i].ifr_addr))->sin_addr.s_addr;
state = GetInterfaceNetMask(fd, &buf[i]);
if (state == NSTACKX_EFAILED) {
goto L_ERROR;
} else if (state == NSTACKX_EINVAL) {
continue;
}
netMask = ((struct sockaddr_in *)&(buf[i].ifr_netmask))->sin_addr.s_addr;
/* if localIp and dstIp are in the same LAN, fetch the interface name of thie localIp and return */
if ((dstAddr->sin_addr.s_addr & netMask) == (localIp & netMask)) {
if (strncpy_s(localDev->ifr_ifrn.ifrn_name, IFNAMSIZ, buf[i].ifr_name, strlen(buf[i].ifr_name)) != EOK) {
LOGE(TAG, "ifreq name copy failed");
goto L_ERROR;
}
CloseSocketInner(fd);
return NSTACKX_EOK;
}
}
L_ERROR:
CloseSocketInner(fd);
return NSTACKX_EFAILED;
}
void BindToDevInTheSameLan(SocketDesc sockfd, const struct sockaddr_in *sockAddr)
{
struct ifreq localInterface;
if (sockfd < 0) {
return;
}
(void)memset_s(&localInterface, sizeof(localInterface), 0, sizeof(localInterface));
if (GetTargetInterface(sockAddr, &localInterface) != NSTACKX_EOK) {
LOGE(TAG, "get target interface fail");
return;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&localInterface, sizeof(localInterface)) < 0) {
LOGE(TAG, "bind to device fail, errno = %d", errno);
return;
}
LOGI(TAG, "bind to %s successfully", localInterface.ifr_name);
}
int32_t BindToTargetDev(SocketDesc sockfd, const char *targetInterfaceName)
{
struct ifreq buf[INTERFACE_MAX];
struct ifconf ifc;
int32_t ret = NSTACKX_EFAILED;
int32_t fd = GetInterfaceList(&ifc, buf, sizeof(buf));
if (fd < 0) {
return NSTACKX_EFAILED;
}
int32_t ifreqLen = (int32_t)sizeof(struct ifreq);
int32_t interfaceNum = (int32_t)(ifc.ifc_len / ifreqLen);
for (int32_t i = 0; i < interfaceNum && i < INTERFACE_MAX; i++) {
/* get IP of this interface */
int32_t state = GetInterfaceIP(fd, &buf[i]);
if (state == NSTACKX_EFAILED) {
break;
} else if (state == NSTACKX_EINVAL) {
continue;
}
if (strlen(buf[i].ifr_name) == strlen(targetInterfaceName) &&
strcmp(buf[i].ifr_name, targetInterfaceName) == 0) {
ret = BindToDeviceInner(sockfd, &buf[i]);
break;
}
}
CloseSocketInner(fd);
return ret;
}

View File

@ -0,0 +1,109 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nstackx_epoll.h"
#include "nstackx_log.h"
#include "nstackx_error.h"
#define TAG "nStackXEpoll"
#define MAX_EPOLL_SIZE 128
int32_t RefreshEpollTask(EpollTask *task, uint32_t events)
{
struct epoll_event event;
if (task == NULL) {
return NSTACKX_EINVAL;
}
event.data.ptr = task;
event.events = events;
if (epoll_ctl(task->epollfd, EPOLL_CTL_MOD, task->taskfd, &event) < 0) {
LOGE(TAG, "Refresh task failed: %d", errno);
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
int32_t RegisterEpollTask(EpollTask *task, uint32_t events)
{
struct epoll_event event;
if (task == NULL) {
return NSTACKX_EINVAL;
}
event.data.ptr = task;
event.events = events;
if (epoll_ctl(task->epollfd, EPOLL_CTL_ADD, task->taskfd, &event) < 0) {
LOGE(TAG, "Register task failed: %d", errno);
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
int32_t DeRegisterEpollTask(EpollTask *task)
{
if (task == NULL) {
return NSTACKX_EINVAL;
}
if (epoll_ctl(task->epollfd, EPOLL_CTL_DEL, task->taskfd, NULL) < 0) {
LOGE(TAG, "De-register task failed: %d", errno);
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
EpollDesc CreateEpollDesc(void)
{
return epoll_create(1);
}
int32_t EpollLoop(EpollDesc epollfd, int32_t timeout)
{
int32_t i, nfds;
EpollTask *task = NULL;
struct epoll_event events[MAX_EPOLL_SIZE];
nfds = epoll_wait(epollfd, events, MAX_EPOLL_SIZE, timeout);
if (nfds < 0) {
LOGE(TAG, "epoll_wait returned n=%d, error: %d", nfds, errno);
if (errno != EINTR) {
return NSTACKX_EFAILED;
} else {
return NSTACKX_EINTR;
}
}
for (i = 0; i < nfds; i++) {
task = events[i].data.ptr;
if (task == NULL) {
continue;
}
if (events[i].events & EPOLLIN) {
if (task->readHandle != NULL) {
task->readHandle(task);
}
}
if (events[i].events & EPOLLOUT) {
if (task->writeHandle != NULL) {
task->writeHandle(task);
}
}
}
return ((nfds > 0) ? nfds : NSTACKX_ETIMEOUT);
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SYS_EPOLL_H
#define SYS_EPOLL_H
#include "nstackx_common_header.h"
#include "sys_util.h"
typedef int32_t EpollDesc;
typedef int32_t TaskDesc;
#define INVALID_EPOLL_DESC (-1)
#define INVALID_TASK_DESC (-1)
#define REPRESENT_EPOLL_DESC(epollfd) (epollfd)
static inline bool IsEpollDescValid(EpollDesc epollfd)
{
return (epollfd >= 0);
}
static inline bool IsEpollDescEqual(EpollDesc epollfd1, EpollDesc epollfd2)
{
return (epollfd1 == epollfd2);
}
static inline void CloseEpollDesc(EpollDesc epollfd)
{
CloseDesc(epollfd);
}
#endif // SYS_EPOLL_H

View File

@ -0,0 +1,190 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nstackx_event.h"
#include "nstackx_log.h"
#include "nstackx_error.h"
#include "nstackx_util.h"
#include "securec.h"
#define TAG "nStackXEvent"
typedef struct {
EventHandle handle;
void *arg;
} EventInfo;
EventNode *SearchEventNode(const List *eventNodeChain, EpollDesc epollfd);
void CloseNodePipe(const EventNode *node)
{
CloseDesc(node->pipeFd[PIPE_OUT]);
CloseDesc(node->pipeFd[PIPE_IN]);
}
static void EventProcessHandle(void *arg)
{
int32_t ret;
EventInfo event = {0};
EpollTask *task = arg;
EventNode *node = container_of(task, EventNode, task);
ret = (int32_t)read(node->pipeFd[PIPE_OUT], &event, sizeof(event));
if (ret != (int32_t)sizeof(event)) {
LOGE(TAG, "failed to read from pipe: %d", GetErrno());
return;
}
if (event.handle != NULL) {
event.handle(event.arg);
}
}
int32_t PostEvent(const List *eventNodeChain, EpollDesc epollfd, EventHandle handle, void *arg)
{
int32_t ret;
EventNode *node = NULL;
EventInfo event = {
.handle = handle,
.arg = arg,
};
if (eventNodeChain == NULL || handle == NULL) {
return NSTACKX_EINVAL;
}
node = SearchEventNode(eventNodeChain, epollfd);
if (node == NULL) {
LOGE(TAG, "Cannot find event node for %d", epollfd);
return NSTACKX_EFAILED;
}
ret = (int32_t)write(node->pipeFd[PIPE_IN], &event, sizeof(event));
if (ret != (int32_t)sizeof(event)) {
LOGE(TAG, "failed to write to pipe: %d", errno);
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
void ClearEvent(const List *eventNodeChain, EpollDesc epollfd)
{
EventNode *node = NULL;
EventInfo event = {0};
int32_t eventLen = (int32_t)sizeof(event);
if (eventNodeChain == NULL) {
LOGE(TAG, "eventNodeChain is null");
return;
}
node = SearchEventNode(eventNodeChain, epollfd);
if (node == NULL) {
return;
}
int32_t ret = eventLen;
while (ret == eventLen) {
ret = (int32_t)read(node->pipeFd[PIPE_OUT], &event, sizeof(event));
if (ret != eventLen) {
break;
}
if (event.handle != NULL) {
event.handle(event.arg);
}
}
}
static int32_t CreateNonBlockPipe(EventNode *node)
{
int32_t ret;
int32_t i, flags;
if (pipe(node->pipeFd) < 0) {
LOGE(TAG, "create pipe error: %d", errno);
return NSTACKX_EFAILED;
}
for (i = 0; i < PIPE_FD_NUM; i++) {
flags = fcntl(node->pipeFd[i], F_GETFL, 0);
if (flags < 0) {
LOGE(TAG, "fcntl get flags failed: %d", errno);
CloseNodePipe(node);
return NSTACKX_EFAILED;
}
flags = (int32_t)((uint32_t)flags | O_NONBLOCK);
ret = fcntl(node->pipeFd[i], F_SETFL, flags);
if (ret < 0) {
LOGE(TAG, "fcntl set flags to non-blocking failed: %d", errno);
CloseNodePipe(node);
return NSTACKX_EFAILED;
}
}
return NSTACKX_EOK;
}
int32_t EventModuleInit(List *eventNodeChain, EpollDesc epollfd)
{
List *pos = NULL;
EventNode *node = NULL;
if (eventNodeChain == NULL) {
LOGE(TAG, "eventNodeChain is null");
return NSTACKX_EINVAL;
}
LIST_FOR_EACH(pos, eventNodeChain) {
node = (EventNode *)pos;
if (node->epollfd == epollfd) {
return NSTACKX_EOK;
}
}
node = calloc(1, sizeof(EventNode));
if (node == NULL) {
return NSTACKX_ENOMEM;
}
if (CreateNonBlockPipe(node) != NSTACKX_EOK) {
goto L_ERR_FAILED;
}
node->task.taskfd = node->pipeFd[PIPE_OUT];
node->task.epollfd = epollfd;
node->task.readHandle = EventProcessHandle;
node->epollfd = epollfd;
if (RegisterEpollTask(&node->task, EPOLLIN) != NSTACKX_EOK) {
LOGE(TAG, "RegisterEpollTask failed");
CloseNodePipe(node);
goto L_ERR_FAILED;
}
ListInsertTail(eventNodeChain, &(node->list));
return NSTACKX_EOK;
L_ERR_FAILED:
free(node);
return NSTACKX_EFAILED;
}
void DeleteEventNode(EventNode *node)
{
ListRemoveNode(&node->list);
if (DeRegisterEpollTask(&node->task) != NSTACKX_EOK) {
LOGE(TAG, "DeRegisterEpollTask failed");
}
CloseNodePipe(node);
free(node);
}

View File

@ -0,0 +1,25 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SYS_EVENT_H
#define SYS_EVENT_H
#include "nstackx_common_header.h"
typedef int32_t PipeDesc;
#define INVALID_PIPE_DESC (-1)
#endif // SYS_EVENT_H

View File

@ -0,0 +1,27 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nstackx_log.h"
__attribute__((format(printf, 3, 4)))
void PrintfImpl(const char *moduleName, uint32_t logLevel, const char *format, ...)
{
va_list args;
va_start(args, format);
printf("%u %s: ", logLevel, moduleName);
vprintf(format, args);
va_end(args);
}

View File

@ -0,0 +1,159 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nstackx_timer.h"
#include "nstackx_log.h"
#include "nstackx_error.h"
#include "securec.h"
#define TAG "nStackXTimer"
void TimerDelete(Timer *timer)
{
if (timer == NULL) {
return;
}
if (timer->task.taskfd != INVALID_TASK_DESC) {
if (DeRegisterEpollTask(&(timer->task)) != NSTACKX_EOK) {
LOGE(TAG, "DeRegisterEpollTask failed");
}
if (close(timer->task.taskfd) < 0) {
LOGE(TAG, "close timer task failed");
}
timer->task.taskfd = INVALID_TASK_DESC;
}
free(timer);
}
static void TimerReadHandle(void *arg)
{
EpollTask *task = arg;
Timer *timer = NULL;
uint64_t exp;
if (task == NULL) {
LOGE(TAG, "Timer task is NULL");
return;
}
timer = task->ptr;
if (timer == NULL) {
LOGE(TAG, "Timer is NULL");
return;
}
if (timer->disabled) {
LOGD(TAG, "User disable timer before timer callback.");
return;
}
if (read(task->taskfd, &exp, sizeof(exp)) != (ssize_t)(sizeof(uint64_t))) {
LOGE(TAG, "read invalid exp");
return;
}
if (timer->timeoutHandle != NULL) {
timer->timeoutHandle(timer->data);
}
return;
}
int32_t TimerGetRemainTime(Timer *timer, uint32_t *remainTimeMsPtr)
{
struct itimerspec currValue = {{0}, {0}};
if (timer == NULL || remainTimeMsPtr == NULL) {
LOGE(TAG, "Invalid timer parameter");
return NSTACKX_EINVAL;
}
if (timerfd_gettime(timer->task.taskfd, &currValue) < 0) {
LOGE(TAG, "timerfd_gettime() failed! %d", errno);
return NSTACKX_EFAILED;
}
*remainTimeMsPtr = (uint32_t)(currValue.it_value.tv_sec * NSTACKX_MILLI_TICKS +
currValue.it_value.tv_nsec / NSTACKX_MILLI_TICKS / NSTACKX_MILLI_TICKS);
return NSTACKX_EOK;
}
int32_t TimerSetTimeout(Timer *timer, uint32_t timeoutMs, uint8_t repeated)
{
struct itimerspec ts;
if (timer == NULL) {
LOGE(TAG, "Invalid timer parameter");
return NSTACKX_EINVAL;
}
(void)memset_s(&ts, sizeof(ts), 0, sizeof(ts));
if (timeoutMs) {
ts.it_value.tv_sec = timeoutMs / NSTACKX_MILLI_TICKS;
ts.it_value.tv_nsec = (timeoutMs % NSTACKX_MILLI_TICKS) * NSTACKX_NANO_SEC_PER_MILLI_SEC;
if (repeated) {
ts.it_interval.tv_sec = ts.it_value.tv_sec;
ts.it_interval.tv_nsec = ts.it_value.tv_nsec;
}
timer->disabled = NSTACKX_FALSE;
} else {
timer->disabled = NSTACKX_TRUE;
}
if (timerfd_settime(timer->task.taskfd, 0, &ts, NULL) < 0) {
LOGE(TAG, "timerfd_settime failed! %d", errno);
return NSTACKX_EFAILED;
}
return NSTACKX_EOK;
}
Timer *TimerStart(EpollDesc epollfd, uint32_t ms, uint8_t repeated, TimeoutHandle handle, void *data)
{
Timer *timer = calloc(1, sizeof(Timer));
if (timer == NULL) {
LOGE(TAG, "timer malloc failed");
return NULL;
}
timer->timeoutHandle = handle;
timer->data = data;
timer->disabled = NSTACKX_FALSE;
timer->task.taskfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
if (timer->task.taskfd < 0) {
LOGE(TAG, "timer create failed! errno %d", errno);
TimerDelete(timer);
return NULL;
}
if (TimerSetTimeout(timer, ms, repeated) != NSTACKX_EOK) {
TimerDelete(timer);
return NULL;
}
timer->task.epollfd = epollfd;
timer->task.readHandle = TimerReadHandle;
timer->task.writeHandle = NULL;
timer->task.endHandle = NULL;
timer->task.errorHandle = NULL;
timer->task.ptr = timer;
if (RegisterEpollTask(&timer->task, EPOLLIN) != NSTACKX_EOK) {
LOGE(TAG, "RegisterEpollTask failed");
TimerDelete(timer);
return NULL;
}
return timer;
}

View File

@ -0,0 +1,217 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "nstackx_util.h"
#include "nstackx_error.h"
#include "nstackx_log.h"
#include "securec.h"
#define TAG "nStackXUtil"
static const char *g_illegalPathString[] = {
"/../",
};
static const char *g_illegalPathHeadString[] = {
"../",
};
uint8_t IsFileNameLegal(const char *fileName)
{
if (fileName == NULL || strlen(fileName) == 0) {
return NSTACKX_FALSE;
}
for (uint32_t idx = 0; idx < sizeof(g_illegalPathHeadString) / sizeof(g_illegalPathHeadString[0]); idx++) {
if (g_illegalPathHeadString[idx] == NULL || strlen(fileName) < strlen(g_illegalPathHeadString[idx])) {
continue;
}
if (memcmp(fileName, g_illegalPathHeadString[idx], strlen(g_illegalPathHeadString[idx])) == 0) {
LOGE(TAG, "illegal filename");
return NSTACKX_FALSE;
}
}
for (uint32_t idx = 0; idx < sizeof(g_illegalPathString) / sizeof(g_illegalPathString[0]); idx++) {
if (g_illegalPathString[idx] == NULL || strlen(fileName) < strlen(g_illegalPathString[idx])) {
continue;
}
if (strstr(fileName, g_illegalPathString[idx]) != NULL) {
LOGE(TAG, "illegal filename");
return NSTACKX_FALSE;
}
}
return NSTACKX_TRUE;
}
int32_t GetCpuNum(void)
{
return (int)sysconf(_SC_NPROCESSORS_CONF);
}
void StartThreadBindCore(int32_t cpu)
{
int32_t cpus;
cpu_set_t mask;
int32_t syscallres;
pid_t tid = gettid();
if (cpu < 0) {
return;
}
cpus = GetCpuNum();
if (cpus < cpu + 1) {
return;
}
CPU_ZERO(&mask);
CPU_SET(cpu, &mask);
syscallres = (int32_t)syscall(__NR_sched_setaffinity, tid, sizeof(mask), &mask);
if (syscallres < 0) {
LOGE(TAG, "set thread affinity failed, ret %d, error(%d)", syscallres, errno);
return;
}
}
void BindThreadToTargetMask(pid_t tid, uint32_t cpuMask)
{
if (tid == 0) {
LOGE(TAG, "invalid tid");
return;
}
int32_t cpus = GetCpuNum();
if (cpus < 0) {
return;
}
if (cpuMask == 0 || cpuMask >= (1U << (uint32_t)cpus)) {
LOGE(TAG, "invalid cpu mask");
return;
}
cpu_set_t mask;
int32_t syscallres;
uint32_t cpu = CPU_IDX_0;
CPU_ZERO(&mask);
LOGI(TAG, "bind thread %d to target core :%x", tid, cpuMask);
while (cpuMask > 0) {
if ((cpuMask & 1) == 1) {
CPU_SET(cpu, &mask);
}
cpu++;
cpuMask = cpuMask >> 1;
}
syscallres = (int32_t)syscall(__NR_sched_setaffinity, tid, sizeof(mask), &mask);
if (syscallres < 0) {
LOGE(TAG, "set thread affinity failed, ret %d, error(%d)", syscallres, errno);
return;
}
}
void SetThreadName(const char *name)
{
if (name == NULL || strlen(name) == 0 || strlen(name) >= MAX_THREAD_NAME_LEN) {
LOGE(TAG, "invalid input");
}
if (prctl(PR_SET_NAME, name) < 0) {
LOGE(TAG, "prctl errno %d", errno);
}
}
void SetMaximumPriorityForThread(void)
{
if (nice(THREAD_MAXIMUM_PRIORITY) == -1) {
LOGE(TAG, "nice set error: %d", errno);
}
}
void ClockGetTime(clockid_t id, struct timespec *tp)
{
if (clock_gettime(id, tp) != 0) {
LOGE(TAG, "clock_gettime error: %d", errno);
}
}
int32_t SemInit(sem_t *sem, int pshared, unsigned int value)
{
return sem_init(sem, pshared, value);
}
void SemGetValue(sem_t *sem, int *sval)
{
if (sem_getvalue(sem, sval) != 0) {
LOGE(TAG, "sem get error: %d", errno);
}
}
void SemPost(sem_t *sem)
{
if (sem_post(sem) != 0) {
LOGE(TAG, "sem post error: %d", errno);
}
}
void SemWait(sem_t *sem)
{
if (sem_wait(sem) != 0) {
LOGE(TAG, "sem wait error: %d", errno);
}
}
void SemDestroy(sem_t *sem)
{
if (sem_destroy(sem) != 0) {
LOGE(TAG, "sem destroy error: %d", errno);
}
}
int32_t PthreadCreate(pthread_t *tid, const pthread_attr_t *attr, void *(*entry)(void *), void *arg)
{
return pthread_create(tid, attr, entry, arg);
}
void PthreadJoin(pthread_t thread, void **retval)
{
if (pthread_join(thread, retval) != 0) {
LOGE(TAG, "pthread_join failed error: %d", errno);
}
}
int32_t PthreadMutexInit(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
{
return pthread_mutex_init(mutex, attr);
}
void PthreadMutexDestroy(pthread_mutex_t *mutex)
{
if (pthread_mutex_destroy(mutex) != 0) {
LOGE(TAG, "pthread mutex destroy error: %d", errno);
}
}
int32_t PthreadMutexLock(pthread_mutex_t *mutex)
{
return pthread_mutex_lock(mutex);
}
int32_t PthreadMutexUnlock(pthread_mutex_t *mutex)
{
return pthread_mutex_unlock(mutex);
}
void CloseDesc(int32_t desc)
{
if (close(desc) != 0) {
LOGE(TAG, "close desc error : %d", errno);
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SYS_UTIL_H
#define SYS_UTIL_H
#include "nstackx_common_header.h"
#ifdef __cplusplus
extern "C" {
#endif
#define PATH_SEPARATOR '/'
#define INVALID_TID (pthread_t)(-1)
typedef uint64_t atomic_t;
#define NSTACKX_ATOM_FETCH(ptr) (*ptr)
#define NSTACKX_ATOM_SET(ptr, i) ((*ptr) = (i))
#define NSTACKX_ATOM_FETCH_INC(ptr) __sync_fetch_and_add((ptr), 1)
#define NSTACKX_ATOM_FETCH_DEC(ptr) __sync_fetch_and_sub((ptr), 1)
#define NSTACKX_ATOM_ADD_RETURN(ptr, i) __sync_add_and_fetch((ptr), i)
#define NSTACKX_ATOM_FETCH_ADD(ptr, val) __sync_fetch_and_add((ptr), (val))
#define NSTACKX_ATOM_FETCH_SUB(ptr, val) __sync_fetch_and_sub((ptr), (val))
static inline int32_t GetErrno(void)
{
return errno;
}
#define CloseSocketInner CloseDesc
#define gettid() (pid_t)syscall(__NR_gettid)
NSTACKX_EXPORT void CloseDesc(int32_t desc);
NSTACKX_EXPORT int32_t GetInterfaceList(struct ifconf *ifc, struct ifreq *buf, uint32_t size);
NSTACKX_EXPORT int32_t GetInterfaceIP(int32_t fd, struct ifreq *interface);
NSTACKX_EXPORT int32_t GetTargetInterface(const struct sockaddr_in *dstAddr, struct ifreq *localDev);
#ifdef __cplusplus
}
#endif
#endif // NSTACKX_UTIL_H

27
core/BUILD.gn Executable file
View File

@ -0,0 +1,27 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/config/component/lite_component.gni")
lite_component("softbus_server") {
features = [
"connection:softbus_connection",
"frame/lite:softbus_server_frame",
"common:softbus_core_common",
"bus_center:softbus_bus_center",
"transmission:softbus_server_transmission",
"adapter/kernel:softbus_adapter_kernel",
"adapter/bus_center:softbus_adapter_bus_center",
]
}

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BT_RFCOM_H
#define BT_RFCOM_H
#include "ohos_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define BT_ADDR_LEN 6
#define BT_UUID_LEN 16
#define BT_RFCOM_NAME_MAX_LEN 31
#define BT_RFCOM_CLIENT_INVALID_HANDLE 0xFF
typedef uint8 BT_UUID[BT_UUID_LEN];
typedef uint8 BD_ADDR[BT_ADDR_LEN];
typedef enum {
BT_RFCOM_EVENT_READ = 0x00, /* not used */
BT_RFCOM_EVENT_ACCEPT,
BT_RFCOM_EVENT_DISCONNECT,
BT_RFCOM_EVENT_CONNECT,
BT_RFCOM_EVENT_CONGEST,
} BtRfcomEventType;
typedef struct {
/* event type BtRfcomEventType */
void (*OnEvent)(uint8 type, uint8 handle, int value);
void (*OnDataReceived)(uint8 handle, const uint8 *buf, uint16 len);
} BtRfcomEventCallback;
typedef enum {
BT_RFCOM_STATUS_OK,
BT_RFCOM_STATUS_INVALID_HANDLE,
BT_RFCOM_STATUS_UNUSED_HANDLE,
BT_RFCOM_STATUS_INVALID_PARAM,
} BtRfcomStatus;
/*
* return handle, BT_RFCOM_CLIENT_INVALID_HANDLE is invalid
*/
uint8 BtRfcomClientCreate(const BD_ADDR mac, const BT_UUID uuid);
/*
* BT_RFCOM_STATUS_OK means success, otherwise fail
*/
uint8 BtRfcomClientConnect(uint8 handle, BtRfcomEventCallback *cb);
/*
* BT_RFCOM_STATUS_OK means success, otherwise fail
*/
uint8 BtRfcomClientDisconnect(uint8 handle);
/*
* BT_RFCOM_STATUS_OK means success, otherwise fail
*/
uint8 BtRfcomClientWrite(uint8 handle, uint8 *data, uint16 dataLen);
/*
* BT_RFCOM_STATUS_OK means success, otherwise fail
*/
uint8 BtRfcomServerAccept(uint8 handle, BtRfcomEventCallback *cb);
/*
* return handle, BT_RFCOM_CLIENT_INVALID_HANDLE is invalid
*/
uint8 BtRfcomServerCreate(const char *name, const BT_UUID uuid);
void BtRfcomHandleResponse(const uint8 *data, uint16 dataLen);
#ifdef __cplusplus
}
#endif
#endif /* BT_RFCOM_H */

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WRAPPER_BR_INTERFACE_H
#define WRAPPER_BR_INTERFACE_H
#include <stdint.h>
#include "ohos_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define BR_NAME_LEN 16
#define BT_ADDR_LEN 6
#define BT_UUID_LEN 16
typedef uint8_t BT_UUIDL[BT_UUID_LEN];
typedef uint8_t BT_ADDR[BT_ADDR_LEN];
enum SppEventType {
SPP_EVENT_TYPE_ACCEPT = 1,
SPP_EVENT_TYPE_DISCONNECTED,
SPP_EVENT_TYPE_CONNECTED,
SPP_EVENT_TYPE_CONGEST
};
typedef struct {
// 0:read, 1:accept, 2:disconnected, 3:congest, 4:connteced
void (*OnEvent)(int32_t type, int32_t socketFd, int32_t value);
void (*OnDataReceived)(int32_t socketFd, const char* buf, int32_t len);
} SppSocketEventCallback;
typedef struct {
BT_UUIDL uuid;
BT_ADDR mac;
char name[BR_NAME_LEN];
} BluetoothRemoteDevice;
typedef struct tagSppSocketDriver {
void (*Init)(const struct tagSppSocketDriver* this_p);
int32_t (*OpenSppServer)(const BT_ADDR mac, const BT_UUIDL uuid, int32_t isSecure);
int32_t (*OpenSppClient)(const BT_ADDR mac, const BT_UUIDL uuid, int32_t isSecure);
int32_t (*CloseClient)(int32_t clientFd);
void (*CloseServer)(int32_t serverFd);
int32_t (*Connect)(int32_t clientFd, const SppSocketEventCallback* callback);
int32_t (*GetRemoteDeviceInfo)(int32_t clientFd, const BluetoothRemoteDevice* device);
int32_t (*IsConnected)(int32_t clientFd);
int32_t (*Accept)(int32_t serverFd, const SppSocketEventCallback* callback);
int32_t (*Write)(int32_t clientFd, const char* buf, const int32_t length);
} SppSocketDriver;
SppSocketDriver* InitSppSocketDriver();
#ifdef __cplusplus
}
#endif
#endif /* WRAPPER_BR_INTERFACE_H */

24
core/adapter/br/mock/BUILD.gn Executable file
View File

@ -0,0 +1,24 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//foundation/communication/dsoftbus/dsoftbus.gni")
static_library("br_adapter") {
sources = [ "wrapper_br_interface.c" ]
include_dirs = [
"$dsoftbus_root_path/core/common/include",
"$dsoftbus_root_path/core/connection/interface",
"$dsoftbus_root_path/core/adapter/br/include",
"$dsoftbus_root_path/core/common/message_handler/include",
]
}

View File

@ -0,0 +1,151 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "wrapper_br_interface.h"
#include "bt_rfcom.h"
#include "message_handler.h"
#include "softbus_errcode.h"
#include "softbus_log.h"
static SppSocketEventCallback *g_connectCallback = NULL;
static SppSocketEventCallback *g_connectServiceCallback = NULL;
static void OnEventRfcom(uint8 type, uint8 handle, int value)
{
g_connectCallback->OnEvent((int32_t)type, (int32_t)handle, value);
}
static void OnDataReceivedRfcom(uint8 handle, const uint8 *buf, uint16 len)
{
g_connectCallback->OnDataReceived((int32_t)handle, (char*)buf, (int32_t)len);
}
static BtRfcomEventCallback g_rfcomEventcb = {
.OnEvent = OnEventRfcom,
.OnDataReceived = OnDataReceivedRfcom
};
static void OnEventServiceRfcom(uint8 type, uint8 handle, int value)
{
LOG_INFO("[Client event call back form bt, and socketid = %u, tpye = %u]", handle, type);
if (g_connectServiceCallback == NULL) {
LOG_INFO("[g_connectServiceCallback is NULL]");
return;
}
g_connectServiceCallback->OnEvent((int32_t)type, (int32_t)handle, value);
}
static void OnDataReceivedServiceRfcom(uint8 handle, const uint8 *buf, uint16 len)
{
LOG_INFO("[Client received call back form bt, and socketid = %u, len = %u]", handle, len);
if (g_connectServiceCallback == NULL) {
LOG_INFO("[g_connectServiceCallback is NULL]");
return;
}
g_connectServiceCallback->OnDataReceived((int32_t)handle, (char*)buf, (int32_t)len);
}
static BtRfcomEventCallback g_rfcomServiceEventcb = {
.OnEvent = OnEventServiceRfcom,
.OnDataReceived = OnDataReceivedServiceRfcom
};
static int32_t Connect(int32_t clientFd, const SppSocketEventCallback *callback)
{
LOG_INFO("[mock clientFd = %d]", clientFd);
g_connectCallback = (SppSocketEventCallback*)callback;
int ret = BtRfcomClientConnect((uint8)clientFd, &g_rfcomEventcb);
LOG_INFO("[BtRfcom return = %d]", ret);
ret = (ret == BT_RFCOM_STATUS_OK) ? SOFTBUS_OK : SOFTBUS_ERR;
return ret;
}
static void Init(const struct tagSppSocketDriver *sppDriver)
{
(void)sppDriver;
}
static int32_t OpenSppServer(const BT_ADDR mac, const BT_UUIDL uuid, int32_t isSecure)
{
LOG_INFO("[OpenSppServer connect]");
return SOFTBUS_ERR;
}
static int32_t OpenSppClient(const BT_ADDR mac, const BT_UUIDL uuid, int32_t isSecure)
{
(void)isSecure;
int ret = BtRfcomClientCreate(mac, uuid);
if (ret == BT_RFCOM_CLIENT_INVALID_HANDLE) {
return SOFTBUS_ERR;
}
return ret;
}
static int32_t CloseClient(int32_t clientFd)
{
LOG_INFO("[CloseClient connect, and serverFd = %d]", clientFd);
return BtRfcomClientDisconnect((uint8)clientFd);
}
static void CloseServer(int32_t serverFd)
{
LOG_INFO("[CloseServer Connect, and serverFd = %d]", serverFd);
}
static int32_t GetRemoteDeviceInfo(int32_t clientFd, const BluetoothRemoteDevice *device)
{
LOG_INFO("[to get remotedeviceinfo, clientFd = %d]", clientFd);
return 0;
}
static int32_t IsConnected(int32_t clientFd)
{
LOG_INFO("[to get connected state from bt, clientFd = %d]", clientFd);
return true;
}
static int32_t Accept(int32_t serverFd, const SppSocketEventCallback *callback)
{
LOG_INFO("[Accept remote device to connect, and serverFd = %d]", serverFd);
g_connectServiceCallback = (SppSocketEventCallback*)callback;
return 0;
}
static int32_t Write(int32_t g_clientFd, const char *buf, const int32_t length)
{
LOG_INFO("[mock Write] g_clientFd=%d,len=%d", g_clientFd, length);
return BtRfcomClientWrite((uint8)g_clientFd, (uint8 *)buf, (uint16)length);
}
static SppSocketDriver g_sppSocketDriver = {
.Init = Init,
.OpenSppServer = OpenSppServer,
.OpenSppClient = OpenSppClient,
.CloseClient = CloseClient,
.CloseServer = CloseServer,
.Connect = Connect,
.GetRemoteDeviceInfo = GetRemoteDeviceInfo,
.IsConnected = IsConnected,
.Accept = Accept,
.Write = Write
};
SppSocketDriver *InitSppSocketDriver()
{
LOG_INFO("[InitSppSocketDriver]");
Init(&g_sppSocketDriver);
return &g_sppSocketDriver;
}

View File

@ -0,0 +1,34 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/config/component/lite_component.gni")
import("//foundation/communication/dsoftbus/dsoftbus.gni")
if (ohos_kernel_type == "liteos_m") {
static_library("softbus_adapter_bus_center") {
include_dirs = [
"include",
"$dsoftbus_root_path/core/common/include",
"//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite",
]
sources = [ "platform/bus_center_adapter_weak.c" ]
}
} else {
shared_library("softbus_adapter_bus_center") {
include_dirs = [
"include",
"$dsoftbus_root_path/core/common/include",
]
sources = [ "platform/bus_center_adapter_weak.c" ]
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SOFTBUS_BUS_CENTER_ADAPTER_H
#define SOFTBUS_BUS_CENTER_ADAPTER_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
COMM_DEVICE_KEY_UDID,
COMM_DEVICE_KEY_DEVTYPE,
COMM_DEVICE_KEY_DEVNAME,
COMM_DEVICE_KEY_BT_MAC,
COMM_DEVICE_KEY_BUTT
} CommonDeviceKey;
#define TYPE_UNKNOWN "UNKNOWN"
#define TYPE_PHONE "PHONE"
#define TYPE_PAD "PAD"
#define TYPE_TV "TV"
#define TYPE_PC "PC"
#define TYPE_CAR "CAR"
#define TYPE_WATCH "WATCH"
#define TYPE_IPCAMERA "WiFiCamara"
int32_t GetCommonDevInfo(const CommonDeviceKey key, char *value, uint32_t len);
#ifdef __cplusplus
}
#endif
#endif // SOFTBUS_BUS_CENTER_ADAPTER_H

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <securec.h>
#include "bus_center_adapter.h"
#include "softbus_errcode.h"
#include "softbus_log.h"
#define DEFAULT_DEVICE_NAME "UNKNOWN"
#define DEFAULT_UDID_NAME "ABCDEF00ABCDEF00ABCDEF00ABCDEF00ABCDEF00ABCDEF00ABCDEF00ABCDEF00"
int __attribute__ ((weak)) GetCommonDevInfo(const CommonDeviceKey key, char *value, uint32_t len)
{
if (value == NULL) {
LOG_ERR("fail: para error!");
return SOFTBUS_INVALID_PARAM;
}
switch (key) {
case COMM_DEVICE_KEY_DEVNAME:
if (strncpy_s(value, len, DEFAULT_DEVICE_NAME, strlen(DEFAULT_DEVICE_NAME)) != EOK) {
return SOFTBUS_ERR;
}
break;
case COMM_DEVICE_KEY_UDID:
if (strncpy_s(value, len, DEFAULT_UDID_NAME, strlen(DEFAULT_UDID_NAME)) != EOK) {
return SOFTBUS_ERR;
}
break;
case COMM_DEVICE_KEY_DEVTYPE:
break;
default:
break;
}
return SOFTBUS_OK;
}

45
core/adapter/kernel/BUILD.gn Executable file
View File

@ -0,0 +1,45 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/config/component/lite_component.gni")
import("//foundation/communication/dsoftbus/dsoftbus.gni")
if (ohos_kernel_type == "liteos_m") {
static_library("softbus_adapter_kernel") {
include_dirs = [
"include",
"$dsoftbus_root_path/core/common/include",
"//kernel/liteos_m/components/bounds_checking_function/include",
"//kernel/liteos_m/kal/cmsis",
"//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite",
]
sources = [
"liteos_m/softbus_mem_interface.c",
"liteos_m/softbus_os_interface.c",
]
}
} else {
shared_library("softbus_adapter_kernel") {
include_dirs = [
"include",
"$dsoftbus_root_path/core/common/include",
"//third_party/bounds_checking_function/include",
"//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite",
]
sources = [
"liteos_a/softbus_mem_interface.c",
"liteos_a/softbus_os_interface.c",
]
public_deps = [ "//third_party/bounds_checking_function:libsec_shared" ]
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SOFTBUS_MEM_INTERFACE_H
#define SOFTBUS_MEM_INTERFACE_H
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#define MAX_MALLOC_SIZE (512 * 1024 * 1024) // 512M
/* Low speed memory pool */
void *SoftBusMalloc(unsigned int size);
void *SoftBusCalloc(unsigned int size);
void SoftBusFree(void *pt);
/* High speed memory pool */
void *SoftBusHighSpeedMalloc(unsigned int size);
void *SoftBusHighSpeedCalloc(unsigned int size);
void SoftBusHighSpeedFree(void *pt);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SOFTBUS_OS_INTERFACE_H
#define SOFTBUS_OS_INTERFACE_H
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
/* Timer */
void *SoftBusCreateTimer(void **timerId, void *timerFunc, unsigned int type);
int SoftBusStartTimer(void *timerId, unsigned int tickets);
int SoftBusDeleteTimer(void *timerId);
/* Sleep */
int SoftBusSleepMs(unsigned int ms);
/* File operation */
int SoftBusReadFile(const char *fileName, char *readBuf, int maxLen);
int SoftBusWriteFile(const char *fileName, const char *writeBuf, int len);
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "softbus_mem_interface.h"
#include <securec.h>
#include <stdlib.h>
#include "softbus_log.h"
void *SoftBusMalloc(unsigned int size)
{
if (size > MAX_MALLOC_SIZE) {
return NULL;
}
return malloc(size);
}
void *SoftBusCalloc(unsigned int size)
{
void *tmp = SoftBusMalloc(size);
if (tmp == NULL) {
return NULL;
}
errno_t err = memset_s(tmp, size, 0, size);
if (err != EOK) {
LOG_ERR("memset_s failed");
SoftBusFree(tmp);
return NULL;
}
return tmp;
}
void SoftBusFree(void *pt)
{
if (pt == NULL) {
return;
}
free(pt);
}
void *SoftBusHighSpeedMalloc(unsigned int size)
{
return SoftBusMalloc(size);
}
void *SoftBusHighSpeedCalloc(unsigned int size)
{
void *tmp = SoftBusHighSpeedMalloc(size);
if (tmp == NULL) {
return NULL;
}
errno_t err = memset_s(tmp, size, 0, size);
if (err != EOK) {
LOG_ERR("memset_s failed");
SoftBusHighSpeedFree(tmp);
return NULL;
}
return tmp;
}
void SoftBusHighSpeedFree(void *pt)
{
if (pt == NULL) {
return;
}
free(pt);
}

View File

@ -0,0 +1,170 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "softbus_os_interface.h"
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "securec.h"
#include "softbus_def.h"
#include "softbus_errcode.h"
#include "softbus_log.h"
#define MS_PER_SECOND 1000
#define US_PER_MSECOND 1000
static unsigned int g_timerType;
void *SoftBusCreateTimer(void **timerId, void *timerFunc, unsigned int type)
{
if (timerId == NULL) {
LOG_ERR("timerId is null");
return NULL;
}
struct sigevent envent;
(void)memset_s(&envent, sizeof(envent), 0, sizeof(envent));
envent.sigev_notify = SIGEV_SIGNAL;
envent.sigev_signo = SIGUSR1;
signal(SIGUSR1, timerFunc);
g_timerType = type;
if (timer_create(CLOCK_REALTIME, &envent, timerId) != 0) {
LOG_ERR("timer create error, errno code: [%d]", errno);
return NULL;
}
return *timerId;
}
int SoftBusStartTimer(void *timerId, unsigned int tickets)
{
if (timerId == NULL) {
LOG_ERR("timerId is null");
return SOFTBUS_ERR;
}
struct itimerspec value;
(void)memset_s(&value, sizeof(value), 0, sizeof(value));
value.it_value.tv_sec = tickets / MS_PER_SECOND;
value.it_value.tv_nsec = 0;
if (g_timerType == TIMER_TYPE_ONCE) {
value.it_interval.tv_sec = tickets = 0;
value.it_interval.tv_nsec = 0;
} else {
value.it_interval.tv_sec = tickets / MS_PER_SECOND;
value.it_interval.tv_nsec = 0;
}
if (timer_settime(timerId, 0, &value, NULL) != 0) {
LOG_ERR("timer start error, errno code: [%d]", errno);
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}
int SoftBusDeleteTimer(void *timerId)
{
if (timerId == NULL) {
LOG_ERR("timerId is null");
return SOFTBUS_ERR;
}
if (timer_delete(timerId) != 0) {
LOG_ERR("timer delete err, errno code: [%d]", errno);
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}
int SoftBusSleepMs(unsigned int ms)
{
int ret;
struct timeval tm;
tm.tv_sec = ms / MS_PER_SECOND;
tm.tv_usec = (ms % MS_PER_SECOND) * US_PER_MSECOND;
do {
ret = select(0, NULL, NULL, NULL, &tm);
} while ((ret == -1) && (errno == EINTR));
return SOFTBUS_ERR;
}
int SoftBusReadFile(const char *fileName, char *readBuf, int maxLen)
{
if (fileName == NULL || readBuf == NULL || maxLen <= 0) {
return SOFTBUS_FILE_ERR;
}
int fd = open(fileName, O_RDONLY, S_IRUSR | S_IWUSR);
if (fd < 0) {
LOG_ERR("ReadFile get deviceid open file fail");
return SOFTBUS_FILE_ERR;
}
int fileLen = lseek(fd, 0, SEEK_END);
if (fileLen <= 0 || fileLen > maxLen) {
LOG_ERR("ReadFile maxLen failed or over maxLen");
close(fd);
return SOFTBUS_FILE_ERR;
}
int ret = lseek(fd, 0, SEEK_SET);
if (ret < 0) {
LOG_ERR("ReadFile get deviceid lseek file fail");
close(fd);
return SOFTBUS_FILE_ERR;
}
ret = read(fd, readBuf, fileLen);
if (ret < 0) {
LOG_ERR("ReadFile read deviceid fail, ret=%d", ret);
close(fd);
return SOFTBUS_FILE_ERR;
}
close(fd);
return SOFTBUS_OK;
}
int SoftBusWriteFile(const char *fileName, const char *writeBuf, int len)
{
if (fileName == NULL || writeBuf == NULL || len <= 0) {
return SOFTBUS_FILE_ERR;
}
int ret;
int fd;
fd = open(fileName, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
LOG_ERR("WriteDeviceId open file fail");
return SOFTBUS_FILE_ERR;
}
ret = write(fd, writeBuf, len);
if (ret != len) {
LOG_ERR("WriteDeviceId write fail");
close(fd);
return SOFTBUS_FILE_ERR;
}
close(fd);
return SOFTBUS_OK;
}

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "softbus_mem_interface.h"
#include <securec.h>
#include <stdlib.h>
#if defined(OHOS_MEM)
#include "ohos_mem_pool.h"
#endif
void *SoftBusMalloc(unsigned int size)
{
if (size > MAX_MALLOC_SIZE) {
return NULL;
}
#if defined(OHOS_MEM)
void *tmp = OhosMalloc(MEM_TYPE_SOFTBUS_LSRAM, size);
#else
void *tmp = malloc(size);
#endif
return tmp;
}
void *SoftBusCalloc(unsigned int size)
{
void *tmp = SoftBusMalloc(size);
if (tmp == NULL) {
return NULL;
}
errno_t err = memset_s(tmp, size, 0, size);
if (err != EOK) {
SoftBusFree(tmp);
return NULL;
}
return tmp;
}
void SoftBusFree(void *pt)
{
if (pt == NULL) {
return;
}
#if defined(OHOS_MEM)
OhosFree(pt);
#else
free(pt);
#endif
}
void *SoftBusHighSpeedMalloc(unsigned int size)
{
if (size > MAX_MALLOC_SIZE) {
return NULL;
}
return malloc(size);
}
void *SoftBusHighSpeedCalloc(unsigned int size)
{
void *tmp = SoftBusHighSpeedMalloc(size);
if (tmp == NULL) {
return NULL;
}
errno_t err = memset_s(tmp, size, 0, size);
if (err != EOK) {
SoftBusHighSpeedFree(tmp);
return NULL;
}
return tmp;
}
void SoftBusHighSpeedFree(void *pt)
{
if (pt == NULL) {
return;
}
free(pt);
}

View File

@ -0,0 +1,123 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "softbus_os_interface.h"
#include "cmsis_os2.h"
#include "securec.h"
#include "softbus_errcode.h"
#include "softbus_log.h"
#include "utils_file.h"
#define MS_PER_SECOND 1000
void *SoftBusCreateTimer(void **timerId, void *timerFunc, unsigned int type)
{
(void)timerId;
void *id = osTimerNew((osTimerFunc_t)timerFunc, type, NULL, NULL);
if (id != NULL) {
LOG_INFO("create timer success");
return id;
}
LOG_ERR("create timer failed");
return NULL;
}
int SoftBusStartTimer(void *timerId, unsigned int ms)
{
if (osTimerStart(timerId, ms * osKernelGetTickFreq() / MS_PER_SECOND) != osOK) {
LOG_ERR("start timer failed");
(void)osTimerDelete(timerId);
return SOFTBUS_ERR;
}
LOG_INFO("start timer success");
return SOFTBUS_OK;
}
int SoftBusDeleteTimer(void *timerId)
{
if (osTimerDelete(timerId) != osOK) {
LOG_ERR("delete timer failed");
return SOFTBUS_ERR;
}
LOG_INFO("delete timer success");
return SOFTBUS_OK;
}
int SoftBusSleepMs(unsigned int ms)
{
osDelay(ms * osKernelGetTickFreq() / MS_PER_SECOND);
return SOFTBUS_OK;
}
int SoftBusReadFile(const char *fileName, char *readBuf, int maxLen)
{
if (fileName == NULL || readBuf == NULL || maxLen <= 0) {
return SOFTBUS_INVALID_PARAM;
}
uint32_t fileLen = 0;
int fd = UtilsFileOpen(fileName, O_RDONLY_FS, 0);
if (fd < 0) {
LOG_ERR("Read UtilsFileOpen fail");
return SOFTBUS_FILE_ERR;
}
int ret = UtilsFileStat(fileName, &fileLen);
if (ret < 0) {
UtilsFileClose(fd);
goto EXIT;
}
ret = UtilsFileSeek(fd, 0, SEEK_SET_FS);
if (ret < 0) {
LOG_ERR("Read UtilsFileSeek fail");
goto EXIT;
}
if (fileLen > maxLen) {
LOG_ERR("Read file len not legal, clear buf");
goto EXIT;
}
ret = UtilsFileRead(fd, readBuf, maxLen);
if (ret < 0) {
LOG_ERR("Read UtilsFileRead, ret=%d", ret);
goto EXIT;
}
UtilsFileClose(fd);
return SOFTBUS_OK;
EXIT:
UtilsFileClose(fd);
return SOFTBUS_FILE_ERR;
}
int SoftBusWriteFile(const char *fileName, const char *writeBuf, int len)
{
int ret;
int fd;
fd = UtilsFileOpen(fileName, O_RDWR_FS | O_CREAT_FS | O_TRUNC_FS, 0);
if (fd < 0) {
LOG_ERR("WriteDeviceId UtilsFileOpen fail");
return SOFTBUS_FILE_ERR;
}
ret = UtilsFileWrite(fd, writeBuf, len);
if (ret != len) {
LOG_ERR("UtilsFileOpen UtilsFileWrite fail");
UtilsFileClose(fd);
return SOFTBUS_FILE_ERR;
}
UtilsFileClose(fd);
return SOFTBUS_OK;
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AUTH_COMMON_H
#define AUTH_COMMON_H
#include <stdint.h>
#include <string.h>
#include "auth_manager.h"
#ifdef __cplusplus
extern "C" {
#endif
int64_t GetSeq(AuthSideFlag flag);
void UniqueIdInit(void);
AuthSideFlag AuthGetSideByRemoteSeq(int64_t seq);
int32_t AuthGetDeviceKey(char *key, uint32_t size, uint32_t *len, const ConnectOption *option);
int32_t AuthConvertConnInfo(ConnectOption *option, const ConnectionInfo *connInfo);
#ifdef __cplusplus
}
#endif
#endif /* AUTH_COMMON_H */

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AUTH_CONNECTION_H
#define AUTH_CONNECTION_H
#include "auth_manager.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TAG "MsgGetDeviceId"
#define CMD_TAG "TECmd"
#define DATA_TAG "TEData"
#define TE_DEVICE_ID_TAG "TEDeviceId"
#define DATA_BUF_SIZE_TAG "DataBufSize"
#define CMD_GET_AUTH_INFO "getAuthInfo"
#define CMD_RET_AUTH_INFO "retAuthInfo"
#define SOFTBUS_VERSION_INFO "softbusVersion"
#define CMD_TAG_LEN 30
#define PACKET_SIZE (64 * 1024)
int32_t AuthSyncDeviceUuid(AuthManager *auth);
int32_t AuthUnpackDeviceInfo(AuthManager *auth, uint8_t *data);
char *AuthGenDeviceLevelParam(const AuthManager *auth, bool isClient);
void AuthTryCloseConnection(uint32_t connectionId);
bool AuthOnTransmit(int64_t authId, const uint8_t *data, uint32_t len);
void AuthSendCloseAck(uint32_t connectionId);
#ifdef __cplusplus
}
#endif
#endif /* AUTH_CONNECTION_H */

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AUTH_MANAGER_H
#define AUTH_MANAGER_H
#include <pthread.h>
#include <stdint.h>
#include <string.h>
#include "auth_interface.h"
#include "bus_center_info_key.h"
#include "common_list.h"
#include "device_auth.h"
#include "softbus_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#define AUTH_APPID "softbus_auth"
/* auth timeout delay */
#define AUTH_DELAY_MS (10 * 1000)
/* auth data max length */
#define AUTH_MAX_DATA_LEN (2 * 1024)
/* auth status */
#define INIT_STATE 0
#define WAIT_CONNECTION_ESTABLISHED 1
#define IN_AUTH_PROGRESS 2
#define IN_SYNC_PROGRESS 3
#define SYNC_FINISH 4
#define AUTH_PASSED 5
#define AUTH_FAIL 6
typedef struct {
uint32_t type;
int32_t module;
int64_t authId;
int32_t flag;
uint32_t dataLen;
} AuthDataInfo;
typedef struct {
uint32_t requestId;
uint32_t connectionId;
int64_t authId;
AuthSideFlag side;
uint8_t status;
int32_t fd;
ConnectOption option;
const GroupAuthManager *hichain;
VerifyCallback *cb;
char peerUdid[UDID_BUF_LEN];
char peerUuid[UUID_BUF_LEN];
int32_t softbusVersion;
SoftBusVersion peerVersion;
uint8_t *encryptDevData;
uint32_t encryptLen;
pthread_mutex_t lock;
ListNode node;
} AuthManager;
AuthManager *AuthGetManagerByRequestId(uint32_t requestId);
AuthManager *AuthGetManagerByAuthId(int64_t authId, AuthSideFlag side);
AuthManager *AuthGetManagerByFd(int32_t fd);
void AuthHandlePeerSyncDeviceInfo(AuthManager *auth, uint8_t *data, uint32_t len);
void HandleReceiveDeviceId(AuthManager *auth, uint8_t *data);
void HandleReceiveAuthData(AuthManager *auth, int32_t module, uint8_t *data, uint32_t dataLen);
#ifdef __cplusplus
}
#endif
#endif /* AUTH_MANAGER_H */

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AUTH_SESSIONKEY_H
#define AUTH_SESSIONKEY_H
#include "auth_manager.h"
#include "common_list.h"
#include "softbus_crypto.h"
#include "softbus_def.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MESSAGE_INDEX_LEN 4
#define ENCRYPT_OVER_HEAD_LEN (OVERHEAD_LEN + MESSAGE_INDEX_LEN)
#define MAX_KEY_LIST_SIZE 10
#define LOW_32_BIT 0xFFFFFFFF
typedef struct {
uint32_t type;
char deviceKey[MAX_DEVICE_KEY_LEN];
uint32_t deviceKeyLen;
AuthSideFlag side;
int32_t seq;
} NecessaryDevInfo;
typedef struct {
char deviceKey[MAX_DEVICE_KEY_LEN];
uint32_t deviceKeyLen;
uint32_t type;
int32_t seq;
uint8_t sessionKey[SESSION_KEY_LENGTH];
uint32_t sessionKeyLen;
char peerUdid[UDID_BUF_LEN];
AuthSideFlag side;
ListNode node;
} SessionKeyList;
void AuthSetLocalSessionKey(const NecessaryDevInfo *devInfo, const char *peerUdid,
const uint8_t *sessionKey, uint32_t sessionKeyLen);
bool AuthIsDeviceVerified(uint32_t type, const char *deviceKey, uint32_t deviceKeyLen);
bool AuthIsSeqInKeyList(int32_t seq);
void AuthSessionKeyListInit(void);
void AuthClearSessionKeyByDeviceInfo(uint32_t type, const char *deviceKey, uint32_t deviceKeyLen);
void AuthClearAllSessionKey(void);
#ifdef __cplusplus
}
#endif
#endif /* AUTH_SESSIONKEY_H */

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AUTH_SOCKET_H
#define AUTH_SOCKET_H
#include "auth_manager.h"
#include "softbus_conn_interface.h"
#include "softbus_def.h"
#ifdef __cplusplus
extern "C" {
#endif
int32_t HandleIpVerifyDevice(AuthManager *auth, const ConnectOption *option);
void AuthCloseTcpFd(int32_t fd);
int32_t OpenAuthServer(void);
int32_t AuthSocketSendData(AuthManager *auth, const AuthDataHead *head, const uint8_t *data, uint32_t len);
#ifdef __cplusplus
}
#endif
#endif /* AUTH_SOCKET_H */

View File

@ -0,0 +1,126 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AUTH_INTERFACE_H
#define AUTH_INTERFACE_H
#include <stdbool.h>
#include <stdint.h>
#include "softbus_conn_interface.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_DEVICE_KEY_LEN 64
#define AUTH_ERROR_CODE (-1)
typedef enum {
/* nearby type v1 */
SOFT_BUS_OLD_V1 = 1,
/* nearby type v2 */
SOFT_BUS_OLD_V2 = 2,
/* softbus type v1 */
SOFT_BUS_NEW_V1 = 100,
} SoftBusVersion;
typedef enum {
/* data type for device authentication */
DATA_TYPE_AUTH = 0xFFFF0001,
/* data type for synchronizing peer device information */
DATA_TYPE_SYNC = 0xFFFF0002,
/* data type for synchronizing peer device id */
DATA_TYPE_DEVICE_ID = 0xFFFF0003,
/* data type for connection */
DATA_TYPE_CONNECTION = 0xFFFF0004,
/* data type for closing ack */
DATA_TYPE_CLOSE_ACK = 0xFFFF0005,
} AuthDataType;
typedef enum {
/* reserved */
NONE = 0,
/* trust Engine, use plain text */
TRUST_ENGINE = 1,
/* hiChain, use plain text */
HICHAIN = 2,
/* authentication SDK, use plain text */
AUTH_SDK = 3,
/* hichain sync data, use plain text */
HICHAIN_SYNC = 4,
} AuthDataModule;
typedef enum {
CLIENT_SIDE_FLAG = 0,
SERVER_SIDE_FLAG = 1,
} AuthSideFlag;
typedef enum {
LNN = 0,
MODULE_NUM,
} AuthModuleId;
typedef struct {
uint8_t *buf;
uint32_t bufLen;
uint32_t outLen;
} OutBuf;
typedef struct {
AuthDataType dataType;
int32_t module;
int64_t authId;
AuthSideFlag flag;
} AuthDataHead;
typedef struct {
void (*onDeviceVerifyPass)(int64_t authId, ConnectOption *option, SoftBusVersion peerVersion);
void (*onDeviceVerifyFail)(int64_t authId, ConnectOption *option);
void (*onRecvSyncDeviceInfo)(int64_t authId, AuthSideFlag side, const char *peerUuid, uint8_t *data, uint32_t len);
void (*onDeviceNotTrusted)(const char *peerUdid);
} VerifyCallback;
uint32_t AuthGetEncryptHeadLen(void);
int32_t AuthEncrypt(const ConnectOption *option, AuthSideFlag *side, uint8_t *data, uint32_t len, OutBuf *outBuf);
int32_t AuthDecrypt(const ConnectOption *option, AuthSideFlag side, uint8_t *data, uint32_t len, OutBuf *outbuf);
int32_t OpenAuthServer(void);
void CloseAuthServer(void);
int32_t AuthRegCallback(AuthModuleId moduleId, VerifyCallback *cb);
int32_t AuthVerifyInit(void);
int32_t AuthVerifyDevice(AuthModuleId moduleId, const ConnectOption *option);
int32_t AuthVerifyDeinit(void);
int32_t AuthPostData(const AuthDataHead *head, const uint8_t *data, uint32_t len);
int32_t AuthHandleLeaveLNN(int64_t authId);
int32_t AuthGetUuidByOption(const ConnectOption *option, char *buf, uint32_t bufLen);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,127 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "auth_common.h"
#include <securec.h>
#include <sys/time.h>
#include "softbus_errcode.h"
#include "softbus_log.h"
#ifdef __cplusplus
extern "C" {
#endif
#define INTERVAL_VALUE 2
#define OFFSET_BITS 24
#define INT_MAX_VALUE 0xFFFFFEL
#define LOW_24_BITS 0xFFFFFFL
static uint64_t g_uniqueId = 0;
int64_t GetSeq(AuthSideFlag flag)
{
static uint64_t integer = 0;
if (integer == INT_MAX_VALUE) {
integer = 0;
}
integer += INTERVAL_VALUE;
uint64_t temp = integer;
temp = ((g_uniqueId << OFFSET_BITS) | (temp & LOW_24_BITS));
int64_t seq = 0;
if (memcpy_s(&seq, sizeof(int64_t), &temp, sizeof(uint64_t)) != EOK) {
LOG_ERR("memcpy_s seq error");
}
return seq;
}
AuthSideFlag AuthGetSideByRemoteSeq(int64_t seq)
{
/* even odd check */
return (seq % 2) == 0 ? SERVER_SIDE_FLAG : CLIENT_SIDE_FLAG;
}
void UniqueIdInit(void)
{
struct timeval time = {0};
gettimeofday(&time, NULL);
g_uniqueId = (uint64_t)(time.tv_usec);
}
int32_t AuthGetDeviceKey(char *key, uint32_t size, uint32_t *len, const ConnectOption *option)
{
if (key == NULL || len == NULL || option == NULL) {
LOG_ERR("invalid parameter");
return SOFTBUS_ERR;
}
switch (option->type) {
case CONNECT_BR: {
if (strncpy_s(key, size, option->info.brOption.brMac, BT_MAC_LEN) != EOK) {
LOG_ERR("strncpy_s failed");
return SOFTBUS_ERR;
}
*len = BT_MAC_LEN;
break;
}
case CONNECT_TCP: {
if (strncpy_s(key, size, option->info.ipOption.ip, IP_LEN) != EOK) {
LOG_ERR("strncpy_s failed");
return SOFTBUS_ERR;
}
*len = IP_LEN;
break;
}
default: {
LOG_ERR("unknown type");
return SOFTBUS_ERR;
}
}
return SOFTBUS_OK;
}
int32_t AuthConvertConnInfo(ConnectOption *option, const ConnectionInfo *connInfo)
{
if (option == NULL || connInfo == NULL) {
LOG_ERR("invalid parameter");
return SOFTBUS_ERR;
}
option->type = connInfo->type;
switch (connInfo->type) {
case CONNECT_BR: {
if (strncpy_s(option->info.brOption.brMac, BT_MAC_LEN, connInfo->info.brInfo.brMac, BT_MAC_LEN) != EOK) {
LOG_ERR("strncpy_s failed");
return SOFTBUS_ERR;
}
break;
}
case CONNECT_TCP: {
if (strncpy_s(option->info.ipOption.ip, IP_LEN, connInfo->info.ipInfo.ip, IP_LEN) != EOK) {
LOG_ERR("strncpy_s failed");
return SOFTBUS_ERR;
}
option->info.ipOption.port = connInfo->info.ipInfo.port;
break;
}
default: {
LOG_ERR("unknown type");
return SOFTBUS_ERR;
}
}
return SOFTBUS_OK;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,404 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "auth_connection.h"
#include <securec.h>
#include "auth_common.h"
#include "bus_center_manager.h"
#include "device_auth.h"
#include "softbus_conn_interface.h"
#include "softbus_errcode.h"
#include "softbus_json_utils.h"
#include "softbus_log.h"
#include "softbus_mem_interface.h"
#ifdef __cplusplus
extern "C" {
#endif
int32_t __attribute__ ((weak)) AuthSocketSendData(AuthManager *auth,
const AuthDataHead *head, const uint8_t *data, uint32_t len)
{
(void)auth;
(void)head;
(void)data;
(void)len;
return SOFTBUS_ERR;
}
typedef struct {
AuthSideFlag side;
int64_t seq;
uint32_t connectionId;
int32_t connModule;
} PostDataInfo;
static int32_t PostDataByConn(const PostDataInfo *info, char *buf, uint32_t postDataLen)
{
int64_t seq = 0;
if (info->connModule == MODULE_DEVICE_AUTH ||
info->connModule == MODULE_TRUST_ENGINE || info->connModule == MODULE_AUTH_SDK) {
seq = info->seq;
} else if (info->connModule == MODULE_AUTH_CONNECTION) {
seq = GetSeq(info->side);
} else {
LOG_ERR("invalid conn module.");
SoftBusFree(buf);
return SOFTBUS_INVALID_PARAM;
}
ConnPostData postParam;
postParam.module = info->connModule;
postParam.seq = seq;
postParam.flag = info->side;
postParam.pid = 0;
postParam.buf = buf;
postParam.len = postDataLen + ConnGetHeadSize();
return ConnPostBytes(info->connectionId, &postParam);
}
static int32_t SetBufData(char *buf, const AuthManager *auth, const AuthDataHead *head,
const uint8_t *data, uint32_t len)
{
buf += ConnGetHeadSize();
if (auth->option.type != CONNECT_TCP) {
*(int32_t *)buf = head->dataType;
buf += sizeof(int32_t);
*(int32_t *)buf = head->module;
buf += sizeof(int32_t);
*(int64_t *)buf = head->authId;
buf += sizeof(int64_t);
*(int32_t *)buf = head->flag;
buf += sizeof(int32_t);
*(int32_t *)buf = len;
buf += sizeof(int32_t);
}
if (memcpy_s(buf, len, data, len) != EOK) {
LOG_ERR("memcpy_s failed");
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}
static void HandlePeerSyncDeviceInfo(AuthManager *auth, const AuthDataHead *head)
{
if (head->dataType == DATA_TYPE_SYNC) {
auth->status = SYNC_FINISH;
}
if (head->dataType == DATA_TYPE_SYNC && auth->encryptDevData != NULL) {
AuthHandlePeerSyncDeviceInfo(auth, auth->encryptDevData, auth->encryptLen);
SoftBusFree(auth->encryptDevData);
auth->encryptDevData = NULL;
}
}
int32_t AuthPostData(const AuthDataHead *head, const uint8_t *data, uint32_t len)
{
if (head == NULL || data == NULL) {
LOG_ERR("invalid parameter");
return SOFTBUS_INVALID_PARAM;
}
AuthManager *auth = NULL;
auth = AuthGetManagerByAuthId(head->authId, false);
if (auth == NULL) {
auth = AuthGetManagerByAuthId(head->authId, true);
if (auth == NULL) {
LOG_ERR("no match auth found, AuthPostData failed");
return SOFTBUS_ERR;
}
}
if (auth->option.type == CONNECT_TCP) {
if (AuthSocketSendData(auth, head, data, len) != SOFTBUS_OK) {
LOG_ERR("AuthSocketSendData failed");
return SOFTBUS_ERR;
}
} else {
PostDataInfo info;
uint32_t postDataLen;
info.side = auth->side;
info.connectionId = auth->connectionId;
postDataLen = sizeof(AuthDataInfo) + len;
info.connModule = MODULE_DEVICE_AUTH;
info.seq = GetSeq(auth->side);
char *connPostData = NULL;
char *buf = (char *)SoftBusMalloc(ConnGetHeadSize() + postDataLen);
if (buf == NULL) {
LOG_ERR("SoftBusMalloc failed");
return SOFTBUS_ERR;
}
connPostData = buf;
if (SetBufData(buf, auth, head, data, len) != SOFTBUS_OK) {
LOG_ERR("SetBufData failed");
SoftBusFree(connPostData);
return SOFTBUS_ERR;
}
LOG_INFO("auth start post data, authId is %lld, connectionId is %u, moduleId is %d, seq is %lld",
auth->authId, info.connectionId, info.connModule, info.seq);
if (PostDataByConn(&info, connPostData, postDataLen) != SOFTBUS_OK) {
LOG_ERR("PostDataByConn failed");
return SOFTBUS_ERR;
}
}
HandlePeerSyncDeviceInfo(auth, head);
return SOFTBUS_OK;
}
static cJSON *AuthPackDeviceInfo(const AuthManager *auth)
{
if (auth == NULL) {
return NULL;
}
cJSON *msg = cJSON_CreateObject();
if (msg == NULL) {
return NULL;
}
char uuid[UUID_BUF_LEN] = {0};
if (LnnGetLocalStrInfo(STRING_KEY_UUID, uuid, UUID_BUF_LEN) != SOFTBUS_OK) {
LOG_ERR("auth get uuid failed!");
cJSON_Delete(msg);
return NULL;
}
char udid[UDID_BUF_LEN] = {0};
if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, udid, UDID_BUF_LEN) != SOFTBUS_OK) {
LOG_ERR("auth get device udid failed!");
cJSON_Delete(msg);
return NULL;
}
if (auth->option.type == CONNECT_TCP && auth->side == CLIENT_SIDE_FLAG) {
if (AddStringToJsonObject(msg, CMD_TAG, CMD_GET_AUTH_INFO) == false) {
LOG_ERR("AddStringToJsonObject failed!");
cJSON_Delete(msg);
return NULL;
}
} else {
if (AddStringToJsonObject(msg, CMD_TAG, CMD_RET_AUTH_INFO) == false) {
LOG_ERR("AddStringToJsonObject failed!");
cJSON_Delete(msg);
return NULL;
}
}
if (!AddStringToJsonObject(msg, DATA_TAG, uuid) ||
!AddStringToJsonObject(msg, TE_DEVICE_ID_TAG, udid) ||
!AddNumberToJsonObject(msg, DATA_BUF_SIZE_TAG, PACKET_SIZE) ||
!AddNumberToJsonObject(msg, SOFTBUS_VERSION_INFO, auth->softbusVersion)) {
LOG_ERR("AddStringToJsonObject Fail.");
cJSON_Delete(msg);
return NULL;
}
return msg;
}
int32_t AuthSyncDeviceUuid(AuthManager *auth)
{
if (auth == NULL) {
LOG_ERR("invalid parameter");
return SOFTBUS_INVALID_PARAM;
}
AuthDataHead head;
(void)memset_s(&head, sizeof(head), 0, sizeof(head));
cJSON *obj = AuthPackDeviceInfo(auth);
if (obj == NULL) {
LOG_ERR("AuthPackDeviceInfo failed");
return SOFTBUS_ERR;
}
char *msgStr = cJSON_PrintUnformatted(obj);
if (msgStr == NULL) {
LOG_ERR("cJSON_PrintUnformatted failed");
cJSON_Delete(obj);
return SOFTBUS_ERR;
}
auth->status = IN_AUTH_PROGRESS;
if (auth->option.type == CONNECT_TCP) {
head.module = MODULE_TRUST_ENGINE;
} else {
head.dataType = DATA_TYPE_DEVICE_ID;
head.module = NONE;
}
head.authId = auth->authId;
head.flag = auth->side;
if (AuthPostData(&head, (uint8_t *)msgStr, strlen(msgStr) + 1) != SOFTBUS_OK) {
LOG_ERR("AuthPostData failed");
cJSON_free(msgStr);
cJSON_Delete(obj);
return SOFTBUS_ERR;
}
cJSON_free(msgStr);
cJSON_Delete(obj);
return SOFTBUS_OK;
}
static int32_t UnpackDeviceId(cJSON *msg, AuthManager *auth)
{
if (!GetJsonObjectStringItem(msg, DATA_TAG, auth->peerUuid, UUID_BUF_LEN)) {
LOG_ERR("auth get peer uuid failed");
return SOFTBUS_ERR;
}
if (!GetJsonObjectStringItem(msg, TE_DEVICE_ID_TAG, auth->peerUdid, UDID_BUF_LEN)) {
LOG_ERR("auth get peer udid failed");
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}
int32_t AuthUnpackDeviceInfo(AuthManager *auth, uint8_t *data)
{
if (auth == NULL || data == NULL) {
LOG_ERR("invalid parameter");
return SOFTBUS_INVALID_PARAM;
}
cJSON *msg = cJSON_Parse((char*)data);
if (msg == NULL) {
LOG_ERR("json parse failed.");
return SOFTBUS_ERR;
}
char cmd[CMD_TAG_LEN] = {0};
if (!GetJsonObjectStringItem(msg, CMD_TAG, cmd, CMD_TAG_LEN)) {
LOG_ERR("auth get cmd tag failed");
cJSON_Delete(msg);
return SOFTBUS_ERR;
}
if (auth->option.type == CONNECT_TCP && auth->side == SERVER_SIDE_FLAG) {
if (strncmp(cmd, CMD_GET_AUTH_INFO, strlen(CMD_GET_AUTH_INFO)) != 0) {
LOG_ERR("auth cmd tag error");
cJSON_Delete(msg);
return SOFTBUS_ERR;
}
} else {
if (strncmp(cmd, CMD_RET_AUTH_INFO, strlen(CMD_RET_AUTH_INFO)) != 0) {
LOG_ERR("auth cmd tag error");
cJSON_Delete(msg);
return SOFTBUS_ERR;
}
}
if (UnpackDeviceId(msg, auth) != SOFTBUS_OK) {
LOG_ERR("UnpackDeviceId failed");
cJSON_Delete(msg);
return SOFTBUS_ERR;
}
int32_t packetSize;
if (!GetJsonObjectNumberItem(msg, DATA_BUF_SIZE_TAG, &packetSize)) {
LOG_ERR("auth get packet size failed");
cJSON_Delete(msg);
return SOFTBUS_ERR;
}
int32_t peerVersion;
if (!GetJsonObjectNumberItem(msg, SOFTBUS_VERSION_INFO, &peerVersion)) {
auth->peerVersion = SOFT_BUS_OLD_V2;
} else {
auth->peerVersion = (SoftBusVersion)peerVersion;
}
cJSON_Delete(msg);
return SOFTBUS_OK;
}
char *AuthGenDeviceLevelParam(const AuthManager *auth, bool isClient)
{
if (auth == NULL) {
LOG_ERR("invalid parameter");
return NULL;
}
cJSON *msg = cJSON_CreateObject();
if (msg == NULL) {
return NULL;
}
if (!AddStringToJsonObject(msg, FIELD_PEER_CONN_DEVICE_ID, auth->peerUdid) ||
!AddStringToJsonObject(msg, FIELD_SERVICE_PKG_NAME, AUTH_APPID) ||
cJSON_AddBoolToObject(msg, FIELD_IS_CLIENT, isClient) == NULL ||
!AddNumberToJsonObject(msg, FIELD_KEY_LENGTH, SESSION_KEY_LENGTH)) {
LOG_ERR("AddStringToJsonObject Fail.");
cJSON_Delete(msg);
return NULL;
}
char *data = cJSON_PrintUnformatted(msg);
if (data == NULL) {
LOG_ERR("cJSON_PrintUnformatted failed");
}
cJSON_Delete(msg);
return data;
}
void AuthSendCloseAck(uint32_t connectionId)
{
LOG_INFO("auth finished, send close ack");
const char *closeData = "close ack";
uint32_t closeDataLen = strlen(closeData) + 1;
PostDataInfo info;
uint32_t postDataLen = sizeof(AuthDataInfo) + closeDataLen;
char *connPostData = NULL;
char *buf = (char *)SoftBusMalloc(ConnGetHeadSize() + postDataLen);
if (buf == NULL) {
LOG_ERR("SoftBusMalloc failed");
return;
}
connPostData = buf;
buf += ConnGetHeadSize();
*(int32_t *)buf = DATA_TYPE_CLOSE_ACK;
buf += sizeof(int32_t);
*(int32_t *)buf = NONE;
buf += sizeof(int32_t);
*(int64_t *)buf = 0;
buf += sizeof(int64_t);
*(int32_t *)buf = 0;
buf += sizeof(int32_t);
*(int32_t *)buf = closeDataLen;
buf += sizeof(int32_t);
if (memcpy_s(buf, closeDataLen, closeData, closeDataLen) != EOK) {
LOG_ERR("memcpy_s failed");
SoftBusFree(connPostData);
return;
}
info.side = (AuthSideFlag)0;
info.seq = 0;
info.connectionId = connectionId;
info.connModule = MODULE_DEVICE_AUTH;
if (PostDataByConn(&info, connPostData, postDataLen) != SOFTBUS_OK) {
LOG_ERR("PostDataByConn failed");
return;
}
}
void AuthTryCloseConnection(uint32_t connectionId)
{
(void)ConnDisconnectDevice(connectionId);
}
bool AuthOnTransmit(int64_t authId, const uint8_t *data, uint32_t len)
{
AuthManager *auth = NULL;
AuthDataHead head;
(void)memset_s(&head, sizeof(head), 0, sizeof(head));
auth = AuthGetManagerByAuthId(authId, false);
if (auth == NULL) {
auth = AuthGetManagerByAuthId(authId, true);
if (auth == NULL) {
LOG_ERR("no match auth found");
return false;
}
}
head.dataType = DATA_TYPE_AUTH;
head.module = AUTH_SDK;
head.authId = auth->authId;
head.flag = auth->side;
return AuthPostData(&head, data, len) == SOFTBUS_OK;
}
#ifdef __cplusplus
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,306 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "auth_sessionkey.h"
#include <securec.h>
#include "auth_common.h"
#include "softbus_errcode.h"
#include "softbus_log.h"
#include "softbus_mem_interface.h"
#ifdef __cplusplus
extern "C" {
#endif
static ListNode g_sessionKeyListHead;
void AuthSessionKeyListInit(void)
{
ListInit(&g_sessionKeyListHead);
}
void AuthSetLocalSessionKey(const NecessaryDevInfo *devInfo, const char *peerUdid,
const uint8_t *sessionKey, uint32_t sessionKeyLen)
{
uint32_t listSize = 0;
if (devInfo == NULL || peerUdid == NULL || sessionKey == NULL) {
LOG_ERR("invalid parameter");
return;
}
SessionKeyList *sessionKeyList = NULL;
ListNode *item = NULL;
LIST_FOR_EACH(item, &g_sessionKeyListHead) {
listSize++;
}
if (listSize == MAX_KEY_LIST_SIZE) {
item = GET_LIST_TAIL(&g_sessionKeyListHead);
sessionKeyList = LIST_ENTRY(item, SessionKeyList, node);
(void)memset_s(sessionKeyList->sessionKey, SESSION_KEY_LENGTH, 0, SESSION_KEY_LENGTH);
ListDelete(&sessionKeyList->node);
SoftBusFree(sessionKeyList);
sessionKeyList = NULL;
}
sessionKeyList = (SessionKeyList *)SoftBusMalloc(sizeof(SessionKeyList));
if (sessionKeyList == NULL) {
LOG_ERR("SoftBusMalloc failed");
return;
}
(void)memset_s(sessionKeyList, sizeof(SessionKeyList), 0, sizeof(SessionKeyList));
sessionKeyList->type = devInfo->type;
sessionKeyList->side = devInfo->side;
sessionKeyList->seq = devInfo->seq;
if (memcpy_s(sessionKeyList->peerUdid, UDID_BUF_LEN, peerUdid, strlen(peerUdid)) != EOK) {
LOG_ERR("memcpy_s failed");
SoftBusFree(sessionKeyList);
return;
}
if (memcpy_s(sessionKeyList->deviceKey, MAX_DEVICE_KEY_LEN, devInfo->deviceKey, devInfo->deviceKeyLen) != EOK) {
LOG_ERR("memcpy_s failed");
SoftBusFree(sessionKeyList);
return;
}
sessionKeyList->deviceKeyLen = devInfo->deviceKeyLen;
if (memcpy_s(sessionKeyList->sessionKey, SESSION_KEY_LENGTH, sessionKey, sessionKeyLen) != EOK) {
LOG_ERR("memcpy_s failed");
SoftBusFree(sessionKeyList);
return;
}
sessionKeyList->sessionKeyLen = sessionKeyLen;
ListNodeInsert(&g_sessionKeyListHead, &sessionKeyList->node);
}
bool AuthIsDeviceVerified(uint32_t type, const char *deviceKey, uint32_t deviceKeyLen)
{
if (deviceKey == NULL) {
LOG_ERR("invalid parameter");
return false;
}
SessionKeyList *sessionKeyList = NULL;
if (IsListEmpty(&g_sessionKeyListHead) == true) {
LOG_WARN("no session key in memory, need to verify device");
return false;
}
ListNode *item = NULL;
LIST_FOR_EACH(item, &g_sessionKeyListHead) {
sessionKeyList = LIST_ENTRY(item, SessionKeyList, node);
if (sessionKeyList->type == type && strncmp(sessionKeyList->deviceKey, deviceKey, deviceKeyLen) == 0) {
return true;
}
}
return false;
}
bool AuthIsSeqInKeyList(int32_t seq)
{
SessionKeyList *sessionKeyList = NULL;
if (IsListEmpty(&g_sessionKeyListHead) == true) {
LOG_WARN("no session key in memory");
return false;
}
ListNode *item = NULL;
LIST_FOR_EACH(item, &g_sessionKeyListHead) {
sessionKeyList = LIST_ENTRY(item, SessionKeyList, node);
if (sessionKeyList->seq == seq) {
return true;
}
}
return false;
}
static SessionKeyList *AuthGetLastSessionKey(const NecessaryDevInfo *devInfo)
{
if (devInfo == NULL) {
LOG_ERR("invalid parameter");
return NULL;
}
SessionKeyList *sessionKeyList = NULL;
if (IsListEmpty(&g_sessionKeyListHead) == true) {
LOG_ERR("no session key in memory");
return NULL;
}
ListNode *item = NULL;
LIST_FOR_EACH(item, &g_sessionKeyListHead) {
sessionKeyList = LIST_ENTRY(item, SessionKeyList, node);
if (sessionKeyList->type == devInfo->type &&
strncmp(sessionKeyList->deviceKey, devInfo->deviceKey, devInfo->deviceKeyLen) == 0) {
LOG_INFO("get last session key succ");
return sessionKeyList;
}
}
LOG_ERR("auth get last session key failed");
return NULL;
}
static SessionKeyList *GetSessionKeyByDevinfo(const NecessaryDevInfo *devInfo)
{
if (devInfo == NULL) {
LOG_ERR("invalid parameter");
return NULL;
}
SessionKeyList *sessionKeyList = NULL;
if (IsListEmpty(&g_sessionKeyListHead) == true) {
LOG_ERR("no session key in memory");
return NULL;
}
ListNode *item = NULL;
LIST_FOR_EACH(item, &g_sessionKeyListHead) {
sessionKeyList = LIST_ENTRY(item, SessionKeyList, node);
if (sessionKeyList->type == devInfo->type &&
sessionKeyList->side == devInfo->side &&
sessionKeyList->seq == devInfo->seq &&
strncmp(sessionKeyList->deviceKey, devInfo->deviceKey, devInfo->deviceKeyLen) == 0) {
LOG_INFO("get session key seccessfully.");
return sessionKeyList;
}
}
LOG_ERR("auth cannot find session key by seq");
return NULL;
}
int32_t AuthEncrypt(const ConnectOption *option, AuthSideFlag *side, uint8_t *data, uint32_t len, OutBuf *outBuf)
{
if (option == NULL || side == NULL || data == NULL ||
outBuf == NULL || outBuf->bufLen < (len + ENCRYPT_OVER_HEAD_LEN)) {
LOG_ERR("invalid parameter");
return SOFTBUS_INVALID_PARAM;
}
int32_t ret;
SessionKeyList *sessionKeyList = NULL;
NecessaryDevInfo devInfo = {0};
uint32_t outLen;
devInfo.type = option->type;
ret = AuthGetDeviceKey(devInfo.deviceKey, MAX_DEVICE_KEY_LEN, &(devInfo.deviceKeyLen), option);
if (ret != SOFTBUS_OK) {
LOG_ERR("AuthGetDeviceKey failed");
return SOFTBUS_ENCRYPT_ERR;
}
sessionKeyList = AuthGetLastSessionKey(&devInfo);
if (sessionKeyList == NULL) {
LOG_ERR("AuthGetLastSessionKey failed");
return SOFTBUS_ENCRYPT_ERR;
}
*side = sessionKeyList->side;
// add seq first
if (memcpy_s(outBuf->buf, sizeof(int32_t), &sessionKeyList->seq, sizeof(int32_t)) != EOK) {
LOG_ERR("memcpy_s failed");
return SOFTBUS_ENCRYPT_ERR;
}
AesGcmCipherKey cipherKey = {0};
cipherKey.keyLen = SESSION_KEY_LENGTH;
if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKeyList->sessionKey, sessionKeyList->sessionKeyLen) != EOK) {
LOG_ERR("memcpy_s failed");
return SOFTBUS_ENCRYPT_ERR;
}
if (SoftBusEncryptDataWithSeq(&cipherKey, data, len, outBuf->buf + MESSAGE_INDEX_LEN,
&outLen, sessionKeyList->seq) != SOFTBUS_OK) {
LOG_ERR("SoftBusEncryptDataWithSeq failed");
return SOFTBUS_ENCRYPT_ERR;
}
outBuf->outLen = outLen + MESSAGE_INDEX_LEN;
return SOFTBUS_OK;
}
int32_t AuthDecrypt(const ConnectOption *option, AuthSideFlag side, uint8_t *data, uint32_t len, OutBuf *outBuf)
{
if (option == NULL || data == NULL || outBuf == NULL || outBuf->bufLen < (len - ENCRYPT_OVER_HEAD_LEN)) {
LOG_ERR("invalid parameter");
return SOFTBUS_INVALID_PARAM;
}
SessionKeyList *sessionKeyList = NULL;
NecessaryDevInfo devInfo = {0};
devInfo.type = option->type;
int32_t ret = AuthGetDeviceKey(devInfo.deviceKey, MAX_DEVICE_KEY_LEN, &(devInfo.deviceKeyLen), option);
if (ret != SOFTBUS_OK) {
LOG_ERR("AuthGetDeviceKey failed");
return SOFTBUS_ENCRYPT_ERR;
}
int32_t seq;
if (memcpy_s(&seq, sizeof(int32_t), data, sizeof(int32_t)) != EOK) {
LOG_ERR("memcpy_s failed");
return SOFTBUS_ENCRYPT_ERR;
}
devInfo.seq = seq;
data += sizeof(int32_t);
len -= sizeof(int32_t);
devInfo.side = side;
sessionKeyList = GetSessionKeyByDevinfo(&devInfo);
if (sessionKeyList == NULL) {
LOG_ERR("GetSessionKeyByDevinfo failed");
return SOFTBUS_ENCRYPT_ERR;
}
AesGcmCipherKey cipherKey = {0};
cipherKey.keyLen = SESSION_KEY_LENGTH;
if (memcpy_s(cipherKey.key, SESSION_KEY_LENGTH, sessionKeyList->sessionKey, sessionKeyList->sessionKeyLen) != EOK) {
LOG_ERR("memcpy_s failed");
return SOFTBUS_ENCRYPT_ERR;
}
if (SoftBusDecryptDataWithSeq(&cipherKey, data, len, outBuf->buf,
&outBuf->outLen, sessionKeyList->seq) != SOFTBUS_OK) {
LOG_ERR("SoftBusDecryptDataWithSeq failed");
return SOFTBUS_ENCRYPT_ERR;
}
return SOFTBUS_OK;
}
uint32_t AuthGetEncryptHeadLen(void)
{
return ENCRYPT_OVER_HEAD_LEN;
}
void AuthClearSessionKeyByDeviceInfo(uint32_t type, const char *deviceKey, uint32_t deviceKeyLen)
{
SessionKeyList *sessionKeyList = NULL;
if (IsListEmpty(&g_sessionKeyListHead) == true) {
return;
}
ListNode *item = NULL;
ListNode *tmp = NULL;
LIST_FOR_EACH_SAFE(item, tmp, &g_sessionKeyListHead) {
sessionKeyList = LIST_ENTRY(item, SessionKeyList, node);
if (sessionKeyList->type == type && strncmp(sessionKeyList->deviceKey, deviceKey, deviceKeyLen) == 0) {
(void)memset_s(sessionKeyList->sessionKey, SESSION_KEY_LENGTH, 0, SESSION_KEY_LENGTH);
ListDelete(&sessionKeyList->node);
SoftBusFree(sessionKeyList);
sessionKeyList = NULL;
}
}
}
void AuthClearAllSessionKey(void)
{
SessionKeyList *sessionKeyList = NULL;
if (IsListEmpty(&g_sessionKeyListHead) == true) {
return;
}
ListNode *item = NULL;
ListNode *tmp = NULL;
LIST_FOR_EACH_SAFE(item, tmp, &g_sessionKeyListHead) {
sessionKeyList = LIST_ENTRY(item, SessionKeyList, node);
(void)memset_s(sessionKeyList->sessionKey, SESSION_KEY_LENGTH, 0, SESSION_KEY_LENGTH);
ListDelete(&sessionKeyList->node);
SoftBusFree(sessionKeyList);
sessionKeyList = NULL;
}
ListInit(&g_sessionKeyListHead);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,224 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "auth_socket.h"
#include <securec.h>
#include "auth_connection.h"
#include "bus_center_manager.h"
#include "softbus_base_listener.h"
#include "softbus_conn_manager.h"
#include "softbus_errcode.h"
#include "softbus_log.h"
#include "softbus_mem_interface.h"
#include "softbus_tcp_socket.h"
#define AUTH_DEFAULT_PORT (-1)
#ifdef __cplusplus
extern "C" {
#endif
static SoftbusBaseListener g_ethListener = {0};
int32_t HandleIpVerifyDevice(AuthManager *auth, const ConnectOption *option)
{
if (auth == NULL || option == NULL) {
LOG_ERR("invalid parameter");
return SOFTBUS_ERR;
}
char localIp[IP_MAX_LEN] = {0};
if (LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, localIp, IP_MAX_LEN) != SOFTBUS_OK) {
LOG_ERR("auth get local ip failed");
return SOFTBUS_ERR;
}
int fd = OpenTcpClientSocket(option->info.ipOption.ip, localIp, option->info.ipOption.port);
if (fd < 0) {
LOG_ERR("auth OpenTcpClientSocket failed");
return SOFTBUS_ERR;
}
auth->fd = fd;
if (AddTrigger(AUTH, fd, RW_TRIGGER) != SOFTBUS_OK) {
LOG_ERR("auth AddTrigger failed");
return SOFTBUS_ERR;
}
if (AuthSyncDeviceUuid(auth) != SOFTBUS_OK) {
LOG_ERR("AuthSyncDeviceUuid failed");
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}
static void AuthIpOnDataReceived(int32_t fd, const ConnPktHead *head, char *data, int len)
{
if (head == NULL || data == NULL) {
LOG_ERR("invalid parameter");
return;
}
AuthManager *auth = NULL;
auth = AuthGetManagerByFd(fd);
if (auth == NULL || auth->authId != head->seq) {
LOG_ERR("ip get auth failed");
return;
}
LOG_INFO("auth ip data module is %d", head->module);
switch (head->module) {
case MODULE_TRUST_ENGINE: {
HandleReceiveDeviceId(auth, (uint8_t *)data);
break;
}
case MODULE_AUTH_SDK: {
HandleReceiveAuthData(auth, head->module, (uint8_t *)data, head->len);
break;
}
case MODULE_AUTH_CONNECTION: {
AuthHandlePeerSyncDeviceInfo(auth, (uint8_t *)data, head->len);
break;
}
default: {
LOG_ERR("unknown data type");
break;
}
}
}
static int32_t AuthOnDataEvent(int32_t events, int32_t fd)
{
if (events != SOFTBUS_SOCKET_IN) {
return SOFTBUS_ERR;
}
ConnPktHead *head = NULL;
char *ipData = NULL;
uint32_t headSize = sizeof(ConnPktHead);
char *data = (char *)SoftBusMalloc(AUTH_MAX_DATA_LEN);
if (data == NULL) {
LOG_ERR("SoftBusMalloc failed");
return SOFTBUS_ERR;
}
ssize_t len = RecvTcpData(fd, data, AUTH_MAX_DATA_LEN, 0);
if (len < (int32_t)headSize) {
if (len == -1) {
LOG_ERR("RecvTcpData failed, DelTrigger");
(void)DelTrigger(AUTH, fd, RW_TRIGGER);
}
LOG_ERR("auth recv data len not correct, len %d", len);
SoftBusFree(data);
return SOFTBUS_ERR;
}
LOG_INFO("AuthOnDataEvent len is %d", len);
head = (ConnPktHead *)data;
LOG_INFO("auth recv eth data, head.len is %d, module = %d, flag = %d, seq = %lld",
head->len, head->module, head->flag, head->seq);
ipData = data + headSize;
AuthIpOnDataReceived(fd, head, ipData, head->len);
SoftBusFree(data);
return SOFTBUS_OK;
}
static int32_t AuthOnConnectEvent(int32_t events, int32_t cfd, const char *ip)
{
(void)events;
(void)ip;
(void)cfd;
LOG_INFO("in auth AuthOnConnectEvent");
return SOFTBUS_OK;
}
int32_t AuthSocketSendData(AuthManager *auth, const AuthDataHead *head, const uint8_t *data, uint32_t len)
{
if (auth == NULL || head == NULL || data == NULL) {
LOG_ERR("invalid parameter");
return SOFTBUS_ERR;
}
ConnPktHead ethHead;
uint32_t postDataLen;
char *connPostData = NULL;
ethHead.magic = MAGIC_NUMBER;
ethHead.module = head->module;
ethHead.seq = auth->authId;
ethHead.flag = auth->side;
ethHead.len = len;
postDataLen = sizeof(ConnPktHead) + len;
char *buf = (char *)SoftBusMalloc(postDataLen);
if (buf == NULL) {
LOG_ERR("SoftBusMalloc failed");
return SOFTBUS_ERR;
}
connPostData = buf;
if (memcpy_s(buf, sizeof(ConnPktHead), &ethHead, sizeof(ConnPktHead)) != EOK) {
LOG_ERR("memcpy_s failed");
SoftBusFree(connPostData);
return SOFTBUS_ERR;
}
buf += sizeof(ConnPktHead);
if (memcpy_s(buf, len, data, len) != EOK) {
LOG_ERR("memcpy_s failed");
SoftBusFree(connPostData);
return SOFTBUS_ERR;
}
LOG_INFO("auth start post eth data, authId is %lld, moduleId is %d, len is %u",
auth->authId, head->module, len);
ssize_t byte = SendTcpData(auth->fd, connPostData, postDataLen, 0);
if (byte != (ssize_t)postDataLen) {
LOG_ERR("SendTcpData failed");
SoftBusFree(connPostData);
return SOFTBUS_ERR;
}
SoftBusFree(connPostData);
return SOFTBUS_OK;
}
int32_t OpenAuthServer(void)
{
int32_t localPort;
g_ethListener.onConnectEvent = AuthOnConnectEvent;
g_ethListener.onDataEvent = AuthOnDataEvent;
if (SetSoftbusBaseListener(AUTH, &g_ethListener) != SOFTBUS_OK) {
LOG_ERR("auth SetSoftbusBaseListener failed");
return AUTH_ERROR_CODE;
}
char localIp[IP_MAX_LEN] = {0};
if (LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, localIp, IP_MAX_LEN) != SOFTBUS_OK) {
LOG_ERR("auth LnnGetLocalStrInfo failed");
return AUTH_ERROR_CODE;
}
localPort = StartBaseListener(AUTH, localIp, 0, SERVER_MODE);
if (localPort <= 0) {
LOG_ERR("auth StartBaseListener failed!");
return AUTH_ERROR_CODE;
}
return localPort;
}
void AuthCloseTcpFd(int32_t fd)
{
(void)DelTrigger(AUTH, fd, RW_TRIGGER);
CloseTcpFd(fd);
}
void CloseAuthServer(void)
{
LOG_INFO("close auth listener");
if (StopBaseListener(AUTH) != SOFTBUS_OK) {
LOG_ERR("auth StopBaseListener failed");
}
DestroyBaseListener(AUTH);
}
#ifdef __cplusplus
}
#endif

132
core/bus_center/BUILD.gn Executable file
View File

@ -0,0 +1,132 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/lite/config/component/lite_component.gni")
import("//foundation/communication/dsoftbus/dsoftbus.gni")
if (ohos_kernel_type == "liteos_m") {
static_library("softbus_bus_center") {
sources = [
"ipc/mini_system/lnn_bus_center_ipc.c",
"lnn/lane_hub/lane_manager/src/lnn_lane_info.c",
"lnn/lane_hub/lane_manager/src/lnn_lane_manager.c",
"lnn/lane_hub/lane_manager/src/lnn_smart_communication.c",
"lnn/net_builder/src/lnn_net_builder.c",
"lnn/net_builder/src/lnn_network_id.c",
"lnn/net_builder/src/lnn_state_machine.c",
"lnn/net_ledger/common/src/lnn_device_info.c",
"lnn/net_ledger/common/src/lnn_map.c",
"lnn/net_ledger/common/src/lnn_net_capability.c",
"lnn/net_ledger/common/src/lnn_node_info.c",
"lnn/net_ledger/distributed_ledger/src/lnn_distributed_net_ledger.c",
"lnn/net_ledger/local_ledger/src/lnn_local_net_ledger.c",
"lnn/net_ledger/sync_ledger/src/lnn_exchange_ledger_info.c",
"lnn/net_ledger/sync_ledger/src/lnn_sync_ledger_item_info.c",
"service/src/bus_center_event.c",
"service/src/bus_center_manager.c",
"utils/src/lnn_connection_addr_utils.c",
]
include_dirs = [
"interface",
"ipc/include",
"lnn/lane_hub/lane_manager/include",
"lnn/net_builder/include",
"lnn/net_ledger/common/include",
"lnn/net_ledger/distributed_ledger/include",
"lnn/net_ledger/local_ledger/include",
"lnn/net_ledger/sync_ledger/include",
"service/include",
"utils/include",
"$dsoftbus_root_path/core/adapter/bus_center/include",
"$dsoftbus_root_path/core/adapter/kernel/include",
"$dsoftbus_root_path/core/authentication/interface",
"$dsoftbus_root_path/core/common/include",
"$dsoftbus_root_path/core/common/inner_communication",
"$dsoftbus_root_path/core/common/message_handler/include",
"$dsoftbus_root_path/core/connection/interface",
"$dsoftbus_root_path/core/transmission/interface",
"$dsoftbus_root_path/interfaces/kits",
"$dsoftbus_root_path/interfaces/kits/bus_center",
"$dsoftbus_root_path/interfaces/kits/common",
"$dsoftbus_root_path/interfaces/kits/discovery",
"$dsoftbus_root_path/interfaces/kits/transport",
"//third_party/cJSON",
"//base/hiviewdfx/hilog_lite/interfaces/native/kits/hilog_lite",
]
cflags = [
"-Wall",
"-Werror",
"-fPIC",
"-fno-builtin",
"-std=c99",
]
}
} else {
shared_library("softbus_bus_center") {
sources = [
"ipc/mini_system/lnn_bus_center_ipc.c",
"lnn/lane_hub/lane_manager/src/lnn_lane_info.c",
"lnn/lane_hub/lane_manager/src/lnn_lane_manager.c",
"lnn/lane_hub/lane_manager/src/lnn_smart_communication.c",
"lnn/net_builder/src/lnn_net_builder.c",
"lnn/net_builder/src/lnn_network_id.c",
"lnn/net_builder/src/lnn_state_machine.c",
"lnn/net_ledger/common/src/lnn_device_info.c",
"lnn/net_ledger/common/src/lnn_map.c",
"lnn/net_ledger/common/src/lnn_net_capability.c",
"lnn/net_ledger/common/src/lnn_node_info.c",
"lnn/net_ledger/distributed_ledger/src/lnn_distributed_net_ledger.c",
"lnn/net_ledger/local_ledger/src/lnn_local_net_ledger.c",
"lnn/net_ledger/sync_ledger/src/lnn_exchange_ledger_info.c",
"lnn/net_ledger/sync_ledger/src/lnn_sync_ledger_item_info.c",
"service/src/bus_center_event.c",
"service/src/bus_center_manager.c",
"utils/src/lnn_connection_addr_utils.c",
]
include_dirs = [
"interface",
"ipc/include",
"lnn/lane_hub/lane_manager/include",
"lnn/net_builder/include",
"lnn/net_ledger/common/include",
"lnn/net_ledger/distributed_ledger/include",
"lnn/net_ledger/local_ledger/include",
"lnn/net_ledger/sync_ledger/include",
"service/include",
"utils/include",
"$dsoftbus_root_path/core/adapter/bus_center/include",
"$dsoftbus_root_path/core/adapter/kernel/include",
"$dsoftbus_root_path/core/authentication/interface",
"$dsoftbus_root_path/core/common/include",
"$dsoftbus_root_path/core/common/inner_communication",
"$dsoftbus_root_path/core/common/message_handler/include",
"$dsoftbus_root_path/core/connection/interface",
"$dsoftbus_root_path/core/transmission/interface",
"$dsoftbus_root_path/interfaces/kits",
"$dsoftbus_root_path/interfaces/kits/bus_center",
"$dsoftbus_root_path/interfaces/kits/common",
"$dsoftbus_root_path/interfaces/kits/discovery",
"$dsoftbus_root_path/interfaces/kits/transport",
"//third_party/bounds_checking_function/include",
"//third_party/cJSON",
]
cflags = [
"-Wall",
"-fPIC",
]
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BUS_CENTER_INFO_KEY_H
#define BUS_CENTER_INFO_KEY_H
#ifdef __cplusplus
extern "C" {
#endif
#define DEVICE_TYPE_BUF_LEN 17
#define NET_IF_NAME_LEN 20
#define IP_MAX_LEN 46
#define ID_MAX_LEN 72
#define VERSION_MAX_LEN 16
#define MAC_LEN 18
typedef enum {
STRING_KEY_BEGIN = 0,
STRING_KEY_HICE_VERSION = STRING_KEY_BEGIN,
STRING_KEY_DEV_UDID,
STRING_KEY_NETWORKID,
STRING_KEY_UUID,
STRING_KEY_DEV_TYPE,
STRING_KEY_DEV_NAME,
STRING_KEY_BT_MAC,
STRING_KEY_WLAN_IP,
STRING_KEY_NET_IF_NAME,
STRING_KEY_END,
NUM_KEY_BEGIN = 100,
NUM_KEY_SESSION_PORT = NUM_KEY_BEGIN,
NUM_KEY_AUTH_PORT,
NUM_KEY_PROXY_PORT,
NUM_KEY_NET_CAP,
NUM_KEY_DEV_TYPE_ID,
NUM_KEY_END,
} InfoKey;
#ifdef __cplusplus
}
#endif
#endif // BUS_CENTER_INFO_KEY_H

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BUS_CENTER_MANAGER_H
#define BUS_CENTER_MANAGER_H
#include <stdint.h>
#include "bus_center_info_key.h"
#include "softbus_bus_center.h"
#ifdef __cplusplus
extern "C" {
#endif
int32_t LnnGetRemoteStrInfo(const char *netWorkId, InfoKey key, char *info, uint32_t len);
int32_t LnnGetRemoteNumInfo(const char *netWorkId, InfoKey key, int32_t *info);
int32_t LnnSetLocalStrInfo(InfoKey key, const char *info);
int32_t LnnSetLocalNumInfo(InfoKey key, int32_t info);
int32_t LnnGetLocalStrInfo(InfoKey key, char *info, uint32_t len);
int32_t LnnGetLocalNumInfo(InfoKey key, int32_t *info);
int32_t LnnServerJoin(ConnectionAddr *addr);
int32_t LnnServerLeave(const char *networkId);
int32_t LnnGetAllOnlineNodeInfo(NodeBasicInfo **info, int32_t *infoNum);
int32_t LnnGetLocalDeviceInfo(NodeBasicInfo *info);
int32_t LnnGetNodeKeyInfo(const char *networkId, int key, uint8_t *info, int32_t infoLen);
int32_t LnnGetNetworkIdByUuid(const char *uuid, char *buf, uint32_t len);
#ifdef __cplusplus
}
#endif
#endif // BUS_CENTER_MANAGER_H

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LNN_BUS_CENTER_IPC_H
#define LNN_BUS_CENTER_IPC_H
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
int32_t LnnIpcServerJoin(const char *pkgName, void *addr, uint32_t addrTypeLen);
int32_t LnnIpcServerLeave(const char *pkgName, const char *networkId);
int32_t LnnIpcGetAllOnlineNodeInfo(const char *pkgName, void **info, uint32_t infoTypeLen, int *infoNum);
int32_t LnnIpcGetLocalDeviceInfo(const char *pkgName, void *info, uint32_t infoTypeLen);
int32_t LnnIpcGetNodeKeyInfo(const char *pkgName, const char *networkId, int key, unsigned char *buf, uint32_t len);
int32_t LnnIpcNotifyJoinResult(void *addr, uint32_t addrTypeLen, const char *networkId, int32_t retCode);
int32_t LnnIpcNotifyLeaveResult(const char *networkId, int32_t retCode);
int32_t LnnIpcNotifyOnlineState(bool isOnline, void *info, uint32_t infoTypeLen);
int32_t LnnIpcNotifyBasicInfoChanged(void *info, uint32_t infoTypeLen, int32_t type);
#ifdef __cplusplus
}
#endif
#endif /* LNN_L2_BUS_CENTER_IPC_H */

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "lnn_bus_center_ipc.h"
#include <securec.h>
#include <string.h>
#include "bus_center_manager.h"
#include "softbus_interface.h"
int32_t LnnIpcServerJoin(const char *pkgName, void *addr, uint32_t addrTypeLen)
{
(void)pkgName;
(void)addrTypeLen;
return LnnServerJoin((ConnectionAddr *)addr);
}
int32_t LnnIpcServerLeave(const char *pkgName, const char *networkId)
{
(void)pkgName;
return LnnServerLeave(networkId);
}
int32_t LnnIpcGetAllOnlineNodeInfo(const char *pkgName, void **info, uint32_t infoTypeLen, int *infoNum)
{
(void)pkgName;
(void)infoTypeLen;
return LnnGetAllOnlineNodeInfo((NodeBasicInfo **)info, infoNum);
}
int32_t LnnIpcGetLocalDeviceInfo(const char *pkgName, void *info, uint32_t infoTypeLen)
{
(void)pkgName;
(void)infoTypeLen;
return LnnGetLocalDeviceInfo((NodeBasicInfo *)info);
}
int32_t LnnIpcGetNodeKeyInfo(const char *pkgName, const char *networkId, int key, unsigned char *buf, uint32_t len)
{
(void)pkgName;
return LnnGetNodeKeyInfo(networkId, key, buf, len);
}
int32_t LnnIpcNotifyJoinResult(void *addr, uint32_t addrTypeLen, const char *networkId, int32_t retCode)
{
return GetClientProvideInterface()->onJoinLNNResult(NULL, addr, addrTypeLen, networkId, retCode);
}
int32_t LnnIpcNotifyLeaveResult(const char *networkId, int32_t retCode)
{
return GetClientProvideInterface()->onLeaveLNNResult(NULL, networkId, retCode);
}
int32_t LnnIpcNotifyOnlineState(bool isOnline, void *info, uint32_t infoTypeLen)
{
return GetClientProvideInterface()->onNodeOnlineStateChanged(isOnline, info, infoTypeLen);
}
int32_t LnnIpcNotifyBasicInfoChanged(void *info, uint32_t infoTypeLen, int32_t type)
{
return GetClientProvideInterface()->onNodeBasicInfoChanged(info, infoTypeLen, type);
}

View File

@ -0,0 +1,228 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "lnn_bus_center_ipc.h"
#include <cstring>
#include <mutex>
#include <securec.h>
#include <vector>
#include "bus_center_manager.h"
#include "lnn_connection_addr_utils.h"
#include "softbus_def.h"
#include "softbus_errcode.h"
#include "softbus_interface.h"
#include "softbus_log.h"
#include "softbus_permission.h"
struct JoinLnnRequestInfo {
char pkgName[PKG_NAME_SIZE_MAX];
ConnectionAddr addr;
};
struct LeaveLnnRequestInfo {
char pkgName[PKG_NAME_SIZE_MAX];
char networkId[NETWORK_ID_BUF_LEN];
};
static std::mutex g_lock;
static std::vector<JoinLnnRequestInfo *> g_joinLNNRequestInfo;
static std::vector<LeaveLnnRequestInfo *> g_leaveLNNRequestInfo;
static bool IsRepeatJoinLNNRequest(const char *pkgName, const ConnectionAddr *addr)
{
std::vector<JoinLnnRequestInfo *>::iterator iter;
for (iter = g_joinLNNRequestInfo.begin(); iter != g_joinLNNRequestInfo.end(); ++iter) {
if (strncmp(pkgName, (*iter)->pkgName, strlen(pkgName)) != 0) {
continue;
}
if (LnnIsSameConnectionAddr(addr, &(*iter)->addr)) {
return true;
}
}
return false;
}
static int32_t AddJoinLNNInfo(const char *pkgName, const ConnectionAddr *addr)
{
JoinLnnRequestInfo *info = new JoinLnnRequestInfo();
if (strncpy_s(info->pkgName, PKG_NAME_SIZE_MAX, pkgName, strlen(pkgName)) != EOK) {
LOG_ERR("copy pkgName fail");
delete info;
return SOFTBUS_ERR;
}
info->addr = *addr;
g_joinLNNRequestInfo.push_back(info);
return SOFTBUS_OK;
}
static bool IsRepeatLeaveLNNRequest(const char *pkgName, const char *networkId)
{
std::vector<LeaveLnnRequestInfo *>::iterator iter;
for (iter = g_leaveLNNRequestInfo.begin(); iter != g_leaveLNNRequestInfo.end(); ++iter) {
if (strncmp(pkgName, (*iter)->pkgName, strlen(pkgName)) != 0) {
continue;
}
if (strncmp(networkId, (*iter)->networkId, strlen(networkId)) == 0) {
return true;
}
}
return false;
}
static int32_t AddLeaveLNNInfo(const char *pkgName, const char *networkId)
{
LeaveLnnRequestInfo *info = new LeaveLnnRequestInfo();
if (strncpy_s(info->pkgName, PKG_NAME_SIZE_MAX, pkgName, strlen(pkgName)) != EOK) {
LOG_ERR("copy pkgName fail");
delete info;
return SOFTBUS_ERR;
}
if (strncpy_s(info->networkId, NETWORK_ID_BUF_LEN, networkId, strlen(networkId)) != EOK) {
LOG_ERR("copy networkId fail");
delete info;
return SOFTBUS_ERR;
}
g_leaveLNNRequestInfo.push_back(info);
return SOFTBUS_OK;
}
int32_t LnnIpcServerJoin(const char *pkgName, void *addr, uint32_t addrTypeLen)
{
if (CheckBusCenterPermission(pkgName) != true) {
LOG_ERR("ServerJoinLNN no permission!");
return SOFTBUS_PERMISSION_DENIED;
}
ConnectionAddr *connAddr = (ConnectionAddr *)addr;
(void)addrTypeLen;
if (pkgName == nullptr || connAddr == nullptr) {
LOG_ERR("parameters are nullptr!\n");
return SOFTBUS_ERR;
}
std::lock_guard<std::mutex> autoLock(g_lock);
if (IsRepeatJoinLNNRequest(pkgName, connAddr)) {
LOG_ERR("repeat join lnn request from: %s", pkgName);
return SOFTBUS_ERR;
}
int32_t ret = LnnServerJoin(connAddr);
if (ret == SOFTBUS_OK) {
ret = AddJoinLNNInfo(pkgName, connAddr);
}
return ret;
}
int32_t LnnIpcServerLeave(const char *pkgName, const char *networkId)
{
if (CheckBusCenterPermission(pkgName) != true) {
LOG_ERR("ServerLeaveLNN no permission!");
return SOFTBUS_PERMISSION_DENIED;
}
if (pkgName == nullptr || networkId == nullptr) {
LOG_ERR("parameters are nullptr!\n");
return SOFTBUS_ERR;
}
std::lock_guard<std::mutex> autoLock(g_lock);
if (IsRepeatLeaveLNNRequest(pkgName, networkId)) {
LOG_ERR("repeat leave lnn request from: %s", pkgName);
return SOFTBUS_ERR;
}
int32_t ret = LnnServerLeave(networkId);
if (ret == SOFTBUS_OK) {
ret = AddLeaveLNNInfo(pkgName, networkId);
}
return ret;
}
int32_t LnnIpcGetAllOnlineNodeInfo(const char *pkgName, void **info, uint32_t infoTypeLen, int *infoNum)
{
if (CheckBusCenterPermission(pkgName) != true) {
LOG_ERR("ServerGetAllOnlineNodeInfo no permission!");
return SOFTBUS_PERMISSION_DENIED;
}
(void)infoTypeLen;
return LnnGetAllOnlineNodeInfo((NodeBasicInfo **)info, infoNum);
}
int32_t LnnIpcGetLocalDeviceInfo(const char *pkgName, void *info, uint32_t infoTypeLen)
{
if (CheckBusCenterPermission(pkgName) != true) {
LOG_ERR("ServerGetLocalDeviceInfo no permission!");
return SOFTBUS_PERMISSION_DENIED;
}
(void)infoTypeLen;
return LnnGetLocalDeviceInfo((NodeBasicInfo *)info);
}
int32_t LnnIpcGetNodeKeyInfo(const char *pkgName, const char *networkId, int key, unsigned char *buf, uint32_t len)
{
if (CheckBusCenterPermission(pkgName) != true) {
LOG_ERR("ServerGetNodeKeyInfo no permission!");
return SOFTBUS_PERMISSION_DENIED;
}
return LnnGetNodeKeyInfo(networkId, key, buf, len);
}
int32_t LnnIpcNotifyJoinResult(void *addr, uint32_t addrTypeLen, const char *networkId, int32_t retCode)
{
if (addr == nullptr) {
return SOFTBUS_INVALID_PARAM;
}
ConnectionAddr *connAddr = (ConnectionAddr *)addr;
std::lock_guard<std::mutex> autoLock(g_lock);
std::vector<JoinLnnRequestInfo *>::iterator iter, iter2;
for (iter = g_joinLNNRequestInfo.begin(); iter != g_joinLNNRequestInfo.end();) {
if (!LnnIsSameConnectionAddr(connAddr, &(*iter)->addr)) {
++iter;
continue;
}
GetClientProvideInterface()->onJoinLNNResult((*iter)->pkgName, addr, addrTypeLen, networkId, retCode);
iter2 = iter;
iter = g_joinLNNRequestInfo.erase(iter);
delete *iter2;
}
return SOFTBUS_OK;
}
int32_t LnnIpcNotifyLeaveResult(const char *networkId, int32_t retCode)
{
if (networkId == nullptr) {
return SOFTBUS_INVALID_PARAM;
}
std::lock_guard<std::mutex> autoLock(g_lock);
std::vector<LeaveLnnRequestInfo *>::iterator iter, iter2;
for (iter = g_leaveLNNRequestInfo.begin(); iter != g_leaveLNNRequestInfo.end();) {
if (strncmp(networkId, (*iter)->networkId, strlen(networkId))) {
++iter;
continue;
}
GetClientProvideInterface()->onLeaveLNNResult((*iter)->pkgName, networkId, retCode);
iter2 = iter;
iter = g_leaveLNNRequestInfo.erase(iter);
delete *iter2;
}
return SOFTBUS_OK;
}
int32_t LnnIpcNotifyOnlineState(bool isOnline, void *info, uint32_t infoTypeLen)
{
return GetClientProvideInterface()->onNodeOnlineStateChanged(isOnline, info, infoTypeLen);
}
int32_t LnnIpcNotifyBasicInfoChanged(void *info, uint32_t infoTypeLen, int32_t type)
{
return GetClientProvideInterface()->onNodeBasicInfoChanged(info, infoTypeLen, type);
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LNN_LANE_INFO_H
#define LNN_LANE_INFO_H
#include <stdint.h>
#include "softbus_bus_center.h"
#ifdef __cplusplus
extern "C" {
#endif
#define LNN_REQUEST_MAX_LANE_NUM 1
/* Link type */
typedef enum {
LNN_LINK_TYPE_WLAN_5G = 0x0,
LNN_LINK_TYPE_WLAN_2P4G,
LNN_LINK_TYPE_BR,
LNN_LINK_TYPE_BUTT,
} LnnLaneLinkType;
typedef struct {
bool isProxy;
ConnectionAddr conOption;
} LnnLaneInfo;
typedef enum {
LNN_MESSAGE_LANE = 1,
LNN_BYTES_LANE,
LNN_FILE_LANE,
LNN_STREAM_LANE,
LNN_LANE_PROPERTY_BUTT,
} LnnLaneProperty;
ConnectionAddrType LnnGetLaneType(int32_t laneId);
void LnnReleaseLane(int32_t laneId);
const LnnLaneInfo *LnnGetConnection(int32_t laneId);
bool LnnUpdateLaneRemoteInfo(const char *netWorkId, LnnLaneLinkType type, bool mode);
void LnnLanesInit(void);
#ifdef __cplusplus
}
#endif
#endif /* LNN_LANE_INFO_H */

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LNN_LANE_MANAGER_H
#define LNN_LANE_MANAGER_H
#include <stdint.h>
#include "lnn_lane_info.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct LnnLanesObject LnnLanesObject;
LnnLanesObject *LnnRequestLanesObject(const char *netWorkId, LnnLaneProperty prop, uint32_t laneNum);
void LnnReleaseLanesObject(LnnLanesObject *lanesObject);
uint32_t LnnGetLaneNum(LnnLanesObject *lanesObject);
int32_t LnnGetLaneId(LnnLanesObject *lanesObject, uint32_t num);
#ifdef __cplusplus
}
#endif
#endif /* LNN_LANE_MANAGER_H */

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LNN_SMART_COMMUNICATION_H
#define LNN_SMART_COMMUNICATION_H
#include <stdint.h>
#include "lnn_lane_info.h"
#ifdef __cplusplus
extern "C" {
#endif
int32_t LnnGetRightLane(const char *netWorkId, LnnLaneProperty prop);
#ifdef __cplusplus
}
#endif
#endif /* LNN_SMART_COMMUNICATION_H */

View File

@ -0,0 +1,166 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "lnn_lane_info.h"
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include "bus_center_info_key.h"
#include "bus_center_manager.h"
#include "softbus_log.h"
typedef struct {
LnnLaneInfo laneInfo;
int32_t laneId;
bool isUse;
pthread_mutex_t lock;
} LaneInfoImpl;
static LaneInfoImpl g_lanes[LNN_LINK_TYPE_BUTT];
void LnnLanesInit(void)
{
uint32_t firstLaneId = LNN_LINK_TYPE_WLAN_5G;
for (uint32_t i = firstLaneId; i < LNN_LINK_TYPE_BUTT; i++) {
g_lanes[i].laneId = firstLaneId++;
(void)pthread_mutex_init(&g_lanes[i].lock, NULL);
}
}
static bool IsValidLaneId(int32_t laneId)
{
if (laneId < LNN_LINK_TYPE_WLAN_5G || laneId >= LNN_LINK_TYPE_BUTT) {
LOG_ERR("param error. laneId = %d", laneId);
return false;
}
if (pthread_mutex_lock(&g_lanes[laneId].lock) != 0) {
LOG_ERR("lock failed");
return false;
}
if (!g_lanes[laneId].isUse) {
LOG_ERR("The laneId cannot be used. laneId: %d.", laneId);
(void)pthread_mutex_unlock(&g_lanes[laneId].lock);
return false;
}
(void)pthread_mutex_unlock(&g_lanes[laneId].lock);
return true;
}
void LnnReleaseLane(int32_t laneId)
{
if (laneId < LNN_LINK_TYPE_WLAN_5G || laneId >= LNN_LINK_TYPE_BUTT) {
return;
}
if (pthread_mutex_lock(&g_lanes[laneId].lock) != 0) {
LOG_ERR("lock failed");
return;
}
g_lanes[laneId].isUse = false;
(void)pthread_mutex_unlock(&g_lanes[laneId].lock);
}
ConnectionAddrType LnnGetLaneType(int32_t laneId)
{
if (!IsValidLaneId(laneId)) {
return CONNECTION_ADDR_MAX;
}
if (laneId == LNN_LINK_TYPE_WLAN_5G || laneId == LNN_LINK_TYPE_WLAN_2P4G) {
return CONNECTION_ADDR_WLAN;
}
return laneId;
}
const LnnLaneInfo *LnnGetConnection(int32_t laneId)
{
if (!IsValidLaneId(laneId)) {
return NULL;
}
return &g_lanes[laneId].laneInfo;
}
static bool SetPeerIPInfo(const char *netWorkId, LnnLaneLinkType type, bool mode)
{
int32_t ret;
int32_t port;
ret = LnnGetRemoteStrInfo(netWorkId, STRING_KEY_WLAN_IP,
g_lanes[type].laneInfo.conOption.info.ip.ip, IP_STR_MAX_LEN);
if (ret < 0 || strncmp(g_lanes[type].laneInfo.conOption.info.ip.ip, "127.0.0.1", strlen("127.0.0.1")) == 0) {
LOG_ERR("LnnGetRemoteStrInfo error.");
return false;
}
if (mode) {
ret = LnnGetRemoteNumInfo(netWorkId, NUM_KEY_PROXY_PORT, &port);
} else {
ret = LnnGetRemoteNumInfo(netWorkId, NUM_KEY_AUTH_PORT, &port);
}
if (ret < 0) {
LOG_ERR("LnnGetRemoteNumInfo error.");
return false;
}
g_lanes[type].laneInfo.conOption.type = CONNECTION_ADDR_WLAN;
g_lanes[type].laneInfo.conOption.info.ip.port = (uint16_t)port;
g_lanes[type].laneInfo.isProxy = mode;
return true;
}
static bool SetPeerMacInfo(const char *netWorkId, LnnLaneLinkType type, bool mode)
{
int32_t ret;
ret = LnnGetRemoteStrInfo(netWorkId, STRING_KEY_BT_MAC, g_lanes[type].laneInfo.conOption.info.br.brMac, BT_MAC_LEN);
if (ret < 0) {
LOG_ERR("LnnGetRemoteStrInfo error.");
return false;
}
if (type == LNN_LINK_TYPE_BR) {
g_lanes[type].laneInfo.conOption.type = CONNECTION_ADDR_BR;
g_lanes[type].laneInfo.isProxy = mode;
}
return true;
}
bool LnnUpdateLaneRemoteInfo(const char *netWorkId, LnnLaneLinkType type, bool mode)
{
if (netWorkId == NULL || type >= LNN_LINK_TYPE_BUTT || type < LNN_LINK_TYPE_WLAN_5G) {
LOG_ERR("param error. type = %d", type);
return false;
}
if (!g_lanes[type].isUse) {
if (pthread_mutex_lock(&g_lanes[type].lock) != 0) {
LOG_ERR("lock failed");
return false;
}
if (g_lanes[type].isUse) {
(void)pthread_mutex_unlock(&g_lanes[type].lock);
return true;
}
}
bool ret = false;
switch (type) {
case LNN_LINK_TYPE_WLAN_5G:
case LNN_LINK_TYPE_WLAN_2P4G: // the WLAN_5G and the WLAN_2P4G is same process.
ret = SetPeerIPInfo(netWorkId, type, mode);
break;
case LNN_LINK_TYPE_BR:
ret = SetPeerMacInfo(netWorkId, type, true);
break;
default:
break;
}
g_lanes[type].isUse = true;
(void)pthread_mutex_unlock(&g_lanes[type].lock);
return ret;
}

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "lnn_lane_manager.h"
#include <securec.h>
#include "lnn_smart_communication.h"
#include "softbus_errcode.h"
#include "softbus_log.h"
#include "softbus_mem_interface.h"
struct LnnLanesObject {
LnnLaneProperty prop;
uint32_t laneNum;
int32_t laneId[0];
};
LnnLanesObject *LnnRequestLanesObject(const char *netWorkId, LnnLaneProperty prop, uint32_t laneNum)
{
if (prop < LNN_MESSAGE_LANE || prop >= LNN_LANE_PROPERTY_BUTT || netWorkId == NULL ||
laneNum == 0 || laneNum > LNN_REQUEST_MAX_LANE_NUM) {
LOG_ERR("param error, prop = %d, laneNum = %u", prop, laneNum);
return NULL;
}
uint32_t memLen = sizeof(LnnLanesObject) + sizeof(int32_t) * laneNum;
LnnLanesObject *lanesObject = (LnnLanesObject *)SoftBusMalloc(memLen);
if (lanesObject == NULL) {
LOG_ERR("SoftBusMalloc error.");
return NULL;
}
(void)memset_s(lanesObject, memLen, 0, memLen);
lanesObject->prop = prop;
lanesObject->laneNum = laneNum;
for (uint32_t i = 0; i < laneNum; i++) {
int32_t laneId = LnnGetRightLane(netWorkId, prop);
if (laneId < 0) {
LOG_ERR("LnnGetRightLane error. laneId = %d", laneId);
SoftBusFree(lanesObject);
return NULL;
}
lanesObject->laneId[i] = laneId;
}
return lanesObject;
}
void LnnReleaseLanesObject(LnnLanesObject *lanesObject)
{
if (lanesObject == NULL) {
return;
}
for (uint32_t i = 0; i < lanesObject->laneNum; i++) {
LnnReleaseLane(lanesObject->laneId[i]);
}
SoftBusFree(lanesObject);
}
int32_t LnnGetLaneId(LnnLanesObject *lanesObject, uint32_t num)
{
if (lanesObject == NULL || num >= lanesObject->laneNum) {
LOG_ERR("param error. num = %u", num);
return SOFTBUS_ERR;
}
return lanesObject->laneId[num];
}
uint32_t LnnGetLaneNum(LnnLanesObject *lanesObject)
{
if (lanesObject == NULL) {
LOG_ERR("param error");
return SOFTBUS_ERR;
}
return lanesObject->laneNum;
}

View File

@ -0,0 +1,135 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "lnn_smart_communication.h"
#include "bus_center_info_key.h"
#include "bus_center_manager.h"
#include "lnn_lane_info.h"
#include "lnn_net_capability.h"
#include "softbus_errcode.h"
#include "softbus_log.h"
static int32_t GetLaneOf5GWlan(const char *netWorkId, LnnLaneProperty prop);
static int32_t GetLaneOf2P4GWlan(const char *netWorkId, LnnLaneProperty prop);
static int32_t GetLaneOfBR(const char *netWorkId, LnnLaneProperty prop);
typedef int32_t (*GetLaneByType)(const char *netWorkId, LnnLaneProperty prop);
typedef struct {
uint8_t preferredLinkNum;
GetLaneByType getLaneByType[LNN_LINK_TYPE_BUTT];
} SmartLaneMapEntry;
SmartLaneMapEntry g_smartLaneMap[LNN_LANE_PROPERTY_BUTT] = {
[LNN_MESSAGE_LANE] = {3, {GetLaneOf5GWlan, GetLaneOf2P4GWlan, GetLaneOfBR}}, // the preferredLinkNum is 3
[LNN_BYTES_LANE] = {3, {GetLaneOf5GWlan, GetLaneOf2P4GWlan, GetLaneOfBR}}, // the preferredLinkNum is 3
[LNN_FILE_LANE] = {3, {GetLaneOf5GWlan, GetLaneOf2P4GWlan, GetLaneOfBR}}, // the preferredLinkNum is 3
[LNN_STREAM_LANE] = {2, {GetLaneOf5GWlan, GetLaneOf2P4GWlan}}, // the preferredLinkNum is 2
};
int32_t LnnGetRightLane(const char *netWorkId, LnnLaneProperty prop)
{
if (prop < LNN_MESSAGE_LANE || prop >= LNN_LANE_PROPERTY_BUTT || netWorkId == NULL) {
LOG_ERR("param error. prop = %d", prop);
return SOFTBUS_ERR;
}
int32_t lane = SOFTBUS_ERR;
for (uint8_t i = 0; i < g_smartLaneMap[prop].preferredLinkNum; i++) {
lane = g_smartLaneMap[prop].getLaneByType[i](netWorkId, prop);
if (lane >= 0) {
return lane;
}
}
return lane;
}
static bool IsProxyPort(LnnLaneProperty prop, LnnLaneLinkType type)
{
if (prop == LNN_MESSAGE_LANE &&
(type == LNN_LINK_TYPE_WLAN_5G || type == LNN_LINK_TYPE_WLAN_2P4G || type == LNN_LINK_TYPE_BR)) {
return true;
}
return false;
}
static bool GetNumInfo(const char *netWorkId, int32_t *local, int32_t *remote)
{
int32_t ret;
ret = LnnGetLocalNumInfo(NUM_KEY_NET_CAP, local);
if (ret < 0 || *local < 0) {
LOG_ERR("LnnGetLocalNumInfo error. ret = %d, local = %d", ret, *local);
return false;
}
ret = LnnGetRemoteNumInfo(netWorkId, NUM_KEY_NET_CAP, remote);
if (ret < 0 || *remote < 0) {
LOG_ERR("LnnGetRemoteNumInfo error. ret = %d, remote = %d", ret, *remote);
return false;
}
return true;
}
static int32_t GetLaneOf5GWlan(const char* netWorkId, LnnLaneProperty prop)
{
int32_t local, remote;
if (!GetNumInfo(netWorkId, &local, &remote)) {
LOG_ERR("GetNumInfo error.");
return SOFTBUS_ERR;
}
if (((local & (1 << BIT_WIFI_5G)) || (local & (1 << BIT_ETH))) &&
((remote & (1 << BIT_WIFI_5G)) || (remote & (1 << BIT_ETH)))) {
if (LnnUpdateLaneRemoteInfo(netWorkId, LNN_LINK_TYPE_WLAN_5G, IsProxyPort(prop, LNN_LINK_TYPE_WLAN_5G))) {
return LNN_LINK_TYPE_WLAN_5G; // the LNN_LINK_TYPE_WLAN_5G is laneID.
}
}
LOG_INFO("Can't support WIFI WLAN 5G.");
return SOFTBUS_ERR;
}
static int32_t GetLaneOf2P4GWlan(const char* netWorkId, LnnLaneProperty prop)
{
int32_t local, remote;
if (!GetNumInfo(netWorkId, &local, &remote)) {
LOG_ERR("GetLaneOf2P4GWlan error.");
return SOFTBUS_ERR;
}
if (((local & (1 << BIT_WIFI_24G)) || (local & (1 << BIT_WIFI_5G)) || (local & (1 << BIT_ETH))) &&
((remote & (1 << BIT_WIFI_24G)) || (remote & (1 << BIT_WIFI_5G)) || (remote & (1 << BIT_ETH)))) {
if (LnnUpdateLaneRemoteInfo(netWorkId, LNN_LINK_TYPE_WLAN_2P4G, IsProxyPort(prop, LNN_LINK_TYPE_WLAN_2P4G))) {
return LNN_LINK_TYPE_WLAN_2P4G;
}
}
LOG_INFO("Can't support WIFI WLAN 2P4G.");
return SOFTBUS_ERR;
}
static int32_t GetLaneOfBR(const char *netWorkId, LnnLaneProperty prop)
{
int32_t local, remote;
if (!GetNumInfo(netWorkId, &local, &remote)) {
LOG_ERR("GetLaneOfBR error.");
return SOFTBUS_ERR;
}
if ((local & (1 << BIT_BR)) && (remote & (1 << BIT_BR))) {
if (LnnUpdateLaneRemoteInfo(netWorkId, LNN_LINK_TYPE_BR, IsProxyPort(prop, LNN_LINK_TYPE_BR))) {
return LNN_LINK_TYPE_BR;
}
}
LOG_INFO("Can't support BR.");
return SOFTBUS_ERR;
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LNN_CONN_TYPE_HOOK_H
#define LNN_CONN_TYPE_HOOK_H
#include <stdint.h>
#include "lnn_state_machine.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
NETWORK_TYPE_ACTIVE,
NETWORK_TYPE_SELF
} NetworkType;
#define JOIN_DISCOVERY_TIMEOUT_LEN (60 * 1000UL)
typedef struct {
int32_t (*preprocess)(const ConnectionAddr *addr, FsmStateMachine *fsm, NetworkType type);
void (*shutdown)(const ConnectionAddr *addr);
} ConnTypeHook;
void LnnInitIpHook(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LNN_NET_BUILDER_H
#define LNN_NET_BUILDER_H
#include <stdint.h>
#include "lnn_sync_ledger_item_info.h"
#include "lnn_conn_type_hook.h"
#include "softbus_bus_center.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
NODE_TYPE_C,
NODE_TYPE_L
} NodeType;
typedef enum {
FSM_MSG_TYPE_JOIN_LNN,
FSM_MSG_TYPE_DISCOVERY_TIMEOUT,
FSM_MSG_TYPE_AUTH_DONE,
FSM_MSG_TYPE_SYNC_DEVICE_INFO,
FSM_MSG_TYPE_SYNC_DEVICE_INFO_DONE,
FSM_MSG_TYPE_EST_HEART_BEAT,
FSM_MSG_TYPE_LEAVE_LNN,
FSM_MSG_TYPE_NOT_TRUSTED,
FSM_MSG_TYPE_PEER_INFO_CHANGE,
FSM_MSG_TYPE_JOIN_LNN_TIMEOUT,
FSM_MSG_TYPE_SYNC_OFFLINE_DONE,
FSM_MSG_TYPE_SEND_OFFLINE_MESSAGE,
FSM_MSG_TYPE_LEAVE_LNN_TIMEOUT,
} StateMessageType;
int32_t LnnInitNetBuilder(void);
void LnnDeinitNetBuilder(void);
int32_t LnnRegisterConnTypeHook(ConnectionAddrType type, const ConnTypeHook *hook);
int32_t LnnNotifyPeerDevInfoChanged(const char *udid, SyncItemInfo *info);
int32_t LnnNotifySyncOfflineFinish(void);
int32_t LnnNotifySendOfflineMessage(int32_t id);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LNN_NETWORK_ID_H
#define LNN_NETWORK_ID_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
int32_t LnnGenLocalNetworkId(char *networkId, int32_t len);
int32_t LnnGenLocalUuid(char *uuid, int32_t len);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LNN_STATE_MACHINE_H
#define LNN_STATE_MACHINE_H
#include <stdint.h>
#include "common_list.h"
#include "message_handler.h"
#ifdef __cplusplus
extern "C" {
#endif
#define FSM_FLAG_RUNNING 0x1
typedef void (*StateEnterFunc)(void);
typedef void (*StateExitFunc)(void);
typedef bool (*StateProcessFunc)(int32_t msgType, void *para);
typedef struct {
ListNode list;
StateEnterFunc enter;
StateProcessFunc process;
StateExitFunc exit;
} FsmState;
struct tagFsmStateMachine;
typedef void (*FsmDinitCallback)(struct tagFsmStateMachine *fsm);
typedef struct tagFsmStateMachine {
FsmState *curState;
uint32_t flag;
ListNode stateList;
SoftBusLooper *looper;
SoftBusHandler handler;
FsmDinitCallback deinitCallback;
} FsmStateMachine;
int32_t LnnFsmInit(FsmStateMachine *fsm, char *name, FsmDinitCallback cb);
int32_t LnnFsmDeinit(FsmStateMachine *fsm);
int32_t LnnFsmAddState(FsmStateMachine *fsm, FsmState *state);
int32_t LnnFsmStart(FsmStateMachine *fsm, FsmState *initialState);
int32_t LnnFsmStop(FsmStateMachine *fsm);
int32_t LnnFsmPostMessage(FsmStateMachine *fsm, int32_t msgType, void *data);
int32_t LnnFsmPostMessageDelay(FsmStateMachine *fsm, int32_t msgType,
void *data, uint64_t delayMillis);
int32_t LnnFsmRemoveMessage(FsmStateMachine *fsm, int32_t msgType);
int32_t LnnFsmTransactState(FsmStateMachine *fsm, FsmState *state);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,434 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <arpa/inet.h>
#include <netinet/in.h>
#include <net/if.h>
#include <securec.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include "auth_socket.h"
#include "bus_center_manager.h"
#include "disc_interface.h"
#include "lnn_connect_info.h"
#include "lnn_net_builder.h"
#include "lnn_state_machine.h"
#include "softbus_conn_interface.h"
#include "softbus_errcode.h"
#include "softbus_log.h"
#include "softbus_mem_interface.h"
#include "trans_tcp_direct_listener.h"
#define WLAN_IF_NAME_PRE "wlan"
#define ETH_IF_NAME_PRE "eth"
#define IF_COUNT_MAX 16
#define LNN_DISC_CAPABILITY "ddmpCapability"
#define LNN_PUBLISH_ID 0
#define LNN_SUBSCRIBE_ID 0
#define IP_DEFAULT_PORT 0
typedef struct {
FsmStateMachine *fsm;
ConnectionAddrType type;
} IpHookStatus;
typedef struct {
char *ifName;
uint32_t ifNameLen;
} IfInfo;
static IpHookStatus g_status = {
.fsm = NULL,
.type = CONNECTION_ADDR_WLAN,
};
static int32_t GetNetworkIfList(int32_t fd, struct ifconf *conf, struct ifreq *buf, uint32_t len)
{
if (fd < 0 || conf == NULL || buf == NULL) {
LOG_ERR("fail: parameter error!");
return SOFTBUS_INVALID_PARAM;
}
conf->ifc_len = len;
conf->ifc_buf = (char *)buf;
if (ioctl(fd, SIOCGIFCONF, (char*)conf) < 0) {
LOG_ERR("ioctl fail, errno = %d", errno);
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}
static int32_t GetNetworkIfIp(int32_t fd, struct ifreq *req, char *ip, uint32_t len)
{
if (fd < 0 || req == NULL || ip == NULL) {
LOG_ERR("fail: parameter error!");
return SOFTBUS_INVALID_PARAM;
}
if (ioctl(fd, SIOCGIFFLAGS, (char*)req) < 0) {
LOG_ERR("ioctl SIOCGIFFLAGS fail, errno = %d", errno);
return SOFTBUS_ERR;
}
if (!((uint16_t)req->ifr_flags & IFF_UP)) {
LOG_ERR("interface is not up");
return SOFTBUS_ERR;
}
/* get IP of this interface */
if (ioctl(fd, SIOCGIFADDR, (char*)req) < 0) {
LOG_ERR("ioctl SIOCGIFADDR fail, errno = %d", errno);
return SOFTBUS_ERR;
}
if (strcpy_s(ip, len, inet_ntoa(((struct sockaddr_in *)&(req->ifr_addr))->sin_addr)) != EOK) {
LOG_ERR("STR COPY ERROR!");
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}
static char *GetIfNamePre(ConnectionAddrType type)
{
if (type == CONNECTION_ADDR_WLAN) {
return WLAN_IF_NAME_PRE;
} else if (type == CONNECTION_ADDR_ETH) {
return ETH_IF_NAME_PRE;
} else {
LOG_ERR("type = %d, error!", type);
return NULL;
}
}
static int32_t GetLocalIp(char *ip, uint32_t len, IfInfo *info, ConnectionAddrType type)
{
LOG_INFO("type = %d", type);
if (ip == NULL || len < IP_MAX_LEN || info == NULL || info->ifName == NULL) {
LOG_ERR("fail : para error!");
return SOFTBUS_INVALID_PARAM;
}
char *pre = GetIfNamePre(type);
if (pre == NULL) {
return SOFTBUS_INVALID_PARAM;
}
uint32_t preLen = strlen(pre);
int32_t fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
return SOFTBUS_ERR;
}
struct ifreq req[IF_COUNT_MAX];
struct ifconf conf;
int32_t ret = GetNetworkIfList(fd, &conf, req, sizeof(req));
if (ret != SOFTBUS_OK) {
LOG_ERR("GetNetworkIfList fail!");
close(fd);
return SOFTBUS_ERR;
}
int32_t num = conf.ifc_len / sizeof(struct ifreq);
ret = SOFTBUS_ERR;
LOG_INFO("network interface num = %d", num);
for (int32_t i = 0; (i < num) && (i < IF_COUNT_MAX); i++) {
LOG_INFO("network interface name is %s", req[i].ifr_name);
if (strlen(req[i].ifr_name) < preLen) {
continue;
}
if (memcmp(pre, req[i].ifr_name, preLen) == 0) {
if (GetNetworkIfIp(fd, &req[i], ip, len) == SOFTBUS_OK) {
(void)strncpy_s(info->ifName, info->ifNameLen, req[i].ifr_name, strlen(req[i].ifr_name));
LOG_INFO("GetNetworkIfIp ok!");
ret = SOFTBUS_OK;
}
break;
}
}
close(fd);
return ret;
}
static void DeviceFound(const DeviceInfo *device)
{
ConnectionAddr *para = NULL;
if (device == NULL) {
LOG_ERR("DeviceFound error!");
return;
}
LOG_INFO("DeviceFound! type = %d", g_status.type);
para = (ConnectionAddr *)SoftBusCalloc(sizeof(ConnectionAddr));
if (para == NULL) {
LOG_ERR("malloc init message fail");
return;
}
para->type = g_status.type;
para->info.ip.port = device->addr[0].port;
if (strncpy_s(para->info.ip.ip, IP_STR_MAX_LEN, device->addr[0].addr, strlen(device->addr[0].addr)) != EOK) {
LOG_ERR("STR ERROR!");
SoftBusFree(para);
return;
}
if (g_status.fsm != NULL) {
LOG_INFO("PostMessageToFsm!");
(void)LnnFsmRemoveMessage(g_status.fsm, FSM_MSG_TYPE_DISCOVERY_TIMEOUT);
if (LnnFsmPostMessage(g_status.fsm, FSM_MSG_TYPE_JOIN_LNN, para) != SOFTBUS_OK) {
LOG_ERR("LnnFsmPostMessage FSM_MSG_TYPE_JOIN_LNN error!");
SoftBusFree(para);
}
} else {
LOG_ERR("DeviceFound don't post to fsm!");
SoftBusFree(para);
}
return;
}
static DiscInnerCallback g_discCb = {
.OnDeviceFound = DeviceFound,
};
static int32_t EnableCoapDisc(void)
{
LOG_INFO("EnableCoapDisc begin");
int32_t ret = DiscSetDiscoverCallback(MODULE_LNN, &g_discCb);
if (ret != SOFTBUS_OK) {
LOG_ERR("DiscSetDiscoverCallback error!");
return SOFTBUS_ERR;
}
PublishInnerInfo publishInfo = {
.publishId = LNN_PUBLISH_ID,
.medium = COAP,
.freq = HIGH,
.capability = LNN_DISC_CAPABILITY,
.capabilityData = (unsigned char *)LNN_DISC_CAPABILITY,
.dataLen = strlen(LNN_DISC_CAPABILITY) + 1,
};
LOG_INFO("DiscStartScan!");
ret = DiscStartScan(MODULE_LNN, &publishInfo);
if (ret != SOFTBUS_OK) {
LOG_ERR("DiscStartScan fail!");
return SOFTBUS_ERR;
}
SubscribeInnerInfo subscribeInfo = {
.subscribeId = LNN_SUBSCRIBE_ID,
.medium = COAP,
.freq = HIGH,
.isSameAccount = false,
.isWakeRemote = false,
.capability = LNN_DISC_CAPABILITY,
.capabilityData = (unsigned char *)LNN_DISC_CAPABILITY,
.dataLen = strlen(LNN_DISC_CAPABILITY) + 1,
};
LOG_INFO("DiscStartAdvertise!");
ret = DiscStartAdvertise(MODULE_LNN, &subscribeInfo);
if (ret != SOFTBUS_OK) {
LOG_ERR("DiscStartAdvertise fail!");
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}
static int32_t UpdateLocalIp(ConnectionAddrType type)
{
char ipAddr[IP_MAX_LEN] = {0};
char ifName[NET_IF_NAME_LEN] = {0};
IfInfo info = {
.ifName = ifName,
.ifNameLen = NET_IF_NAME_LEN,
};
int32_t ret = GetLocalIp(ipAddr, IP_MAX_LEN, &info, type);
if (ret != SOFTBUS_OK) {
LOG_ERR("GetLocalIp error!");
return SOFTBUS_ERR;
}
ret = LnnSetLocalStrInfo(STRING_KEY_WLAN_IP, ipAddr);
if (ret != SOFTBUS_OK) {
LOG_ERR("LnnSetLocalStrInfo error!");
return SOFTBUS_ERR;
}
(void)LnnSetLocalStrInfo(STRING_KEY_NET_IF_NAME, ifName);
return SOFTBUS_OK;
}
static int32_t UpdateProxyPort(void)
{
LocalListenerInfo listenerInfo = {0};
char ipAddr[IP_MAX_LEN] = {0};
listenerInfo.type = CONNECT_TCP;
listenerInfo.info.ipListenerInfo.port = 0;
if (LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, ipAddr, IP_MAX_LEN) != SOFTBUS_OK) {
LOG_ERR("LnnGetLocalStrInfo fail!");
return SOFTBUS_ERR;
}
if (strncpy_s(listenerInfo.info.ipListenerInfo.ip, IP_LEN, ipAddr, strlen(ipAddr)) != EOK) {
LOG_ERR("fail:strncpy_s fail!");
return SOFTBUS_MEM_ERR;
}
int32_t port = ConnStartLocalListening(&listenerInfo);
return LnnSetLocalNumInfo(NUM_KEY_PROXY_PORT, port);
}
static int32_t UpdateSessionPort(void)
{
char ipAddr[IP_MAX_LEN] = {0};
if (LnnGetLocalStrInfo(STRING_KEY_WLAN_IP, ipAddr, IP_MAX_LEN) != SOFTBUS_OK) {
LOG_ERR("LnnGetLocalStrInfo fail!");
return SOFTBUS_ERR;
}
int32_t port = TransTdcStartSessionListener(ipAddr, 0);
return LnnSetLocalNumInfo(NUM_KEY_SESSION_PORT, port);
}
static int32_t UpdateAuthPort(void)
{
int32_t port = OpenAuthServer();
return LnnSetLocalNumInfo(NUM_KEY_AUTH_PORT, port);
}
static void CloseAuthPort(void)
{
CloseAuthServer();
(void)LnnSetLocalNumInfo(NUM_KEY_AUTH_PORT, IP_DEFAULT_PORT);
return;
}
static void CloseSessionPort(void)
{
TransTdcStopSessionListener();
(void)LnnSetLocalNumInfo(NUM_KEY_SESSION_PORT, IP_DEFAULT_PORT);
return;
}
static void CloseProxyPort(void)
{
LocalListenerInfo listenerInfo = {0};
listenerInfo.type = CONNECT_TCP;
if (ConnStopLocalListening(&listenerInfo) != SOFTBUS_OK) {
LOG_ERR("ConnStopLocalListening fail!");
}
(void)LnnSetLocalNumInfo(NUM_KEY_PROXY_PORT, IP_DEFAULT_PORT);
return;
}
static int32_t OpenIpLink(void)
{
int32_t ret = UpdateAuthPort();
if (ret != SOFTBUS_OK) {
LOG_ERR("UpdateSeesionPort fail!");
return SOFTBUS_ERR;
}
ret = UpdateSessionPort();
if (ret != SOFTBUS_OK) {
LOG_ERR("UpdateSeesionPort fail!");
CloseAuthPort();
return SOFTBUS_ERR;
}
ret = UpdateProxyPort();
if (ret != SOFTBUS_OK) {
LOG_ERR("UpdateProxyPort fail!");
CloseAuthPort();
CloseSessionPort();
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}
static void CloseIpLink(void)
{
CloseAuthPort();
CloseSessionPort();
CloseProxyPort();
}
static void CloseCoapDisc(void)
{
if (DiscUnpublish(MODULE_LNN, LNN_PUBLISH_ID) != SOFTBUS_OK) {
LOG_ERR("DiscUnpublish fail!");
}
if (DiscStopAdvertise(MODULE_LNN, LNN_SUBSCRIBE_ID) != SOFTBUS_OK) {
LOG_ERR("DiscStopAdvertise fail!");
}
return;
}
static int32_t IpPreprocess(const ConnectionAddr *addr, FsmStateMachine *fsm, NetworkType networkType)
{
if (addr == NULL || fsm == NULL) {
LOG_ERR("para error!");
return SOFTBUS_ERR;
}
ConnectionAddrType type = addr->type;
if (UpdateLocalIp(type) != SOFTBUS_OK) {
LOG_ERR("UpdateLocalIp fail!");
return SOFTBUS_ERR;
}
if (OpenIpLink() != SOFTBUS_OK) {
LOG_ERR("OpenIpLink fail!");
return SOFTBUS_ERR;
}
if (networkType == NETWORK_TYPE_ACTIVE) {
ConnectionAddrType *para = (ConnectionAddrType *)SoftBusCalloc(sizeof(ConnectionAddrType));
if (para == NULL) {
LOG_ERR("malloc init message fail");
return SOFTBUS_ERR;
}
*para = type;
if (LnnFsmPostMessageDelay(fsm, FSM_MSG_TYPE_DISCOVERY_TIMEOUT, para, JOIN_DISCOVERY_TIMEOUT_LEN)
!= SOFTBUS_OK) {
SoftBusFree(para);
return SOFTBUS_ERR;
}
}
if (EnableCoapDisc() != SOFTBUS_OK) {
LOG_ERR("EnableCoapDisc fail!");
return SOFTBUS_ERR;
}
LOG_INFO("IpPreprocess ok!");
g_status.fsm = fsm;
g_status.type = type;
return SOFTBUS_OK;
}
static void IpShutdown(const ConnectionAddr *addr)
{
(void)addr;
(void)LnnSetLocalStrInfo(STRING_KEY_WLAN_IP, LOCAL_IP);
CloseIpLink();
CloseCoapDisc();
g_status.fsm = NULL;
return;
}
static ConnTypeHook g_hook = {
.preprocess = IpPreprocess,
.shutdown = IpShutdown,
};
void LnnInitIpHook(void)
{
LnnRegisterConnTypeHook(CONNECTION_ADDR_WLAN, &g_hook);
LnnRegisterConnTypeHook(CONNECTION_ADDR_ETH, &g_hook);
if (UpdateLocalIp(CONNECTION_ADDR_ETH) == SOFTBUS_OK) {
LOG_INFO("update eth ip success");
return;
}
if (UpdateLocalIp(CONNECTION_ADDR_WLAN) == SOFTBUS_OK) {
LOG_INFO("update wlan ip success");
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "lnn_network_id.h"
#include <stdbool.h>
#include <stdlib.h>
#include <securec.h>
#include "bus_center_info_key.h"
#include "softbus_bus_center.h"
#include "softbus_errcode.h"
#include "softbus_log.h"
#include "softbus_mem_interface.h"
#include "softbus_utils.h"
static int32_t GenerateRandomId(char *id, int32_t len)
{
uint32_t hexLen = len / HEXIFY_UNIT_LEN;
uint8_t *hexId = NULL;
hexId = (uint8_t *)SoftBusMalloc(hexLen);
if (hexId == NULL) {
LOG_ERR("malloc fail");
return SOFTBUS_MEM_ERR;
}
if (GenerateRandomArray(hexId, hexLen) != SOFTBUS_OK) {
// HUKS will ensure the id is global uniq
LOG_ERR("generate random array fail");
SoftBusFree(hexId);
return SOFTBUS_ERR;
}
if (ConvertBytesToHexString(id, len, hexId, hexLen) != SOFTBUS_OK) {
LOG_ERR("convert bytes to hex string fail");
SoftBusFree(hexId);
return SOFTBUS_ERR;
}
SoftBusFree(hexId);
return SOFTBUS_OK;
}
int32_t LnnGenLocalNetworkId(char *networkId, int32_t len)
{
if (networkId == NULL || len < NETWORK_ID_BUF_LEN) {
return SOFTBUS_INVALID_PARAM;
}
if (GenerateRandomId(networkId, NETWORK_ID_BUF_LEN) != SOFTBUS_OK) {
LOG_ERR("generate network id fail");
return SOFTBUS_ERR;
}
networkId[len - 1] = '\0';
return SOFTBUS_OK;
}
int32_t LnnGenLocalUuid(char *uuid, int32_t len)
{
static bool isGenerated = false;
static char localUuid[UUID_BUF_LEN] = {0};
if (uuid == NULL || len < UUID_BUF_LEN) {
return SOFTBUS_INVALID_PARAM;
}
if (isGenerated == false) {
if (GenerateRandomId(localUuid, UUID_BUF_LEN) != SOFTBUS_OK) {
LOG_ERR("generate network id fail");
return SOFTBUS_ERR;
}
isGenerated = true;
}
if (strncpy_s(uuid, len, localUuid, UUID_BUF_LEN) != EOK) {
LOG_ERR("copy uuid id fail");
return SOFTBUS_ERR;
}
return SOFTBUS_OK;
}

View File

@ -0,0 +1,373 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "lnn_state_machine.h"
#include <stdlib.h>
#include <securec.h>
#include "softbus_errcode.h"
#include "softbus_log.h"
#include "softbus_mem_interface.h"
#define FSM_CTRL_MSG_START 0
#define FSM_CTRL_MSG_CHANGE_STATE 1
#define FSM_CTRL_MSG_DATA 2
#define FSM_CTRL_MSG_STOP 3
#define FSM_CTRL_MSG_DEINIT 4
typedef struct {
FsmStateMachine *fsm;
void *obj;
} FsmCtrlMsgObj;
static bool IsDuplicateState(FsmStateMachine *fsm, FsmState *state)
{
struct ListNode *item = NULL;
LIST_FOR_EACH(item, &fsm->stateList) {
if (item == (struct ListNode *)state) {
return true;
}
}
return false;
}
static void FreeFsmHandleMsg(SoftBusMessage *msg)
{
if (msg != NULL) {
if (msg->obj != NULL) {
SoftBusFree(msg->obj);
}
SoftBusFree(msg);
}
}
static void FreeFsmHandleMsgObj(FsmCtrlMsgObj *ctrlMsgObj)
{
if (ctrlMsgObj == NULL) {
return;
}
if (ctrlMsgObj->obj != NULL) {
SoftBusFree(ctrlMsgObj->obj);
ctrlMsgObj->obj = NULL;
}
}
static SoftBusMessage *CreateFsmHandleMsg(FsmStateMachine *fsm,
int32_t what, uint64_t arg1, uint64_t arg2, void *obj)
{
SoftBusMessage *msg = NULL;
FsmCtrlMsgObj *ctrlMsgObj = NULL;
msg = SoftBusCalloc(sizeof(*msg));
if (msg == NULL) {
return NULL;
}
msg->what = what;
msg->arg1 = arg1;
msg->arg2 = arg2;
msg->handler = &fsm->handler;
msg->FreeMessage = FreeFsmHandleMsg;
ctrlMsgObj = SoftBusMalloc(sizeof(*ctrlMsgObj));
if (ctrlMsgObj == NULL) {
SoftBusFree(msg);
return NULL;
}
ctrlMsgObj->fsm = fsm;
ctrlMsgObj->obj = obj;
msg->obj = ctrlMsgObj;
return msg;
}
static void ProcessStartMessage(SoftBusMessage *msg)
{
FsmCtrlMsgObj *ctrlMsgObj = msg->obj;
FsmStateMachine *fsm = NULL;
FsmState *state = NULL;
if (ctrlMsgObj == NULL) {
return;
}
fsm = ctrlMsgObj->fsm;
state = (FsmState *)ctrlMsgObj->obj;
if (fsm == NULL || state == NULL) {
return;
}
if (fsm->curState != NULL || (fsm->flag & FSM_FLAG_RUNNING) != 0) {
LOG_ERR("unexpected state");
return;
}
if (IsDuplicateState(fsm, state) == true) {
fsm->curState = state;
if (fsm->curState->enter != NULL) {
fsm->curState->enter();
}
fsm->flag |= FSM_FLAG_RUNNING;
}
}
static void ProcessChangeStateMessage(SoftBusMessage *msg)
{
FsmCtrlMsgObj *ctrlMsgObj = msg->obj;
FsmStateMachine *fsm = NULL;
FsmState *state = NULL;
if (ctrlMsgObj == NULL) {
return;
}
fsm = ctrlMsgObj->fsm;
state = (FsmState *)ctrlMsgObj->obj;
if (fsm == NULL || state == NULL) {
return;
}
if (fsm->curState == NULL || (fsm->flag & FSM_FLAG_RUNNING) == 0) {
LOG_ERR("unexpected state");
return;
}
if (IsDuplicateState(fsm, state)) {
if (fsm->curState->exit != NULL) {
fsm->curState->exit();
}
fsm->curState = state;
if (fsm->curState->enter != NULL) {
fsm->curState->enter();
}
}
}
static void ProcessDataMessage(SoftBusMessage *msg)
{
FsmCtrlMsgObj *ctrlMsgObj = msg->obj;
FsmStateMachine *fsm = NULL;
if (ctrlMsgObj == NULL) {
return;
}
fsm = ctrlMsgObj->fsm;
if (fsm == NULL) {
return;
}
if (fsm->curState == NULL || (fsm->flag & FSM_FLAG_RUNNING) == 0) {
LOG_ERR("unexpected state");
return;
}
if (fsm->curState->process != NULL) {
fsm->curState->process((int32_t)msg->arg1, ctrlMsgObj->obj);
}
}
static void ProcessStopMessage(SoftBusMessage *msg)
{
FsmCtrlMsgObj *ctrlMsgObj = msg->obj;
FsmStateMachine *fsm = NULL;
if (ctrlMsgObj == NULL) {
return;
}
fsm = ctrlMsgObj->fsm;
if (fsm == NULL) {
return;
}
if (fsm->curState == NULL || (fsm->flag & FSM_FLAG_RUNNING) == 0) {
LOG_ERR("unexpected state");
return;
}
fsm->curState = NULL;
fsm->flag &= ~FSM_FLAG_RUNNING;
}
static void ProcessDeinitMessage(SoftBusMessage *msg)
{
FsmCtrlMsgObj *ctrlMsgObj = msg->obj;
FsmStateMachine *fsm = NULL;
if (ctrlMsgObj == NULL) {
return;
}
fsm = ctrlMsgObj->fsm;
if (fsm == NULL) {
return;
}
if (fsm->deinitCallback != NULL) {
fsm->deinitCallback(fsm);
}
}
static void FsmStateMsgHandler(SoftBusMessage *msg)
{
if (msg == NULL) {
return;
}
if (msg->what != FSM_CTRL_MSG_DATA) {
LOG_INFO("process fsm ctrl msg: %d", msg->what);
}
switch (msg->what) {
case FSM_CTRL_MSG_START:
ProcessStartMessage(msg);
break;
case FSM_CTRL_MSG_CHANGE_STATE:
ProcessChangeStateMessage(msg);
break;
case FSM_CTRL_MSG_DATA:
ProcessDataMessage(msg);
break;
case FSM_CTRL_MSG_STOP:
ProcessStopMessage(msg);
break;
case FSM_CTRL_MSG_DEINIT:
ProcessDeinitMessage(msg);
break;
default:
break;
}
}
static int32_t PostMessageToFsm(FsmStateMachine *fsm, int32_t what, uint64_t arg1, uint64_t arg2, void *obj)
{
SoftBusMessage *msg = NULL;
msg = CreateFsmHandleMsg(fsm, what, arg1, arg2, obj);
if (msg == NULL) {
LOG_ERR("create fsm handle msg fail");
return SOFTBUS_ERR;
}
fsm->looper->PostMessage(fsm->looper, msg);
return SOFTBUS_OK;
}
/* remove message when return 0, else return 1 */
static int32_t RemoveMessageFunc(const SoftBusMessage *msg, void *para)
{
int32_t msgType;
if (msg == NULL || para == NULL) {
return 1;
}
msgType = (int32_t)para;
if (msg->what == FSM_CTRL_MSG_DATA && (int32_t)msg->arg1 == msgType) {
LOG_INFO("remove fsm data message: %d", msgType);
FreeFsmHandleMsgObj((FsmCtrlMsgObj *)msg->obj);
return 0;
}
return 1;
}
int32_t LnnFsmInit(FsmStateMachine *fsm, char *name, FsmDinitCallback cb)
{
if (fsm == NULL || name == NULL) {
return SOFTBUS_INVALID_PARAM;
}
(void)memset_s(fsm, sizeof(*fsm), 0, sizeof(*fsm));
ListInit(&fsm->stateList);
fsm->looper = GetLooper(LOOP_TYPE_DEFAULT);
if (fsm->looper == NULL) {
LOG_ERR("get looper fail");
return SOFTBUS_ERR;
}
fsm->handler.name = name;
fsm->handler.HandleMessage = FsmStateMsgHandler;
fsm->handler.looper = fsm->looper;
fsm->deinitCallback = cb;
return SOFTBUS_OK;
}
int32_t LnnFsmDeinit(FsmStateMachine *fsm)
{
if (fsm == NULL || fsm->looper == NULL) {
return SOFTBUS_INVALID_PARAM;
}
return PostMessageToFsm(fsm, FSM_CTRL_MSG_DEINIT, 0, 0, NULL);
}
int32_t LnnFsmAddState(FsmStateMachine *fsm, FsmState *state)
{
if (fsm == NULL || fsm->looper == NULL || state == NULL) {
return SOFTBUS_INVALID_PARAM;
}
if (IsDuplicateState(fsm, state)) {
LOG_ERR("already exist state");
return SOFTBUS_ERR;
}
ListInit(&state->list);
ListAdd(&fsm->stateList, &state->list);
return SOFTBUS_OK;
}
int32_t LnnFsmStart(FsmStateMachine *fsm, FsmState *initialState)
{
if (fsm == NULL || fsm->looper == NULL || initialState == NULL) {
return SOFTBUS_INVALID_PARAM;
}
return PostMessageToFsm(fsm, FSM_CTRL_MSG_START, 0, 0, initialState);
}
int32_t LnnFsmStop(FsmStateMachine *fsm)
{
if (fsm == NULL || fsm->looper == NULL) {
return SOFTBUS_INVALID_PARAM;
}
return PostMessageToFsm(fsm, FSM_CTRL_MSG_STOP, 0, 0, NULL);
}
int32_t LnnFsmPostMessage(FsmStateMachine *fsm, int32_t msgType, void *data)
{
if (fsm == NULL || fsm->looper == NULL) {
return SOFTBUS_INVALID_PARAM;
}
return PostMessageToFsm(fsm, FSM_CTRL_MSG_DATA, msgType, 0, data);
}
int32_t LnnFsmPostMessageDelay(FsmStateMachine *fsm, int32_t msgType,
void *data, uint64_t delayMillis)
{
SoftBusMessage *msg = NULL;
if (fsm == NULL || fsm->looper == NULL) {
return SOFTBUS_INVALID_PARAM;
}
msg = CreateFsmHandleMsg(fsm, FSM_CTRL_MSG_DATA, msgType, 0, data);
if (msg == NULL) {
LOG_ERR("create fsm handle msg fail");
return SOFTBUS_ERR;
}
fsm->looper->PostMessageDelay(fsm->looper, msg, delayMillis);
return SOFTBUS_OK;
}
int32_t LnnFsmRemoveMessage(FsmStateMachine *fsm, int32_t msgType)
{
if (fsm == NULL || fsm->looper == NULL) {
return SOFTBUS_INVALID_PARAM;
}
fsm->looper->RemoveMessageCustom(fsm->looper, &fsm->handler,
RemoveMessageFunc, (void *)msgType);
return SOFTBUS_OK;
}
int32_t LnnFsmTransactState(FsmStateMachine *fsm, FsmState *state)
{
if (fsm == NULL || fsm->looper == NULL || state == NULL) {
return SOFTBUS_INVALID_PARAM;
}
return PostMessageToFsm(fsm, FSM_CTRL_MSG_CHANGE_STATE, 0, 0, state);
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LNN_CONNECT_INFO_H
#define LNN_CONNECT_INFO_H
#include <stdint.h>
#include "bus_center_info_key.h"
#ifdef __cplusplus
extern "C" {
#endif
#define LOCAL_IP "127.0.0.1"
#define DEFAULT_IP ""
#define DEFAULT_MAC ""
typedef struct {
char netIfName[NET_IF_NAME_LEN];
char deviceIp[IP_MAX_LEN];
char macAddr[MAC_LEN];
int authPort;
int proxyPort;
int sessionPort;
} ConnectInfo;
#ifdef __cplusplus
}
#endif
#endif // LNN_CONNECT_INFO_H

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef LNN_DEVICE_INFO_H
#define LNN_DEVICE_INFO_H
#include <stdint.h>
#include "bus_center_info_key.h"
#include "softbus_bus_center.h"
#include "bus_center_adapter.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TYPE_UNKNOW_ID 0x00
#define TYPE_PHONE_ID 0x0E
#define TYPE_PAD_ID 0x11
#define TYPE_TV_ID 0x9C
#define TYPE_PC_ID 0x0C
#define TYPE_AUDIO_ID 0x0A
#define TYPE_CAR_ID 0x83
#define TYPE_WATCH_ID 0x6D
#define TYPE_IPCAMERA_ID 0X08
typedef struct {
char deviceName[DEVICE_NAME_BUF_LEN];
char deviceUdid[UDID_BUF_LEN];
uint8_t deviceTypeId;
} DeviceBasicInfo;
int32_t LnnSetDeviceName(DeviceBasicInfo *info, const char *name);
const char *LnnGetDeviceName(const DeviceBasicInfo *info);
int32_t LnnGetDeviceTypeId(const DeviceBasicInfo *info, uint8_t *typeId);
int32_t LnnConvertDeviceTypeToId(const char *deviceType, uint8_t *typeId);
char *LnnConvertIdToDeviceType(uint8_t typeId);
#ifdef __cplusplus
}
#endif
#endif // LNN_DEVICE_INFO_H

Some files were not shown because too many files have changed in this diff Show More