Skip to content
Back to skills

Hmos Connectivity Kit P2p Mode

ASecurity

P2P点对点连接开发,支持创建删除群组、建立P2P连接、获取对端IP及Socket通信,需要SystemCapability.Communication.WiFi.P2P系统能力,适用于设备间直接通信场景

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 22, 2026
developmenttypescriptgoapiperformance

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 6 files and shows the line behind each finding

Scanned September 22, 2026

npx -y skills add IsKenKenYa/skills --skill hmos-connectivity-kit-p2p-mode --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Hmos Connectivity Kit P2p Mode?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Hmos Connectivity Kit P2p Mode
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/iskenkenya-hmos-connectivity-kit-p2p-mode/badge)](https://www.skillsdirectory.com/skills/iskenkenya-hmos-connectivity-kit-p2p-mode)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: hmos-connectivity-kit-p2p-mode
description: P2P点对点连接开发,支持创建删除群组、建立P2P连接、获取对端IP及Socket通信,需要SystemCapability.Communication.WiFi.P2P系统能力,适用于设备间直接通信场景
---

# P2P模式开发技能

## 功能描述

本技能提供HarmonyOS WLAN P2P(peer-to-peer)点对点连接开发能力,允许两台STA设备直接建立TCP/IP连接,无需AP参与。支持创建临时组或永久组、发现P2P设备、建立连接、获取连接信息和群组IP地址,以及后续的Socket通信。需要SystemCapability.Communication.WiFi.P2P系统能力和ohos.permission.GET_WIFI_INFO权限。

## 使用场景

### 触发词
- "P2P连接" - 建立设备间点对点连接
- "创建P2P群组" - 创建临时组或永久组
- "删除P2P群组" - 移除现有群组
- "发现P2P设备" - 扫描查找附近的P2P设备
- "获取P2P连接信息" - 查询当前连接状态
- "P2P点对点通信" - 设备间直接通信
- "WLAN P2P" - WLAN点对点模式开发

### 能做
- 创建P2P群组(临时组或永久组)
- 删除已创建的P2P群组
- 发现并扫描附近的P2P设备
- 与目标P2P设备建立连接
- 获取P2P连接状态和信息
- 获取群组IP地址用于Socket通信
- 注册和取消P2P相关事件监听
- 处理P2P连接过程中的错误和异常

### 绝不做
- 不直接处理Socket通信的详细实现(需要路由到Socket通信技能)
- 不处理超出P2P范围的WLAN功能(如STA模式、热点模式)
- 不替代网络连接管理功能
- 不处理不满足权限要求的场景
- 不处理不支持P2P系统能力的设备

### 补充
- 需要设备开启Wi-Fi功能
- 需要SystemCapability.Communication.WiFi.P2P系统能力
- 需要ohos.permission.GET_WIFI_INFO权限(API 10起)
- 永久组(netId=-2)下次连接不需要重新GO和WPS密钥协商
- 临时组(netId=-1)下次连接需要重新GO协商
- 作为GO时不能主动发起连接
- P2P连接完成后需要注册"p2pConnectionChange"事件监听

## 调用规范和规则

### 输入约束
- 网络ID范围:-1(临时组)或-2(永久组)
- 设备地址:符合MAC地址格式(如"00:11:22:33:44:55")
- 群组密钥:最小8个字符
- 群组名称:非空字符串
- 群组带宽:0(自动)、1(2.4GHZ)、2(5GHZ)
- 设备地址类型:可选参数,默认为随机设备地址类型

### 执行约束
- 最大耗时:P2P扫描建议不超过125秒
- 最大迭代次数:设备发现循环建议不超过10次
- API调用频次:避免频繁调用startDiscoverDevices
- 必须先开启Wi-Fi功能再执行P2P操作
- 必须注册事件监听再执行连接操作
- 必须在连接成功后才能获取IP地址

### 内容约束
- 禁止生成:不生成Socket通信的详细实现代码
- 禁止使用高危函数:不使用eval、exec等高危函数
- 禁止操作:不执行超出P2P范围的WLAN操作
- 必须校验:必须校验Wi-Fi是否开启、权限是否获取
- 必须处理:必须处理P2P事件回调、错误码处理

### 降级约束
- Wi-Fi未开启:提示用户开启Wi-Fi并等待用户操作
- 权限不足:提示用户申请必要权限并说明申请方法
- 系统能力不支持:明确告知用户设备不支持P2P功能
- P2P连接失败:提供重试机制或提示检查设备状态
- 扫描超时:停止扫描并提示用户检查设备距离或环境

## 调用流程和步骤

### 步骤1:准备阶段

**前置校验**:
1. 检查设备Wi-Fi是否已开启(使用isWifiActive)
2. 检查设备是否支持SystemCapability.Communication.WiFi.P2P系统能力
3. 检查应用是否已获取ohos.permission.GET_WIFI_INFO权限
4. 准备必要的参数(设备地址、netId、密钥、群组名称等)

**参数准备**:
```typescript
import { wifiManager } from '@kit.ConnectivityKit';

async function prepareP2PConfig(): Promise<wifiManager.WifiP2PConfig> {
  try {
    let deviceInfo = await wifiManager.getP2pLocalDevice();
    let config: wifiManager.WifiP2PConfig = {
      deviceAddress: deviceInfo.deviceAddress,
      deviceAddressType: 1,
      netId: -2,
      passphrase: "12345678",
      groupName: "testGroup",
      goBand: 0
    };
    console.info(`P2P config prepared: deviceAddress=${config.deviceAddress}`);
    return config;
  } catch (error) {
    console.error(`Prepare config failed: ${JSON.stringify(error)}`);
    throw error;
  }
}
```

### 步骤2:创建P2P群组

**示例代码**:
```typescript
import { wifiManager } from '@kit.ConnectivityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';

async function createP2PGroup(config: wifiManager.WifiP2PConfig): Promise<void> {
  try {
    if (!wifiManager.isWifiActive()) {
      console.error("Wi-Fi is not active, please enable Wi-Fi first");
      return;
    }
    
    if (config.netId === -2) {
      let recvP2pPersistentGroupChangeFunc = () => {
        console.info("P2P persistent group change event received");
      };
      wifiManager.on("p2pPersistentGroupChange", recvP2pPersistentGroupChangeFunc);
    }
    
    await wifiManager.createGroup(config);
    console.info("P2P group created successfully");
    console.info(`Group name: ${config.groupName}, Passphrase: ${config.passphrase}`);
  } catch (error) {
    console.error(`Create group failed: ${JSON.stringify(error)}`);
    switch (error.code) {
      case 201:
        console.error("Permission denied, please check GET_WIFI_INFO permission");
        break;
      case 401:
        console.error("Invalid parameters, please check config format");
        break;
      case 2801000:
        console.error("P2P module exception, please try restart Wi-Fi");
        break;
      case 2801001:
        console.error("Wi-Fi STA disabled, please enable Wi-Fi first");
        break;
      default:
        console.error(`Unknown error: ${error.message}`);
    }
    throw error;
  }
}
```

### 步骤3:删除P2P群组

**示例代码**:
```typescript
import { wifiManager } from '@kit.ConnectivityKit';

async function removeP2PGroup(): Promise<void> {
  try {
    wifiManager.removeGroup();
    console.info("P2P group removed successfully");
  } catch (error) {
    console.error(`Remove group failed: ${JSON.stringify(error)}`);
    switch (error.code) {
      case 201:
        console.error("Permission denied");
        break;
      case 2801000:
        console.error("P2P module exception");
        break;
      case 2801001:
        console.error("Wi-Fi STA disabled");
        break;
      default:
        console.error(`Unknown error: ${error.message}`);
    }
    throw error;
  }
}
```

### 步骤4:发现P2P设备

**示例代码**:
```typescript
import { wifiManager } from '@kit.ConnectivityKit';

async function discoverP2PDevices(): Promise<void> {
  try {
    if (!wifiManager.isWifiActive()) {
      console.error("Wi-Fi is not active");
      return;
    }
    
    let recvP2pPeerDeviceChangeFunc = (result: wifiManager.WifiP2pDevice[]) => {
      console.info(`P2P peer device change event: found ${result.length} devices`);
      for (let device of result) {
        console.info(`Device: ${device.deviceName}, Address: ${device.deviceAddress}`);
      }
    };
    
    wifiManager.on("p2pPeerDeviceChange", recvP2pPeerDeviceChangeFunc);
    wifiManager.startDiscoverDevices();
    console.info("P2P device discovery started");
    
    setTimeout(() => {
      wifiManager.off("p2pPeerDeviceChange", recvP2pPeerDeviceChangeFunc);
      console.info("P2P device discovery stopped after timeout");
    }, 125 * 1000);
  } catch (error) {
    console.error(`Discover devices failed: ${JSON.stringify(error)}`);
    throw error;
  }
}
```

### 步骤5:建立P2P连接

**示例代码**:
```typescript
import { wifiManager } from '@kit.ConnectivityKit';

async function connectP2PDevice(targetDeviceAddress: string): Promise<void> {
  try {
    let recvP2pConnectionChangeFunc = (result: wifiManager.WifiP2pLinkedInfo) => {
      console.info(`P2P connection change event: ${JSON.stringify(result)}`);
      wifiManager.getP2pLinkedInfo((err, data) => {
        if (err) {
          console.error(`Get P2P linked info failed: ${JSON.stringify(err)}`);
          return;
        }
        console.info(`P2P linked info: ${JSON.stringify(data)}`);
        if (data.connectState === wifiManager.P2pConnectState.P2P_CONNECTED) {
          console.info("P2P connection established successfully");
        }
      });
    };
    
    wifiManager.on("p2pConnectionChange", recvP2pConnectionChangeFunc);
    
    let recvP2pPeerDeviceChangeFunc = (result: wifiManager.WifiP2pDevice[]) => {
      wifiManager.getP2pPeerDevices((err, data) => {
        if (err) {
          console.error(`Get peer devices failed: ${JSON.stringify(err)}`);
          return;
        }
        for (let device of data) {
          if (device.deviceAddress === targetDeviceAddress) {
            let config: wifiManager.WifiP2PConfig = {
              deviceAddress: device.deviceAddress,
              deviceAddressType: 1,
              netId: -2,
              passphrase: "",
              groupName: "",
              goBand: 0
            };
            wifiManager.p2pConnect(config);
            console.info(`P2P connect request sent to ${targetDeviceAddress}`);
            break;
          }
        }
      });
    };
    
    wifiManager.on("p2pPeerDeviceChange", recvP2pPeerDeviceChangeFunc);
    wifiManager.startDiscoverDevices();
    
    setTimeout(() => {
      wifiManager.off("p2pConnectionChange", recvP2pConnectionChangeFunc);
      wifiManager.off("p2pPeerDeviceChange", recvP2pPeerDeviceChangeFunc);
    }, 125 * 1000);
  } catch (error) {
    console.error(`Connect P2P device failed: ${JSON.stringify(error)}`);
    throw error;
  }
}
```

### 步骤6:获取连接信息和IP地址

**示例代码**:
```typescript
import { wifiManager } from '@kit.ConnectivityKit';

async function getP2PConnectionInfo(): Promise<void> {
  try {
    let linkedInfo = await wifiManager.getP2pLinkedInfo();
    console.info(`P2P linked info: connectState=${linkedInfo.connectState}`);
    
    if (linkedInfo.connectState === wifiManager.P2pConnectState.P2P_CONNECTED) {
      let groupInfo = await wifiManager.getCurrentGroup();
      console.info(`Group owner IP: ${groupInfo.goIpAddress}`);
      console.info(`Group owner device address: ${groupInfo.owner.deviceAddress}`);
      
      return {
        connectState: linkedInfo.connectState,
        groupOwnerIP: groupInfo.goIpAddress,
        ownerAddress: groupInfo.owner.deviceAddress
      };
    } else {
      console.warn("P2P not connected yet");
      return null;
    }
  } catch (error) {
    console.error(`Get P2P connection info failed: ${JSON.stringify(error)}`);
    throw error;
  }
}
```

### 步骤7:错误处理和降级

**错误处理代码**:
```typescript
import { wifiManager } from '@kit.ConnectivityKit';

function handleP2PError(error: any, operation: string): void {
  console.error(`${operation} failed with error: ${JSON.stringify(error)}`);
  
  switch (error.code) {
    case 201:
      console.error("Permission denied. Solution: Check and request GET_WIFI_INFO permission");
      break;
    case 401:
      console.error("Invalid parameters. Solution: Verify config parameters format and values");
      break;
    case 801:
      console.error("Capability not supported. Solution: This device doesn't support P2P functionality");
      break;
    case 2801000:
      console.error("P2P module exception. Solution: Try restart Wi-Fi or reboot device");
      break;
    case 2801001:
      console.error("Wi-Fi STA disabled. Solution: Enable Wi-Fi first using enableWifi()");
      break;
    default:
      console.error(`Unknown error. Solution: Check network status and retry`);
  }
}

async function fallbackP2POperation(operation: string): Promise<void> {
  console.warn(`Primary P2P operation failed, attempting fallback for ${operation}`);
  
  if (!wifiManager.isWifiActive()) {
    console.warn("Fallback: Wi-Fi not active, waiting for user to enable Wi-Fi");
    return;
  }
  
  if (operation === "createGroup") {
    try {
      let config: wifiManager.WifiP2PConfig = {
        deviceAddress: "00:00:00:00:00:00",
        netId: -1,
        passphrase: "fallback123",
        groupName: "fallbackGroup",
        goBand: 0
      };
      await wifiManager.createGroup(config);
      console.info("Fallback: Created temporary group successfully");
    } catch (error) {
      console.error("Fallback: Create temporary group also failed");
    }
  }
  
  console.warn("Fallback: All fallback attempts failed, please check device status");
}
```

## 错误码说明

| 错误码 | 说明 | 解决方法 |
|-------|------|---------|
| 201 | 权限被拒绝 | 检查并申请ohos.permission.GET_WIFI_INFO权限 |
| 401 | 参数校验失败 | 检查config参数格式和取值范围,确保deviceAddress格式正确 |
| 801 | 系统能力不支持 | 设备不支持P2P功能,提示用户更换设备或放弃此功能 |
| 2801000 | P2P模块异常 | 重新执行关闭及打开Wi-Fi开关的操作,或重启设备 |
| 2801001 | Wi-Fi STA未打开 | 先使用enableWifi()开启Wi-Fi功能 |
| 2501003 | 服务打开失败 | 服务正在关闭,重新执行打开服务操作 |
| 2501004 | 服务关闭失败 | 服务正在打开,重新执行关闭服务操作 |

## 编译和修复问题

### 依赖声明
```json
{
  "dependencies": {
    "@kit.ConnectivityKit": "^1.0.0",
    "@kit.PerformanceAnalysisKit": "^1.0.0"
  }
}
```

### 环境要求
- HarmonyOS API version 9及以上
- SystemCapability.Communication.WiFi.P2P系统能力
- 开发环境:DevEco Studio 3.1及以上

### 常见编译问题

**问题1:导入模块失败**
```
Cannot find module '@kit.ConnectivityKit'
```
**解决方法**:确保在module.json5中正确配置依赖,并在DevEco Studio中同步项目

**问题2:权限未声明**
```
Permission denied error code 201
```
**解决方法**:在module.json5的requestPermissions中添加:
```json
{
  "name": "ohos.permission.GET_WIFI_INFO"
}
```

**问题3:系统能力不支持**
```
Capability not supported error code 801
```
**解决方法**:检查设备是否支持P2P功能,可以在代码中动态判断系统能力

**问题4:Wi-Fi未开启**
```
Wi-Fi STA disabled error code 2801001
```
**解决方法**:调用enableWifi()开启Wi-Fi,或提示用户手动开启

## 常见问题与解决方法

### Q1:P2P连接总是失败怎么办?
**原因**:可能是Wi-Fi未开启、权限未获取、设备距离过远、目标设备不支持P2P
**解决方法**:
- 检查Wi-Fi是否已开启(使用isWifiActive)
- 检查权限是否已申请(ohos.permission.GET_WIFI_INFO)
- 检查目标设备是否支持P2P功能
- 缩短设备间距离(建议10米以内)
- 尝试重启两台设备的Wi-Fi功能

### Q2:如何判断P2P连接是否成功?
**原因**:P2P连接是异步过程,需要监听事件回调
**解决方法**:
- 注册"p2pConnectionChange"事件监听
- 在回调中检查WifiP2pLinkedInfo的connectState
- connectState为P2P_CONNECTED表示连接成功
- 可以使用getP2pLinkedInfo()主动查询连接状态

### Q3:永久组和临时组有什么区别?
**原因**:两种群组类型的重连机制不同
**解决方法**:
- 永久组(netId=-2):下次连接不需要重新GO协商和WPS密钥协商,适合长期固定的设备连接
- 临时组(netId=-1):每次连接都需要重新GO协商和WPS密钥协商,适合临时性的设备连接
- 根据实际使用场景选择合适的群组类型

### Q4:作为GO能否主动发起连接?
**原因**:P2P协议规定Group Owner不能主动发起连接
**解决方法**:
- 作为GO(Group Owner)时,只能等待其他设备连接
- 如果需要主动连接,应使用Client角色
- 可以通过netId参数控制设备角色

### Q5:如何获取对端IP地址进行Socket通信?
**原因**:连接成功后才能获取IP地址
**解决方法**:
- 确保P2P连接状态为P2P_CONNECTED
- 使用getCurrentGroup()获取群组信息
- 从WifiP2pGroupInfo中获取goIpAddress
- 使用goIpAddress作为Socket通信的目标地址
- 参考Socket通信技能进行后续开发

## 输出结果报告

执行完成后输出以下信息:

```json
{
  "status": "success",
  "operation": "P2P connection established",
  "groupInfo": {
    "groupName": "testGroup",
    "passphrase": "12345678",
    "netId": -2,
    "ownerAddress": "00:11:22:33:44:55",
    "groupOwnerIP": "192.168.49.1"
  },
  "connectionInfo": {
    "connectState": "P2P_CONNECTED",
    "deviceAddress": "00:11:22:33:44:55"
  },
  "apiUsed": [
    "wifiManager.isWifiActive",
    "wifiManager.createGroup",
    "wifiManager.removeGroup",
    "wifiManager.startDiscoverDevices",
    "wifiManager.getP2pPeerDevices",
    "wifiManager.p2pConnect",
    "wifiManager.getP2pLinkedInfo",
    "wifiManager.getCurrentGroup",
    "wifiManager.on",
    "wifiManager.off"
  ]
}
```

## 参考文档

- [P2P模式开发指南](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/p2p-development-guide)
- [WLAN API参考](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-wifimanager)
- [WIFI错误码](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/errorcode-wifi)

## 完整示例代码

- [创建P2P群组示例](assets/p2p-create-group.ets)
- [建立P2P连接示例](assets/p2p-connect.ets)
- [完整P2P开发示例](assets/p2p-complete-example.ets)
- [配置文件示例](assets/module-config.json)

## 测试用例

### 正向测试用例
- [创建永久组测试](tests/test_create_permanent_group.py):验证netId=-2的永久组创建成功
- [建立P2P连接测试](tests/test_p2p_connect.py):验证两台设备成功建立P2P连接
- [获取连接信息测试](tests/test_get_connection_info.py):验证连接成功后能正确获取IP地址

### 边界测试用例
- [最小密钥长度测试](tests/test_min_passphrase_length.py):验证passphrase最小8字符边界
- [临时组和永久组切换测试](tests/test_group_type_switch.py):验证netId=-1和-2的切换
- [超时扫描测试](tests/test_discovery_timeout.py):验证125秒扫描超时处理

### 异常测试用例
- [Wi-Fi未开启测试](tests/test_wifi_disabled.py):验证Wi-Fi未开启时的错误处理
- [权限不足测试](tests/test_permission_denied.py):验证缺少权限时的降级方案
- [设备地址格式错误测试](tests/test_invalid_device_address.py):验证非法MAC地址的参数校验
- [系统能力不支持测试](tests/test_capability_not_supported.py):验证不支持P2P设备的处理

Files in this skill

  • SUB_SKILL.md18.3 KB
  • assets/module-config.json1.4 KB
  • assets/p2p-complete-example.ets6.1 KB
  • assets/p2p-connect.ets3.7 KB
  • assets/p2p-create-group.ets3.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…