设备认证 SDK(安卓)

注意:License 计费不再支持使用设备认证 SDK 认证的设备,请尽快切换到使用 WMPF 认证设备,无需维护 deviceToken,接入更便捷。

在系统集成 rpmbd 后,开发者需要在 Launcher 应用中接入设备认证 SDK,SDK 主要提供以下能力:

  • 注册设备 registerDevice:将 model_id 和 SN 与设备绑定。一旦成功后 model_id 和 SN 不可修改
  • 获取设备凭证 getDeviceToken:进行设备认证并从微信后台获取凭证,设备端发起通话时传给 VOIP 通话插件的 initByCaller 接口的 voipToken 参数。

1. 下载 SDK

请在 此处 下载 SDK 的 aar 文件。

建议使用 1.3 及以上版本(物联网卡应使用 1.3.1 及以上版本)。低版本不支持并发调用 registerVoipDevice,请务必注意在前一次调用返回前不要重复调用。

  • v1.5.0 及以上版本需集成 voipsdk-x.x-release.aarsafeguard-release.aar 两个 aar 文件
  • v1.3.1 及以下版本只需集成 voipsdk-x.x-release.aar

注意:使用设备认证 SDK 前,需先保证 rmpbd 服务正常运行。

2. 接口文档(v1.5.0及以上版本)

2.1 注册设备 registerDevice

将 model_id 和 SN 与设备绑定,一旦成功后 appid、model_id、SN 均不能更换。

int registerDevice(String appid, String model_id, String sn, String sn_ticket) throws Exception

