initialize

This commit is contained in:
罗明
2025-08-08 14:54:09 +08:00
parent 912a352a9a
commit 89b8c2719e
31 changed files with 6071 additions and 2 deletions
+4
View File
@@ -0,0 +1,4 @@
**/.vscode
**/.cache
**/cjpm.lock
**/.idea
+69 -2
View File
@@ -1,3 +1,70 @@
# connectivity_connectivity_cangjie_wrapper
# DSoftBus
WLAN服务能力、蓝牙服务等模块仓颉封装层
## Introduction
The DSoftBus subsystem provides the following communication capabilities for OpenHarmony:
- WLAN: basic WLAN functions, peer-to-peer (P2P) connection, and WLAN notification, enabling your application to communicate with other devices through a WLAN.
- Bluetooth: classic Bluetooth and Bluetooth Low Energy (BLE).
- DSoftBus: distributed communications between near-field devices, and device discovery, connection setup, networking, and data transmission capabilities regardless of communication modes.
- Remote procedure call (RPC): communications between processes on a device or across devices.
## Architecture
**Figure 1** DSoftBus architecture
![](figures/dsoftbus.png)
## Directory Structure
The DSoftBus directory structure is as follows:
```
foundation/communication/connectivity_cangjie_api
├── ohos # Cangjie DSoftBus code
├── kit # Cangjie kit code
├── figures # architecture pictures
```
## Constraints
The devices must be in the same LAN.
## Usage
### RPC
In an RPC, the client process obtains the proxy of the process that provides the service (server). Through the proxy, the two processes communicate with each other.
1. Implement the server capabilities.
2. The client obtains a proxy of the server. This proxy provides the same capabilities as the server. To call a method of the server, the client only needs to call the same method of the proxy.
3. The server processes the received request and returns the result to the proxy via the driver.
4. The proxy returns the result to the client.
### DSoftBus
- Networking
1. The server starts and obtains the list of online devices.
2. Register a listener for device status changes.
3. Obtain the device ID, name, and type.
4. Obtain detailed information about the device, such as the device type, networking type, and device capability.
5. Delete the registered listener when the process exits.
- Transmission
1. Creates a socket instance based on information, such as the socket name and caller bundle name.
2. The server starts listening for the socket, and the client binds the socket.
3. Send data after the bind is successful.
4. Close the socket when it is not used.
## Repositories Involved
**DSoftBus subsystem**
connectivity_cangjie_api
+69
View File
@@ -0,0 +1,69 @@
# 分布式软总线子系统
## 简介
分布式软总线子系统旨在为OpenHarmony系统提供的通信相关的能力,包括:WLAN服务能力、蓝牙服务能力、软总线、进程间通信RPCRemote Procedure Call)等通信能力。
WLAN服务:为用户提供WLAN基础功能、P2Ppeer-to-peer)功能和WLAN消息通知的相应服务,让应用可以通过WLAN和其他设备互联互通。
蓝牙服务:为应用提供传统蓝牙以及低功耗蓝牙相关功能和服务。
软总线:为应用和系统提供近场设备间分布式通信的能力,提供不区分通信方式的设备发现,连接,组网和传输功能。
进程间通信:提供不区分设备内或设备间的进程间通信能力。
## 系统架构
**图 1** 分布式软总线子系统架构图
![](figures/zh-cn_image_0000001162307895.png)
## 目录
分布式软总线子系统主要代码目录结构如下:
```
foundation/communication/connectivity_cangjie_api
├── ohos # 仓颉分布式软总线接口实现
├── kit # 仓颉kit化代码
├── figures # 存放readme中的架构图
```
## 约束
- 组网限制:必须确保设备在同一个局域网中。
## 使用说明
### 进程间通信
在使用RPC时,请求服务的一端进程可获取提供服务一端所在进程的代理 (Proxy),并通过此代理读写数据来实现进程间的数据通信,其详细过程如下:
1. 实现服务端及其提供的能力。
2. 请求服务的一端会建立一个服务提供端的代理对象,这个代理对象具备和服务提供端一样的功能,若想访问服务提供端中的某个方法,只需要访问代理对象中对应的方法即可。
3. 服务提供端处理接收到的请求,处理完之后通过驱动返回处理结果给代理对象。
4. 代理对象将请求结果进一步返回给请求服务端。
### 软总线
- 组网
1. 服务启动之后,获取已经在线的设备列表。
2. 注册上下线监听,通过回调通知感知设备列表变化。
3. 获取设备的Id、设备名称、设备类型。
4. 获取指定设备的设备类型,组网类型,设备能力等更多信息。
5. 进程退出时,删除上下线监听。
- 传输
1. 根据Socket名称,调用者包名等信息,创建Socket。
2. 服务端启动监听,客户端进行绑定。
3. 绑定成功,可发送数据。
4. 待Socket不使用时,关闭Socket。
## 相关仓
**分布式软总线子系统**
connectivity_cangjie_api
+48
View File
@@ -0,0 +1,48 @@
{
"name": "@ohos/connectivity_cangjie_api",
"description": "Provides basic Bluetooth, BLE, WIFI functions for applications",
"version": "6.0",
"license": "Apache-2.0",
"publishAs": "code-segment",
"segment": {
"destPath": "foundation/communication/connectivity_cangjie_api"
},
"dirs": {},
"scripts": {},
"component": {
"name": "connectivity_cangjie_api",
"subsystem": "communication",
"syscap": [
"SystemCapability.Communication.Bluetooth.Core",
"SystemCapability.Communication.WiFi.STA",
"SystemCapability.Communication.WiFi.P2P",
"SystemCapability.Communication.WiFi.Core"
],
"features": [],
"adapted_system_type": [
"standard"
],
"rom": "30000KB",
"ram": "100000KB",
"deps": {
"components": [
"cangjie_api"
]
},
"build": {
"sub_component": [
"//foundation/communication/connectivity_cangjie_api/ohos/bluetooth:ohos.bluetooth",
"//foundation/communication/connectivity_cangjie_api/ohos/bluetooth/baseProfile:ohos.bluetooth.baseProfile",
"//foundation/communication/connectivity_cangjie_api/ohos/bluetooth/ble:ohos.bluetooth.ble",
"//foundation/communication/connectivity_cangjie_api/ohos/bluetooth/connection:ohos.bluetooth.connection",
"//foundation/communication/connectivity_cangjie_api/ohos/bluetooth/constant:ohos.bluetooth.constant",
"//foundation/communication/connectivity_cangjie_api/ohos/wifi_manager:ohos.wifi_manager",
"//foundation/communication/connectivity_cangjie_api/kit/ConnectivityKit:kit.ConnectivityKit"
],
"inner_kits": [
],
"test": [
]
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

+33
View File
@@ -0,0 +1,33 @@
# Copyright (c) 2025 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")
import("//build/cangjie/cjc.gni")
ohos_cj_library("kit.ConnectivityKit") {
sources = [ "index.cj" ]
cj_deps = [
"../../ohos/bluetooth/baseProfile:ohos.bluetooth.baseProfile",
"../../ohos/bluetooth/ble:ohos.bluetooth.ble",
"../../ohos/bluetooth:ohos.bluetooth",
"../../ohos/bluetooth/connection:ohos.bluetooth.connection",
"../../ohos/bluetooth/constant:ohos.bluetooth.constant",
"../../ohos/wifi_manager:ohos.wifi_manager",
]
kit = true
subsystem_name = "communication"
part_name = "connectivity_cangjie_api"
lib_name = "ConnectivityKit"
}
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2025 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.
*/
package kit.ConnectivityKit
public import ohos.bluetooth.*
public import ohos.bluetooth.baseProfile.*
public import ohos.bluetooth.ble.*
public import ohos.bluetooth.constant.*
public import ohos.bluetooth.connection.*
public import ohos.wifi_manager.*
+30
View File
@@ -0,0 +1,30 @@
# Copyright (c) 2025 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")
import("//build/cangjie/cjc.gni")
ohos_cj_library("ohos.bluetooth") {
sources = [ "error_message.cj" ]
cj_external_deps = [
"arkui_cangjie_api:ohos.base",
"cangjie_api:ohos.ffi",
"cangjie_api:ohos.labels",
"hiviewdfx_cangjie_api:ohos.hilog",
]
subsystem_name = "communication"
part_name = "connectivity_cangjie_api"
lib_name = "bluetooth"
}
+34
View File
@@ -0,0 +1,34 @@
# Copyright (c) 2025 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")
import("//build/cangjie/cjc.gni")
ohos_cj_library("ohos.bluetooth.baseProfile") {
sources = [ "base_profile.cj" ]
external_deps = []
cj_external_deps = [
"arkui_cangjie_api:ohos.base",
"cangjie_api:ohos.labels",
]
cj_deps = [
"../constant:ohos.bluetooth.constant",
]
subsystem_name = "communication"
part_name = "connectivity_cangjie_api"
lib_name = "bluetooth.baseProfile"
}
+194
View File
@@ -0,0 +1,194 @@
/*
* Copyright (c) 2025 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.
*/
package ohos.bluetooth.baseProfile
import std.deriving.*
import ohos.base.*
import ohos.bluetooth.constant.ProfileConnectionState
import ohos.labels.*
@Derive[ToString, Equatable]
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public enum DisconnectCause {
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
USER_DISCONNECT
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
CONNECT_FROM_KEYBOARD
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
CONNECT_FROM_MOUSE
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
CONNECT_FROM_CAR
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
TOO_MANY_CONNECTED_DEVICES
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
CONNECT_FAIL_INTERNAL
| ...
static func parse(cause: Int32) {
match (cause) {
case 0 => USER_DISCONNECT
case 1 => CONNECT_FROM_KEYBOARD
case 2 => CONNECT_FROM_MOUSE
case 3 => CONNECT_FROM_CAR
case 4 => TOO_MANY_CONNECTED_DEVICES
case 5 => CONNECT_FAIL_INTERNAL
case _ => throw NoneValueException("Value does not exist!")
}
}
}
@C
protected struct NativeStateChangeParam {
NativeStateChangeParam(
let deviceId: CString,
let state: Int32,
let cause: Int32
) {}
protected func toObject(): StateChangeParam {
return StateChangeParam(
deviceId.toString(),
ProfileConnectionState.parse(state),
DisconnectCause.parse(cause)
)
}
}
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public class StateChangeParam {
StateChangeParam(
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public let deviceId: String,
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public let state: ProfileConnectionState,
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public let cause: DisconnectCause
) {}
}
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public interface BaseProfile {
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
func getConnectedDevices(): Array<String>
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
func getConnectionState(deviceId: String): ProfileConnectionState
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
func on(`type`: ProfileCallbackType, callback: Callback1Argument<StateChangeParam>): Unit
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
func off(`type`: ProfileCallbackType, callback: CallbackObject): Unit
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
func off(`type`: ProfileCallbackType): Unit
}
@Derive[ToString, Hashable, Equatable]
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public enum ProfileCallbackType {
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
CONNECTION_STATE_CHANGE | ...
protected func getValue(): Int32 {
match (this) {
case CONNECTION_STATE_CHANGE => 0
case _ => throw IllegalArgumentException("The type is not supported.")
}
}
}
+44
View File
@@ -0,0 +1,44 @@
# Copyright (c) 2025 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")
import("//build/cangjie/cjc.gni")
ohos_cj_library("ohos.bluetooth.ble") {
sources = [
"ble.cj",
"gatt_client_device.cj",
"gatt_server.cj",
"gatt_util.cj",
"native.cj",
"util.cj",
]
external_deps = [ "bluetooth:cj_bluetooth_ble_ffi" ]
cj_external_deps = [
"arkui_cangjie_api:ohos.base",
"cangjie_api:ohos.ffi",
"cangjie_api:ohos.labels",
"hiviewdfx_cangjie_api:ohos.hilog",
]
cj_deps = [
"../:ohos.bluetooth",
"../constant:ohos.bluetooth.constant",
]
subsystem_name = "communication"
part_name = "connectivity_cangjie_api"
lib_name = "bluetooth.ble"
}
+452
View File
@@ -0,0 +1,452 @@
/*
* Copyright (c) 2025 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.
*/
package ohos.bluetooth.ble
import ohos.base.*
import ohos.bluetooth.*
import ohos.ffi.*
import std.collection.{ArrayList, HashMap}
import std.sync.AtomicBool
import ohos.labels.*
/**
* create a Gatt server instance.
*
* @returns { GattServer } Returns a Gatt server instance {@code GattServer}.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func createGattServer(): GattServer {
var errorCode: Int32 = 0
let id = unsafe { FfiBluetoothBleCreateGattServer(inout errorCode) }
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
return GattServer(id)
}
/**
* create a Gatt client device instance.
*
* @param { String } deviceId - Indicates device ID. For example, "11:22:33:AA:BB:FF".
* @returns { GattClientDevice } Returns a Gatt client device instance {@code GattClientDevice}.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func createGattClientDevice(deviceId: String): GattClientDevice {
var id = 0
var errorCode: Int32 = 0
unsafe {
try (cDeviceId = LibC.mallocCString(deviceId).asResource()) {
id = FfiBluetoothBleCreateGattClientDevice(cDeviceId.value, inout errorCode)
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
}
return GattClientDevice(id)
}
/**
* Starts scanning for specified BLE devices with filters.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { Array<ScanFilter> } filters - Indicates the list of filters used to filter out specified devices.
* If you do not want to use filter, set this parameter to {@code null}.
* @param { ScanOptions } options - Indicates the parameters for scanning and if the user does not assign a value, the default value will be used.
* {@link ScanOptions#interval} set to 0, {@link ScanOptions#dutyMode} set to {@link SCAN_MODE_LOW_POWER}
* and {@link ScanOptions#matchMode} set to {@link MATCH_MODE_AGGRESSIVE}.
* and {@link ScanOptions#phyType} set to {@link PHY_LE_ALL_SUPPORTED}.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900003 - Bluetooth disabled.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func startBLEScan(filters: Array<ScanFilter>, options!: ?ScanOptions = None): Unit {
var errorCode: Int32 = 0
unsafe {
let filtersSize = filters.size
let arr = if (filtersSize == 0) {
CPointer<NativeScanFilter>()
} else {
safeMalloc<NativeScanFilter>(count: filtersSize)
}
for (i in 0..filtersSize) {
arr.write(i, filters[i].toNative())
}
let cFilters = CArrNativeScanFilter(arr, filtersSize)
var cOptions = CPointer<NativeScanOptions>()
if (let Some(v) <- options) {
cOptions = safeMalloc<NativeScanOptions>(count: 1)
cOptions.write(v.toNative())
}
FfiBluetoothBleStartBleScan(cFilters, cOptions, inout errorCode)
cFilters.free()
LibC.free(cOptions)
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Stops BLE scanning.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900003 - Bluetooth disabled.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func stopBLEScan(): Unit {
var errorCode: Int32 = 0
unsafe {
FfiBluetoothBleStopBleScan(inout errorCode)
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Starts BLE advertising.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { AdvertiseSetting } setting - Indicates the settings for BLE advertising.
* @param { AdvertiseData } advData - Indicates the advertising data.
* @param { AdvertiseData } advResponse - Indicates the scan response associated with the advertising data.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900003 - Bluetooth disabled.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func startAdvertising(setting: AdvertiseSetting, advData: AdvertiseData, advResponse!: ?AdvertiseData = None): Unit {
var errorCode: Int32 = 0
let cSetting: NativeAdvertiseSetting = setting.toNative()
let cAdvData: NativeAdvertiseData = advData.toNative()
var cAdvResponse: CPointer<NativeAdvertiseData> = CPointer<NativeAdvertiseData>()
unsafe {
if (let Some(v) <- advResponse) {
cAdvResponse = safeMalloc<NativeAdvertiseData>(count: 1)
cAdvResponse.write(v.toNative())
}
FfiBluetoothBleStartAdvertising(cSetting, cAdvData, cAdvResponse, inout errorCode)
cAdvData.free()
if (cAdvResponse.isNotNull()) {
cAdvResponse.read().free()
}
LibC.free(cAdvResponse)
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Stops BLE advertising.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900003 - Bluetooth disabled.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func stopAdvertising(): Unit {
var errorCode: Int32 = 0
unsafe {
FfiBluetoothBleStopAdvertising(inout errorCode)
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Starts BLE advertising.
* The API returns a advertising ID. The ID can be used to temporarily enable or disable this advertising
* using the API {@link enableAdvertising} or {@link disableAdvertising}.
* To completely stop the advertising corresponding to the ID, invoke the API {@link stopAdvertising} with ID.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { AdvertisingParams } advertisingParams - Indicates the params for BLE advertising.
* @returns { UInt32 } Returns advertise ID.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900003 - Bluetooth disabled.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func startAdvertising(advertisingParams: AdvertisingParams): UInt32 {
var errorCode: Int32 = 0
let id: Int32
unsafe {
let cAdvertisingParams: NativeAdvertisingParams = advertisingParams.toNative()
id = FfiBluetoothBleStartAdvertisingWithId(cAdvertisingParams, inout errorCode)
cAdvertisingParams.free()
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
if (id < 0) {
throw BusinessException(OPERATION_FAILED, getErrorMsg(OPERATION_FAILED))
}
// for usability
return UInt32(id)
}
/**
* Stops BLE advertising.
* Completely stop the advertising corresponding to the ID.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { UInt32 } advertisingId - Indicates the ID for this BLE advertising.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900003 - Bluetooth disabled.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func stopAdvertising(advertisingId: UInt32): Unit {
var errorCode: Int32 = 0
unsafe {
FfiBluetoothBleStopAdvertisingWithId(advertisingId, inout errorCode)
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
private let GLOBAL_CALLBACK_MAP = HashMap<BluetoothBleCallbackType, ArrayList<CallbackObject>>()
private let GLOBAL_REGISTER_MAP = HashMap<BluetoothBleCallbackType, Bool>(
[(ADVERTISING_STATE_CHANGE, false), (BLE_DEVICE_FIND, false)])
private func findCallbackObject(callbackType: BluetoothBleCallbackType, callback: CallbackObject, remove!: Bool = false): Int64 {
let callbackList = GLOBAL_CALLBACK_MAP.get(callbackType) ?? return -1
for (idx in 0..callbackList.size) {
if (refEq(callback, callbackList[idx])) {
if (remove) {
callbackList.remove(at: idx)
}
return idx
}
}
return -1
}
private func register(callbackType: BluetoothBleCallbackType, id: Int64) {
var errorCode: Int32 = 0
unsafe {
FfiBluetoothBleOn(callbackType.getValue(), id, inout errorCode)
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
private func argWrapper1<CT, T>(callbackType: BluetoothBleCallbackType, ctor: (CT) -> T): Int64 where CT <: CType {
let wrapper = {
ctype: CT =>
let cjType = ctor(ctype)
let callbackList = GLOBAL_CALLBACK_MAP.get(callbackType) ?? ArrayList<CallbackObject>()
for (caller in callbackList) {
(caller as Callback1Argument<T>)?.invoke(cjType)
}
}
let registerCall = Callback1Param<CT, Unit>(wrapper)
registerCall.getID()
}
private func commonSubscribe1Arg<CT, T>(callbackType: BluetoothBleCallbackType, callback: CallbackObject,
ctor: (CT) -> T) where CT <: CType {
BLUETOOTH_LOG.debug("subscribe ${callbackType}")
if (!GLOBAL_REGISTER_MAP[callbackType]) {
register(callbackType, argWrapper1<CT, T>(callbackType, ctor))
GLOBAL_REGISTER_MAP[callbackType] = true
} else {
if (findCallbackObject(callbackType, callback) >= 0) {
BLUETOOTH_LOG.info("The ${callbackType} callback is registered, no need to re-registered")
return
}
}
GLOBAL_CALLBACK_MAP.addIfAbsent(callbackType, ArrayList<CallbackObject>())
GLOBAL_CALLBACK_MAP[callbackType].add(callback)
}
/**
* Subscribing to advertising state change event.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BluetoothBleCallbackType } type - Type of the advertising state to listen for.
* @param { Callback1Argument<AdvertisingStateChangeInfo> } callback - Callback used to listen for the advertising state.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func on(`type`: BluetoothBleCallbackType, callback: Callback1Argument<AdvertisingStateChangeInfo>): Unit {
if (`type` != ADVERTISING_STATE_CHANGE) {
BLUETOOTH_LOG.error("Invalid name ${`type`}, valid name is ADVERTISING_STATE_CHANGE")
throw BusinessException(ERR_PARAMETER_ERROR, getErrorMsg(ERR_PARAMETER_ERROR))
}
commonSubscribe1Arg(`type`, callback) {
info: CAdvertisingStateChangeInfo => info.toObject()
}
return
}
/**
* Subscribe BLE scan result.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BluetoothBleCallbackType } type - Type of the scan result event to listen for.
* @param { Callback1Argument<Array<ScanResult>> } callback - Callback used to listen for the scan result event.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func on(`type`: BluetoothBleCallbackType, callback: Callback1Argument<Array<ScanResult>>): Unit {
if (`type` != BLE_DEVICE_FIND) {
BLUETOOTH_LOG.error("Invalid name ${`type`}, valid name is BLE_DEVICE_FIND")
throw BusinessException(ERR_PARAMETER_ERROR, getErrorMsg(ERR_PARAMETER_ERROR))
}
commonSubscribe1Arg(`type`, callback) {
result: CArrScanResult => unsafe {
cArr2cjArr<NativeScanResult, ScanResult>(result.size, result.head) {
r: NativeScanResult => r.toObject()
}
}
}
return
}
/**
* Unsubscribe from callback event.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BluetoothBleCallbackType } type - Type of the callback.
* @param { ?CallbackObject } callback - Callback.
* @throws { BusinessException} 201 - Permission denied.
* @throws { BusinessException} 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException} 801 - Capability not supported.
* @throws { BusinessException} 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func off(`type`: BluetoothBleCallbackType, callback!: ?CallbackObject = None): Unit {
BLUETOOTH_LOG.debug("unsubscribe stateChange")
if (!GLOBAL_CALLBACK_MAP.contains(`type`)) {
return
}
if (let Some(v) <- callback) {
findCallbackObject(`type`, v, remove: true)
return
}
GLOBAL_CALLBACK_MAP[`type`].clear()
return
}
+691
View File
@@ -0,0 +1,691 @@
/*
* Copyright (c) 2025 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.
*/
package ohos.bluetooth.ble
import std.sync.AtomicBool
import ohos.labels.*
import ohos.base.*
import std.collection.{ArrayList, HashMap}
import ohos.ffi.*
import ohos.bluetooth.*
/**
* Manages GATT client. Before calling an Gatt client method, you must use {@link createGattClientDevice} to create an GattClientDevice instance.
*
* @typedef GattClientDevice
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public class GattClientDevice <: RemoteDataLite {
private let callbackMap = HashMap<BluetoothBleGattClientDeviceCallbackType, ArrayList<CallbackObject>>()
private let registerMap = HashMap<BluetoothBleGattClientDeviceCallbackType, Bool>(
[
(BLE_CHARACTERISTIC_CHANGE, false),
(BLE_CONNECTION_STATE_CHANGE, false),
(BLE_MTU_CHANGE, false)
]
)
init(instanceId: Int64) {
super(instanceId)
}
~init() {
releaseFFIData(myDataId)
}
/**
* Connects to a BLE peripheral device.
* <p>The 'BLEConnectionStateChange' event is subscribed to return the connection state.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900003 - Bluetooth disabled.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func connect(): Unit {
var errorCode: Int32 = 0
unsafe {
FfiBluetoothBleGattClientDeviceConnect(getID(), inout errorCode)
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Disconnects from or stops an ongoing connection to a BLE peripheral device.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900003 - Bluetooth disabled.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func disconnect(): Unit {
var errorCode: Int32 = 0
unsafe {
FfiBluetoothBleGattClientDeviceDisconnect(getID(), inout errorCode)
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Disables a BLE peripheral device.
* <p> This method unregisters the device and clears the registered callbacks and handles.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900003 - Bluetooth disabled.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func close(): Unit {
var errorCode: Int32 = 0
unsafe {
FfiBluetoothBleGattClientDeviceClose(getID(), inout errorCode)
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Obtains the name of BLE peripheral device.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @returns { String } Returns a string representation of the name if obtained;
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter.Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func getDeviceName(): String {
var errorCode: Int32 = 0
var outName: String = ""
unsafe {
let name = FfiBluetoothBleGattClientDeviceGetDeviceName(getID(), inout errorCode)
// may be invalid UTF8 and may be parsed abnormally.
try {
outName = name.toString()
} finally {
name.free()
}
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
return outName
}
/**
* Starts discovering services.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @returns { Array<GattService> } Returns the list of services {@link GattService} of the BLE peripheral device.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func getServices(): Array<GattService> {
var errorCode: Int32 = 0
let outServices: Array<GattService>
unsafe {
let nativeServices: CArrGattService = FfiBluetoothBleGattClientDeviceGetServices(getID(), inout errorCode)
outServices = cArr2cjArr<NativeGattService, GattService>(nativeServices.size, nativeServices.head) {
v: NativeGattService => v.toObject()
}
nativeServices.free()
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
return outServices
}
/**
* Reads the characteristic of a BLE peripheral device.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BLECharacteristic } characteristic - Indicates the characteristic to read.
* @param { (?BusinessException, ?BLECharacteristic) -> Unit } callback - Callback invoked to return the characteristic value read.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2901000 - Read forbidden.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func readCharacteristicValue(
characteristic: BLECharacteristic,
callback: (?BusinessException, ?BLECharacteristic) -> Unit
): Unit {
var errorCode: Int32 = 0
let wrapper = {
ret: RetNativeBLECharacteristic =>
let regiestError = ret.code
if (regiestError != SUCCESS_CODE) {
let error = BusinessException(regiestError, getErrorMsg(regiestError))
callback(error, None<BLECharacteristic>)
} else {
callback(None<BusinessException>, ret.data.toObject())
}
}
let registerCall = Callback1Param<RetNativeBLECharacteristic, Unit>(wrapper)
unsafe {
let inputCharacteristic = characteristic.toNative()
FfiBluetoothBleGattClientDeviceReadCharacteristicValue(getID(), inputCharacteristic, registerCall.getID(),
inout errorCode)
inputCharacteristic.free()
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Reads the descriptor of a BLE peripheral device.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BLEDescriptor } descriptor - Indicates the descriptor to read.
* @param { (?BusinessException, ?BLEDescriptor) -> Unit } callback - Callback invoked to return the descriptor read.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2901000 - Read forbidden.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func readDescriptorValue(descriptor: BLEDescriptor, callback: (?BusinessException, ?BLEDescriptor) -> Unit): Unit {
var errorCode: Int32 = 0
let wrapper = {
ret: RetNativeBLEDescriptor =>
let regiestError = ret.code
if (regiestError != SUCCESS_CODE) {
let error = BusinessException(regiestError, getErrorMsg(regiestError))
callback(error, None<BLEDescriptor>)
} else {
callback(None<BusinessException>, ret.data.toObject())
}
}
let registerCall = Callback1Param<RetNativeBLEDescriptor, Unit>(wrapper)
unsafe {
let inputDescriptor = descriptor.toNative()
FfiBluetoothBleGattClientDeviceReadDescriptorValue(getID(), inputDescriptor, registerCall.getID(),
inout errorCode)
inputDescriptor.free()
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Writes the characteristic of a BLE peripheral device.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BLECharacteristic } characteristic - Indicates the characteristic to write.
* @param { GattWriteType } writeType - Write type of the characteristic.
* @param { (?BusinessException) -> Unit } callback - Callback used to return the result.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2901001 - Write forbidden.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func writeCharacteristicValue(characteristic: BLECharacteristic, writeType: GattWriteType,
callback: (?BusinessException) -> Unit): Unit {
var errorCode: Int32 = 0
let wrapper = {
regiestError: Int32 => if (regiestError != SUCCESS_CODE) {
let error = BusinessException(regiestError, getErrorMsg(regiestError))
callback(error)
}
}
let registerCall = Callback1Param<Int32, Unit>(wrapper)
unsafe {
let inputCharacteristic: NativeBLECharacteristic = characteristic.toNative()
FfiBluetoothBleGattClientDeviceWriteCharacteristicValue(getID(), inputCharacteristic, writeType.getValue(),
registerCall.getID(), inout errorCode)
inputCharacteristic.free()
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Writes the descriptor of a BLE peripheral device.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BLEDescriptor } descriptor - Indicates the descriptor to write.
* @param { (?BusinessException) -> Unit } callback - Callback used to return the result.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2901001 - Write forbidden.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func writeDescriptorValue(descriptor: BLEDescriptor, callback: (?BusinessException) -> Unit): Unit {
var errorCode: Int32 = 0
let wrapper = {
regiestError: Int32 => if (regiestError != SUCCESS_CODE) {
let error = BusinessException(regiestError, getErrorMsg(regiestError))
callback(error)
}
}
let registerCall = Callback1Param<Int32, Unit>(wrapper)
unsafe {
let inputDescriptor: NativeBLEDescriptor = descriptor.toNative()
FfiBluetoothBleGattClientDeviceWriteDescriptorValue(getID(), inputDescriptor, registerCall.getID(),
inout errorCode)
inputDescriptor.free()
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Get the RSSI value of this BLE peripheral device.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { (?BusinessException, ?Int32) -> Unit } callback - Callback invoked to return the RSSI, in dBm.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900099 - Operation failed.
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func getRssiValue(callback: (?BusinessException, ?Int32) -> Unit): Unit {
var errorCode: Int32 = 0
let wrapper = {
retRssi: RetDataI32 => if (retRssi.code != SUCCESS_CODE) {
let error = BusinessException(retRssi.code, getErrorMsg(retRssi.code))
callback(error, None<Int32>)
} else {
callback(None<BusinessException>, retRssi.data)
}
}
let registerCall = Callback1Param<RetDataI32, Unit>(wrapper)
unsafe { FfiBluetoothBleGattClientDeviceGetRssiValue(getID(), registerCall.getID(), inout errorCode) }
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Set the mtu size of a BLE peripheral device.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { Int32 } mtu - The maximum transmission unit.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func setBLEMtuSize(mtu: Int32): Unit {
var errorCode: Int32 = 0
unsafe {
FfiBluetoothBleGattClientDeviceSetBLEMtuSize(getID(), mtu, inout errorCode)
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Enables or disables indication of a characteristic when value changed.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BLECharacteristic } characteristic - Indicates the characteristic to indicate.
* @param { Bool } enable - Specifies whether to enable indication of the characteristic. The value {@code true} indicates
* that indication is enabled, and the value {@code false} indicates that indication is disabled.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func setCharacteristicChangeNotification(characteristic: BLECharacteristic, enable: Bool): Unit {
var errorCode: Int32 = 0
unsafe {
let inputCharacteristic: NativeBLECharacteristic = characteristic.toNative()
FfiBluetoothBleGattClientDeviceSetCharacteristicChangeNotification(getID(), inputCharacteristic, enable,
inout errorCode)
inputCharacteristic.free()
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Enables or disables indication of a characteristic when value changed.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BLECharacteristic } characteristic - Indicates the characteristic to indicate.
* @param { Bool } enable - Specifies whether to enable indication of the characteristic. The value {@code true} indicates
* that indication is enabled, and the value {@code false} indicates that indication is disabled.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func setCharacteristicChangeIndication(characteristic: BLECharacteristic, enable: Bool): Unit {
var errorCode: Int32 = 0
unsafe {
let inputCharacteristic: NativeBLECharacteristic = characteristic.toNative()
FfiBluetoothBleGattClientDeviceSetCharacteristicChangeIndication(getID(), inputCharacteristic, enable,
inout errorCode)
inputCharacteristic.free()
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Subscribe characteristic value changed event.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BluetoothBleGattClientDeviceCallbackType } type - Type of the characteristic value changed event to listen for.
* @param { Callback1Argument<BLECharacteristic>} callback - Callback used to listen for the characteristic value changed event.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @syscap SystemCapability.Communication.Bluetooth.Core
* @since 12
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func on(`type`: BluetoothBleGattClientDeviceCallbackType, callback: Callback1Argument<BLECharacteristic>): Unit {
if (`type` != BLE_CHARACTERISTIC_CHANGE) {
BLUETOOTH_LOG.error("Invalid name ${`type`}, valid name is BLE_CHARACTERISTIC_CHANGE")
throw BusinessException(ERR_PARAMETER_ERROR, getErrorMsg(ERR_PARAMETER_ERROR))
}
commonSubscribe1Arg(`type`, callback) {
characteristic: NativeBLECharacteristic => characteristic.toObject()
}
return
}
/**
* Subscribe client connection state changed event.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BluetoothBleGattClientDeviceCallbackType } type - Type of the connection state changed event to listen for.
* @param { Callback1Argument<BLEConnectionChangeState> } callback - Callback used to listen for the connection state changed event.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func on(
`type`: BluetoothBleGattClientDeviceCallbackType,
callback: Callback1Argument<BLEConnectionChangeState>
): Unit {
if (`type` != BLE_CONNECTION_STATE_CHANGE) {
BLUETOOTH_LOG.error("Invalid name ${`type`}, valid name is BLE_CONNECTION_STATE_CHANGE")
throw BusinessException(ERR_PARAMETER_ERROR, getErrorMsg(ERR_PARAMETER_ERROR))
}
commonSubscribe1Arg(`type`, callback) {
state: NativeBLEConnectionChangeState => state.toObject()
}
return
}
/**
* Subscribe mtu changed event.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BluetoothBleGattClientDeviceCallbackType } type - Type of the mtu changed event to listen for.
* @param { Callback1Argument<Int32> } callback - Callback used to listen for the mtu changed event.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func on(`type`: BluetoothBleGattClientDeviceCallbackType, callback: Callback1Argument<Int32>): Unit {
if (`type` != BluetoothBleGattClientDeviceCallbackType.BLE_MTU_CHANGE) {
BLUETOOTH_LOG.error("Invalid name ${`type`}, valid name is BLE_MTU_CHANGE")
throw BusinessException(ERR_PARAMETER_ERROR, getErrorMsg(ERR_PARAMETER_ERROR))
}
commonSubscribe1Arg(`type`, callback) {
i: Int32 => i
}
return
}
/**
* Unsubscribe mtu changed event.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BluetoothBleGattClientDeviceCallbackType } type - Type of the mtu changed event to listen for.
* @param { CallbackObject} callback - Callback event.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func off(`type`: BluetoothBleGattClientDeviceCallbackType, callback!: ?CallbackObject = None): Unit {
BLUETOOTH_LOG.debug("unsubscribe ${`type`}")
if (!callbackMap.contains(`type`)) {
return
}
if (let Some(v) <- callback) {
findCallbackObject(`type`, v, remove: true)
return
}
callbackMap[`type`].clear()
return
}
private func findCallbackObject(callbackType: BluetoothBleGattClientDeviceCallbackType, callback: CallbackObject,
remove!: Bool = false): Int64 {
let callbackList = callbackMap.get(callbackType) ?? return -1
for (idx in 0..callbackList.size) {
if (refEq(callback, callbackList[idx])) {
if (remove) {
callbackList.remove(at: idx)
}
return idx
}
}
return -1
}
private func argWrapper1<CT, T>(callbackType: BluetoothBleGattClientDeviceCallbackType, ctor: (CT) -> T): Int64 where CT <: CType {
let wrapper = {
ctype: CT =>
let cjType = ctor(ctype)
let callbackList = callbackMap.get(callbackType) ?? ArrayList<CallbackObject>()
for (caller in callbackList) {
(caller as Callback1Argument<T>)?.invoke(cjType)
}
}
let registerCall = Callback1Param<CT, Unit>(wrapper)
registerCall.getID()
}
private func register(callbackType: BluetoothBleGattClientDeviceCallbackType, id: Int64) {
var errorCode: Int32 = 0
unsafe {
FfiBluetoothBleGattClientDeviceOn(getID(), callbackType.getValue(), id, inout errorCode)
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
private func commonSubscribe1Arg<CT, T>(callbackType: BluetoothBleGattClientDeviceCallbackType,
callback: CallbackObject, ctor: (CT) -> T) where CT <: CType {
BLUETOOTH_LOG.debug("subscribe ${callbackType}")
if (!registerMap[callbackType]) {
register(callbackType, argWrapper1<CT, T>(callbackType, ctor))
registerMap[callbackType] = true
} else {
if (findCallbackObject(callbackType, callback) >= 0) {
BLUETOOTH_LOG.info("The ${callbackType} callback is registered, no need to re-registered")
return
}
}
callbackMap.addIfAbsent(callbackType, ArrayList<CallbackObject>())
callbackMap[callbackType].add(callback)
}
}
+477
View File
@@ -0,0 +1,477 @@
/*
* Copyright (c) 2025 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.
*/
package ohos.bluetooth.ble
import std.sync.AtomicBool
import ohos.labels.*
import ohos.base.*
import std.collection.{ArrayList, HashMap}
import ohos.ffi.*
import ohos.bluetooth.*
/**
* Manages GATT server. Before calling an Gatt server method, you must use {@link createGattServer} to create an GattServer instance.
*
* @typedef GattServer
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public class GattServer <: RemoteDataLite {
private let callbackMap = HashMap<BluetoothBleGattServerCallbackType, ArrayList<CallbackObject>>()
private let registerMap = HashMap<BluetoothBleGattServerCallbackType, Bool>(
[
(CHARACTERISTIC_READ, false),
(CHARACTERISTIC_WRITE, false),
(DESCRIPTOR_READ, false),
(DESCRIPTOR_WRITE, false),
(CONNECTION_STATE_CHANGE, false),
(BLE_MTU_CHANGE, false)
]
)
init(instanceId: Int64) {
super(instanceId)
}
~init() {
releaseFFIData(myDataId)
}
/**
* Adds a specified service to be hosted.
* <p>The added service and its characteristics are provided by the local device.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { GattService } service - Indicates the service to add.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900003 - Bluetooth disabled.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func addService(service: GattService): Unit {
var errorCode: Int32 = 0
unsafe {
let cGattService: NativeGattService = service.toNative()
FfiBluetoothBleGattServerAddService(getID(), cGattService, inout errorCode)
cGattService.free()
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Removes a specified service from the list of GATT services provided by this device.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { String } serviceUuid - Indicates the UUID of the service to remove.
* @throws { BusinessException} 201 - Permission denied.
* @throws { BusinessException} 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException} 801 - Capability not supported.
* @throws { BusinessException} 2900001 - Service stopped.
* @throws { BusinessException} 2900003 - Bluetooth disabled.
* @throws { BusinessException} 2900004 - Profile not supported.
* @throws { BusinessException} 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func removeService(serviceUuid: String): Unit {
var errorCode: Int32 = 0
unsafe {
try (serviceUuidCString = LibC.mallocCString(serviceUuid).asResource()) {
FfiBluetoothBleGattServerRemoveService(getID(), serviceUuidCString.value, inout errorCode)
}
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Closes this {@code GattServer} object and unregisters its callbacks.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900003 - Bluetooth disabled.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func close(): Unit {
var errorCode: Int32 = 0
unsafe {
FfiBluetoothBleGattServerClose(getID(), inout errorCode)
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Sends a notification of a change in a specified local characteristic with a asynchronous callback.
* <p>This method should be called for every BLE peripheral device that has requested notifications.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { String } deviceId - Indicates device ID. For example, "11:22:33:AA:BB:FF".
* @param { NotifyCharacteristic } notifyCharacteristic - Indicates the local characteristic that has changed.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900003 - Bluetooth disabled.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func notifyCharacteristicChanged(deviceId: String, notifyCharacteristic: NotifyCharacteristic): Unit {
var errorCode: Int32 = 0
unsafe {
try (deviceIdCString = LibC.mallocCString(deviceId).asResource()) {
let cNotifyCharacteristic = notifyCharacteristic.toNative()
FfiBluetoothBleGattServerNotifyCharacteristicChanged(getID(), deviceIdCString.value,
cNotifyCharacteristic, inout errorCode)
cNotifyCharacteristic.free()
}
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Sends a response to a specified read or write request to a given BLE peripheral device.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { ServerResponse } serverResponse - Indicates the response parameters {@link ServerResponse}.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @throws { BusinessException } 2900001 - Service stopped.
* @throws { BusinessException } 2900003 - Bluetooth disabled.
* @throws { BusinessException } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func sendResponse(serverResponse: ServerResponse): Unit {
var errorCode: Int32 = 0
unsafe {
let cServerResponse: NativeServerResponse = serverResponse.toNative()
FfiBluetoothBleGattServerSendResponse(getID(), cServerResponse, inout errorCode)
cServerResponse.free()
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
/**
* Subscribe characteristic read event.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BluetoothBleGattServerCallbackType } type - Type of the characteristic read event to listen for.
* @param { Callback1Argument<CharacteristicReadRequest> } callback - Callback used to listen for the characteristic read event.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func on(`type`: BluetoothBleGattServerCallbackType, callback: Callback1Argument<CharacteristicReadRequest>): Unit {
if (`type` != CHARACTERISTIC_READ) {
BLUETOOTH_LOG.error("Invalid name ${`type`}, valid name is CHARACTERISTIC_READ")
throw BusinessException(ERR_PARAMETER_ERROR, getErrorMsg(ERR_PARAMETER_ERROR))
}
commonSubscribe1Arg(`type`, callback) {
request: NativeCharacteristicReadRequest => request.toObject()
}
return
}
/**
* Subscribe characteristic write event.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BluetoothBleGattServerCallbackType } type - Type of the characteristic write event to listen for.
* @param { Callback1Argument<CharacteristicWriteRequest> } callback - Callback used to listen for the characteristic write event.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func on(`type`: BluetoothBleGattServerCallbackType, callback: Callback1Argument<CharacteristicWriteRequest>): Unit {
if (`type` != CHARACTERISTIC_WRITE) {
BLUETOOTH_LOG.error("Invalid name ${`type`}, valid name is CHARACTERISTIC_WRITE")
throw BusinessException(ERR_PARAMETER_ERROR, getErrorMsg(ERR_PARAMETER_ERROR))
}
commonSubscribe1Arg(`type`, callback) {
request: NativeCharacteristicWriteRequest => request.toObject()
}
return
}
/**
* Subscribe descriptor read event.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BluetoothBleGattServerCallbackType } type - Type of the descriptor read event to listen for.
* @param { Callback1Argument<DescriptorReadRequest> } callback - Callback used to listen for the descriptor read event.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func on(`type`: BluetoothBleGattServerCallbackType, callback: Callback1Argument<DescriptorReadRequest>): Unit {
if (`type` != DESCRIPTOR_READ) {
BLUETOOTH_LOG.error("Invalid name ${`type`}, valid name is DESCRIPTOR_READ")
throw BusinessException(ERR_PARAMETER_ERROR, getErrorMsg(ERR_PARAMETER_ERROR))
}
commonSubscribe1Arg(`type`, callback) {
request: NativeDescriptorReadRequest => request.toObject()
}
return
}
/**
* Subscribe descriptor write event.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BluetoothBleGattServerCallbackType } type - Type of the descriptor write event to listen for.
* @param { Callback1Argument<DescriptorWriteRequest> } callback - Callback used to listen for the descriptor write event.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func on(`type`: BluetoothBleGattServerCallbackType, callback: Callback1Argument<DescriptorWriteRequest>): Unit {
if (`type` != DESCRIPTOR_WRITE) {
BLUETOOTH_LOG.error("Invalid name ${`type`}, valid name is DESCRIPTOR_WRITE")
throw BusinessException(ERR_PARAMETER_ERROR, getErrorMsg(ERR_PARAMETER_ERROR))
}
commonSubscribe1Arg(`type`, callback) {
request: NativeDescriptorWriteRequest => request.toObject()
}
return
}
/**
* Subscribe server connection state changed event.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BluetoothBleGattServerCallbackType } type - Type of the connection state changed event to listen for.
* @param { Callback1Argument<BLEConnectionChangeState> } callback - Callback used to listen for the connection state changed event.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func on(`type`: BluetoothBleGattServerCallbackType, callback: Callback1Argument<BLEConnectionChangeState>): Unit {
if (`type` != CONNECTION_STATE_CHANGE) {
BLUETOOTH_LOG.error("Invalid name ${`type`}, valid name is CONNECTION_STATE_CHANGE")
throw BusinessException(ERR_PARAMETER_ERROR, getErrorMsg(ERR_PARAMETER_ERROR))
}
commonSubscribe1Arg(`type`, callback) {
request: NativeBLEConnectionChangeState => request.toObject()
}
return
}
/**
* Subscribe mtu changed event.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BluetoothBleGattServerCallbackType } type - Type of the mtu changed event to listen for.
* @param { Callback1Argument<Int32> } callback - Callback used to listen for the mtu changed event.
* @throws { BusinessException } 201 - Permission denied.
* @throws { BusinessException } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException } 801 - Capability not supported.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func on(`type`: BluetoothBleGattServerCallbackType, callback: Callback1Argument<Int32>): Unit {
if (`type` != BluetoothBleGattServerCallbackType.BLE_MTU_CHANGE) {
BLUETOOTH_LOG.error("Invalid name ${`type`}, valid name is BLE_MTU_CHANGE")
throw BusinessException(ERR_PARAMETER_ERROR, getErrorMsg(ERR_PARAMETER_ERROR))
}
commonSubscribe1Arg(`type`, callback) {
i: Int32 => i
}
return
}
/**
* Unsubscribe mtu changed event.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { BluetoothBleGattServerCallbackType } type - Type of the mtu changed event to listen for.
* @param { ?CallbackObject } callback - Callback event.
* @throws { BusinessException} 201 - Permission denied.
* @throws { BusinessException} 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessException} 801 - Capability not supported.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func off(`type`: BluetoothBleGattServerCallbackType, callback!: ?CallbackObject = None): Unit {
BLUETOOTH_LOG.debug("unsubscribe ${`type`}")
if (!callbackMap.contains(`type`)) {
return
}
if (let Some(v) <- callback) {
findCallbackObject(`type`, v, remove: true)
return
}
callbackMap[`type`].clear()
return
}
private func findCallbackObject(callbackType: BluetoothBleGattServerCallbackType, callback: CallbackObject,
remove!: Bool = false): Int64 {
let callbackList = callbackMap.get(callbackType) ?? return -1
for (idx in 0..callbackList.size) {
if (refEq(callback, callbackList[idx])) {
if (remove) {
callbackList.remove(at: idx)
}
return idx
}
}
return -1
}
private func argWrapper1<CT, T>(callbackType: BluetoothBleGattServerCallbackType, ctor: (CT) -> T): Int64 where CT <: CType {
let wrapper = {
ctype: CT =>
let cjType = ctor(ctype)
let callbackList = callbackMap.get(callbackType) ?? ArrayList<CallbackObject>()
for (caller in callbackList) {
(caller as Callback1Argument<T>)?.invoke(cjType)
}
}
let registerCall = Callback1Param<CT, Unit>(wrapper)
registerCall.getID()
}
private func register(callbackType: BluetoothBleGattServerCallbackType, id: Int64) {
var errorCode: Int32 = 0
unsafe {
FfiBluetoothBleGattServerOn(getID(), callbackType.getValue(), id, inout errorCode)
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
private func commonSubscribe1Arg<CT, T>(callbackType: BluetoothBleGattServerCallbackType, callback: CallbackObject,
ctor: (CT) -> T) where CT <: CType {
BLUETOOTH_LOG.debug("subscribe ${callbackType}")
if (!registerMap[callbackType]) {
register(callbackType, argWrapper1<CT, T>(callbackType, ctor))
registerMap[callbackType] = true
} else {
if (findCallbackObject(callbackType, callback) >= 0) {
BLUETOOTH_LOG.info("The ${callbackType} callback is registered, no need to re-registered")
return
}
}
callbackMap.addIfAbsent(callbackType, ArrayList<CallbackObject>())
callbackMap[callbackType].add(callback)
}
}
File diff suppressed because it is too large Load Diff
+90
View File
@@ -0,0 +1,90 @@
/*
* Copyright (c) 2025 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.
*/
package ohos.bluetooth.ble
import ohos.ffi.*
foreign {
// global ffi function
func FfiBluetoothBleCreateGattServer(errCode: CPointer<Int32>): Int64
func FfiBluetoothBleCreateGattClientDevice(deviceId: CString, errCode: CPointer<Int32>): Int64
func FfiBluetoothBleStartBleScan(filters: CArrNativeScanFilter, options: CPointer<NativeScanOptions>,
errCode: CPointer<Int32>): Unit
func FfiBluetoothBleStopBleScan(errCode: CPointer<Int32>): Unit
func FfiBluetoothBleStartAdvertising(setting: NativeAdvertiseSetting, advData: NativeAdvertiseData,
advResponse: CPointer<NativeAdvertiseData>, errCode: CPointer<Int32>): Unit
func FfiBluetoothBleStopAdvertising(errCode: CPointer<Int32>): Int64
func FfiBluetoothBleStartAdvertisingWithId(advertisingParams: NativeAdvertisingParams, errCode: CPointer<Int32>): Int32
func FfiBluetoothBleStopAdvertisingWithId(advertisingId: UInt32, errCode: CPointer<Int32>): Unit
func FfiBluetoothBleOn(callbackType: Int32, id: Int64, errCode: CPointer<Int32>): Unit
// GattClientDevice ffi function
func FfiBluetoothBleGattClientDeviceConnect(id: Int64, errCode: CPointer<Int32>): Unit
func FfiBluetoothBleGattClientDeviceDisconnect(id: Int64, errCode: CPointer<Int32>): Unit
func FfiBluetoothBleGattClientDeviceClose(id: Int64, errCode: CPointer<Int32>): Unit
func FfiBluetoothBleGattClientDeviceGetDeviceName(id: Int64, errCode: CPointer<Int32>): CString
func FfiBluetoothBleGattClientDeviceGetServices(id: Int64, errCode: CPointer<Int32>): CArrGattService
func FfiBluetoothBleGattClientDeviceReadCharacteristicValue(id: Int64, characteristic: NativeBLECharacteristic,
callback: Int64, errCode: CPointer<Int32>): NativeBLECharacteristic
func FfiBluetoothBleGattClientDeviceReadDescriptorValue(id: Int64, descriptor: NativeBLEDescriptor, callback: Int64,
errCode: CPointer<Int32>): NativeBLEDescriptor
func FfiBluetoothBleGattClientDeviceWriteCharacteristicValue(id: Int64, characteristic: NativeBLECharacteristic,
writeType: Int32, callback: Int64, errCode: CPointer<Int32>): Unit
func FfiBluetoothBleGattClientDeviceWriteDescriptorValue(id: Int64, descriptor: NativeBLEDescriptor,
callback: Int64, errCode: CPointer<Int32>): Unit
func FfiBluetoothBleGattClientDeviceGetRssiValue(id: Int64, callback: Int64, errCode: CPointer<Int32>): Int32
func FfiBluetoothBleGattClientDeviceSetBLEMtuSize(id: Int64, mtu: Int32, errCode: CPointer<Int32>): Unit
func FfiBluetoothBleGattClientDeviceSetCharacteristicChangeNotification(id: Int64,
characteristic: NativeBLECharacteristic, enable: Bool, errCode: CPointer<Int32>): Unit
func FfiBluetoothBleGattClientDeviceSetCharacteristicChangeIndication(id: Int64,
characteristic: NativeBLECharacteristic, enable: Bool, errCode: CPointer<Int32>): Unit
func FfiBluetoothBleGattClientDeviceOn(id: Int64, callbackType: Int32, callbackId: Int64, errCode: CPointer<Int32>): Unit
// GattServer ffi function
func FfiBluetoothBleGattServerAddService(id: Int64, service: NativeGattService, errCode: CPointer<Int32>): Unit
func FfiBluetoothBleGattServerRemoveService(id: Int64, serviceUuid: CString, errCode: CPointer<Int32>): Unit
func FfiBluetoothBleGattServerClose(id: Int64, errCode: CPointer<Int32>): Unit
func FfiBluetoothBleGattServerNotifyCharacteristicChanged(id: Int64, deviceId: CString,
notifyCharacteristic: NativeNotifyCharacteristic, errCode: CPointer<Int32>): Unit
func FfiBluetoothBleGattServerSendResponse(id: Int64, serverResponse: NativeServerResponse, errCode: CPointer<Int32>): Unit
func FfiBluetoothBleGattServerOn(id: Int64, callbackType: Int32, callbackId: Int64, errCode: CPointer<Int32>): Unit
}
File diff suppressed because it is too large Load Diff
+39
View File
@@ -0,0 +1,39 @@
# Copyright (c) 2025 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")
import("//build/cangjie/cjc.gni")
ohos_cj_library("ohos.bluetooth.connection") {
sources = [
"connection.cj",
"native.cj",
]
external_deps = [ "bluetooth:cj_bluetooth_connection_ffi" ]
cj_external_deps = [
"arkui_cangjie_api:ohos.base",
"cangjie_api:ohos.ffi",
"cangjie_api:ohos.labels",
"hiviewdfx_cangjie_api:ohos.hilog",
]
cj_deps = [
"../:ohos.bluetooth",
]
subsystem_name = "communication"
part_name = "connectivity_cangjie_api"
lib_name = "bluetooth.connection"
}
+55
View File
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2025 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.
*/
package ohos.bluetooth.connection
import ohos.base.*
import ohos.bluetooth.*
import ohos.ffi.*
import ohos.labels.*
/**
* Sets the Bluetooth friendly name of a device. It is used only by system applications for security.
* If a non-system application invokes the interface, exception 801 is thrown.
*
* @permission ohos.permission.ACCESS_BLUETOOTH
* @param { String } name - Indicates a valid Bluetooth name.
* @throws { BusinessError } 201 - Permission denied.
* @throws { BusinessError } 401 - Invalid parameter. Possible causes: 1. Mandatory parameters are left unspecified.
* <br>2. Incorrect parameter types. 3. Parameter verification failed.
* @throws { BusinessError } 801 - Capability not supported.
* @throws { BusinessError } 2900001 - Service stopped.
* @throws { BusinessError } 2900003 - Bluetooth disabled.
* @throws { BusinessError } 2900099 - Operation failed.
* @syscap SystemCapability.Communication.Bluetooth.Core
*/
@!APILevel[
21,
deprecated: 21,
permission: "ohos.permission.ACCESS_BLUETOOTH",
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public func setLocalName(name: String): Unit {
var errorCode: Int32 = 0
unsafe {
try (cName = LibC.mallocCString(name).asResource()) {
FfiBluetoothConSetLocalName(cName.value, inout errorCode)
}
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
+21
View File
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2025 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.
*/
package ohos.bluetooth.connection
foreign {
// global ffi function
func FfiBluetoothConSetLocalName(name: CString, errCode: CPointer<Int32>): Unit
}
+27
View File
@@ -0,0 +1,27 @@
# Copyright (c) 2025 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")
import("//build/cangjie/cjc.gni")
ohos_cj_library("ohos.bluetooth.constant") {
sources = [ "constant.cj" ]
cj_external_deps = [
"cangjie_api:ohos.labels",
]
subsystem_name = "communication"
part_name = "connectivity_cangjie_api"
lib_name = "bluetooth.constant"
}
+66
View File
@@ -0,0 +1,66 @@
/*
* Copyright (c) 2025 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.
*/
package ohos.bluetooth.constant
import std.deriving.*
import ohos.labels.*
/**
* The enum of profile connection state.
*/
@Derive[ToString, Equatable]
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
public enum ProfileConnectionState {
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
STATE_DISCONNECTED
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
STATE_CONNECTING
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
STATE_CONNECTED
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.Bluetooth.Core"
]
STATE_DISCONNECTING
| ...
protected static func parse(state: Int32): ProfileConnectionState {
match (state) {
case 0i32 => STATE_DISCONNECTED
case 1i32 => STATE_CONNECTING
case 2i32 => STATE_CONNECTED
case 3i32 => STATE_DISCONNECTING
case _ => throw NoneValueException("Value does not exist!")
}
}
}
+71
View File
@@ -0,0 +1,71 @@
/*
* Copyright (c) 2025 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.
*/
package ohos.bluetooth
import std.collection.HashMap
import ohos.hilog.*
import ohos.base.*
import ohos.ffi.*
protected let BLUETOOTH_LOG = HilogChannel(0, 0xD000101, "CJ-Bluetooth")
protected const SERVICE_STOPPED = 2900001i32
protected const BLUETOOTH_DISABLED = 2900003i32
protected const PROFILE_NOT_SUPPORTED = 2900004i32
protected const DEVICE_NOT_CONNECTED = 2900005i32
protected const THE_MAXIMUM_NUMBER_OF_CONNECTIONS_HAS_BEEN_REACHED = 2900006i32
protected const THE_VALUE_OF_PROXY_IS_A_NULL_POINTER = 2900008i32
protected const OPERATION_FAILED = 2900099i32
protected const IPC_FAILED = 2900100i32
protected const READ_FORBIDDEN = 2901000i32
protected const WRITE_FORBIDDEN = 2901001i32
protected const IO_ERROR = 2901054i32
let ERROR_CODE_MAP = HashMap<Int32, String>(
[
(SERVICE_STOPPED, "Service stopped."),
(BLUETOOTH_DISABLED, "Bluetooth disabled."),
(PROFILE_NOT_SUPPORTED, "Profile not supported."),
(DEVICE_NOT_CONNECTED, "Device not connected."),
(THE_MAXIMUM_NUMBER_OF_CONNECTIONS_HAS_BEEN_REACHED, "The maximum number of connections has been reached."),
(THE_VALUE_OF_PROXY_IS_A_NULL_POINTER, "The value of proxy is a null pointer."),
(OPERATION_FAILED, "Operation failed."),
(IPC_FAILED, "IPC failed."),
(READ_FORBIDDEN, "Read forbidden."),
(WRITE_FORBIDDEN, "Write forbidden."),
(IO_ERROR, "IO error.")
]
)
protected func getErrorMsg(code: Int32): String {
if (let Some(v) <- getUniversalErrorMsg(code)) {
return v
} else if (ERROR_CODE_MAP.contains(code)) {
return ERROR_CODE_MAP[code]
} else {
return "Inner error code ${code}"
}
}
const INVALID_PARAMETER: Int32 = 401
protected func checkRet(errorCode: Int32): Unit {
if (errorCode == INVALID_PARAMETER) {
throw IllegalArgumentException("Invalid parameter.")
}
if (errorCode != SUCCESS_CODE) {
throw BusinessException(errorCode, getErrorMsg(errorCode))
}
}
+39
View File
@@ -0,0 +1,39 @@
# Copyright (c) 2025 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")
import("//build/cangjie/cjc.gni")
ohos_cj_library("ohos.wifi_manager") {
sources = [
"common.cj",
"error_code.cj",
"ip_info.cj",
"wifi_info_elem.cj",
"wifi_scan_info.cj",
"wifi.cj",
]
cj_external_deps = [
"arkui_cangjie_api:ohos.base",
"cangjie_api:ohos.ffi",
"cangjie_api:ohos.labels",
"hiviewdfx_cangjie_api:ohos.hilog",
]
external_deps = [ "wifi:cj_wifi_ffi" ]
subsystem_name = "communication"
part_name = "connectivity_cangjie_api"
lib_name = "wifi_manager"
}
+298
View File
@@ -0,0 +1,298 @@
/*
* Copyright (c) 2025 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.
*/
package ohos.wifi_manager
import std.collection.HashMap
import ohos.labels.*
import ohos.base.*
import ohos.ffi.*
const EVENT_STA_POWER_STATE_CHANGE = "wifiStateChange"
const EVENT_STA_CONN_STATE_CHANGE = "wifiConnectionChange"
const EVENT_STA_RSSI_STATE_CHANGE = "wifiRssiChange"
const EVENT_STA_SCAN_STATE_CHANGE = "wifiScanStateChange"
const EVENT_HOTSPOT_STATE_CHANGE = "hotspotStateChange"
const EVENT_P2P_STATE_CHANGE = "p2pStateChange"
const EVENT_P2P_PERSISTENT_GROUP_CHANGE = "p2pPersistentGroupChange"
const EVENT_P2P_DEVICE_STATE_CHANGE = "p2pDeviceChange"
const EVENT_P2P_PEER_DEVICE_CHANGE = "p2pPeerDeviceChange"
const EVENT_P2P_CONN_STATE_CHANGE = "p2pConnectionChange"
const EVENT_P2P_DISCOVERY_CHANGE = "p2pDiscoveryChange"
// syscap code
const SYSCAP_WIFI_CORE = 2400000i32
const SYSCAP_WIFI_STA = 2500000i32
const SYSCAP_WIFI_P2P = 2800000i32
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
public enum DeviceAddressType <: ToString {
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
RANDOM_DEVICE_ADDRESS
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
REAL_DEVICE_ADDRESS
| ...
func getValue(): Int32 {
match (this) {
case RANDOM_DEVICE_ADDRESS => 0
case REAL_DEVICE_ADDRESS => 1
case _ => throw IllegalArgumentException("The type is not supported.")
}
}
static func parse(val: Int32): DeviceAddressType {
match (val) {
case 0 => RANDOM_DEVICE_ADDRESS
case 1 => REAL_DEVICE_ADDRESS
case _ => throw IllegalArgumentException("The type is not supported.")
}
}
static func tryParse(val: Int32): ?DeviceAddressType {
match (val) {
case 0 => RANDOM_DEVICE_ADDRESS
case 1 => REAL_DEVICE_ADDRESS
case _ => None
}
}
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
public func toString(): String {
match (this) {
case RANDOM_DEVICE_ADDRESS => "RANDOM_DEVICE_ADDRESS"
case REAL_DEVICE_ADDRESS => "REAL_DEVICE_ADDRESS"
case _ => throw IllegalArgumentException("The type is not supported.")
}
}
}
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
public enum WifiSecurityType <: Equatable<WifiSecurityType> & ToString {
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
WIFI_SEC_TYPE_INVALID
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
WIFI_SEC_TYPE_OPEN
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
WIFI_SEC_TYPE_WEP
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
WIFI_SEC_TYPE_PSK
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
WIFI_SEC_TYPE_SAE
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
WIFI_SEC_TYPE_EAP
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
WIFI_SEC_TYPE_EAP_SUITE_B
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
WIFI_SEC_TYPE_OWE
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
WIFI_SEC_TYPE_WAPI_CERT
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
WIFI_SEC_TYPE_WAPI_PSK
| ...
func getValue(): Int32 {
match (this) {
case WIFI_SEC_TYPE_INVALID => 0
case WIFI_SEC_TYPE_OPEN => 1
case WIFI_SEC_TYPE_WEP => 2
case WIFI_SEC_TYPE_PSK => 3
case WIFI_SEC_TYPE_SAE => 4
case WIFI_SEC_TYPE_EAP => 5
case WIFI_SEC_TYPE_EAP_SUITE_B => 6
case WIFI_SEC_TYPE_OWE => 7
case WIFI_SEC_TYPE_WAPI_CERT => 8
case WIFI_SEC_TYPE_WAPI_PSK => 9
case _ => throw IllegalArgumentException("The type is not supported.")
}
}
static func parse(val: Int32): WifiSecurityType {
match (val) {
case 0 => WIFI_SEC_TYPE_INVALID
case 1 => WIFI_SEC_TYPE_OPEN
case 2 => WIFI_SEC_TYPE_WEP
case 3 => WIFI_SEC_TYPE_PSK
case 4 => WIFI_SEC_TYPE_SAE
case 5 => WIFI_SEC_TYPE_EAP
case 6 => WIFI_SEC_TYPE_EAP_SUITE_B
case 7 => WIFI_SEC_TYPE_OWE
case 8 => WIFI_SEC_TYPE_WAPI_CERT
case 9 => WIFI_SEC_TYPE_WAPI_PSK
case _ => throw IllegalArgumentException("The type is not supported.")
}
}
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
public operator func ==(that: WifiSecurityType): Bool {
match ((this, that)) {
case (WIFI_SEC_TYPE_INVALID, WIFI_SEC_TYPE_INVALID) => true
case (WIFI_SEC_TYPE_OPEN, WIFI_SEC_TYPE_OPEN) => true
case (WIFI_SEC_TYPE_WEP, WIFI_SEC_TYPE_WEP) => true
case (WIFI_SEC_TYPE_PSK, WIFI_SEC_TYPE_PSK) => true
case (WIFI_SEC_TYPE_SAE, WIFI_SEC_TYPE_SAE) => true
case (WIFI_SEC_TYPE_EAP, WIFI_SEC_TYPE_EAP) => true
case (WIFI_SEC_TYPE_EAP_SUITE_B, WIFI_SEC_TYPE_EAP_SUITE_B) => true
case (WIFI_SEC_TYPE_OWE, WIFI_SEC_TYPE_OWE) => true
case (WIFI_SEC_TYPE_WAPI_CERT, WIFI_SEC_TYPE_WAPI_CERT) => true
case (WIFI_SEC_TYPE_WAPI_PSK, WIFI_SEC_TYPE_WAPI_PSK) => true
case _ => false
}
}
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.Core"
]
public func toString(): String {
match (this) {
case WIFI_SEC_TYPE_INVALID => "WIFI_SEC_TYPE_INVALID"
case WIFI_SEC_TYPE_OPEN => "WIFI_SEC_TYPE_OPEN"
case WIFI_SEC_TYPE_WEP => "WIFI_SEC_TYPE_WEP"
case WIFI_SEC_TYPE_PSK => "WIFI_SEC_TYPE_PSK"
case WIFI_SEC_TYPE_SAE => "WIFI_SEC_TYPE_SAE"
case WIFI_SEC_TYPE_EAP => "WIFI_SEC_TYPE_EAP"
case WIFI_SEC_TYPE_EAP_SUITE_B => "WIFI_SEC_TYPE_EAP_SUITE_B"
case WIFI_SEC_TYPE_OWE => "WIFI_SEC_TYPE_OWE"
case WIFI_SEC_TYPE_WAPI_CERT => "WIFI_SEC_TYPE_WAPI_CERT"
case WIFI_SEC_TYPE_WAPI_PSK => "WIFI_SEC_TYPE_WAPI_PSK"
case _ => throw IllegalArgumentException("The type is not supported.")
}
}
}
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public enum WifiCategory <: ToString {
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
DEFAULT
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
WIFI6
| @!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
WIFI6_PLUS
| ...
func getValue(): Int32 {
match (this) {
case DEFAULT => 1
case WIFI6 => 2
case WIFI6_PLUS => 3
case _ => throw IllegalArgumentException("The type is not supported.")
}
}
static func parse(val: Int32): WifiCategory {
match (val) {
case 1 => DEFAULT
case 2 => WIFI6
case 3 => WIFI6_PLUS
case _ => throw IllegalArgumentException("The type is not supported.")
}
}
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public func toString(): String {
match (this) {
case DEFAULT => "DEFAULT"
case WIFI6 => "WIFI6"
case WIFI6_PLUS => "WIFI6_PLUS"
case _ => throw IllegalArgumentException("The type is not supported.")
}
}
}
+104
View File
@@ -0,0 +1,104 @@
/*
* Copyright (c) 2025 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.
*/
package ohos.wifi_manager
import ohos.base.*
import ohos.ffi.*
import std.collection.HashMap
const WIFI_OPT_FAILED = 1i32
const WIFI_OPT_NOT_SUPPORTED = 2i32
const WIFI_OPT_INVALID_PARAM = 3i32
const WIFI_OPT_FORBID_AIRPLANE = 4i32
const WIFI_OPT_FORBID_POWSAVING = 5i32
const WIFI_OPT_PERMISSION_DENIED = 6i32
const WIFI_OPT_OPEN_FAIL_WHEN_CLOSING = 7i32
const WIFI_OPT_OPEN_SUCC_WHEN_OPENED = 8i32
const WIFI_OPT_CLOSE_FAIL_WHEN_OPENING = 9i32
const WIFI_OPT_CLOSE_SUCC_WHEN_CLOSED = 10i32
const WIFI_OPT_STA_NOT_OPENED = 11i32
const WIFI_OPT_SCAN_NOT_OPENED = 12i32
const WIFI_OPT_AP_NOT_OPENED = 13i32
const WIFI_OPT_INVALID_CONFIG = 14i32
const WIFI_OPT_P2P_NOT_OPENED = 15i32
const WIFI_OPT_P2P_MAC_NOT_FOUND = 16i32
const WIFI_OPT_P2P_ERR_MAC_FORMAT = 17i32
const WIFI_OPT_P2P_ERR_INTENT = 18i32
const WIFI_OPT_P2P_ERR_SIZE_NW_NAME = 19i32
const WIFI_OPT_MOVING_FREEZE_CTRL = 20i32
const WIFI_OPT_NON_SYSTEMAPP = 21i32
const WIFI_ERRCODE_OPERATION_FAILED = 1000i32 /* failed */
const WIFI_ERRCODE_WIFI_NOT_OPENED = 1001i32 /* sta service not opened */
const WIFI_ERRCODE_OPEN_FAIL_WHEN_CLOSING = 1003i32 /* forbid when current airplane opened */
const WIFI_ERRCODE_CLOSE_FAIL_WHEN_OPENING = 1004i32 /* forbid when current powersaving opened */
const WIFI_ERRMSG_OPERATION_FAILED = "Operation failed."
const WIFI_ERRMSG_WIFI_NOT_OPENED = "WIFI doesn't open."
const WIFI_ERRMSG_PERMISSION_DENIED = "Permission denied."
const WIFI_ERRMSG_NON_SYSTEMAPP = "non-system application."
const WIFI_ERRMSG_INVALID_PARAM = "Parameter error."
const WIFI_ERRMSG_NOT_SUPPORTED = "Capability not supported."
const WIFI_ERRMSG_OPEN_FAIL_WHEN_CLOSING = "Failed for wifi is closing."
const WIFI_ERRMSG_CLOSE_FAIL_WHEN_OPENING = "Failed for wifi is opening."
let CODE_MAP = HashMap<Int32, Int32>(
[
(WIFI_OPT_FAILED, WIFI_ERRCODE_OPERATION_FAILED),
(WIFI_OPT_NOT_SUPPORTED, ERR_NOT_SUPPOERTED),
(WIFI_OPT_INVALID_PARAM, ERR_PARAMETER_ERROR),
(WIFI_OPT_FORBID_AIRPLANE, WIFI_ERRCODE_OPERATION_FAILED),
(WIFI_OPT_FORBID_POWSAVING, WIFI_ERRCODE_OPERATION_FAILED),
(WIFI_OPT_PERMISSION_DENIED, ERR_NO_PERMISSION),
(WIFI_OPT_NON_SYSTEMAPP, ERR_NOT_SYSTEM_APP),
(WIFI_OPT_OPEN_FAIL_WHEN_CLOSING, WIFI_ERRCODE_OPEN_FAIL_WHEN_CLOSING),
(WIFI_OPT_OPEN_SUCC_WHEN_OPENED, WIFI_ERRCODE_CLOSE_FAIL_WHEN_OPENING),
(WIFI_OPT_CLOSE_FAIL_WHEN_OPENING, WIFI_ERRCODE_CLOSE_FAIL_WHEN_OPENING),
(WIFI_OPT_CLOSE_SUCC_WHEN_CLOSED, WIFI_ERRCODE_OPERATION_FAILED),
(WIFI_OPT_STA_NOT_OPENED, WIFI_ERRCODE_WIFI_NOT_OPENED),
(WIFI_OPT_SCAN_NOT_OPENED, WIFI_ERRCODE_OPERATION_FAILED),
(WIFI_OPT_AP_NOT_OPENED, WIFI_ERRCODE_OPERATION_FAILED),
(WIFI_OPT_INVALID_CONFIG, WIFI_ERRCODE_OPERATION_FAILED),
(WIFI_OPT_P2P_NOT_OPENED, WIFI_ERRCODE_WIFI_NOT_OPENED),
(WIFI_OPT_P2P_MAC_NOT_FOUND, WIFI_ERRCODE_OPERATION_FAILED),
(WIFI_OPT_P2P_ERR_MAC_FORMAT, WIFI_ERRCODE_OPERATION_FAILED),
(WIFI_OPT_P2P_ERR_INTENT, WIFI_ERRCODE_OPERATION_FAILED),
(WIFI_OPT_P2P_ERR_SIZE_NW_NAME, WIFI_ERRCODE_OPERATION_FAILED),
(WIFI_OPT_MOVING_FREEZE_CTRL, WIFI_ERRCODE_OPERATION_FAILED)
]
)
let ERR_MSG_MAP = HashMap<Int32, String>(
[
(ERR_NO_PERMISSION, WIFI_ERRMSG_PERMISSION_DENIED),
(ERR_NOT_SYSTEM_APP, WIFI_ERRMSG_NON_SYSTEMAPP),
(ERR_PARAMETER_ERROR, WIFI_ERRMSG_INVALID_PARAM),
(ERR_NOT_SUPPOERTED, WIFI_ERRMSG_NOT_SUPPORTED),
(WIFI_ERRCODE_OPERATION_FAILED, WIFI_ERRMSG_OPERATION_FAILED),
(WIFI_ERRCODE_WIFI_NOT_OPENED, WIFI_ERRMSG_WIFI_NOT_OPENED),
(WIFI_ERRCODE_OPEN_FAIL_WHEN_CLOSING, WIFI_ERRMSG_OPEN_FAIL_WHEN_CLOSING),
(WIFI_ERRCODE_CLOSE_FAIL_WHEN_OPENING, WIFI_ERRMSG_CLOSE_FAIL_WHEN_OPENING)
]
)
func getCodeAndMsg(value: Int32, syscap: Int32): (Int32, String) {
match (CODE_MAP.get(value)) {
case Some(v) =>
if (v == ERR_NO_PERMISSION || v == ERR_NOT_SYSTEM_APP || v == ERR_PARAMETER_ERROR || v == ERR_NOT_SUPPOERTED) {
(v, ERR_MSG_MAP[v])
} else {
(syscap + v, ERR_MSG_MAP[v])
}
case None => (value, ERR_MSG_MAP[WIFI_ERRCODE_OPERATION_FAILED])
}
}
+317
View File
@@ -0,0 +1,317 @@
/*
* Copyright (c) 2025 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.
*/
package ohos.wifi_manager
import ohos.base.*
import ohos.ffi.*
import ohos.labels.*
foreign {
func FfiWifiIsWifiActive(ret: CPointer<Bool>): Int32
func FfiWifiGetScanInfoList(ret: CPointer<Int32>): WifiScanInfoArr
func FfiWifiRemoveCandidateConfig(id: Int32): Int32
func FfiWifiConnectToCandidateConfig(id: Int32): Int32
func FfiWifiGetSignalLevel(rssi: Int32, band: Int32, ret: CPointer<UInt32>): Int32
func FfiWifiIsConnected(ret: CPointer<Bool>): Int32
func FfiWifiIsFeatureSupported(featureId: Int64, ret: CPointer<Bool>): Int32
func FfiWifiGetIpInfo(ret: CPointer<CIpInfo>): Int32
func FfiWifiGetIpv6Info(ret: CPointer<CIpv6Info>): Int32
func FfiWifiGetCountryCode(code: CPointer<Int32>): CString
func FfiWifiIsBandTypeSupported(bandType: Int32, ret: CPointer<Bool>): Int32
func FfiWifiIsMeteredHotspot(ret: CPointer<Bool>): Int32
func FfiWifiRemoveGroup(): Int32
func FfiWifiP2pCancelConnect(): Int32
func FfiWifiStartDiscoverDevices(): Int32
func FfiWifiStopDiscoverDevices(): Int32
func FfiWifiGetP2pLinkedInfo(info: CPointer<CWifiP2pLinkedInfo>): Int32
func FfiWifiGetLinkedInfo(info: CPointer<CWifiLinkedInfo>): Int32
func FfiWifiAddCandidateConfig(cfg: CWifiDeviceConfig, ret: CPointer<Int32>): Int32
func FfiWifiGetCandidateConfigs(code: CPointer<Int32>): WifiDeviceConfigArr
func FfiWifiWifiOn(event: CString, id: Int64): Int32
func FfiWifiWifiOff(event: CString): Int32
}
@C
struct CWifiInfoElem {
CWifiInfoElem(
let eid: UInt32,
let content: CArrUI8
) {}
func free() {
unsafe { LibC.free(content.head) }
}
}
@C
struct CWifiScanInfo {
CWifiScanInfo(
let ssid: CString, // the maximum length is 32
let bssid: CString, // the length is 6
let bssidType: Int32,
let capabilities: CString,
let securityType: Int32,
let rssi: Int32, // Received signal strength indicator
let band: Int32, // Frequency band, 1: 2.4G, 2: 5G
let frequency: Int32,
let channelWidth: Int32,
let centerFrequency0: Int32,
let centerFrequency1: Int32,
let infoElems: CPointer<CWifiInfoElem>,
let elemsSize: Int64,
let timestamp: Int64,
let supportedWifiCategory: Int32,
let isHiLinkNetwork: Bool
) {}
func free() {
unsafe {
LibC.free(ssid)
LibC.free(bssid)
LibC.free(capabilities)
if (infoElems.isNotNull()) {
for (i in 0..elemsSize) {
infoElems.read(i).free()
}
}
LibC.free(infoElems)
}
}
}
@C
struct WifiScanInfoArr {
WifiScanInfoArr(
let head: CPointer<CWifiScanInfo>,
let size: Int64
) {}
unsafe func free() {
if (head.isNotNull()) {
for (i in 0..size) {
head.read(i).free()
}
}
LibC.free(head)
}
}
@C
struct CWifiDeviceConfig {
var securityType: Int32 = 0
var bssidType: Int32 = 0
var isHiddenSsid: Bool = false
var bssid: CString = CString(CPointer<UInt8>())
var ssid: CString = CString(CPointer<UInt8>())
var preSharedKey: CString = CString(CPointer<UInt8>())
var eapConfig: CWifiEapConfig = CWifiEapConfig()
var wapiConfig: CWifiWapiConfig = CWifiWapiConfig()
init() {}
func free() {
unsafe {
LibC.free(bssid)
LibC.free(ssid)
LibC.free(preSharedKey)
eapConfig.free()
wapiConfig.free()
}
}
}
@C
struct WifiDeviceConfigArr {
WifiDeviceConfigArr(
let head: CPointer<CWifiDeviceConfig>,
let size: Int64
) {}
unsafe func free() {
if (head.isNotNull()) {
for (i in 0..size) {
head.read(i).free()
}
}
LibC.free(head)
}
}
@C
struct CWifiEapConfig {
var eapMethod: Int32 = 0
var phase2Method: Int32 = 0
var identity: CString = CString(CPointer<UInt8>())
var anonymousIdentity: CString = CString(CPointer<UInt8>())
var password: CString = CString(CPointer<UInt8>())
var caCertAlias: CString = CString(CPointer<UInt8>())
var caPath: CString = CString(CPointer<UInt8>())
var clientCertAlias: CString = CString(CPointer<UInt8>())
var certEntry: CArrUI8 = CArrUI8(CPointer<UInt8>(), 0)
var certPassword: CString = CString(CPointer<UInt8>())
var altSubjectMatch: CString = CString(CPointer<UInt8>())
var domainSuffixMatch: CString = CString(CPointer<UInt8>())
var realm: CString = CString(CPointer<UInt8>())
var plmn: CString = CString(CPointer<UInt8>())
var eapSubId: Int32 = 0
var isNone: Bool = true
init() {}
func free() {
unsafe {
LibC.free(identity)
LibC.free(anonymousIdentity)
LibC.free(password)
LibC.free(caCertAlias)
LibC.free(caPath)
LibC.free(clientCertAlias)
LibC.free(certPassword)
LibC.free(altSubjectMatch)
LibC.free(domainSuffixMatch)
LibC.free(realm)
LibC.free(plmn)
LibC.free(certEntry.head)
}
}
}
@C
struct CWifiWapiConfig {
var wapiPskType: Int32 = 0
var wapiAsCert: CString = CString(CPointer<UInt8>())
var wapiUserCert: CString = CString(CPointer<UInt8>())
var isNone: Bool = true
init() {}
func free() {
unsafe {
LibC.free(wapiAsCert)
LibC.free(wapiUserCert)
}
}
}
@C
struct CIpInfo {
CIpInfo(
let ipAddress: UInt32,
let gateway: UInt32,
let netmask: UInt32,
let primaryDns: UInt32,
let secondDns: UInt32,
let serverIp: UInt32,
let leaseDuration: UInt32
) {}
}
@C
struct CIpv6Info {
CIpv6Info(
let linkIpv6Address: CString,
let globalIpv6Address: CString,
let randomGlobalIpv6Address: CString,
let uniqueIpv6Address: CString,
let randomUniqueIpv6Address: CString,
let gateway: CString,
let netmask: CString,
let primaryDNS: CString,
let secondDNS: CString
) {}
func free() {
unsafe {
LibC.free(linkIpv6Address)
LibC.free(globalIpv6Address)
LibC.free(randomGlobalIpv6Address)
LibC.free(uniqueIpv6Address)
LibC.free(randomUniqueIpv6Address)
LibC.free(gateway)
LibC.free(netmask)
LibC.free(primaryDNS)
LibC.free(secondDNS)
}
}
}
@C
struct CWifiP2pLinkedInfo {
CWifiP2pLinkedInfo(
let connectState: Int32,
let isGroupOwner: Bool,
let groupOwnerAddr: CString
) {}
func free() {
unsafe { LibC.free(groupOwnerAddr) }
}
}
@C
struct CWifiLinkedInfo {
CWifiLinkedInfo(
let ssid: CString,
let bssid: CString,
let rssi: Int32,
let band: Int32,
let linkSpeed: Int32,
let rxLinkSpeed: Int32,
let maxSupportedTxLinkSpeed: Int32,
let maxSupportedRxLinkSpeed: Int32,
let frequency: Int32,
let isHidden: Bool,
let isRestricted: Bool,
let macType: Int32, // Type of macAddress: 0 - real mac, 1 - random mac.
let macAddress: CString,
let ipAddress: UInt32,
let connState: Int32,
let channelWidth: Int32,
let wifiStandard: Int32,
let supportedWifiCategory: Int32,
let isHiLinkNetwork: Bool
) {}
func free() {
unsafe {
LibC.free(ssid)
LibC.free(bssid)
LibC.free(macAddress)
}
}
}
+202
View File
@@ -0,0 +1,202 @@
/*
* Copyright (c) 2025 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.
*/
package ohos.wifi_manager
import ohos.base.*
import ohos.ffi.*
import ohos.hilog.*
import std.collection.{HashMap, ArrayList}
import std.sync.AtomicBool
import ohos.labels.*
let LOGGER = HilogChannel(0, 0xD001560, "CJ-wifi")
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public func isWifiActive(): Bool {
var ret = false
let code = unsafe { FfiWifiIsWifiActive(inout ret) }
if (code != SUCCESS_CODE) {
let err = getCodeAndMsg(code, SYSCAP_WIFI_STA)
throw BusinessException(err[0], "isWifiActive failed: ${err[1]}")
}
ret
}
@!APILevel[
21,
permission: "ohos.permission.GET_WIFI_INFO",
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public func getScanInfoList(): Array<WifiScanInfo> {
var code = 0i32
var arr: Array<WifiScanInfo> = Array<WifiScanInfo>()
unsafe {
let ret = FfiWifiGetScanInfoList(inout code)
if (code != SUCCESS_CODE) {
ret.free()
let err = getCodeAndMsg(code, SYSCAP_WIFI_STA)
throw BusinessException(err[0], "getScanInfoList failed: ${err[1]}")
}
try {
arr = cArr2cjArr<CWifiScanInfo, WifiScanInfo>(ret.size, ret.head) {
ct => WifiScanInfo(ct)
}
} finally {
ret.free()
}
}
arr
}
@!APILevel[
21,
permission: "ohos.permission.GET_WIFI_INFO",
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.P2P"
]
public func p2pCancelConnect(): Unit {
let code = unsafe { FfiWifiP2pCancelConnect() }
if (code != SUCCESS_CODE) {
let err = getCodeAndMsg(code, SYSCAP_WIFI_P2P)
throw BusinessException(err[0], "p2pCancelConnect failed: ${err[1]}")
}
}
@!APILevel[
21,
permission: "ohos.permission.GET_WIFI_INFO",
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.P2P"
]
public func startDiscoverDevices(): Unit {
let code = unsafe { FfiWifiStartDiscoverDevices() }
if (code != SUCCESS_CODE) {
let err = getCodeAndMsg(code, SYSCAP_WIFI_P2P)
throw BusinessException(err[0], "startDiscoverDevices failed: ${err[1]}")
}
}
// ----------- for callback ----------------
private let CALLBACK_MAP = HashMap<String, ArrayList<CallbackObject>>()
private let REGISTER_MAP = HashMap<String, AtomicBool>(
[
(EVENT_STA_POWER_STATE_CHANGE, AtomicBool(false)),
(EVENT_STA_CONN_STATE_CHANGE, AtomicBool(false)),
(EVENT_STA_RSSI_STATE_CHANGE, AtomicBool(false)),
(EVENT_STA_SCAN_STATE_CHANGE, AtomicBool(false)),
(EVENT_HOTSPOT_STATE_CHANGE, AtomicBool(false)),
(EVENT_P2P_STATE_CHANGE, AtomicBool(false)),
(EVENT_P2P_PERSISTENT_GROUP_CHANGE, AtomicBool(false)),
(EVENT_P2P_DEVICE_STATE_CHANGE, AtomicBool(false)),
(EVENT_P2P_PEER_DEVICE_CHANGE, AtomicBool(false)),
(EVENT_P2P_CONN_STATE_CHANGE, AtomicBool(false)),
(EVENT_P2P_DISCOVERY_CHANGE, AtomicBool(false))
]
)
// return index of the object in array
private func findCallbackObject(callbackType: String, callback: CallbackObject, remove!: Bool = false): Int64 {
let callbackList = CALLBACK_MAP.get(callbackType) ?? return -1
for (idx in 0..callbackList.size) {
if (refEq(callback, callbackList[idx])) {
if (remove) {
callbackList.remove(at: idx)
}
return idx
}
}
return -1
}
private func on(callbackType: String, id: Int64) {
let code: Int32
try (cstr = unsafe { LibC.mallocCString(callbackType) }.asResource()) {
code = unsafe { FfiWifiWifiOn(cstr.value, id) }
if (code != SUCCESS_CODE) {
let err = getCodeAndMsg(code, SYSCAP_WIFI_STA)
throw BusinessException(err[0], "on ${callbackType} failed: ${err[1]}")
}
}
}
private func argWrapper1<CT, T>(callbackType: String, ctor: (CT) -> T): Int64 where CT <: CType {
let wrapper = {
ctype: CT =>
let cjType = ctor(ctype)
let callbackList = CALLBACK_MAP.get(callbackType) ?? ArrayList<CallbackObject>()
for (caller in callbackList) {
(caller as Callback1Argument<T>)?.invoke(cjType)
}
}
let registerCall = Callback1Param<CT, Unit>(wrapper)
registerCall.getID()
}
private func commonSubscribe1Arg<CT, T>(callbackType: String, callback: CallbackObject, ctor: (CT) -> T) where CT <: CType {
LOGGER.debug("subscribe ${callbackType}")
if (REGISTER_MAP[callbackType].compareAndSwap(false, true)) {
on(callbackType, argWrapper1<CT, T>(callbackType, ctor))
} else {
if (findCallbackObject(callbackType, callback) >= 0) {
LOGGER.info("[Wifi] The callback object already exists.")
return
}
}
CALLBACK_MAP.addIfAbsent(callbackType, ArrayList<CallbackObject>())
CALLBACK_MAP[callbackType].add(callback)
}
private func argWrapper0(callbackType: String): Int64 {
let wrapper = {
=>
let callbackList = CALLBACK_MAP.get(callbackType) ?? ArrayList<CallbackObject>()
for (caller in callbackList) {
(caller as Callback0Argument)?.invoke()
}
}
let registerCall = Callback0Param<Unit>(wrapper)
registerCall.getID()
}
private func commonSubscribe0Arg(callbackType: String, callback: CallbackObject): Unit {
LOGGER.debug("subscribe ${callbackType}")
if (REGISTER_MAP[callbackType].compareAndSwap(false, true)) {
on(callbackType, argWrapper0(callbackType))
} else {
if (findCallbackObject(callbackType, callback) >= 0) {
LOGGER.info("[Wifi] The callback object already exists.")
return
}
}
CALLBACK_MAP.addIfAbsent(callbackType, ArrayList<CallbackObject>())
CALLBACK_MAP[callbackType].add(callback)
}
// no need to call FfiWifiWifiOff because there is no unregister api in ndk
private func commonUnSubscribe<T>(callbackType: String, callback!: ?T = None): Unit where T <: CallbackObject {
LOGGER.debug("unsubscribe ${callbackType}")
match (callback) {
case Some(v) => findCallbackObject(callbackType, v, remove: true)
case None => CALLBACK_MAP.get(callbackType)?.clear()
}
}
+60
View File
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2025 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.
*/
package ohos.wifi_manager
import ohos.labels.*
import ohos.base.*
import ohos.ffi.*
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public class WifiInfoElem <: ToString {
WifiInfoElem(
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let eid: UInt32,
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let content: Array<UInt8>
) {}
init(info: CWifiInfoElem) {
this.eid = info.eid
this.content = unsafe {
cArr2cjArr<UInt8, UInt8>(info.content.size, info.content.head) {
i => i
}
}
}
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public func toString(): String {
"eid: ${eid}, content: ${content}"
}
}
+156
View File
@@ -0,0 +1,156 @@
/*
* Copyright (c) 2025 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.
*/
package ohos.wifi_manager
import ohos.base.*
import ohos.ffi.*
import ohos.labels.*
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public class WifiScanInfo <: ToString {
WifiScanInfo(
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let ssid: String, // the maximum length is 32
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let bssid: String, // the length is 6
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let bssidType: DeviceAddressType,
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let capabilities: String,
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let securityType: WifiSecurityType,
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let rssi: Int32, // Received signal strength indicator
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let band: Int32, // Frequency band, 1: 2.4G, 2: 5G
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let frequency: Int32,
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let channelWidth: Int32,
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let centerFrequency0: Int32,
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let centerFrequency1: Int32,
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let infoElems: Array<WifiInfoElem>,
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let timestamp: Int64,
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let supportedWifiCategory: WifiCategory,
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public let isHiLinkNetwork: Bool
) {}
init(info: CWifiScanInfo) {
this.supportedWifiCategory = WifiCategory.parse(info.supportedWifiCategory)
this.securityType = WifiSecurityType.parse(info.securityType)
this.bssidType = DeviceAddressType.parse(info.bssidType)
this.isHiLinkNetwork = info.isHiLinkNetwork
this.timestamp = info.timestamp
this.rssi = info.rssi
this.band = info.band
this.frequency = info.frequency
this.channelWidth = info.channelWidth
this.centerFrequency0 = info.centerFrequency0
this.centerFrequency1 = info.centerFrequency1
this.infoElems = unsafe {
cArr2cjArr<CWifiInfoElem, WifiInfoElem>(info.elemsSize, info.infoElems) {
elem => WifiInfoElem(elem)
}
}
this.ssid = info.ssid.toString()
this.bssid = info.bssid.toString()
this.capabilities = info.capabilities.toString()
}
@!APILevel[
21,
stagemodelonly: true,
syscap: "SystemCapability.Communication.WiFi.STA"
]
public func toString(): String {
"""
supportedWifiCategory: ${supportedWifiCategory}, securityType: ${securityType}, bssidType: ${bssidType},
isHiLinkNetwork: ${isHiLinkNetwork}, timestamp: ${timestamp}, rssi: ${rssi},
band: ${band}, frequency: ${frequency}, channelWidth: ${channelWidth},
centerFrequency0: ${centerFrequency0}, centerFrequency1: ${centerFrequency1}, infoElems: ${infoElems},
ssid: ${ssid}, bssid: ${bssid}, capabilities: ${capabilities}"""
}
}