2 功能说明

2.1 基础功能

功能实现对应类名: DeviceController

Important

设备控制器初始化, 参考 1.3   SDK初始化

2.1.1 接收命令回调

//设备控制器,参考【SDK初始化】章节,进行初始化
DeviceController controller = null;
if (null == controller) return;
//设备状态回调
final OnDeviceStateCallback onDeviceStateCallback = new OnDeviceStateCallback() {
    @Override
    public void onConnection(@NonNull String mac, int status) {
        //回调设备连接状态
        //mac     --- 设备地址
        //status  --- 连接状态
    }

    @Override
    public void onReceiveCommand(@NonNull String mac, @NonNull Command<?, ?> command) {
        //回调接收到的命令
        //mac     --- 设备地址
        //command --- 命令对象
    }
};
//注册设备状态回调
controller.addOnDeviceStateCallback(onDeviceStateCallback);
//移除设备状态回调
//        controller.removeOnDeviceStateCallback(onDeviceStateCallback);

2.1.2 发送命令

//设备控制器,参考【SDK初始化】章节,进行初始化
DeviceController controller = null;
if (null == controller) return;
//需要确保【设备控制器】初始化成功
//command         ---- 命令对象
//CommandCallback ---- 命令结果回调
//执行发送命令操作
controller.sendCommand(new CmdReadConfiguration(new CmdReadConfiguration.ReadCfgParam()),
        new CommandCallback<CmdReadConfiguration>() {
            @Override
            public void onSuccess(@NonNull String mac, @NonNull CmdReadConfiguration command) {
                //回调发送命令成功
                //mac      --- 设备地址
                //command  --- 回复命令
            }

            @Override
            public void onFailed(@NonNull String mac, int code, String message) {
                //回调发送命令失败
                //mac     --- 设备地址
                //code    --- 错误码
                //message --- 错误描述
            }
        });

2.2 文件传输功能

功能实现对应类名: FileTransfer

2.2.1 初始化

//设备控制器,参考【SDK初始化】章节,进行初始化
DeviceController controller = null;
if (null == controller || !controller.isInit()) return;
//初始化文件传输功能
fileTransfer = new FileTransfer(controller);

设备控制器初始化, 参考 1.3   SDK初始化

2.2.2 创建文件

if (null == fileTransfer) {
    //先初始化文件传输功能对象
    return;
}
long fileVersion = 0x0200000000000000L; //文件版本号
//执行创建文件操作
fileTransfer.createFile(new CreateFileParam(fileVersion, "文件路径"), new FileTransferListener() {
    @Override
    public void onStart(@NonNull CreateFileParam param) {
        //回调文件传输开始
        //param  --- 创建文件参数
    }

    @Override
    public void onProgress(int progress) {
        //回调文件传输进度
        //progress --- 进度
    }

    @Override
    public void onStop() {
        //回调文件传输完成
    }

    @Override
    public void onCancel(int reason) {
        //回调文件传输被取消
        //reason --- 原因码
    }

    @Override
    public void onError(int code, String message) {
        //回调文件传输发生异常
        //code    --- 错误码
        //message --- 错误描述
    }
});

Important

  1. 文件版本号,需要是有效的。

  2. 文件传输,不能并行调用,不能重复开始。

  3. 必现等前一个文件传输结束后,才能开始下一轮文件传输。

2.2.2.1 CreateFileParam

创建文件参数

public class CreateFileParam {

    /**
     * 文件版本信息
     */
    private final long fileVersion;
    /**
     * 输入文件
     */
    @NonNull
    private final String filePath;
}

2.2.3 取消文件传输

if (null == fileTransfer) {
    //先初始化文件传输功能对象
    return;
}
if (!fileTransfer.isFileTransferring()) return; //不在文件传输中
//执行取消文件传输操作
fileTransfer.cancelFileTransfer(new ResultCallback<Boolean>() {
    @Override
    public void onSuccess(Boolean result) {
        //回调取消传输操作成功
        //会触发FileTransferListener#onCancel(int)回调
    }

    @Override
    public void onFailure(int code, String message) {
        //回调取消传输操作失败
        //code    --- 错误码
        //message --- 错误描述
    }
});

