实现 thingsboard 网关下设备 OTA 升级功能(九)

1,011 阅读2分钟

处理网关获取升级包的请求(三)

曙光就在前头,坚持就是胜利

前面参数提取完毕,接下来就是发送了,继续改造,先贴出原先的代码:

String otaPackageId = otaPackSessions.get(requestId);

if (otaPackageId != null) {
    sendOtaPackage(ctx, mqttMsg.variableHeader().packetId(), otaPackageId, requestId, chunkSize, chunk, type);
} else {
    TransportProtos.SessionInfoProto sessionInfo = deviceSessionCtx.getSessionInfo();
    TransportProtos.GetOtaPackageRequestMsg getOtaPackageRequestMsg = TransportProtos.GetOtaPackageRequestMsg.newBuilder()
            .setDeviceIdMSB(sessionInfo.getDeviceIdMSB())
            .setDeviceIdLSB(sessionInfo.getDeviceIdLSB())
            .setTenantIdMSB(sessionInfo.getTenantIdMSB())
            .setTenantIdLSB(sessionInfo.getTenantIdLSB())
            .setType(type.name())
            .build();
    transportService.process(deviceSessionCtx.getSessionInfo(), getOtaPackageRequestMsg,
            new OtaPackageCallback(ctx, msgId, getOtaPackageRequestMsg, requestId, chunkSize, chunk));
}

首先将sendOtaPackage方法,改名为sendOtaPackageToGateway,因为sendOtaPackage方法内部将发送的topic写死了,就只好再写个方法sendOtaPackageToGateway,将topic更正为我们需要的。

TransportProtos.SessionInfoProto sessionInfo = deviceSessionCtx.getSessionInfo(); 这句话需要改造,我们需要的是 deviceName 的 sessionInfo。

OtaPackageCallback也需要改名,改名为GatewayOtaPackageCallback,因为 OtaPackageCallback 内部逻辑会调用 sendOtaPackage 方法,而我们需要调用 sendOtaPackageToGateway 方法。

改造之后,代码如下:

String otaPackageId = otaPackSessions.get(requestId);

if (otaPackageId != null) {
    sendOtaPackageToGateway(ctx, mqttMsg.variableHeader().packetId(), otaPackageId, requestId, chunkSize, chunk, type);
} else {
    final int chunkSizeFinal = chunkSize;

    Futures.addCallback(gatewaySessionHandler.getDeviceSessionInfo(deviceName),
            new FutureCallback<TransportProtos.SessionInfoProto>() {
                @Override
                public void onSuccess(@Nullable TransportProtos.SessionInfoProto sessionInfo) {

                    TransportProtos.GetOtaPackageRequestMsg getOtaPackageRequestMsg = TransportProtos.GetOtaPackageRequestMsg.newBuilder()
                            .setDeviceIdMSB(sessionInfo.getDeviceIdMSB())
                            .setDeviceIdLSB(sessionInfo.getDeviceIdLSB())
                            .setTenantIdMSB(sessionInfo.getTenantIdMSB())
                            .setTenantIdLSB(sessionInfo.getTenantIdLSB())
                            .setType(type.name())
                            .build();

                    transportService.process(deviceSessionCtx.getSessionInfo(), getOtaPackageRequestMsg,
                            new GatewayOtaPackageCallback(ctx, msgId, getOtaPackageRequestMsg, requestId, chunkSizeFinal, chunk, type));
                }

                @Override
                public void onFailure(Throwable t) {
                    log.debug("[{}] Failed to process device ota request command: {}", sessionId, deviceName, t);
                }
            }, context.getExecutor());

}

最终整个 getOtaPackageCallbackByGateway()方法如下:

@Data
private class GatewayOtaPackageRequestDTO {
    private String deviceName;
    private Integer chunkSize;
}

private void getOtaPackageCallbackByGateway(ChannelHandlerContext ctx, MqttPublishMessage mqttMsg, int msgId, Matcher fwMatcher, OtaPackageType type) {
    String requestId = fwMatcher.group("requestId");
    int chunk = Integer.parseInt(fwMatcher.group("chunk"));

    String payload = mqttMsg.content().toString(UTF8);
    Gson gson = new Gson();

    GatewayOtaPackageRequestDTO dto = null;
    try {
        dto = gson.fromJson(payload, GatewayOtaPackageRequestDTO.class);
    } catch (JsonSyntaxException e){
        sendOtaPackageErrorToGateway(ctx, msgId, requestId, "解析JSON出错,请求负载不合法,负载示例:{deviceName:"SN-001", chunkSize:512}", type);
        return;
    }

    if(dto == null) {
        sendOtaPackageErrorToGateway(ctx, msgId, requestId, "请求没有负载,负载示例:{deviceName:"SN-001", chunkSize:512}", type);
        return;
    }

    Integer chunkSize = dto.getChunkSize();
    String deviceName = dto.getDeviceName();

    if(chunkSize == null) {
        sendOtaPackageErrorToGateway(ctx, msgId, requestId, "请求负载缺少chunkSize,负载示例:{deviceName:"SN-001", chunkSize:512}", type);
        return;
    }

    if(deviceName == null) {
        sendOtaPackageErrorToGateway(ctx, msgId, requestId, "请求负载缺少deviceName,负载示例:{deviceName:"SN-001", chunkSize:512}", type);
        return;
    }

    if (chunkSize > 0) {
        this.chunkSizes.put(requestId, chunkSize);
    } else {
        chunkSize = chunkSizes.getOrDefault(requestId, 0);
    }

    if (chunkSize > context.getMaxPayloadSize()) {
        sendOtaPackageError(ctx, PAYLOAD_TOO_LARGE);
        return;
    }

    String otaPackageId = otaPackSessions.get(requestId);

    if (otaPackageId != null) {
        sendOtaPackageToGateway(ctx, mqttMsg.variableHeader().packetId(), otaPackageId, requestId, chunkSize, chunk, type);
    } else {
        final int chunkSizeFinal = chunkSize;

        Futures.addCallback(gatewaySessionHandler.getDeviceSessionInfo(deviceName),
                new FutureCallback<TransportProtos.SessionInfoProto>() {
                    @Override
                    public void onSuccess(@Nullable TransportProtos.SessionInfoProto sessionInfo) {

                        TransportProtos.GetOtaPackageRequestMsg getOtaPackageRequestMsg = TransportProtos.GetOtaPackageRequestMsg.newBuilder()
                                .setDeviceIdMSB(sessionInfo.getDeviceIdMSB())
                                .setDeviceIdLSB(sessionInfo.getDeviceIdLSB())
                                .setTenantIdMSB(sessionInfo.getTenantIdMSB())
                                .setTenantIdLSB(sessionInfo.getTenantIdLSB())
                                .setType(type.name())
                                .build();

                        transportService.process(deviceSessionCtx.getSessionInfo(), getOtaPackageRequestMsg,
                                new GatewayOtaPackageCallback(ctx, msgId, getOtaPackageRequestMsg, requestId, chunkSizeFinal, chunk, type));
                    }

                    @Override
                    public void onFailure(Throwable t) {
                        log.debug("[{}] Failed to process device ota request command: {}", sessionId, deviceName, t);
                    }
                }, context.getExecutor());

    }
}