注意事项(调用前必读

  • 注册设备成功后,会将 SN 固化至 EMMC/RPMB 分区中,标定此设备的唯一身份。SN 和 model_id 一经写入后续即不可更改
  • 此处使用的 SN,必须经过 WMPF 的 addDevice 接口作为 deviceId 注册,并与 WMPF 设备激活 使用的 deviceId 一致。 否则后续无法正常发起通话。
  • 注册成功后会在本 APK 的存储里存放数字证书,如果 APK 有变动(Android 系统认为应用变更了),则证书失效(会报错cert fail),可以清理 APK 的数据再以相同的 appid、model_id、SN调用接口重新申请即可。
  • 注册过程会有网络请求,时长根据网络情况会有所不同。高版本 android 不允许在主线程里进行网络请求,可以加处理或在线程里来调用 sdk。

参数说明

参数 类型 说明
appid String 微信小程序的 appid
model_id String 设备接入时从「微信小程序管理后台」申请获得的 model_id
sn String 设备序列号。厂商自己生成,长度不能超过 128 字节。字符只接受数字,大小写字母,下划线(*)和连字符(-)。
此处使用的 sn 必须与 WMPF 激活设备使用的 deviceId 一致
sn_ticket String 通过获取设备票据接口获得

返回值

其他异常说明请参考设备验证常见问题

名称 描述
OK 0 成功
ERR_ARGS -1 参数错误
ERR_IO -2 通用 IO 错误
ERR_KEY_IO -3 KEY 不匹配
ERR_RESPONSE -4 网络请求无回复
ERR_PEM -5 权限错误
ERR_INVALID_KEY -6 KEY 不可用
ERR_SERVICE -7 rpmbd 服务没运行
ERR_EMMC_UFS_CONFUSED -8 EMMC/UFS 不匹配。里面已经存在 SN
ERR_EMMC_UFS_IO -9 EMMC/UFS IO 错误
ERR_REG_NOPEM -10 密钥不存在

2.2 获取设备凭证 getDeviceToken

进行设备认证,并从微信后台获取设备凭证。设备发起通话时需要将这一凭证传给 VOIP 通话插件的 initByCaller 接口的 voipToken 参数。

String getDeviceToken(String appid, String model_id) throws Exception

如果设备是使用 v1.5 及以上版本 SDK 进行注册设备的,可以使用无参数的版本。

String getDeviceToken() throws Exception

参数说明

参数 类型 说明
appid String 微信小程序的 appid
model_id String 设备接入时从「微信小程序管理后台」申请获得的 model_id

注意事项

  • 接口耗时与网络有关,正常会在 1 秒左右。高版本 android 不允许在主线程里做,可以加处理或在线程里来调用 sdk。
  • ticket 有一个小时的有效期,一个小时内可被多次通话复用。建议开发者在用户发起通话前,提前调用 getCallerTicket 并缓存,避免在发起通话时再进行获取,以缩短发起通话时的用户等待时长。

2.3 获取设备 SN getDeviceSn(仅调试用)

获取 registerDevice 接口写入的 SN。

String getDeviceSn()

2.4 获取设备 modelId getDeviceModelid(仅调试用)

获取使用 registerDevice 接口写入的 modelId。仅在设备是使用 v1.5 及以上版本 SDK 进行注册设备时有效。

String getDeviceModelid()

3. 接口文档(v1.3.1 及以下版本)

3.1 初始化 init

SDK 初始化,其它接口在调用之前需要保证 init 成功。

boolean init()

3.2 注册设备 registerVoipDevice

参考 2.1 registerDevice

  • 1.3 以下版本 SDK,此接口严禁并发执行,务必在逻辑中保证一次 registerVoipDevice 返回后才能再次调用。

3.3 获取拨打方票据 getCallerTicket

参考 2.2 getDeviceToken

3.4 获取设备 SN GetDeviceSn(仅调试用)

同 2.3 getDeviceSn

设备认证 TEE 规范

1. 背景

设备身份是微信 VOIP 业务能够正常运行的基础,开发者在接入 VOIP 业务时,会通过如下两个流程来进行身份的确定:

  1. 设备注册。通过 SN + modelId 两个维度来标定这台设备。
  2. 拿票据。在进行 VOIP 通话前,需要拿到这台设备所对应的票据。

对于没有 TEE 的机器,我们要求设备系统里能够操作 EMMC 存储的 RPMB 区域,并且需要将 RPMB 的归属权给到 VOIP 业务,VOIP 在设备注册时会将与设备对应的唯一密钥写入存储的 KEY 区域,用来做身份校验。

而对于有 TEE 的机器,我们信赖 TEE 的结果,但需要 TEE 里按照规范完成 TA 的开发。

2. TA 开发

不管是 optee,还是 trusty 或 qsee 等,TEE 的使用流程通常如下:

打开 TEE 环境 > 开启一个会话 > 发送命令 > 获取信息 > 结束会话 > 关闭 TEE 环境

这里我们需要定义如下标准:

  1. 会话名称。
  2. 命令的功能。
  3. 命令的交互数据定义。
  4. TA 里的运算逻辑

设备开发者需要根据规范进行如下开发:

  1. TA 开发,需要开发者或 tee 提供商按照规范开发 TA。
  2. HAL 开发,HAL 用于与 TA 的交互,微信的系统服务基于此 HAL。
  3. 服务集成,将微信发布的 rpmbd_tee 以系统服务方式运行起来。

TA 在逻辑上将存储分为两个区域。需要注意的是,这些数据最终应都存在于 EMMC 或 UFS 的 rpmb 分区,或其它 REE 访问不到的安全器件区域。

  1. 密钥区:32个字节。TA 代码逻辑里需要将此区域实现成只能写一次,类似于硬件上的 OTP (One Time Programmable) 区域。
  2. 数据区:单位为 Block,每个 Block 有 256 个字节,最小需要 32 个,开发者可根据实际情况来确定大小,若越界则返回相应错误码即可。Block 的地址从 0 开始。

2.1 会话名称

TA 的名称统一为 ta_devauth

2.2 命令定义

定义三个命令,分别是读数据、写数据、写密钥。

#define TA_DEVAUTH_CMD_READ   0x10
#define TA_DEVAUTH_CMD_WRITE  0x11
#define TA_DEVAUTH_CMD_PROKEY 0x12

详细说明:

命令 TA_DEVAUTH_CMD_READ 0x10
功能 读 1 个 Block 的数据
参数 输入:Block 地址
输入/输出:Block 数据 BUFFER,284字节,见 2.3 数据定义。
输出:签名 BUFFER,=32字节
返回 0:成功读取,并返回 284 字节数据和 32 字节签名
-1:参数错误。
-2:地址越界。
-3:密钥区还没被写。
-5:其它错误。
特别说明 若密钥区还没被写(例如裸数据全是0x00,或没有TEE文件系统里的文件?),这种情况认为是一台全新的未激活设备,需要读取错误返回 -3。
命令 TA_DEVAUTH_CMD_WRITE 0x11
功能 写 1 个 Block 的数据
参数 输入:Block 地址
输入:Block 数据 BUFFER,=284字节,见 2.3 数据定义。
输入:对应的签名 BUFFER,=32字节
返回 0:写入成功。
-1:参数错误。
-2:地址越界。
-3:密钥区还没被写。
-4:签名错误。
-5:其它错误。
特别说明 若密钥区还没被写(例如裸数据全是0x00,或没有TEE文件系统里的文件?),这种情况认为是一台全新的未激活设备,需要返回 -3。
此功能在写数据前,需要计算数据对应的签名,并且与参数传入的签名比对,若比对不成功返回 -4
命令 TA_DEVAUTH_CMD_PROKEY 0x12
功能 写密钥
参数 密钥 BUFFER,=32字节
返回 0:写入成功。
-1:参数错误。
-3:密钥区已有数据。
-5:其它错误。
特别说明 若密钥区已有数据(例如裸数据不为0x00,或有文件?),则需要返回 -3。

2.3 数据定义

与 TA 交互时传入传出 Buffer 的大小为 284 字节,它的定义如下:

struct ta_data {
    uint8_t  data[256];    // 此 256 字节是 TA 写入到1个Block的内容
    uint8_t  nonce[16];    // 一般为随机字节,传入与传出的一定要一致。
    uint32_t reserve1;
    uint16_t reserve2;
    uint16_t reserve3;
    uint16_t reserve4;
    uint16_t reserve5;
};

// sizeof(struct ta_data) = 284

签名 Buffer 大小为 32 字节


CA 与 TA 交互消息定义:

struct ta_message {
    uint32_t        cmd;        // 命令号
    uint32_t        block;      // 读写地址
    struct ta_data  data;       // 284 字节数据
    uint8_t         key[32];    // 32 字节 Key
    uint8_t         hmac[32];   // 32 字节 hmac
    int             ret;        // 返回值
};

CA 侧参考伪代码:

static int tee_send_cmd_req(struct ta_message* ta_msg) {
    int rc = 0;

    if (ca_handle == 0) {
        printf("not connected\n");
        return -EINVAL;
    }

    if (tee_send_msg(ca_handle, ta_msg) < 0) {
        return -1;
    }

    if (tee_resp_msg(ca_handle, ta_msg) < 0) {
        return -1;
    }

    return 0;
}

2.4 运算逻辑

数据签名的算法为 HMAC_SHA256。

读数据时,TA 的流程:

  1. 若密钥区没数据,返回 -3。
  2. 读地址参数对应 Block 的 256 字节数据。
  3. 将读到的 256 字节与输入参数里的 16 字节 noce 以及其它 reserve,一共有 284 个字节。
  4. 利用密钥区的 32 字节密钥,对 284 字节进行签名,并返回 284 字节以及签名。

写数据时,TA 的流程:

  1. 若密钥区没数据,返回 -3。
  2. 得到输入参数里的 284 字节,得到输入参数中的签名1。
  3. 利用密钥区的 32 字节密钥,对 284 字节进行签名,得到签名2。
  4. 比较签名1与签名2,如果相等则将 284 字节中的 256 字节写入对应的 Block,如果不等则返回错误 -4。

写密钥时,TA 的流程:

  1. 若密钥区已有数据,返回 -3。
  2. 将 32 字节的密钥写入密钥区。

一个签名的数据示例,开发者可以此为基准来验证自己的 hmac_sha256:

char *key = "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHH";
uint8_t buffer[284] = {0};

int main(int argc, char **argv) {
    uint8_t hmac[32] = {0};
    memset(buffer, 0x55, 284);

    hmac_sha256(key, 32,
      buffer, 284,
      hmac, sizeof(hmac)
    );

    for (int i=0; i < 32; i++) {
        printf("%02x ", hmac[i]);
    }
    return 0;
}
// 以上代码输出:
// 61 16 67 22 a0 93 66 74 bb 75 f8 87 0e 5e d4 59 2c d6 99 c0 14 a6 93 70 bd ff ea 3e 8e 84 52 4e 

hmac_sha256 为标准算法,一般 tee 里已有此类算法,如果没有,可参考开源实现

2.5 注意事项

  1. TEE 里的密钥区和数据区需保证具有 “永久存储” 特性,并且不应该被 REE 以任何方式直接访问,不会随用户的刷机、升级或其它常规行为而丢失。
  2. 密钥区域需要实现为 OTP 特性,即仅一次写入。
  3. 密钥区域无数据时,需要按规范返回错误码。
  4. 厂商需要将 CA 测试例程和代码给到微信,微信进行验收测试。

3. HAL 开发

按照 HAL 规范完成 HAL 的开发,HAL 里使用 CA 代码与 TA 进行交互,完成 TEE 的使用。

HAL 路径:android/hardware/interface/devauth

3.1 HAL 规范

types.hal

package android.hardware.devauth@1.0;

enum TA_CMD : uint32_t {
    TA_DEVAUTH_CMD_READ = 0x10,
    TA_DEVAUTH_CMD_WRITE = 0x11,
    TA_DEVAUTH_CMD_PROKEY = 0x12,
};

struct ta_data {
    uint8_t[256] data; // 此 256 字节是 TA 写入到1个Block的内容
    uint8_t[16]  nonce; // 一般为随机字节,传入与传出的一定要一致。
    uint32_t reserve1;
    uint16_t reserve2;
    uint16_t reserve3;
    uint16_t reserve4;
    uint16_t reserve5;
};

struct ta_message {
    uint32_t        cmd;        // 命令号
    uint32_t        block;      // 读写地址
    ta_data         data;       // 284 字节数据
    uint8_t[32]     key;        // 32 字节 Key
    HMacBuffer      hmac;       // 32 字节 hmac
    int8_t          ret;        // 返回值
};

typedef uint8_t[32] HMacBuffer;
typedef uint8_t[32] ProKeyBuffer;

typedef ta_data ta_data_t;
typedef ta_message ta_message_t;

IDevauth.hal

package android.hardware.devauth@1.0;

interface IDevauth {

    /**
     * 读 Block 数据
     *
     * @param addr:     Block 地址
     * @param data:     输入的 struct ta_data
     * @return retval:  返回值,返回值说明请见规范
     * @return data:    返回的 struct ta_data,284 字节。
     * @return hmac:    返回的签名, 32 字节。
     *
     */
    read_block(uint16_t addr, ta_data data) generates (int8_t retval, vec<uint8_t> data, vec<uint8_t> hmac); 

    /**
     * 写 Block 数据
     *
     * @param addr:     Block 地址
     * @param data:     输入输出数据,对应规范里的 struct ta_data,284 字节。
     * @param hmac:     HAL 写数据时用的签名, 32 字节
     *
     * @return retval:  返回值说明请见规范
     */
    write_block(uint16_t addr, ta_data data, HMacBuffer hmac) generates (int8_t retval); 

    /**
     * 写 Key
     *
     * @param key:      32 字节key
     *
     * @return retval:  返回值说明请见规范
     */
    program_key(ProKeyBuffer key) generates(int8_t retval);
};

3.2 开发参考

hardware/interfaces/devauth/1.0/ 下放置 IDevauth.haltypes.hal,内容如上。

然后使用如下方式来生成代码:

LOC=hardware/interfaces/devauth/1.0/default
PACKAGE=android.hardware.devauth@1.0
hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport ${PACKAGE}
hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport ${PACKAGE}
./hardware/interfaces/update-makefiles.sh

此时 hal 目录应该如下:

root~/android> tree hardware/interfaces/devauth/
hardware/interfaces/devauth/
└── 1.0
    ├── Android.bp
    ├── default
    │   ├── Android.bp
    │   ├── Devauth.cpp
    │   └── Devauth.h
    ├── IDevauth.hal
    └── types.hal

2 directories, 6 files

再按照 HAL 接口定义,在相应的接口函数里完成 CA 代码的开发即可。

4. 验收

4.1 提交资料

  • ✓ 芯片平台,存储类型。例:MTK81xx、EMMC 64GB
  • ✓ REE 操作系统详细信息。例:Android 7 64位
  • ✓ TEE 系统详细信息。例:基于 optee 的自研 tee,提供商为 xxx
  • ✓ TEE 里数据存储位置。例:EMMC 里的 RPMB 分区
  • ✓ TEE 侧的 TA 代码。例:ta_devauth 模块代码
  • ✓ REE 侧的 CA 代码。例:测试用例代码包及相应 TEE 功能 so。
  • ✓ REE 侧的 HAL 代码。例:hardware/interface/devauth 下的代码。
  • ✓ 能 adb root 的样机。

4.2 测试用例

开发者完成 TEE 的 TA 开发后,应该进行测试用例开发,以验证 TA 的功能与逻辑。 前置条件:ta_deauth 所管理的区域无任何数据,再按顺序进行以下测试项。

  1. 读数据测试,预期返回 -3
  2. 写数据测试,预期返回 -3
  3. 写密钥测试,预期返回 0
  4. 写密钥测试,预期返回 -3
  5. 读数据测试,预期返回 0,且数据全是 0x00 且有签名。
  6. 用正确的 HMAC 写数据测试,预期返回 0
  7. 用错误的 HMAC 写数据测试,预期返回 -4
  8. 读数据测试,预期返回 0,并且返回正确的数据和签名。

可在官方测试用例代码的基础上,加上自己的 CA 实现,以快速验证 TA。

开发者完成 HAL 开发后,可用测试用例进行测试,

也可以直接下载已编译好的 tee_hal_test 进行测试,测试方法如下

  1. tee_hal_test a 进行一次全新的测试,需要一个 ta_devauth 所管理的区域无任何数据。
  2. tee_hal_test 不带任何参数,可在 1. 后运行。

4.3 集成

4.2 中的测试用例通过后,下载 rpmbd_tee 并集成到系统中以服务方式运行起来即可,参考:

service rpmbd_tee /system/bin/rpmbd_tee
  class main
  user root
  group root system

穿戴设备微信小程序框架

1. 产品介绍

微信小程序框架已适配手表穿戴类设备,可针对 RTOS(实时操作系统)等低功耗设备场景,实现最小可用的微信小程序运行。

2. 技术方案

由于市场主流穿戴设备的 CPU 性能和内存大小十分有限(整机内存小于 8M),我们针对性实现了最小可用的微信小程序框架,提供:

  1. 熟悉的 WXML + WXSS + JS 的微信小程序开发体验
  2. 最必要的微信小程序 wx 接口
  3. 基本完整的微信小程序页面框架和组件系统
  4. 基础的 WXSS 样式和内置组件支持
  5. 微信小程序代码包编译器
  6. 模拟调试环境

穿戴设备的硬件资源十分有限。为减小存储占用,该微信小程序框架只提供普通微信小程序的功能子集,请开发者严格按照本文档提供的特性列表实现微信小程序。由于接口能力的差异较大,一般需要开发者针对穿戴设备单独开发新的微信小程序。

2.1 UI能力

2.1.1 组件框架

可以使用微信小程序中 Page、Component能力。支持完整的 WXML、WXSS 语法。

2.1.1.1 支持的特性

可以在微信小程序中使用 App、getApp、Page、getCurrentPages、Component。支持 ES6 import / export 与 CommonJS require 两种 JS 模块加载机制。

2.1.1.2 使用差异

使用微信小程序组件框架时应注意下列差异:

  • 组件的 styleIsolation 需在 JSON 中配置,不支持在组件 options 中指定
  • 不再支持 addGlobalClass,请使用 styleIsolation 代替
  • 当使用组件间通信与事件时,可以直接定义 export 属性,不需要声明 wx://component-export
2.1.1.3 暂未支持的特性

以下能力暂未支持

  • Chaining API

  • behavior

  • WXS

  • 暂不支持自定义组件的下列方法:

    • createSelectorQuery
    • createIntersectionObserver
    • createMediaQueryObserver
    • getTabBar
    • animate
    • clearAnimation
    • applyAnimatedStyle
    • clearAnimatedStyle
    • setUpdatePerformanceListener

2.1.2 内置组件

目前仅支持下列内置组件

2.1.2.1 view

属性:无

2.1.2.2 image

属性:

属性 类型 默认值 必填 说明
src string 图片资源地址。如果使用代码包内图片资源,src需为绝对路径。

说明:

  • 不建议显示高清图片。部分穿戴设备的屏幕分辨率边长仅 200~300 像素,且内存有限,过大图片无法清晰渲染且可能导致内存溢出。
  • 不建议使用图片组件显示微信小程序码、二维码、条形码等,建议使用 qrcode 组件。
2.1.2.3 text

属性:无

2.1.2.4 qrcode

穿戴设备微信小程序框架的专属组件,能够根据输入的文本生成并渲染二维码。

考虑到资源消耗,穿戴设备不建议使用图片展示二维码。
对于需要展示微信小程序码的情况,可以参考扫普通链接二维码打开微信小程序

属性 类型 必填 默认值 说明
value string “” 二维码文本内容
light-color HexColor #000000 二维码颜色
dark-color HexColor #FFFFFF 二维码背景颜色
2.1.2.5 scroll-view
属性 类型 默认值 必填 说明
enable-flex boolean false 启用 flexbox 布局。开启后,当前节点声明了 display: flex 就会成为 flex container,并作用于其孩子节点。
2.1.2.6 swiper/swiper-item

swiper 支持属性:

属性 类型 默认值 必填 说明
current number 0 当前所在滑块的 index
bind:change eventhandle current 改变时会触发 change 事件,event.detail = {current, source}

2.1.3 WXSS样式

  • display: block/flex(支持弹性盒子布局),不支持 inline/inline-block/inline-flex/grid
  • position 绝对布局(top、right、bottom、left)
  • width、height、margin、padding 等组件尺寸设置
  • color 等文本属性
  • border 相关属性:border-radius 不支持分别设置四角圆角大小,不支持百分比写法。
  • background 相关属性: background-image, background-color
  • font-size 等字体设置暂不支持

不支持子元素选择器、后代选择器、接续兄弟选择器、后续兄弟选择器,若有相关开发需求,请通过普通选择器实现。
注意:WXML支持内联样式,但不支持binding(不可以通过setData()修改WXML组件的style属性值)。

2.2 微信小程序配置

2.2.1 app.json

配置项:
属性 类型 必填 说明
entryPagePath string 微信小程序默认启动首页
pages string[] 页面路径列表
networkTimeout Object 网络超时时间
window Object 全局的默认窗口表现
usingComponents Object 全局自定义组件配置
window:

用于设置微信小程序的状态栏、导航条、标题、窗口背景色。穿戴设备微信小程序框架只支持设置窗口背景色。

属性 类型 必填 默认值 说明
backgroundColor HexColor #FFFFFF 窗口的背景色
networkTimeout

各类网络请求的超时时间,单位均为毫秒。穿戴设备微信小程序框架只支持设置request的超时时间。

属性 类型 必填 默认值 说明
request number 60_000 wx.request 的超时时间,单位:毫秒。

2.2.2 component.json

配置项
属性 类型 必填 说明
component boolean 一个自定义组件由 json、wxml、wxss、js 4个文件组成。如设置component为true,将声明这一组文件为自定义组件
styleIsolation string 样式隔离
usingComponents Object 全局自定义组件配置
styleIsolation
说明
isolated 启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响(一般情况下的默认值)
apply-shared 表示页面 wxss 样式将影响到自定义组件,但自定义组件 wxss 中指定的样式不会影响页面
shared 表示页面 wxss 样式将影响到自定义组件,自定义组件 wxss 中指定的样式也会影响页面和其他设置了 apply-shared 或 shared 的自定义组件。

2.2.3 page.json

每一个微信小程序页面可以使用同名.json文件来对本页面的窗口表现进行配置,页面中配置项会覆盖 app.json 的 window 中相同的配置项。

配置项:
属性 类型 必填 默认值 说明
backgroundColor HexColor #FFFFFF 窗口的背景色

2.3 接口能力

  • JSAPI 调用方式与完整版一致,支持回调和 Promise 两种调用形式,详情请参考相关文档。
  • 本节仅说明和完整版的差异部分,完整的 API 接口说明请参考官网文档。为避免重复,本文省略参数中 success/fail/complete 回调函数的说明,如无特殊说明,均提供与完整版一致的 success/fail/complete 回调接口

2.3.1 微信生态能力

  • wx.login:一致
  • wx.checkSession: 一致
  • wx.getAccountInfoSync:一致

2.3.2 系统信息

  • wx.getWindowInfo:一致。额外增加返回值 screenShape。
  • wx.getDeviceInfo: 仅支持返回 brand、model、system、platform、cpuType、memorySize。额外增加返回值 deviceType。

wx.getWindowInfo 新增返回值

属性 类型 说明
screenShape string rect: 方形屏幕;round 圆形屏幕

wx.getDeviceInfo 新增返回值

属性 类型 说明
deviceType string 可选值:watch, phone, tv, vehicle, pc

注意:

本框架不提供wx.getSystemInfo系列接口,请使用getWindowInfo/getDeviceInfo代替。

2.3.3 网络请求

wx.request()

  • 参数仅支持 url、data、header、timeout、method(仅支持GET, POST)、dataType、responseType、redirect。
  • 返回的 RequestTask 仅支持 abort
  • success 回调参数仅支持 data、statusCode、header
  • fail 回调参数一致

注意

  • 目前暂未提供文件系统支持,故暂未支持 wx.downloadFile/wx.uploadFile。
  • 目前仅支持https,不支持TCP、UDP、WebSocket等其他类型的网络请求。

2.3.4 页面路由

  • wx.navigateTo:参数仅支持 url
  • wx.navigateBack:一致
  • wx.redirectTo:一致
  • wx.reLaunch:一致

注意:暂未提供tabBar

2.3.5 数据存储

  • wx.getStorageInfo(sync):一致
  • wx.setStorage(Sync):参数仅支持 key、data
  • wx.getStorage(Sync):参数仅支持 key
  • wx.removeStorage(Sync):一致
  • wx.clearStorage(Sync):一致

注意

  1. 目前只提供KV存储,暂不提供文件存储。
  2. 暂不支持加密存储

2.3.6 UI

  • wx.showToast:一致
  • wx.hideToast:参数不支持 noConflict,toast 和 loading 默认不可混用
  • wx.showLoading:一致
  • wx.hideLoading:参数不支持 noConflict,toast 和 loading 默认不可混用
  • wx.showModal:参数不支持 editable 和 placeholderText
  • wx.getMenuButtonBoundingClientRect:一致

注意:暂无 navigationBar、tabBar、homeButton

2.3.7 生命周期

  • wx.getLaunchOptionsSync:参数仅支持 path、scene、query
  • wx.getEnterOptionsSync:参数仅支持 path、scene、query
  • wx.onUnhandledRejection:一致
  • wx.onError:一致
  • wx.onPageNotFound:一致
  • wx.onAppShow:参数仅支持 path、scene、query
  • wx.onAppHide:一致

2.3.8 事件

  • bind:touchstart
  • bind:touchend
  • bind:tap
  • bind:longpress

其中事件对象仅支持 type, target, currentTarget 字段,target/currentTarget 仅支持 dataset 字段。

2.3.9 其他

  • console.log/info/error/warn/debug:输出会打印在模拟器的命令行窗口中,可以通过 console.log 调试微信小程序逻辑。
  • setTimeout/clearTimeout
  • setInterval/clearInterval

2.4 其他差异

  • 暂不支持微信小程序插件
  • 暂不支持微信小程序分包

3. 开发流程

3.1 注册穿戴设备微信小程序框架专属AppID

前置条件:名下需有普通微信小程序的AppID,并作为该微信小程序的管理员。
步骤:

  1. 打开微信开发者平台
  2. 扫码登录
  3. 点击「前往控制台」

前往控制台

  1. 选择「我的业务–微信小程序」

选择小程序

  1. 页面右上角,切换到穿戴设备微信小程序要挂靠的普通微信小程序。
  2. 切换到「硬件设置」
  3. 点击「申请创建」

申请创建

  1. 创建成功,获得「穿戴端AppID」

创建成功

3.2 安装开发者工具拓展

  1. 打开「微信开发者工具」(需使用版本号 ≥ 2.01.2507252,建议下载最新 nightly 版开发者工具进行使用)
  2. 在「工具栏」选择「设置–拓展设置」
  3. 在弹出的页面中,左侧选择「模拟器插件」,右侧选择安装「低功耗硬件微信小程序模式」

低功耗硬件小程序模式

3.3 启用低功耗微信小程序模式

装好插件后,将开发模式切换到「低功耗硬件微信小程序模式」

切换模式

3.4 开发调试

点击「详情」,确保其中设置的AppID与微信开发者平台一致。

详情

我们不建议开发者将JS代码编译为ES5。穿戴设备微信小程序框架支持ES2023,减少不必要的polyfill有助于显著节省最终微信小程序代码包体积,进而节省运行时内存占用。

3.5 体验与发布

完成开发后,可在「微信开发者工具」中点击「上传」。新上传的版本将覆盖旧的「开发版微信小程序」。
开发者可以前往微信开发者平台,管理微信小程序版本、提交审核、发布上线。

4. 联系我们

有合作意向的硬件厂商、微信小程序开发者,欢迎发送邮件联系我们:wx_iot@tencent.com

微信小程序音视频通话+摄像头(for 硬件)

接入流程和常见问题也可参考微信小程序音视频通话(for 硬件) 使用手册

1. 产品介绍

1.1 微信小程序 Voip

借助微信小程序音视频通话插件,硬件开发者可以通过微信小程序硬件框架(WMPF)、Linux SDK 接入、云云接入三种方式实现智能设备和手机微信端的一对一音视频通话,满足实时触达场景,提升通话体验。

下图为手机端的示意图,授权弹窗、通话提醒、通话界面为微信提供的统一界面,硬件微信小程序接入微信 VOIP 通话插件后,可实现上述功能。

适用于校园话机、门禁机、智能门锁、智慧中控屏、智能电视、智能摄像头、智能音箱、智慧养老等多种设备和场景,支持硬件设备和手机端双向通话,实现通话强提醒。

1.2 微信小程序摄像头

借助微信小程序音视频通话插件里的摄像头能力,开发者能够快速的将摄像头类产品接入微信小程序生态(云对云的方式),用户查看摄像头流媒体也更加方便,培养用户微信小程序观看摄像头的习惯。

针对摄像头涉及的功能,分成组件必选、组件可选、自定义等部分。

类型 模块 功能点 描述
组件必选 播放器 播放 播放、暂停
组件必选 播放器 画面缩放 放大、缩小
组件必选 播放器 音量 音量、静音
组件必选 播放器 屏幕 小屏、全屏
组件必选 对讲 设备呼叫手机 VoIP功能
组件可选 播放器 清晰度 开发者传入
组件可选 对讲 手机呼叫设备 呼叫、挂断
自定义(举例) 轮盘 方向控制 一般用来控制摄像头转动
自定义(举例) 增值服务 云存储
自定义(举例) 增值服务 AI服务

微信小程序界面

全屏界面

2. 设备要求

目前支持安卓系统、Linux 系统、RTOS 系统的设备。每台设备只能绑定一个微信小程序,只能和一个微信小程序进行通话。

目前支持 「设备直连」和「云对云」 两种接入模式:

  • 设备直连:支持安卓和 Linux 设备。由设备端直接向微信后台发送并接受音视频流和信令,与用户手机微信内的微信小程序进行通话。
  • 云对云:支持无法满足设备直连硬件需要的低功耗 Linux、RTOS 等系统设备。设备端仅进行设备验证,由开发者后台(服务端)向微信后台转发音视频流和信令,与用户手机微信内的微信小程序进行通话。

2.1 设备直连(安卓)

安卓系统设备端运行微信小程序硬件框架(WMPF),WMPF 内运行开发者微信小程序,直接与用户手机微信内的微信小程序进行通话;

设备应满足下列基本要求:

  • 具有音视频能力(麦克风、摄像头等硬件设备);
  • 满足微信小程序设备认证的设备要求;
  • 满足安卓微信小程序硬件框架运行要求
    • 系统版本:建议安卓 7.1 及以上版本
    • CPU:至少四核 2GHz,视频通话对 CPU 有更高要求
    • 内存:至少 2GB RAM + 8GB ROM
  • 建议使用微信小程序硬件框架 v2.1.0 及以上版本

2.2 设备直连(Linux)

Linux 系统设备端调用 微信小程序音视频通话 SDK (Linux),直接与用户手机微信内的微信小程序进行通话。

设备应满足下列基本要求:

  • 具有音视频能力(麦克风、摄像头等硬件设备);
  • 满足微信小程序设备认证的设备要求;
  • 满足运行 微信小程序音视频通话 SDK (Linux) 的设备要求。

2.3 云对云

目前支持部分低功耗 Linux、RTOS 等系统的设备。设备端进行设备验证,经由开发者后台中转,与用户手机微信内的微信小程序进行通话。

设备应满足下列基本要求:

  • HTTPS 通信能力
  • 存储能力
  • 音(视)频能力

3. 开发前准备

以下几个环节可以同时进行,涉及到多个平台侧的审核流程,请提前预留时间。

3.1 【仅安卓直连设备】接入微信硬件平台

注册微信终端合作平台和微信开放平台账号、登记设备信息等环节均涉及平台审核,请提早准备。

参考文档指引,完成「微信终端合作平台 (wecooper)」企业主体账号注册、移动应用绑定和硬件注册的流程。

本步骤主要是将设备接入微信的设备体系,完成设备与 APP,以及 APP 与微信小程序之间的关联。

  • 为避免混淆,移动应用的 appId 一般被称为 hostAppId;
  • 每一台硬件设备都需要使用 hostAppId 身份调用 addDevice 接口完成注册,才可以使用 安卓 WMPF。

3.2 设备接入和申请设备能力

此环节涉及平台审核,请提早准备。

微信小程序想要使用音视频通话能力能力,需要在微信小程序管理平台申请开通「微信小程序音视频能力」设备能力。详见「设备接入」文档和微信小程序音视频通话(for 硬件) 使用手册中的流程指引,并关注《硬件 VoIP 审核验证要求》

完成接入后,开发者可获得由平台分配的 model_id。model_id 对应一种设备类型,是调用微信小程序设备能力相关接口的重要凭证。

获取 model_id 后,开发者可以调用获取设备票据接口获取 snTicket,用于后续的设备验证流程。

3.3 接入 VOIP 插件

微信小程序音视频通话的主要功能通过「VOIP 通话」这一微信小程序插件(appId: wxf830863afde621eb)提供。

在微信小程序管理后台完成「微信小程序音视频能力」申请并通过后,微信小程序可以直接使用 VOIP 通话插件,无需额外申请。

如果开发者想要提前进行调试,可以手动进行申请:登录「微信小程序管理后台」——「设置」——「第三方设置」——「插件管理」,点击「添加插件」,搜索并添加「VOIP 通话」插件。

4. 设备端开发

  • 安卓设备端需要运行一个开发者提供的安卓应用,用来进行设备注册、运行微信小程序进行 VOIP 通话。请参考《开发设备端应用(安卓)》
  • Linux 设备端需要集成 微信小程序音视频通话 SDK (Linux)
  • RTOS 设备端需要集成 SDK 用于进行呼叫。

5. 微信小程序开发

开发者需要开发(或使用现有)微信小程序,接入「VOIP 通话」插件,实现拨打和接听音视频通话的能力。

  • 与安卓设备通话时,开发者需要使用同一个微信小程序,既运行在安卓设备端(设备发起或接听通话),也运行在手机端微信客户端(手机用户发起或接听通话)。
  • 与 Linux 设备通话时,设备端运行「微信小程序音视频通话 SDK (Linux)」,手机端微信客户端内运行微信小程序(手机用户发起或接听通话)。
  • 与 RTOS 设备通话时,设备端的 SDK 用于发起呼叫,服务端的 SDK 用于通过过程中的视频流转,手机端微信客户端内运行微信小程序(手机用户发起或接听通话)。

5.1 核心流程

至少使用微信客户端 8.0.30 及以上版本,建议使用当前最新版本。

微信小程序开发主要有以下环节,请参考各环节的文档:

  1. 接入「VOIP 通话」插件:参考插件文档在微信小程序中引入插件;
  2. 设备呼叫手机微信:
  • 需要用户在手机微信端先对设备进行授权,请参考 《用户授权》;
  • 适用于已注册并且用户授权过的设备发起通话,用户在手机微信内接听,请参考《设备呼叫手机微信》;
  1. 手机微信呼叫设备:适用于用户在手机微信内发起通话,已注册并且用户授权过的设备接听,请参考《手机微信呼叫设备(安卓)》和《手机微信呼叫设备(Linux)》;
  2. 性能与体验优化:请参考《性能与体验优化》。

通话相关异常,请参考《通话异常排查指南》

5.2 调试说明

VoIP 通话流程暂不支持在微信开发者工具进行调试,请使用真机进行。

5.2.1 设备端使用「开发版/体验版微信小程序」

安卓设备端可指定使用「开发版/体验版微信小程序」进行调试。请参考《开发设备端应用(安卓)》「3.2 运行开发版/体验版微信小程序」。

5.2.2 使用开发版/体验版微信小程序接听通话

接听方收到消息推送点击接听后,默认打开的是正式版的微信小程序。

在开发阶段,建议在调用 wmpfVoip.initByCaller 时额外传入 miniprogramState 参数指定打开开发版/体验版微信小程序。

const result = await wmpfVoip.initByCaller({
  // 其他参数省略
  miniprogramState: 'developer', // formal/正式版(默认);trial/体验版;developer/开发版
})

使用微信小程序音视频通话 SDK (Linux)时,可以在初始化时设置 wxa_flavor 指定使用开发版/体验版接听通话。

注意:

  • 接听方为手机微信时,应提前扫微信开发者工具生成的开发版二维码下载开发版。
  • 接听方为运行 WMPF 的设备时,应提前按照 5.2.1 的步骤下载开发版。
  • 正式上线时应注意切换为正式版,可以使用 wx.getAccountInfoSync 接口判断当前的微信小程序版本。

6. 服务端开发

RTOS 设备使用云对云方案时,需要进行服务端开发。设备直连(Linux、Android)无需服务端开发。

7. 常见问题

请参考《常见问题(FAQ)》

VoIP 通话插件

本插件主要用于提供「微信小程序音视频通话(for 硬件)」的部分基础能力和统一的通话界面。完整的接入流程和开发指南请参考相关文档

插件接入可参考:微信小程序示例代码

1. 微信小程序引入插件

关于微信小程序插件详细说明请参考微信小程序使用插件文档

在「微信小程序管理后台」添加插件后,使用者还需要在微信小程序的 app.json 中声明本插件。可以在主包引入,也可以在分包引入。

// 主包引入
{
  "plugins": {
    "wmpf-voip": {
      "version": "latest", // latest 表示自动使用最新版本。也可使用具体版本,如 2.3.8
      "provider": "wxf830863afde621eb"
    }
  }
}
// 分包引入
{
  "subpackages": [
    {
      "root": "xxxx",
      "pages": [],
      "plugins": {
        "wmpf-voip": {
          "version": "latest", // latest 表示自动使用最新版本。也可使用具体版本,如 2.3.8
          "provider": "wxf830863afde621eb"
        }
      }
    }
  ]
}

完成声明后,可以在微信小程序中来确认是否引入成功

const wmpfVoip = requirePlugin('wmpf-voip').default
console.log(wmpfVoip) // 有结果即表示引入插件成功

2. 插件接口

从功能上,插件提供的接口可以分为以下几类

2.1 发起通话

发起通话的过程中,插件主要负责通话房间创建、发送接听提醒和通话页面的展示。可以在微信小程序页面或插件页面调用initByCaller 发起通话。

2.2 结束通话

通常情况下,通话结束需要用户点击操作。某些场景下,微信小程序也可以调用 forceHangUpVoip 主动结束当前通话。

非用户点击结束通话可能有以下场景:

  • 用户操作硬件设备的某些按钮结束通话。例如,设备有单独的话机听筒时,用户挂断听筒。
  • 用户通话时长超过限制。建议使用 initByCallertimeLimit 参数。插件低版本也可以根据 calling 事件的 keepTime 字段计算通话时长。

2.3 通话事件

开发者可以通过 onVoipEvent 绑定通话事件的监听,以便更好地分析通话过程。

2.4 自定义设置

插件提供下列接口对通话过程和界面进行设置

  • setCustomBtnText:自定义接听页面按钮。
  • setVoipEndPagePath:设置插件功能执行完成后的跳转页面路径。
  • setUIConfig:设置插件通话界面。

2.5 授权查询

在微信客户端内,可以使用wx.getDeviceVoIPList查询当前登录的用户同意或拒绝授权了哪些设备。

在硬件端,可以通过插件getIotBindContactList接口查询用户是否授权某台设备。

推荐开发者在微信用户授权设备时,即 wx.requestDeviceVoIP 回调 success 后,在后台存储 SN 与 openId。在设备端联系人页面中,配合 getIotBindContactList 接口进行授权验证。

2.6 页面参数

微信小程序可以通过插件getPluginEnterOptions获取从插件页面进入微信小程序时的启动参数。

如果微信小程序在前台时进入插件页面,则需要使用getPluginOnloadOptions获取插件通话页面 onLoad 时页面路径中的参数。

3. 更新日志

请参考《微信小程序音视频通话插件更新日志》

initByCaller(Object req)

本接口为异步接口,返回 Promise 对象。

发起通话并获取通话房间号。调用此接口后,会创建 VoIP 房间,并且向接听方推送接听提醒。

建议先阅读接口介绍。

参数

Object req

属性 类型 默认值 必填 说明 最低版本
roomType string 通话类型。voice: 音频通话;video: 视频通话
caller Object 拨打方信息
caller.id string 拨打方 id,参考 businessType 的说明
caller.name string 显示的拨打方名字。设备端发起通话时无效
caller.cameraStatus number 0 是否启用摄像头。0: 开启;1: 关闭
listener Object 接听方信息
listener.id string 接听方 id,参考 businessType 的说明
listener.name string 显示的接听方名字。
listener.cameraStatus number 0 是否启用摄像头。0: 开启;1: 关闭
businessType number 0 业务类型。详见 businessType 的说明
voipToken string 拨打票据,部分情况下必填,参考 businessType 的说明
miniprogramState string formal 接听方点击通知时打开的微信小程序类型。
取值:formal: 正式版; trial: 体验版; developer: 开发版。
2.1.8 起,正式版微信小程序只能拨打给正式版,设置这一字段无效。
customQuery string 接听方点击通知打开微信小程序时,会作为 query 拼接到插件页面路径后,格式如 a=1&b=2。可在接听端微信小程序内通过 getPluginOnloadOptionsgetPluginEnterOptions 接口获取到
timeLimit number 最大通话时长,需为 > 0 的数字 2.3.8

返回值

由于历史原因,本接口调用失败可能会抛出异常(一般是参数错误),也可能会返回 isSuccess: false(一般是后台错误)。

接口成功返回后,仍需要使用 isSuccess 字段判断调用是否最终成功。

Object

接口调用成功时,返回如下

属性 类型 说明 最低版本
isSuccess boolean 是否调用成功,此时为 true
roomId string 本次通话的房间号 2.4.0
groupId string 与 roomId 相同
chargeType string 计费方式。取值:duration: 时长计费;license: license 计费 2.3.8

调用失败时,接口返回如下:

属性 类型 说明 最低版本
isSuccess boolean 是否调用成功,此时为 false
error object 错误对象,已废弃。{ err_code: string, errMsg: string }
errCode number 错误码,取值参考错误码文档
errMsg string 错误信息
errObj VoipError 错误对象 2.4.0

关于 businessType

不同 businessType 对应的部分参数含义不同,参数获取的具体方式请参考对应业务的文档。

businessType 业务类型 caller.id listener.id voipToken
1 硬件设备呼叫手机微信 设备 SN 微信用户 openId 使用设备认证 SDK注册的设备传入 deviceToken.
使用 WMPF 注册的设备不能有这个字段(插件 2.3.0 支持)
2 手机微信呼叫硬件设备 微信用户 openId 设备 SN 从设备获取的 pushToken
  • 发起通话前,需要在提前让 openId 对应的用户在微信客户端的微信小程序内进行授权,具体流程请参见授权文档;
  • 传入 id 为 设备 SN 时,name 会强制使用用户授权时的「deviceName」+「modelId 对应设备型号」,不使用开发者传入的 name。
  • 本接口 businessType=2 仅支持安卓 WMPF,呼叫 Linux 设备请使用 callDevice。
  • 本接口 businessType=2 不支持 license 计费,手机微信呼叫安卓 WMPF 建议使用 callWMPF。

示例代码

const wmpfVoip = requirePlugin('wmpf-voip').default

try {
  const { isSuccess } = await wmpfVoip.initByCaller({
    caller: {
      id: '拨打方 Id',
      name: '拨打方名字',
    },
    listener: {
      id: '接听方 Id',
      name: '接听方名字',
    },
    roomType: 'video',
    businessType: 1,
    voipToken: 'xxxx*****xxxx',
    miniprogramState: 'developer', // 开发阶段建议使用开发版
  })

  if (isSuccess /* && 当前不在插件页面 */) {
    wx.redirectTo({
      url: wmpfVoip.CALL_PAGE_PATH,
    })
  } else {
    wx.showToast({
      title: '呼叫失败',
      icon: 'error',
    })
  }
} catch (e) {
  wx.showToast({
    title: '呼叫失败',
    icon: 'error',
  })
}

发起通话接口介绍

插件提供设备端和微信用户直接通话的能力。

1. 选择接口

开发者请根据场景选择不同的通话接口。

1.1 安卓 WMPF 设备呼叫手机微信

使用 initByCaller 接口,businessType 传 1。

1.2 Linux 设备呼叫手机微信

Linux 设备不运行微信小程序插件,请使用微信小程序音视频通话 SDK (Linux 设备)。

1.3 手机微信呼叫安卓 WMPF 设备

  • 推荐:使用 callWMPF 接口。需插件 2.4.0 开始支持。若使用 license 计费,必须使用本接口。
  • 使用 initByCaller 接口,businessType 传 2。此方式不支持 license 计费。

1.4 手机微信呼叫 Linux 设备

使用 callDevice 接口。需插件 2.4.0 开始支持。

请注意:呼叫 Linux 设备时,微信不进行消息推送,需要开发者自行将设备端加入房间所需参数(如 roomId 等)从微信端推送到设备端。

2. 使用前必读

2.1 进入通话页面

发起通话的几个接口既可以在微信小程序页面调用,也可以在插件页面调用。但是最终通话流程必须在插件页面才能进行。

  • 如果发起通话时在微信小程序页面,接口调用成功后,开发者需要手动跳转到插件页面,插件页面加载完成后进入通话流程。
  • 如果发起通话时在插件页面,接口调用成功后就会直接进入通话流程。此时请勿重复进行页面跳转,否则当前通话会被中断。
  • 不建议页面栈内存在多个插件页面实例。
// 发起通话成功后,仅在当前不是插件页面的情况下需进行跳转。
wx.redirectTo({
  // 此处只需要传入 path 即可,如果开发者有其他参数需要传递给<a href="https://weixin-xiaochengxu-kaifa.yuannext.com">微信小程序</a>,也可以自行拼接 query,并通过插件 getPluginOnloadOptions 接口获取。
  url: wmpfVoip.CALL_PAGE_PATH,
  // 插件 2.3.9 开始支持 CALL_PAGE_PATH, 低版本请传入 'plugin-private://wxf830863afde621eb/pages/call-page-plugin/call-page-plugin',
})

2.2 最大通话时长

为了降低开发者的开发成本,插件提供了限制最大通话时长的能力。最大通话时长应为 > 0 的数字。

通话时长从 startVoip 事件开始计时,超时后通话自动结束并弹 toast 提示用户,同时触发 hangUpVoip 事件,origin 为 'timeLimit'

2.3 groupId 与 roomId

在插件 2.4.0 以下版本中,通话房间 ID 被称为 groupId,这个名字比较容易与设备组的 ID 产生混淆,因此从 2.4.0 开始,房间号统一更名为 roomId,但为保持向下兼容,groupId 参数仍予以保留。

二者除名字不同外,无其他差异。

callWMPF(Object req)

本接口为异步接口,返回 Promise 对象。

需插件 2.4.0 版本开始支持

从手机客户端的微信小程序呼叫运行安卓 WMPF 的设备。调用此接口后,会创建 VoIP 房间,并且向设备推送 WMPF pushMsg 提醒。详情参考《手机微信呼叫设备(安卓)》。

本接口只能在微信客户端内使用,不可在 WMPF 内使用。建议先阅读接口介绍。

参数

Object req

属性 类型 默认值 必填 说明 最低版本
roomType string 通话类型。voice: 音频通话;video: 视频通话
sn string 接听方设备 SN
modelId string 接听方设备 modelId
pushToken string 从设备获取的 pushToken
nickName string 设备端显示的微信用户名称
deviceName string 微信端显示的设备名称 2.4.1
chargeType string ‘license’ 计费方式。duration: 时长计费;license:license 计费
timeLimit number 最大通话时长,需为 > 0 的数字
enableCallerCamera boolean true 拨打方是否启用摄像头。
enableListenerCamera boolean true 接听方是否启用摄像头。
envVersion string ‘release’ 接听方打开的微信小程序类型。
取值:release: 正式版; trial: 体验版; develop: 开发版。
正式版微信小程序只能拨打给正式版,设置这一字段无效。
customQuery string 接听方打开微信小程序时,会作为 query 拼接到插件页面路径后,格式如 a=1&b=2。可在接听端微信小程序内通过 getPluginOnloadOptionsgetPluginEnterOptions 接口获取到

返回值

本接口调用失败会抛出异常。

Object

接口调用成功时,返回如下:

属性 类型 说明 最低版本
roomId string 本次通话的房间号

示例代码

const wmpfVoip = requirePlugin('wmpf-voip').default

try {
  const { roomId } = await wmpfVoip.callWMPF({
    roomType: 'video',
    sn: '设备 SN',
    modelId: '设备 modelId',
    nickName: '设备端显示的微信用户名称',
    pushToken: 'xxxx*****xxxx',
  })

  if (/* 当前不在插件页面 */) {
    wx.redirectTo({
      url: wmpfVoip.CALL_PAGE_PATH,
    })
  }
} catch (e) {
  console.error('callWMPF failed:', e)
  wx.showToast({
    title: '呼叫失败',
    icon: 'error',
  })
}

callDevice(Object req)

本接口为异步接口,返回 Promise 对象。

需插件 2.4.0 版本开始支持

从手机客户端的微信小程序呼叫 Linux 设备、RTOS 设备。调用此接口后,会创建 VoIP 房间。开发者应自行向设备端推送通话提醒。详情参考《手机微信呼叫设备(Linux 直连)》。

本接口只能在微信客户端内使用,不可在 WMPF 内使用。建议先阅读接口介绍。

参数

Object req

属性 类型 默认值 必填 说明 最低版本
roomType string 通话类型。voice: 音频通话;video: 视频通话
sn string 接听方设备 SN
modelId string 接听方设备 modelId
chargeType string ‘license’ 计费方式。duration: 时长计费;license:license 计费
timeLimit number 最大通话时长,需为 > 0 的数字
enableCallerCamera boolean true 拨打方是否启用摄像头
enableListenerCamera boolean true 接听方是否启用摄像头
nickName string 设备端显示的微信用户名称,仅记录
deviceName string 微信端显示的设备名称 2.4.1
isCloud boolean false 如果是呼叫 RTOS 设备,设置为 true 以触发消息回调
payload string 呼叫 RTOS 时,可以带 payload 到回调消息中
encodeVideoFixedLength number 0 编码的长边值,可取 320、480、640
encodeVideoRotation number 0 编码的视频旋转方向。1: 发出正向流. 2: 保持发出旋转流
encodeVideoRatio number 0 视频的比例, 宽/高*100
encodeVideoMaxFPS number 0 视频的最大 FPS, 8-15

返回值

本接口调用失败会抛出异常。

Object

接口调用成功时,返回如下:

属性 类型 说明 最低版本
roomId string 本次通话的房间号

示例代码

const wmpfVoip = requirePlugin('wmpf-voip').default

try {
  const { roomId } = await wmpfVoip.callDevice({
    roomType: 'video',
    sn: '设备 SN',
    modelId: '设备 modelId',
    nickName: '设备端显示的微信用户名称',
  })

  if (/* 当前不在插件页面 */) {
    wx.redirectTo({
      url: wmpfVoip.CALL_PAGE_PATH,
    })
  }
} catch (e) {
  console.error('callDevice failed:', e)
  wx.showToast({
    title: '呼叫失败',
    icon: 'error',
  })
}