diff --git a/common/pom.xml b/common/pom.xml
index 728d3c9b..802c5498 100755
--- a/common/pom.xml
+++ b/common/pom.xml
@@ -5,7 +5,7 @@
iotkit-parent
cc.iotkit
- 0.2.0-SNAPSHOT
+ 0.2.1-SNAPSHOT
4.0.0
diff --git a/common/src/main/java/cc/iotkit/common/utils/DeviceUtil.java b/common/src/main/java/cc/iotkit/common/utils/DeviceUtil.java
index 747b5ecc..435acb59 100755
--- a/common/src/main/java/cc/iotkit/common/utils/DeviceUtil.java
+++ b/common/src/main/java/cc/iotkit/common/utils/DeviceUtil.java
@@ -15,7 +15,7 @@ public class DeviceUtil {
int maxDnLen = 16;
String dn = deviceNae.replaceAll("[^0-9A-Za-z]", "");
if (dn.length() > maxDnLen) {
- dn = dn.substring(dn.length() - maxDnLen);
+ dn = dn.substring(dn.length() - maxDnLen + 1);
} else {
dn = (dn + "00000000000000000000").substring(0, maxDnLen);
}
diff --git a/common/src/main/java/cc/iotkit/common/utils/HexUtil.java b/common/src/main/java/cc/iotkit/common/utils/HexUtil.java
index 4a5184e9..5cedb890 100755
--- a/common/src/main/java/cc/iotkit/common/utils/HexUtil.java
+++ b/common/src/main/java/cc/iotkit/common/utils/HexUtil.java
@@ -94,6 +94,15 @@ public class HexUtil {
return buffer.array();
}
+ /**
+ * bytes转int
+ */
+ public static int bytesToInt(byte[] bytes) {
+ ByteBuffer buffer = ByteBuffer.wrap(bytes);
+ buffer.flip();
+ return buffer.getInt();
+ }
+
public static int checkSum(ByteBuffer buffer) {
buffer.flip();
byte sum = 0;
@@ -209,4 +218,85 @@ public class HexUtil {
return add33Bytes(HexUtil.parseHex(bcdString(strV)));
}
+ /**
+ * 计算CRC16校验
+ *
+ * @param data 需要计算的数组
+ * @param offset 起始位置
+ * @param len 长度
+ * @return CRC16校验值
+ */
+ public static int calcCrc16(byte[] data, int offset, int len) {
+ byte[] crc16_tab_h = {
+ (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,
+ (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
+ (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
+ (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
+ (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
+ (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
+ (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
+ (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
+ (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,
+ (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
+
+ (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
+ (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
+ (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,
+ (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
+ (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
+ (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
+ (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,
+ (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
+ (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
+ (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
+
+ (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
+ (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,
+ (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
+ (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,
+ (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,
+ (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40
+ };
+ byte[] crc16_tab_l = {
+ (byte) 0x00, (byte) 0xC0, (byte) 0xC1, (byte) 0x01, (byte) 0xC3, (byte) 0x03, (byte) 0x02, (byte) 0xC2, (byte) 0xC6, (byte) 0x06,
+ (byte) 0x07, (byte) 0xC7, (byte) 0x05, (byte) 0xC5, (byte) 0xC4, (byte) 0x04, (byte) 0xCC, (byte) 0x0C, (byte) 0x0D, (byte) 0xCD,
+ (byte) 0x0F, (byte) 0xCF, (byte) 0xCE, (byte) 0x0E, (byte) 0x0A, (byte) 0xCA, (byte) 0xCB, (byte) 0x0B, (byte) 0xC9, (byte) 0x09,
+ (byte) 0x08, (byte) 0xC8, (byte) 0xD8, (byte) 0x18, (byte) 0x19, (byte) 0xD9, (byte) 0x1B, (byte) 0xDB, (byte) 0xDA, (byte) 0x1A,
+ (byte) 0x1E, (byte) 0xDE, (byte) 0xDF, (byte) 0x1F, (byte) 0xDD, (byte) 0x1D, (byte) 0x1C, (byte) 0xDC, (byte) 0x14, (byte) 0xD4,
+ (byte) 0xD5, (byte) 0x15, (byte) 0xD7, (byte) 0x17, (byte) 0x16, (byte) 0xD6, (byte) 0xD2, (byte) 0x12, (byte) 0x13, (byte) 0xD3,
+ (byte) 0x11, (byte) 0xD1, (byte) 0xD0, (byte) 0x10, (byte) 0xF0, (byte) 0x30, (byte) 0x31, (byte) 0xF1, (byte) 0x33, (byte) 0xF3,
+ (byte) 0xF2, (byte) 0x32, (byte) 0x36, (byte) 0xF6, (byte) 0xF7, (byte) 0x37, (byte) 0xF5, (byte) 0x35, (byte) 0x34, (byte) 0xF4,
+ (byte) 0x3C, (byte) 0xFC, (byte) 0xFD, (byte) 0x3D, (byte) 0xFF, (byte) 0x3F, (byte) 0x3E, (byte) 0xFE, (byte) 0xFA, (byte) 0x3A,
+ (byte) 0x3B, (byte) 0xFB, (byte) 0x39, (byte) 0xF9, (byte) 0xF8, (byte) 0x38, (byte) 0x28, (byte) 0xE8, (byte) 0xE9, (byte) 0x29,
+
+ (byte) 0xEB, (byte) 0x2B, (byte) 0x2A, (byte) 0xEA, (byte) 0xEE, (byte) 0x2E, (byte) 0x2F, (byte) 0xEF, (byte) 0x2D, (byte) 0xED,
+ (byte) 0xEC, (byte) 0x2C, (byte) 0xE4, (byte) 0x24, (byte) 0x25, (byte) 0xE5, (byte) 0x27, (byte) 0xE7, (byte) 0xE6, (byte) 0x26,
+ (byte) 0x22, (byte) 0xE2, (byte) 0xE3, (byte) 0x23, (byte) 0xE1, (byte) 0x21, (byte) 0x20, (byte) 0xE0, (byte) 0xA0, (byte) 0x60,
+ (byte) 0x61, (byte) 0xA1, (byte) 0x63, (byte) 0xA3, (byte) 0xA2, (byte) 0x62, (byte) 0x66, (byte) 0xA6, (byte) 0xA7, (byte) 0x67,
+ (byte) 0xA5, (byte) 0x65, (byte) 0x64, (byte) 0xA4, (byte) 0x6C, (byte) 0xAC, (byte) 0xAD, (byte) 0x6D, (byte) 0xAF, (byte) 0x6F,
+ (byte) 0x6E, (byte) 0xAE, (byte) 0xAA, (byte) 0x6A, (byte) 0x6B, (byte) 0xAB, (byte) 0x69, (byte) 0xA9, (byte) 0xA8, (byte) 0x68,
+ (byte) 0x78, (byte) 0xB8, (byte) 0xB9, (byte) 0x79, (byte) 0xBB, (byte) 0x7B, (byte) 0x7A, (byte) 0xBA, (byte) 0xBE, (byte) 0x7E,
+ (byte) 0x7F, (byte) 0xBF, (byte) 0x7D, (byte) 0xBD, (byte) 0xBC, (byte) 0x7C, (byte) 0xB4, (byte) 0x74, (byte) 0x75, (byte) 0xB5,
+ (byte) 0x77, (byte) 0xB7, (byte) 0xB6, (byte) 0x76, (byte) 0x72, (byte) 0xB2, (byte) 0xB3, (byte) 0x73, (byte) 0xB1, (byte) 0x71,
+ (byte) 0x70, (byte) 0xB0, (byte) 0x50, (byte) 0x90, (byte) 0x91, (byte) 0x51, (byte) 0x93, (byte) 0x53, (byte) 0x52, (byte) 0x92,
+
+ (byte) 0x96, (byte) 0x56, (byte) 0x57, (byte) 0x97, (byte) 0x55, (byte) 0x95, (byte) 0x94, (byte) 0x54, (byte) 0x9C, (byte) 0x5C,
+ (byte) 0x5D, (byte) 0x9D, (byte) 0x5F, (byte) 0x9F, (byte) 0x9E, (byte) 0x5E, (byte) 0x5A, (byte) 0x9A, (byte) 0x9B, (byte) 0x5B,
+ (byte) 0x99, (byte) 0x59, (byte) 0x58, (byte) 0x98, (byte) 0x88, (byte) 0x48, (byte) 0x49, (byte) 0x89, (byte) 0x4B, (byte) 0x8B,
+ (byte) 0x8A, (byte) 0x4A, (byte) 0x4E, (byte) 0x8E, (byte) 0x8F, (byte) 0x4F, (byte) 0x8D, (byte) 0x4D, (byte) 0x4C, (byte) 0x8C,
+ (byte) 0x44, (byte) 0x84, (byte) 0x85, (byte) 0x45, (byte) 0x87, (byte) 0x47, (byte) 0x46, (byte) 0x86, (byte) 0x82, (byte) 0x42,
+
+ (byte) 0x43, (byte) 0x83, (byte) 0x41, (byte) 0x81, (byte) 0x80, (byte) 0x40
+ };
+ int pre = 0xffff;
+ int ucCRCHi = (pre & 0xff00) >> 8;
+ int ucCRCLo = pre & 0x00ff;
+ int iIndex;
+ for (int i = 0; i < len; ++i) {
+ iIndex = (ucCRCLo ^ data[offset + i]) & 0x00ff;
+ ucCRCLo = ucCRCHi ^ crc16_tab_h[iIndex];
+ ucCRCHi = crc16_tab_l[iIndex];
+ }
+ return ((ucCRCHi & 0x00ff) << 8) | (ucCRCLo & 0x00ff) & 0xffff;
+ }
}
\ No newline at end of file
diff --git a/dao/pom.xml b/dao/pom.xml
index 36b738bc..ec0cd89f 100755
--- a/dao/pom.xml
+++ b/dao/pom.xml
@@ -5,7 +5,7 @@
iotkit-parent
cc.iotkit
- 0.2.0-SNAPSHOT
+ 0.2.1-SNAPSHOT
4.0.0
diff --git a/manager/pom.xml b/manager/pom.xml
index 5f9cc1bd..991e7c7a 100755
--- a/manager/pom.xml
+++ b/manager/pom.xml
@@ -5,7 +5,7 @@
iotkit-parent
cc.iotkit
- 0.2.0-SNAPSHOT
+ 0.2.1-SNAPSHOT
4.0.0
diff --git a/model/pom.xml b/model/pom.xml
index 891c115f..5e3fbb13 100755
--- a/model/pom.xml
+++ b/model/pom.xml
@@ -5,9 +5,9 @@
iotkit-parent
cc.iotkit
- 0.2.0-SNAPSHOT
+ 0.2.1-SNAPSHOT
- 0.2.0-SNAPSHOT
+ 0.2.1-SNAPSHOT
4.0.0
model
diff --git a/oauth2-server/pom.xml b/oauth2-server/pom.xml
index 89ea1206..2dffe402 100755
--- a/oauth2-server/pom.xml
+++ b/oauth2-server/pom.xml
@@ -5,7 +5,7 @@
iotkit-parent
cc.iotkit
- 0.2.0-SNAPSHOT
+ 0.2.1-SNAPSHOT
4.0.0
diff --git a/pom.xml b/pom.xml
index 42a455b8..ec1e1e80 100755
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
cc.iotkit
iotkit-parent
- 0.2.0-SNAPSHOT
+ 0.2.1-SNAPSHOT
iotkit-parent
iotkit parent
diff --git a/protocol-gateway/component-server/pom.xml b/protocol-gateway/component-server/pom.xml
index 71221cc5..7bc64306 100755
--- a/protocol-gateway/component-server/pom.xml
+++ b/protocol-gateway/component-server/pom.xml
@@ -5,7 +5,7 @@
protocol-gateway
cc.iotkit
- 0.2.0-SNAPSHOT
+ 0.2.1-SNAPSHOT
4.0.0
diff --git a/protocol-gateway/component-server/src/main/java/cc/iotkit/comps/DeviceComponentManager.java b/protocol-gateway/component-server/src/main/java/cc/iotkit/comps/DeviceComponentManager.java
index 141e503e..249fd8fc 100755
--- a/protocol-gateway/component-server/src/main/java/cc/iotkit/comps/DeviceComponentManager.java
+++ b/protocol-gateway/component-server/src/main/java/cc/iotkit/comps/DeviceComponentManager.java
@@ -135,6 +135,7 @@ public class DeviceComponentManager {
deviceBehaviourService, deviceRouter);
messageHandler.putScriptEnv("apiTool", new ApiTool());
messageHandler.putScriptEnv("deviceBehaviour", deviceBehaviourService);
+ messageHandler.putScriptEnv("component", component);
component.setHandler(messageHandler);
component.start();
@@ -178,19 +179,36 @@ public class DeviceComponentManager {
}
IDeviceComponent deviceComponent = (IDeviceComponent) component;
- Device device = new Device(deviceInfo.getDeviceId(), deviceInfo.getModel(), product.isTransparent());
+ //构建必要的设备信息
+ Map tag = new HashMap<>();
+ deviceInfo.getTag().forEach((k, v) -> tag.put(k, v.getValue()));
+ Device device = new Device(deviceInfo.getDeviceId(),
+ deviceInfo.getModel(),
+ deviceInfo.getProperty(),
+ tag,
+ product.isTransparent());
+
//对下发消息进行编码转换
DeviceMessage message = deviceComponent.getConverter().encode(service, device);
if (message == null) {
throw new BizException("encode send message failed");
}
- //保存设备端mid与平台mid对应关系
- redisTemplate.opsForValue().set(
- CacheKey.getKeyCmdMid(message.getDeviceName(), message.getMid()),
- service.getMid(), deviceComponent.getConfig().getCmdTimeout(), TimeUnit.SECONDS);
- //发送消息给设备
- deviceComponent.send(message);
+ String sendMid = message.getMid();
+ long timeout=deviceComponent.getConfig().getCmdTimeout();
+
+ //保存设备端mid与平台mid对应关系
+ saveMidMapping(message,timeout,service.getMid());
+ //发送消息给设备
+ message = deviceComponent.send(message);
+
+ //mid发生改变
+ if (!sendMid.equals(message.getMid())) {
+ //重新保存消息id映射
+ saveMidMapping(message,timeout,service.getMid());
+ }
+
+ //产生下发消息
ThingModelMessage thingModelMessage = ThingModelMessage.builder()
.mid(service.getMid())
.productKey(service.getProductKey())
@@ -202,6 +220,15 @@ public class DeviceComponentManager {
deviceBehaviourService.reportMessage(thingModelMessage);
}
+ /**
+ * 保存设备端mid与平台mid对应关系
+ */
+ private void saveMidMapping(DeviceMessage message, long cmdTimeout, String serviceMid) {
+ redisTemplate.opsForValue().set(
+ CacheKey.getKeyCmdMid(message.getDeviceName(), message.getMid()),
+ serviceMid, cmdTimeout, TimeUnit.SECONDS);
+ }
+
public String getPlatformMid(String deviceName, String mid) {
return redisTemplate.opsForValue().get(CacheKey.getKeyCmdMid(deviceName, mid));
}
diff --git a/protocol-gateway/component/pom.xml b/protocol-gateway/component/pom.xml
index fabd10b0..2a822814 100755
--- a/protocol-gateway/component/pom.xml
+++ b/protocol-gateway/component/pom.xml
@@ -5,7 +5,7 @@
protocol-gateway
cc.iotkit
- 0.2.0-SNAPSHOT
+ 0.2.1-SNAPSHOT
4.0.0
diff --git a/protocol-gateway/component/src/main/java/cc/iotkit/comp/AbstractDeviceComponent.java b/protocol-gateway/component/src/main/java/cc/iotkit/comp/AbstractDeviceComponent.java
index bf7e6e99..9a572914 100755
--- a/protocol-gateway/component/src/main/java/cc/iotkit/comp/AbstractDeviceComponent.java
+++ b/protocol-gateway/component/src/main/java/cc/iotkit/comp/AbstractDeviceComponent.java
@@ -19,7 +19,7 @@ public abstract class AbstractDeviceComponent implements IDeviceComponent {
protected String script;
- private String id;
+ protected String id;
@Override
public void create(CompConfig config) {
diff --git a/protocol-gateway/component/src/main/java/cc/iotkit/comp/IDeviceComponent.java b/protocol-gateway/component/src/main/java/cc/iotkit/comp/IDeviceComponent.java
index ab03e29c..8cc058af 100755
--- a/protocol-gateway/component/src/main/java/cc/iotkit/comp/IDeviceComponent.java
+++ b/protocol-gateway/component/src/main/java/cc/iotkit/comp/IDeviceComponent.java
@@ -14,7 +14,7 @@ public interface IDeviceComponent extends IComponent {
void onDeviceStateChange(DeviceState state);
- void send(DeviceMessage message);
+ DeviceMessage send(DeviceMessage message);
void setHandler(IMessageHandler handler);
diff --git a/protocol-gateway/converter/pom.xml b/protocol-gateway/converter/pom.xml
index fb621ecc..854bd32d 100755
--- a/protocol-gateway/converter/pom.xml
+++ b/protocol-gateway/converter/pom.xml
@@ -5,7 +5,7 @@
protocol-gateway
cc.iotkit
- 0.2.0-SNAPSHOT
+ 0.2.1-SNAPSHOT
4.0.0
diff --git a/protocol-gateway/converter/src/main/java/cc/iotkit/converter/Device.java b/protocol-gateway/converter/src/main/java/cc/iotkit/converter/Device.java
index 2ec7efd2..e8e5e712 100755
--- a/protocol-gateway/converter/src/main/java/cc/iotkit/converter/Device.java
+++ b/protocol-gateway/converter/src/main/java/cc/iotkit/converter/Device.java
@@ -4,6 +4,9 @@ import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
+import java.util.HashMap;
+import java.util.Map;
+
@Data
@NoArgsConstructor
@AllArgsConstructor
@@ -13,6 +16,10 @@ public class Device {
private String model;
+ private Map property = new HashMap<>();
+
+ private Map tag = new HashMap<>();
+
/**
* 是否透传
*/
diff --git a/protocol-gateway/ctwing-component/dependency-reduced-pom.xml b/protocol-gateway/ctwing-component/dependency-reduced-pom.xml
new file mode 100644
index 00000000..fb5a6250
--- /dev/null
+++ b/protocol-gateway/ctwing-component/dependency-reduced-pom.xml
@@ -0,0 +1,84 @@
+
+
+
+ protocol-gateway
+ cc.iotkit
+ 0.2.1-SNAPSHOT
+
+ 4.0.0
+ ctwing-component
+
+
+
+ maven-shade-plugin
+ 3.2.4
+
+
+ package
+
+ shade
+
+
+
+
+
+
+ io.vertx:vertx-web-proxy
+ io.vertx:vertx-web
+ io.vertx:vertx-bridge-common
+ io.vertx:vertx-http-proxy
+ io.vertx:vertx-core
+ io.netty:netty-codec-http2
+ com.ctg.ag:ctg-ag-sdk-core
+ com.ctg.ag:ag-sdk-biz-84356.tar.gz
+ org.apache.httpcomponents:httpasyncclient
+
+
+
+
+
+ maven-compiler-plugin
+
+
+ 8
+
+
+
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.22
+ compile
+
+
+ io.vertx
+ vertx-web-proxy
+ 4.2.2
+ provided
+
+
+ cc.iotkit
+ component
+ 0.2.1-SNAPSHOT
+ compile
+
+
+ com.ctg.ag
+ ctg-ag-sdk-core
+ 2.5.0-SNAPSHOT
+ provided
+
+
+ com.ctg.ag
+ ag-sdk-biz-84356.tar.gz
+ 20220603.182201-SNAPSHOT
+ provided
+
+
+
+ 8
+ 8
+
+
diff --git a/protocol-gateway/ctwing-component/pom.xml b/protocol-gateway/ctwing-component/pom.xml
new file mode 100644
index 00000000..13995e62
--- /dev/null
+++ b/protocol-gateway/ctwing-component/pom.xml
@@ -0,0 +1,92 @@
+
+
+
+ protocol-gateway
+ cc.iotkit
+ 0.2.1-SNAPSHOT
+
+ 4.0.0
+
+ ctwing-component
+
+
+
+ 8
+ 8
+
+
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+ io.vertx
+ vertx-web-proxy
+
+
+
+ cc.iotkit
+ component
+
+
+
+ com.ctg.ag
+ ctg-ag-sdk-core
+ 2.5.0-SNAPSHOT
+
+
+
+ com.ctg.ag
+ ag-sdk-biz-84356.tar.gz
+ 20220603.182201-SNAPSHOT
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.4
+
+
+ package
+
+ shade
+
+
+
+
+
+
+ io.vertx:vertx-web-proxy
+ io.vertx:vertx-web
+ io.vertx:vertx-bridge-common
+ io.vertx:vertx-http-proxy
+ io.vertx:vertx-core
+ io.netty:netty-codec-http2
+ com.ctg.ag:ctg-ag-sdk-core
+ com.ctg.ag:ag-sdk-biz-84356.tar.gz
+ org.apache.httpcomponents:httpasyncclient
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+ 8
+
+
+
+
+
+
\ No newline at end of file
diff --git a/protocol-gateway/ctwing-component/src/main/java/cc/iotkit/comp/http/CtwingConfig.java b/protocol-gateway/ctwing-component/src/main/java/cc/iotkit/comp/http/CtwingConfig.java
new file mode 100644
index 00000000..81b534be
--- /dev/null
+++ b/protocol-gateway/ctwing-component/src/main/java/cc/iotkit/comp/http/CtwingConfig.java
@@ -0,0 +1,25 @@
+package cc.iotkit.comp.http;
+
+import lombok.Data;
+
+@Data
+public class CtwingConfig {
+
+ private int port;
+
+ /**
+ * ctwing推送消息加解密token
+ */
+ private String encryptToken;
+
+ /**
+ * ctwing应用的appKey
+ */
+ private String appKey;
+
+ /**
+ * ctwing应用的appSecret
+ */
+ private String appSecret;
+
+}
diff --git a/protocol-gateway/ctwing-component/src/main/java/cc/iotkit/comp/http/CtwingDeviceComponent.java b/protocol-gateway/ctwing-component/src/main/java/cc/iotkit/comp/http/CtwingDeviceComponent.java
new file mode 100644
index 00000000..c0580da0
--- /dev/null
+++ b/protocol-gateway/ctwing-component/src/main/java/cc/iotkit/comp/http/CtwingDeviceComponent.java
@@ -0,0 +1,197 @@
+package cc.iotkit.comp.http;
+
+import cc.iotkit.common.exception.BizException;
+import cc.iotkit.common.utils.CodecUtil;
+import cc.iotkit.common.utils.JsonUtil;
+import cc.iotkit.comp.AbstractDeviceComponent;
+import cc.iotkit.comp.CompConfig;
+import cc.iotkit.converter.DeviceMessage;
+import com.ctg.ag.sdk.biz.AepDeviceCommandClient;
+import com.ctg.ag.sdk.biz.aep_device_command.CreateCommandRequest;
+import com.ctg.ag.sdk.biz.aep_device_command.CreateCommandResponse;
+import io.vertx.core.Vertx;
+import io.vertx.core.http.HttpServer;
+import io.vertx.core.http.HttpServerRequest;
+import io.vertx.ext.web.Router;
+import io.vertx.ext.web.handler.BodyHandler;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.beanutils.BeanUtils;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 电信天翼接入组件
+ */
+@Slf4j
+public class CtwingDeviceComponent extends AbstractDeviceComponent {
+
+ private final Vertx vertx = Vertx.vertx();
+
+ private CtwingConfig ctwingConfig;
+
+ private HttpServer backendServer;
+
+ private AepDeviceCommandClient commandClient;
+
+ @Override
+ public void create(CompConfig config) {
+ super.create(config);
+ this.ctwingConfig = JsonUtil.parse(config.getOther(), CtwingConfig.class);
+ commandClient = AepDeviceCommandClient.newClient()
+ .appKey(ctwingConfig.getAppKey())
+ .appSecret(ctwingConfig.getAppSecret())
+ .build();
+ }
+
+ @Override
+ public void start() {
+ backendServer = vertx.createHttpServer();
+ Router backendRouter = Router.router(vertx);
+
+ backendRouter.route().handler(BodyHandler.create())
+ .handler(rc -> {
+ try {
+ Map httpHeader = ProtocolUtil.getData(rc.request().headers());
+ log.info("request header:{}", JsonUtil.toJsonString(httpHeader));
+ Map> httpParams = ProtocolUtil.getListData(rc.request().params());
+ log.info("request params:{}", JsonUtil.toJsonString(httpParams));
+
+ HttpServerRequest httpRequest = rc.request();
+ String contentType = httpRequest.headers().get("Content-Type");
+ String requestBody = "";
+ int responseCode = 500;
+ if ("application/json".equals(contentType)) {
+ requestBody = rc.getBody().toString();
+ EncodedMessage msg = JsonUtil.parse(requestBody, EncodedMessage.class);
+ String content = CodecUtil.aesDecrypt(ctwingConfig.getEncryptToken(), msg.getEnc_msg());
+ log.info("decrypt msg:{}", content);
+ getHandler().onReceive(httpHeader, "", content);
+ responseCode = 200;
+ }
+ log.info("request body:{}", requestBody);
+
+ rc.response().setStatusCode(responseCode)
+ .end();
+ } catch (Throwable e) {
+ log.error("handle request error", e);
+ rc.response().setStatusCode(500).end();
+ }
+ });
+
+ backendServer.requestHandler(backendRouter)
+ .listen(ctwingConfig.getPort(), (http) -> {
+ if (http.succeeded()) {
+ log.info("http server create succeed,port:{}", ctwingConfig.getPort());
+ } else {
+ log.error("http server create failed", http.cause());
+ }
+ });
+ }
+
+ @Override
+ public DeviceMessage send(DeviceMessage message) {
+ Object obj = message.getContent();
+ if (!(obj instanceof Map)) {
+ throw new BizException("message content is not Map");
+ }
+ SendContent msg = new SendContent();
+ try {
+ BeanUtils.populate(msg, (Map) obj);
+ } catch (Throwable e) {
+ throw new BizException("message content is incorrect");
+ }
+
+ CreateCommandRequest request = new CreateCommandRequest();
+ request.setParamMasterKey(msg.getMasterKey());
+ request.setBody(("{\n" +
+ " \"content\":{\n" +
+ " \"dataType\":2,\n" +
+ " \"payload\":\"" + msg.getPayload() + "\"\n" +
+ " },\n" +
+ " \"deviceId\":\"" + message.getDeviceName() + "\",\n" +
+ " \"operator\":\"none\",\n" +
+ " \"productId\":" + msg.getProductId() + ",\n" +
+ " \"ttl\":0,\n" +
+ " \"level\":1\n" +
+ "}").getBytes());
+ CreateCommandResponse response;
+ try {
+ response = commandClient.CreateCommand(request);
+ } catch (Exception e) {
+ throw new RuntimeException("send cmd to ctwing error", e);
+ }
+
+ String body = new String(response.getBody());
+ log.info("send ctwing cmd result:{}", body);
+ if (response.getStatusCode() != 200) {
+ throw new RuntimeException("send cmd to ctwing error:" + body);
+ }
+
+ CtwingCmdRsp cmdRsp = JsonUtil.parse(body, CtwingCmdRsp.class);
+ if (cmdRsp.code != 0) {
+ throw new RuntimeException("send cmd to ctwing failed:" + body);
+ }
+
+ return message;
+ }
+
+ @Override
+ public void stop() {
+ backendServer.close();
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+ /**
+ * 将数据编码成68H16H协议数据包,给js调用
+ */
+ public String encode68H16H(String devId, String cardNo, Object[] values) {
+ return ProtocolUtil.encode68H16H(devId, cardNo, values);
+ }
+
+ /**
+ * 将68H16H协议的base64字符串消息解码为map数据,给js调用
+ */
+ public Map decode68H16H(String base64Str) {
+ return ProtocolUtil.decode68H16H(base64Str);
+ }
+
+ @Data
+ public static class EncodedMessage {
+ private String msg_signature;
+ private String enc_msg;
+ }
+
+ @Data
+ public static class SendContent {
+ private String masterKey;
+ private String productId;
+ private String payload;
+ }
+
+
+ @Data
+ public static class CtwingCmdRsp {
+ private int code;
+ protected String msg;
+ protected CmdResult result;
+ }
+
+ @Data
+ public static class CmdResult {
+ private String commandId;
+ private String command;
+ private String commandStatus;
+ private int productId;
+ private String deviceId;
+ private String imei;
+ private String createBy;
+ private String createTime;
+ private int ttl;
+ }
+
+}
diff --git a/protocol-gateway/ctwing-component/src/main/java/cc/iotkit/comp/http/ProtocolUtil.java b/protocol-gateway/ctwing-component/src/main/java/cc/iotkit/comp/http/ProtocolUtil.java
new file mode 100644
index 00000000..e0490c98
--- /dev/null
+++ b/protocol-gateway/ctwing-component/src/main/java/cc/iotkit/comp/http/ProtocolUtil.java
@@ -0,0 +1,120 @@
+package cc.iotkit.comp.http;
+
+import cc.iotkit.common.utils.HexUtil;
+import io.vertx.core.MultiMap;
+
+import java.nio.ByteBuffer;
+import java.util.*;
+
+public class ProtocolUtil {
+
+ /**
+ * 将数据编码成68H16H协议数据包
+ */
+ public static String encode68H16H(String devId, String cardNo, Object[] values) {
+ //构建数据域
+ ByteBuffer bufferData = ByteBuffer.allocate(7);
+ //模拟数据..
+ bufferData.put((byte) 1);
+ bufferData.putShort((short) 4);
+ bufferData.putInt(100);
+ byte[] data = bufferData.array();
+
+ //起始符到卡号部分数据
+ ByteBuffer buffer = ByteBuffer.allocate(1 + 2 + 5 + data.length + 4 + 7 + 2);
+ int len = 1 + 2 + 5 + data.length + 4 + 7 + 2;
+ buffer.put((byte) len);
+ buffer.put((byte) 0x68);
+ buffer.putShort((short) 0);
+ buffer.put(devId.getBytes());
+ buffer.put(data);
+ buffer.putInt(0);
+ buffer.put(cardNo.getBytes());
+ byte[] data1 = buffer.array();
+
+ //校验码
+ int check = HexUtil.calcCrc16(data1, 0, data1.length);
+ //完整数据包
+ buffer = ByteBuffer.allocate(1 + data1.length + 2 + 1);
+ buffer.put((byte) (data1.length + 2));//帧长度
+ buffer.put(data1);//起始符到卡号部分数据
+ buffer.putShort((short) check);//检验码
+ buffer.put((byte) 0x16);
+ return HexUtil.toHexString(buffer.array());
+ }
+
+ /**
+ * 将68H16H协议的base64字符串消息解码为map数据
+ */
+ public static Map decode68H16H(String base64Str) {
+ byte[] bytes = Base64.getDecoder().decode(base64Str);
+
+ Map decodeData = new HashMap<>();
+ ByteBuffer buffer = ByteBuffer.wrap(bytes);
+ buffer.flip();
+ byte len = buffer.get();//帧长度
+ buffer.get();//帧起始符
+ buffer.getShort();//预留2byte
+ byte[] devId = new byte[5];//设备ID
+ buffer.get(devId, 0, 5);
+ String strDevId = new String(devId);
+ decodeData.put("devId", strDevId);
+
+ //数据域长度=帧长度-起始符-预留-设备ID-系统用-卡号-校验码
+ int dataLen = len - 1 - 2 - 5 - 4 - 7 - 2;
+ //数据域
+ byte[] data = new byte[dataLen];
+ buffer.get(data, 0, dataLen);
+ Object[] values = ProtocolUtil.getTlvValues(data);
+ //模拟取1个值
+ decodeData.put("flow", values[0]);
+
+ buffer.getInt();//系统用
+ //卡号
+ byte[] card = new byte[7];
+ buffer.get(card, 0, card.length);
+ String cardNo = new String(card);
+ decodeData.put("cardNo", cardNo);
+
+ return decodeData;
+ }
+
+ public static Object[] getTlvValues(byte[] data) {
+ List