Important

  1. 文件传输中,调用才能生效,否则返回错误。

2.2.4 释放资源

if (null == fileTransfer) {
     return;
 }
 //不再使用功能时,释放资源
 fileTransfer.destroy();
 fileTransfer = null;

2.3 Mesh DFU功能

功能实现对应类名: MeshDFU

2.3.1 初始化

//设备控制器,参考【SDK初始化】章节,进行初始化
DeviceController controller = null;
if (null == controller || !controller.isInit()) return;
//初始化Mesh DFU功能对象
meshDFU = new MeshDFU(controller);

2.3.2 读取分发器DFU配置信息

if (null == meshDFU) {
    //先初始化Mesh DFU功能对象
    return;
}
//执行读取分发器DFU配置信息操作
meshDFU.readDfuCfgInfo(new ResultCallback<DfuFileMsg>() {
    @Override
    public void onSuccess(DfuFileMsg result) {
        //回调操作成功
        //result  ---- DFU配置信息
    }

    @Override
    public void onFailure(int code, String message) {
        //回调操作失败
        //code    --- 错误码
        //message --- 错误描述
    }
});

Note

  1. DFU升级文件信息, 2.3.2.1   DfuFileMsg

2.3.2.1 DfuFileMsg

DFU升级文件信息

public class DfuFileMsg implements Parcelable {
    /**
     * 升级文件版本信息
     */
    private long fileVersion;
    /**
     * 升级文件大小
     */
    private int fileSize;
    /**
     * 文件内容CRC
     */
    private short fileCrc;
    /**
     * 升级文件路径
     */
    @NonNull
    private String filePath;
}

2.3.3 读取分发器DFU状态

if (null == meshDFU) {
    //先初始化Mesh DFU功能对象
    return;
}
//执行读取分发器DFU状态操作
meshDFU.readDfuState(new ResultCallback<DfuState>() {
    @Override
    public void onSuccess(DfuState result) {
        //回调操作成功
        //result  ---- DFU状态信息
    }

    @Override
    public void onFailure(int code, String message) {
        //回调操作失败
        //code    --- 错误码
        //message --- 错误描述
    }
});

Note

  1. 读取分发器DFU状态,包含 2.3.2   读取分发器DFU配置信息 流程。推荐使用

  2. 分发器DFU状态, 2.3.5.2   DfuState

2.3.4 读取目标设备DFU状态

if (null == meshDFU) {
    //先初始化Mesh DFU功能对象
    return;
}
//执行读取目标设备DFU状态操作
meshDFU.readTargetDfuState(new ResultCallback<List<TargetStatus>>() {
    @Override
    public void onSuccess(List<TargetStatus> result) {
        //回调操作成功
        //result  ---- 目标设备DFU状态列表
    }

    @Override
    public void onFailure(int code, String message) {
        //回调操作失败
        //code    --- 错误码
        //message --- 错误描述
    }
});

Note

  1. 目标设备DFU状态, 2.3.5.3   TargetStatus

2.3.5 开始DFU

