package com.casic.util.aep; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.casic.util.SpringContextUtil; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; /** * @author cz * @date 2024-04-24 */ @Slf4j @Data public class AepCommandSend { private String deviceId; private String productId; private String masterApiKey; private Long offset = 0L; private Long lastGetOffsetTime = 0L; private final String CREATE_COMMAND_PATH = "/aep_device_command/command"; private final String CREATE_COMMAND_LWM2M_PROFILE_PATH = "/aep_device_command_lwm_profile/commandLwm2mProfile"; public AepCommandSend() { } public AepCommandSend(String deviceId, String productId, String masterApiKey) { this.deviceId = deviceId; this.productId = productId; this.masterApiKey = masterApiKey; } /** * 处理电信平台的报文解析,并组装回复报文,发送电信平台 * * @param frameStr 业务数据的payload内容 */ public int handleAndReply(String frameStr) throws Exception { HttpResponse response = createCommand(frameStr); JSONObject retObj = new JSONObject(); try { retObj = JSON.parseObject(new String(response.body().getBytes(), StandardCharsets.UTF_8)); log.info("AEP平台返回消息: {}", retObj.toJSONString()); } catch (Exception ex) { log.error("AEP平台发送失败,异常信息{}", ex.getMessage()); } return (int) retObj.get("code"); } private Long getTimeOffset() { AepConfig aepConfig = SpringContextUtil.getBean(AepConfig.class); String timeUrl = aepConfig.getTimeUrl(); try { HttpResponse response = HttpRequest.get(timeUrl).execute(); String timeAg = response.header("x-ag-timestamp"); return Long.parseLong(timeAg) - System.currentTimeMillis(); } catch (Exception ex) { return 0L; } } private String signature(Long timestamp, String appSecret, String appKey, String masterApiKey, byte[] bodyBytes) throws Exception { return Signature.sign(appSecret, appKey, String.valueOf(timestamp), masterApiKey, bodyBytes); } private HttpResponse createCommand(String frameStr) throws Exception { AepConfig aepConfig = SpringContextUtil.getBean(AepConfig.class); String baseUrl = aepConfig.getBaseUrl(); // 消息体 AepCommandBody body = new AepCommandBody(); body.setDeviceId(deviceId); body.setProductId(productId); body.setTtl(aepConfig.getTtl()); body.setOperator(aepConfig.getOperator()); body.setLevel(aepConfig.getLevel()); body.setPayloadString(frameStr); log.info("向AEP平台发送消息: {}", JSON.toJSONString(body)); // 计算时间戳 用于签名 long currentTime = System.currentTimeMillis(); if (currentTime - lastGetOffsetTime > 300 * 1000) //300秒调用一次 { offset = getTimeOffset(); lastGetOffsetTime = currentTime; } long timestamp = currentTime + offset; // 消息头 Map<String, String> header = new HashMap<>(); header.put("application", aepConfig.getKey()); header.put("version", "20190712225145"); header.put("timestamp", String.valueOf(timestamp)); header.put("MasterKey", masterApiKey); header.put("signature", signature(timestamp, aepConfig.getSecret(), aepConfig.getKey(), masterApiKey, JSONObject.toJSONString(body).getBytes())); return HttpRequest.post(baseUrl + CREATE_COMMAND_PATH) .body(JSON.toJSONString(body)) .addHeaders(header) .contentType("application/json; charset=UTF-8") .execute(); } }