if (null == meshDFU) {
     //先初始化Mesh DFU功能对象
     return;
 }
 DfuCfgInfo dfuCfgInfo = new DfuCfgInfo()
         .setDfuCfg(new DfuConfiguration(0x00, 0x00))
         .setSlotInfo(new SlotInfo(0x0200000000000000L, 1024 * 1024 * 256,
                 1, 0x58328ed2, 1))
         .setFileMsg(new DfuFileMsg(0x0200000000000000L, 1024 * 1024 * 256, (short) 0xC9D8));
 //执行开始DFU流程
 meshDFU.startDFU(dfuCfgInfo, new DfuStateCallback() {
     @Override
     public void onDfuState(@NonNull DfuState state) {
         //回调分发器DFU状态
         switch (state.getState()) {
             case DfuState.STATE_IDLE: {
                 //空闲状态
                 break;
             }
             case DfuState.STATE_FILE_TRANSFER_START: {
                 //准备传输升级文件状态
                 break;
             }
             case DfuState.STATE_FILE_TRANSFER_WORKING: {
                 //正在传输升级文件状态
                 break;
             }
             case DfuState.STATE_FILE_TRANSFERRED: {
                 //已传输升级文件状态
                 break;
             }
             case DfuState.STATE_ADDED_SLOT: {
                 //已添加文件信息状态
                 break;
             }
             case DfuState.STATE_ADDED_TARGET: {
                 //已添加目标设备状态
                 break;
             }
             case DfuState.STATE_UPGRADE_START: {
                 //DFU升级开始状态
                 break;
             }
             case DfuState.STATE_TRANSFERRING: {
                 //DFU升级中状态 — 文件传输中
                 break;
             }
             case DfuState.STATE_TRANSFER_SUCCESS: {
                 //DFU升级中状态 — 文件传输完成
                 break;
             }
             case DfuState.STATE_APPLYING: {
                 //DFU升级中状态 — 新程序生效中
                 break;
             }
             case DfuState.STATE_UPGRADE_STOP: {
                 //DFU升级结束状态
                 break;
             }
         }
     }

     @Override
     public void onTargetDfuState(@NonNull TargetStatus targetStatus) {
         //回调目标设备DFU状态
         switch (targetStatus.getState().getStage()) {
             case DfuStatus.TARGET_STAGE_IDLE: {
                 //空闲状态
                 break;
             }
             case DfuStatus.TARGET_STAGE_TRANSFER_FAILED: {
                 //BLOB传输失败
                 break;
             }
             case DfuStatus.TARGET_STAGE_TRANSFERRING: {
                 //BLOB传输中
                 break;
             }
             case DfuStatus.TARGET_STAGE_DATA_VERIFYING: {
                 //数据校验中
                 break;
             }
             case DfuStatus.TARGET_STAGE_DATA_VERIFICATION_SUCCESSFUL: {
                 //数据校验成功
                 break;
             }
             case DfuStatus.TARGET_STAGE_DATA_VERIFICATION_FAILED: {
                 //数据校验失败
                 break;
             }
             case DfuStatus.TARGET_STAGE_APPLYING: {
                 //新程序正在应用
                 break;
             }
             case DfuStatus.TARGET_STAGE_TRANSFER_CANCEL: {
                 //传输取消
                 break;
             }
             case DfuStatus.TARGET_STAGE_APPLY_SUCCESSFUL: {
                 //新程序应用成功
                 break;
             }
             case DfuStatus.TARGET_STAGE_APPLY_FAILED: {
                 //新程序应用失败
                 break;
             }
             case DfuStatus.TARGET_STAGE_UNKNOWN: {
                 //未知的升级状态
                 break;
             }
         }
     }
 });

Important

  1. 开始DFU流程,包括了文件传输,添加存储节点信息,添加目标设备,DFU等流程。

  2. 开始DFU流程,不能并行调用,不能重复调用。

  3. 当DFU过程中,断开连接,可以进行异常恢复处理。参考 2.3.9   DFU异常恢复流程图

  4. 分发器DFU状态, 2.3.5.2   DfuState

  5. 目标设备DFU状态, 2.3.5.3   TargetStatus

2.3.5.1 DfuCfgInfo

DFU信息

public class DfuCfgInfo implements Parcelable {
    /**
     * DFU升级文件信息
     */
    private DfuFileMsg fileMsg;
    /**
     * 存储节点信息
     */
    private SlotInfo slotInfo;
    /**
     * DFU配置信息
     */
    private DfuConfiguration dfuCfg;
    /**
     * 目标设备列表
     */
    @NonNull
    private final List<TargetDevice> targetDevices;
}

Note

  1. DFU升级文件信息, 2.3.2.1   DfuFileMsg

  2. 存储节点信息, SlotInfo

  3. DFU配置参数, DfuConfiguration

  4. 目标设备列表, TargetDevice

SlotInfo

存储节点信息

public class SlotInfo implements IDataOp, Parcelable {
    /**
     * 升级文件版本信息
     */
    private long fileVersion;
    /**
     * 升级文件大小
     */
    private int fileSize;
    /**
     * 升级的core类型
     */
    private int coreType;
    /**
     * target设备端的composition data的hash计算值
     */
    private int compositionHash;
    /**
     * 需要升级文件支持的元素个数
     */
    private int elemMaxCount;
}
DfuConfiguration

DFU配置参数

public class DfuConfiguration implements Parcelable {
    /**
     * AppKey对应的idx
     */
    private int appIdx;
    /**
     * 文件对应的存储slot对应的idx
     */
    private int slotIdx;
    /**
     * target设备订阅的组播地址
     */
    private int group;
    /**
     * 决定DFU升级完成后target是否重启
     */
    private int apply;
    /**
     * 消息中转次数
     */
    private int ttl;
    /**
     * 超时基点
     */
    private int timeoutBase;
    /**
     * DFU BLOB模式
     */
    private int XFerMode;
}
TargetDevice

目标设备

public class TargetDevice implements Parcelable {

     /**
      * 单播地址
      */
     private int address;
     /**
      * 固件Image的idx
      */
     private int imageIdx;
 }

2.3.5.2 DfuState

DFU状态信息

public class DfuState implements Parcelable {

    /**
     * 升级状态
     */
    @State
    private int state = STATE_IDLE;
    /**
     * 上一个升级状态
     */
    @State
    private int lastState = STATE_IDLE;
    /**
     * 文件版本号
     */
    private long fileVersion;
    /**
     * 升级文件路径
     */
    private String filePath;
    /**
     * 进度
     */
    private int progress;
    /**
     * 结果码
     */
    private int code = -1;
    /**
     * 描述
     */
    private String message;
}

2.3.5.3 TargetStatus

目标设备状态

public class TargetStatus implements Parcelable {
    /**
     * 单播地址
     */
    private int address;
    /**
     * 升级状态
     */
    @NonNull
    private DfuStatus state;
}

Note

  1. DFU状态, 2.3.5.4   DfuStatus

2.3.5.4 DfuStatus

DFU状态

public class DfuStatus implements Parcelable {

    /**
     * 升级阶段。
     * <p>
     * 根据 {@link #deviceType} 的值进行区分。
     * </p>
     */
    private int stage;
    /**
     * 数值。
     * <p>
     * 1. 若 {@link #stage} 等于 {@link #TARGET_STAGE_TRANSFERRING} 时,
     * value视为进度值,取值范围: [0. 100]。<br/>
     * 2. 若 {@link #stage} 等于 {@link #TARGET_STAGE_TRANSFER_FAILED} 或者 {@link #TARGET_STAGE_DATA_VERIFICATION_FAILED}
     * 或者 {@link #TARGET_STAGE_TRANSFER_CANCEL} 或者 {@link  #TARGET_STAGE_APPLY_FAILED} 时,
     * value视为错误码, 参考 {@link Error}, 前缀: DFU_ERR
     * </p>
     */
    private int value;
    /**
     * 设备类型。
     * <p>
     * 默认是Mesh分发器 {@link CmdReadDfuStatus#DEVICE_TYPE_DISTRIBUTOR}
     * </p>
     */
    @CmdReadDfuStatus.DeviceType
    private int deviceType = CmdReadDfuStatus.DEVICE_TYPE_DISTRIBUTOR;
}

2.3.6 取消DFU

if (null == meshDFU) {
    //先初始化Mesh DFU功能对象
    return;
}
//执行取消DFU操作
meshDFU.cancelDFU(new ResultCallback<Boolean>() {
    @Override
    public void onSuccess(Boolean result) {
        //回调操作成功
        //result  ---- 操作结果
    }

    @Override
    public void onFailure(int code, String message) {
        //回调操作失败
        //code    --- 错误码
        //message --- 错误描述
    }
});

Important

  1. 取消DFU流程,包括【取消升级文件传输】 和 【取消DFU流程】 等功能,根据 分发器DFU状态 决定。

2.3.7 释放资源

if (null == meshDFU) {
     return;
 }
 //不再使用时,释放资源
 meshDFU.destroy();
 meshDFU = null;

2.3.8 DFU流程图

DFU流程图

2.3.9 DFU异常恢复流程图

DFU异常恢复流程图