├── README.md ├── src ├── main │ ├── resources │ │ ├── kafka.properties │ │ ├── netty-server.properties │ │ ├── important.properties │ │ ├── banner.txt │ │ ├── config │ │ │ ├── spring-config.xml │ │ │ ├── mybatis-sqlmap-config.xml │ │ │ ├── spring-config-druid.xml │ │ │ └── spring-config-druid-datasource.xml │ │ ├── protocol_analyst.properties │ │ ├── protocol_mall_packet.properties │ │ ├── protocol_device_packet.properties │ │ └── log4j.xml │ └── java │ │ └── com │ │ └── mortals │ │ └── iot │ │ ├── server │ │ ├── initializer │ │ │ ├── SystemShutdownHook.java │ │ │ └── NettyServerInitializer.java │ │ └── TCPServer.java │ │ ├── handler │ │ └── protocol808 │ │ │ └── collect │ │ │ ├── protocol │ │ │ ├── handler │ │ │ │ ├── device │ │ │ │ │ ├── SessionAttribute.java │ │ │ │ │ ├── response │ │ │ │ │ │ ├── DrivingRecordToServerHandler.java │ │ │ │ │ │ ├── DeviceParamToServerHandler.java │ │ │ │ │ │ ├── PositionToServerHandler.java │ │ │ │ │ │ └── CommonReplayHandler.java │ │ │ │ │ └── up │ │ │ │ │ │ ├── MultimediaUploadHandler.java │ │ │ │ │ │ ├── EventReport.java │ │ │ │ │ │ ├── LocationHandler.java │ │ │ │ │ │ ├── InfomationSubscribeCancle.java │ │ │ │ │ │ ├── MultimediaEventInfoHandler.java │ │ │ │ │ │ ├── QuizRelayHandler.java │ │ │ │ │ │ ├── UnvarnishedTransmiteHandler.java │ │ │ │ │ │ ├── CompressUploadHandler.java │ │ │ │ │ │ ├── DriverIdentityInfoHandler.java │ │ │ │ │ │ ├── HeartHandler.java │ │ │ │ │ │ ├── ElectronicWaybillHandler.java │ │ │ │ │ │ ├── AuthenticHandler.java │ │ │ │ │ │ └── UnRegistHandler.java │ │ │ │ ├── mall │ │ │ │ │ ├── CallReqHandler.java │ │ │ │ │ ├── QuestionReqHandler.java │ │ │ │ │ ├── TxtSendReqClient.java │ │ │ │ │ ├── RecordStartReqHandler.java │ │ │ │ │ ├── CourseReqHandler.java │ │ │ │ │ ├── SettingPhonebookReqHandler.java │ │ │ │ │ ├── ShootImmediatelyReqHandler.java │ │ │ │ │ ├── PolygonAreaReqHandler.java │ │ │ │ │ ├── SetpCircularAreaHandler.java │ │ │ │ │ ├── UnvarnishedTransmiteReqHandler.java │ │ │ │ │ ├── DeivceDriverICReqHandler.java │ │ │ │ │ ├── DelCircularAreaHandler.java │ │ │ │ │ ├── DelPolygonAreaReqHandle.java │ │ │ │ │ ├── DisarmAlarmReqHandle.java │ │ │ │ │ ├── RectangularAreaReqHandle.java │ │ │ │ │ ├── DelRectangularAreaReqHandle.java │ │ │ │ │ ├── DeviceControllReqHandler.java │ │ │ │ │ ├── DeviceParamSetReqHandler.java │ │ │ │ │ ├── DrivingRecordReqHandler.java │ │ │ │ │ ├── DeivceParamReqHandler.java │ │ │ │ │ └── PositionReqHandler.java │ │ │ │ ├── service │ │ │ │ │ ├── IDeviceCommandContext.java │ │ │ │ │ ├── AbstractDeviceCommandHandler.java │ │ │ │ │ └── AbstractMallCommandHandler.java │ │ │ │ └── MallMessageHandler.java │ │ │ ├── entity │ │ │ │ ├── client │ │ │ │ │ ├── DrivingRecordParam.java │ │ │ │ │ ├── LinkMan.java │ │ │ │ │ ├── AlarmMessage.java │ │ │ │ │ ├── SetPolygonArea_T.java │ │ │ │ │ ├── DeviceParamSetting.java │ │ │ │ │ ├── Recording.java │ │ │ │ │ ├── DeleteCircularArea.java │ │ │ │ │ ├── InfoMenuSettings_T.java │ │ │ │ │ ├── InfoMenuSettings.java │ │ │ │ │ ├── SetCircularArea.java │ │ │ │ │ ├── SaveMedia.java │ │ │ │ │ ├── SetRectangularArea.java │ │ │ │ │ ├── UpdataPack.java │ │ │ │ │ ├── ShootParam.java │ │ │ │ │ ├── SaveMediaUp.java │ │ │ │ │ ├── ConstantParams.java │ │ │ │ │ └── Course.java │ │ │ │ ├── LongPack.java │ │ │ │ └── device │ │ │ │ │ ├── SaveMediaRep.java │ │ │ │ │ └── CameraShootRep.java │ │ │ └── codec │ │ │ │ └── MessageEncoder.java │ │ │ └── commons │ │ │ ├── ConfigUtils.java │ │ │ ├── MyTest.java │ │ │ ├── SpringContextUtils.java │ │ │ ├── SpringContext.java │ │ │ ├── SerialNumber.java │ │ │ └── Log.java │ │ ├── IotHanderReceiveApplication.java │ │ └── framework │ │ └── cfg │ │ ├── SpringBootVFS.java │ │ ├── KafkaProducerConfig.java │ │ ├── KafkaConsumerConfig.java │ │ └── SpringConfig.java └── test │ └── java │ └── com │ └── mortals │ └── iot │ ├── AppTest.java │ └── KafkaProducerTest.java ├── target └── classes │ └── META-INF │ ├── MANIFEST.MF │ └── maven │ └── com.mortals.iot │ └── iot-hander-receive │ ├── pom.properties │ └── pom.xml ├── pom.xml └── mybatis-3-config.dtd /README.md: -------------------------------------------------------------------------------- 1 | jt808 java体系实现,采用技术 netty、spring、spring boot 2 | -------------------------------------------------------------------------------- /src/main/resources/kafka.properties: -------------------------------------------------------------------------------- 1 | kafka.broker.address=192.168.2.169:9092,192.168.2.169:9093,192.168.2.169:9094 -------------------------------------------------------------------------------- /target/classes/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Built-By: chengjun 3 | Build-Jdk: 1.8.0_151 4 | Created-By: Maven Integration for Eclipse 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/netty-server.properties: -------------------------------------------------------------------------------- 1 | tcp.port=8099 2 | #可指定boss组启动线程数量,默认为cpu核心数*2 3 | boss.thread.count=2 4 | worker.thread.count=2 5 | #设置保持心跳 6 | so.keepalive=true 7 | #设置可连接队列的大小 默认128 8 | so.backlog=100 9 | log4j.configuration=SpringNettyLog4j.properties -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/server/initializer/SystemShutdownHook.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.server.initializer; 2 | 3 | public class SystemShutdownHook extends Thread{ 4 | 5 | @Override 6 | public void run() { 7 | //TODO 是否netty chanl 8 | } 9 | 10 | 11 | } 12 | -------------------------------------------------------------------------------- /target/classes/META-INF/maven/com.mortals.iot/iot-hander-receive/pom.properties: -------------------------------------------------------------------------------- 1 | #Generated by Maven Integration for Eclipse 2 | #Tue Dec 19 14:06:28 CST 2017 3 | version=0.0.1-SNAPSHOT 4 | groupId=com.mortals.iot 5 | m2e.projectName=iot-hander-receive 6 | m2e.projectLocation=/Users/chengjun/mywork/workspace/iot/20171114_first_base/iot-hander-receive 7 | artifactId=iot-hander-receive 8 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/SessionAttribute.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device; 2 | 3 | /** 4 | * @ClassName: SessionAttribute 5 | * @Description: SESSION 存储与终端相关的属性列表 6 | * @Company iot 7 | * @author 8 | * @version 1.0, 2017-3-19 下午3:21:52 9 | */ 10 | public class SessionAttribute { 11 | 12 | 13 | // 流水号 14 | public static final String SERIALNUMBER = "SerialNumber"; 15 | 16 | // 终端需要发送鉴权码 17 | public static final String AUTHENTICATION_KEY = "AuthenticationKey"; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/resources/important.properties: -------------------------------------------------------------------------------- 1 | jdbc.driverClassName=com.mysql.jdbc.Driver 2 | jdbc.url=jdbc:mysql://localhost:3306/iot?useUnicode=true&characterEncoding=utf8&useSSL=false&&serverTimezone=UTC 3 | jdbc.username=root 4 | jdbc.password=12345678 5 | hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect 6 | 7 | spring.application.name=iot-hander-receive 8 | mybatis.root-path: com.mortals 9 | mybatis.type-aliases-package: com.mortals.framework.model,com.mortals.iot.common.**.model,com.mortals.iot.**.model 10 | mybatis.mapper-locations: classpath:sqlmap/**/*.xml 11 | mybatis.config-location: classpath:config/mybatis-sqlmap-config.xml 12 | -------------------------------------------------------------------------------- /src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | .__ __ .__ .___ .__ 2 | |__| _____/ |_ | |__ _____ ____ __| _/___________ _______ ____ ____ ____ |__|__ __ ____ 3 | | |/ _ \ __\ | | \\__ \ / \ / __ |/ __ \_ __ \ \_ __ \_/ __ \_/ ___\/ __ \| \ \/ // __ \ 4 | | ( <_> ) | | Y \/ __ \| | \/ /_/ \ ___/| | \/ | | \/\ ___/\ \__\ ___/| |\ /\ ___/ 5 | |__|\____/|__| |___| (____ /___| /\____ |\___ >__| |__| \___ >\___ >___ >__| \_/ \___ > 6 | \/ \/ \/ \/ \/ \/ \/ \/ \/ -------------------------------------------------------------------------------- /src/main/resources/config/spring-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /target/classes/META-INF/maven/com.mortals.iot/iot-hander-receive/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.mortals.iot 6 | iot-hander-receive 7 | 0.0.1-SNAPSHOT 8 | jar 9 | 10 | iot-zipkin 11 | 业务转发服务 12 | 13 | 14 | 15 | junit 16 | junit 17 | 4.11 18 | test 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/test/java/com/mortals/iot/AppTest.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot; 2 | 3 | import junit.framework.Test; 4 | import junit.framework.TestCase; 5 | import junit.framework.TestSuite; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | extends TestCase 12 | { 13 | /** 14 | * Create the test case 15 | * 16 | * @param testName name of the test case 17 | */ 18 | public AppTest( String testName ) 19 | { 20 | super( testName ); 21 | } 22 | 23 | /** 24 | * @return the suite of tests being tested 25 | */ 26 | public static Test suite() 27 | { 28 | return new TestSuite( AppTest.class ); 29 | } 30 | 31 | /** 32 | * Rigourous Test :-) 33 | */ 34 | public void testApp() 35 | { 36 | assertTrue( true ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/CallReqHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | 8 | /** 9 | * @ClassName: CallReqClientHandler 10 | * @Description: 电话回拨0x8400:服务端处理来自客户端发送的请求 11 | * @Company iot 12 | * @author 13 | * @version 1.0, 2017-3-27 上午11:27:43 14 | */ 15 | @Component(value = "p_call_req_client") 16 | public class CallReqHandler extends AbstractMallCommandHandler { 17 | 18 | @Override 19 | public JT808ProtocalPack receive(String message) throws Exception { 20 | return null; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/resources/config/mybatis-sqlmap-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/IotHanderReceiveApplication.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 6 | import org.springframework.context.annotation.ComponentScan; 7 | import org.springframework.context.annotation.ImportResource; 8 | 9 | @ComponentScan(value = { "com.mortals.iot.framework.cfg", "com.mortals.iot.handler", "com.mortals.iot.server" }) 10 | @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) 11 | @ImportResource(locations = { "classpath:config/spring-config.xml" }) 12 | public class IotHanderReceiveApplication { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(IotHanderReceiveApplication.class, args); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/QuestionReqHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | 8 | /** 9 | * @ClassName: QuestionReqHandler 10 | * @Description: 提问下发0x8302:服务端处理来自客户端发送的请求 11 | * @Company iot 12 | * @author 13 | * @version 1.0, 2017-3-27 下午6:07:43 14 | */ 15 | @Component(value = "p_question_req_client") 16 | public class QuestionReqHandler extends AbstractMallCommandHandler { 17 | 18 | @Override 19 | public JT808ProtocalPack receive(String message) throws Exception { 20 | // TODO Auto-generated method stub 21 | return null; 22 | } 23 | 24 | @Override 25 | public void send(JT808ProtocalPack message) throws Exception { 26 | // TODO Auto-generated method stub 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/TxtSendReqClient.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | 8 | /** 9 | * @ClassName: TxtSendReqClient 10 | * @Description: 文本信息下发0x8300:服务端处理来自客户端发送的请求 11 | * @Company iot 12 | * @author 13 | * @version 1.0, 2017-3-26 下午5:38:37 14 | */ 15 | @Component(value = "p_txt_send_req_client") 16 | public class TxtSendReqClient extends AbstractMallCommandHandler { 17 | 18 | @Override 19 | public JT808ProtocalPack receive(String message) throws Exception { 20 | // TODO Auto-generated method stub 21 | return null; 22 | } 23 | 24 | @Override 25 | public void send(JT808ProtocalPack message) throws Exception { 26 | // TODO Auto-generated method stub 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/RecordStartReqHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | 8 | /** 9 | * @ClassName: RecordStartReqHandler 10 | * @Description: 录音开始命令0x8804:服务端处理来自客户端发送的请求 11 | * @Company iot 12 | * @author 13 | * @version 1.0, 2017-3-27 下午5:41:08 14 | */ 15 | @Component(value = "p_record_start_client") 16 | public class RecordStartReqHandler extends AbstractMallCommandHandler { 17 | 18 | @Override 19 | public JT808ProtocalPack receive(String message) throws Exception { 20 | // TODO Auto-generated method stub 21 | return null; 22 | } 23 | 24 | @Override 25 | public void send(JT808ProtocalPack message) throws Exception { 26 | // TODO Auto-generated method stub 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/CourseReqHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | 8 | /** 9 | * #设置路线 8606 10 | * 11 | * @author 12 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.handler.client.request 13 | * @copyright iot 14 | * @date:2017-4-25 下午2:41:07 15 | */ 16 | @Component(value = "p_Course_client") 17 | public class CourseReqHandler extends AbstractMallCommandHandler { 18 | 19 | @Override 20 | public JT808ProtocalPack receive(String message) throws Exception { 21 | return null; 22 | // TODO Auto-generated method stub 23 | 24 | } 25 | 26 | @Override 27 | public void send(JT808ProtocalPack message) throws Exception { 28 | // TODO Auto-generated method stub 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/SettingPhonebookReqHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | 8 | /** 9 | * @ClassName: SettingPhonebookReqHandler 10 | * @Description: 设置电话本0x8401:服务端处理来自客户端发送的请求 11 | * @Company iot 12 | * @author 13 | * @version 1.0, 2017-3-27 下午2:22:16 14 | */ 15 | @Component(value = "p_setting_phonebook_client") 16 | public class SettingPhonebookReqHandler extends AbstractMallCommandHandler { 17 | 18 | @Override 19 | public JT808ProtocalPack receive(String message) throws Exception { 20 | // TODO Auto-generated method stub 21 | return null; 22 | } 23 | 24 | @Override 25 | public void send(JT808ProtocalPack message) throws Exception { 26 | // TODO Auto-generated method stub 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/ShootImmediatelyReqHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | 8 | /** 9 | * @ClassName: ShootImmediatelyReqHandler 10 | * @Description: 摄像头立即拍摄命令0x8801:服务端处理来自客户端发送的请求 11 | * @Company iot 12 | * @author 13 | * @version 1.0, 2017-3-27 下午4:05:43 14 | */ 15 | @Component(value = "p_shoot_immediately_client") 16 | public class ShootImmediatelyReqHandler extends AbstractMallCommandHandler { 17 | 18 | @Override 19 | public JT808ProtocalPack receive(String message) throws Exception { 20 | // TODO Auto-generated method stub 21 | return null; 22 | } 23 | 24 | @Override 25 | public void send(JT808ProtocalPack message) throws Exception { 26 | // TODO Auto-generated method stub 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/PolygonAreaReqHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | 8 | /** 9 | * @MessageID 0x8604 10 | * @author 11 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.handler.client.request 12 | * @copyright iot 13 | * @date:2017-4-17 上午10:16:27 14 | */ 15 | @Component(value = "p_set_Polygon_Area_client") 16 | public class PolygonAreaReqHandler extends AbstractMallCommandHandler { 17 | 18 | @Override 19 | public JT808ProtocalPack receive(String message) throws Exception { 20 | // TODO Auto-generated method stub 21 | return null; 22 | } 23 | 24 | @Override 25 | public void send(JT808ProtocalPack message) throws Exception { 26 | // TODO Auto-generated method stub 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/SetpCircularAreaHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | 8 | /** 9 | * 0x8600 10 | * 11 | * @author 12 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.handler.client.request 13 | * @copyright iot 14 | * @date:2017-4-10 上午10:30:54 15 | */ 16 | @Component(value = "p_set_Circular_Area_client") 17 | public class SetpCircularAreaHandler extends AbstractMallCommandHandler { 18 | 19 | @Override 20 | public JT808ProtocalPack receive(String message) throws Exception { 21 | // TODO Auto-generated method stub 22 | return null; 23 | } 24 | 25 | @Override 26 | public void send(JT808ProtocalPack message) throws Exception { 27 | // TODO Auto-generated method stub 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/UnvarnishedTransmiteReqHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | 8 | /** 9 | * @ClassName: UnvarnishedTransmiteReqHandler 10 | * @Description: 透传消息0x8900:服务端处理来自客户端发送的请求 11 | * @Company iot 12 | * @author 13 | * @version 1.0, 2017-3-27 下午4:56:05 14 | */ 15 | @Component(value = "p_unvarnished_transmite_client") 16 | public class UnvarnishedTransmiteReqHandler extends AbstractMallCommandHandler { 17 | 18 | @Override 19 | public JT808ProtocalPack receive(String message) throws Exception { 20 | // TODO Auto-generated method stub 21 | return null; 22 | } 23 | 24 | @Override 25 | public void send(JT808ProtocalPack message) throws Exception { 26 | // TODO Auto-generated method stub 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/DeivceDriverICReqHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | 8 | /** 9 | * @MessageID 8702 10 | * @author 11 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.handler.client.request 12 | * @copyright iot 13 | * @date:2017-4-15 下午2:48:24 14 | */ 15 | @Component(value = "p_device_driver_req_client") 16 | public class DeivceDriverICReqHandler extends AbstractMallCommandHandler { 17 | 18 | @Override 19 | public JT808ProtocalPack receive(String message) throws Exception { 20 | return null; 21 | // TODO Auto-generated method stub 22 | 23 | } 24 | 25 | @Override 26 | public void send(JT808ProtocalPack message) throws Exception { 27 | // TODO Auto-generated method stub 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/DelCircularAreaHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | 8 | /** 9 | * @MessageID 0x8601 10 | * @author 11 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.handler.client.request 12 | * @copyright iot 13 | * @date:2017-4-16 上午11:25:38 14 | */ 15 | @Component(value = "p_del_Circular_Area_client") 16 | public class DelCircularAreaHandler extends AbstractMallCommandHandler { 17 | 18 | @Override 19 | public JT808ProtocalPack receive(String message) throws Exception { 20 | return null; 21 | // TODO Auto-generated method stub 22 | 23 | } 24 | 25 | @Override 26 | public void send(JT808ProtocalPack message) throws Exception { 27 | // TODO Auto-generated method stub 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/service/IDeviceCommandContext.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.service; 2 | 3 | import java.util.Map; 4 | 5 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 6 | 7 | import io.netty.channel.Channel; 8 | 9 | /** 10 | * 11 | * @ClassName: IDeviceCommandContext 12 | * @Description: 上下文,先接收,再发送 13 | * @author 14 | * @date 2017-9-28 11:13:57 15 | * 16 | */ 17 | @Deprecated 18 | public class IDeviceCommandContext { 19 | 20 | private AbstractDeviceCommandHandler handler; 21 | 22 | public IDeviceCommandContext(AbstractDeviceCommandHandler handler) { 23 | this.handler = handler; 24 | } 25 | 26 | /** 27 | * 先处理设备发送的消息,并返回设备信息 28 | * 29 | * @param content 30 | * @param session 31 | * @throws Exception 32 | */ 33 | public void handle(JT808ProtocalPack content, Channel session) throws Exception { 34 | Map resultMap = handler.receive(content, session); 35 | handler.send(content, session, resultMap); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/DelPolygonAreaReqHandle.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | 8 | /** 9 | * 消息ID:0x8605。 10 | * 11 | * @author 12 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.handler.client.response 13 | * @copyright iot 14 | * @date:2017-4-17 上午11:00:09 15 | */ 16 | @Component(value = "p_del_Polygon_Area_client") 17 | public class DelPolygonAreaReqHandle extends AbstractMallCommandHandler { 18 | 19 | @Override 20 | public JT808ProtocalPack receive(String message) throws Exception { 21 | return null; 22 | // TODO Auto-generated method stub 23 | 24 | } 25 | 26 | @Override 27 | public void send(JT808ProtocalPack message) throws Exception { 28 | // TODO Auto-generated method stub 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/DisarmAlarmReqHandle.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | 8 | /** 9 | * 人工确认报警消息 10 | * 11 | * @MessageID 8203 12 | * @author 13 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.handler.client.request 14 | * @copyright iot 15 | * @date:2017-4-21 上午10:45:11 16 | */ 17 | @Component(value = "p_Disarm_Alarm_client") 18 | public class DisarmAlarmReqHandle extends AbstractMallCommandHandler { 19 | 20 | @Override 21 | public JT808ProtocalPack receive(String message) throws Exception { 22 | // TODO Auto-generated method stub 23 | return null; 24 | } 25 | 26 | @Override 27 | public void send(JT808ProtocalPack message) throws Exception { 28 | // TODO Auto-generated method stub 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/RectangularAreaReqHandle.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | 8 | /** 9 | * 设置矩形区域 消息ID:0x8602 10 | * 11 | * @author 12 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.handler.client.request 13 | * @copyright iot 14 | * @date:2017-4-17 上午11:48:00 15 | */ 16 | @Component(value = "p_set_Rectangular_Area_client") 17 | public class RectangularAreaReqHandle extends AbstractMallCommandHandler { 18 | 19 | @Override 20 | public JT808ProtocalPack receive(String message) throws Exception { 21 | // TODO Auto-generated method stub 22 | return null; 23 | } 24 | 25 | @Override 26 | public void send(JT808ProtocalPack message) throws Exception { 27 | // TODO Auto-generated method stub 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/DelRectangularAreaReqHandle.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | 8 | /** 9 | * 8603删除矩形区域 10 | * 11 | * @author 12 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.handler.client.request 13 | * @copyright iot 14 | * @date:2017-4-17 上午11:46:09 15 | */ 16 | @Component(value = "p_del_Rectangular_Area_client") 17 | public class DelRectangularAreaReqHandle extends AbstractMallCommandHandler { 18 | 19 | @Override 20 | public JT808ProtocalPack receive(String message) throws Exception { 21 | return null; 22 | // TODO Auto-generated method stub 23 | 24 | } 25 | 26 | @Override 27 | public void send(JT808ProtocalPack message) throws Exception { 28 | // TODO Auto-generated method stub 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/DeviceControllReqHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.DeviceControllEntity; 7 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 8 | 9 | /** 10 | * @ClassName: DeviceControllReqHandler 11 | * @Description: 终端控制0x8105 12 | * @Company iot 13 | * @author 14 | * @version 1.0, 2017-3-29 上午11:32:12 15 | */ 16 | @Component(value = "p_device_controll_req_client") 17 | public class DeviceControllReqHandler extends AbstractMallCommandHandler { 18 | 19 | @Override 20 | public JT808ProtocalPack receive(String message) throws Exception { 21 | DeviceControllEntity deviceControllEntity = new DeviceControllEntity(); 22 | JT808ProtocalPack jt808ProtocalPack = deviceControllEntity.toJT808ProtocalPack(message); 23 | return jt808ProtocalPack; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/DeviceParamSetReqHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 6 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 7 | import com.mortals.iot.protocol.jt808.entity.TerminalParameterSettingEntity; 8 | 9 | /** 10 | * @ClassName: DeviceparamSetReqHandler 11 | * @Description: 设置终端参数0x8103:服务端处理来自客户端发送的请求 12 | * @Company iot 13 | * @author 14 | * @version 1.0, 2017-3-29 上午11:32:12 15 | */ 16 | @Component(value = "p_deviceparam_set_req_client") 17 | public class DeviceParamSetReqHandler extends AbstractMallCommandHandler { 18 | 19 | @Override 20 | public JT808ProtocalPack receive(String message) throws Exception { 21 | TerminalParameterSettingEntity terminalParameterEntity = new TerminalParameterSettingEntity(); 22 | JT808ProtocalPack jt808ProtocalPack = terminalParameterEntity.toJT808ProtocalPack(message); 23 | return jt808ProtocalPack; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/response/DrivingRecordToServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.response; 2 | 3 | import java.util.Map; 4 | 5 | import org.springframework.stereotype.Component; 6 | 7 | import com.mortals.iot.handler.protocol808.collect.commons.Log; 8 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 9 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 10 | 11 | import io.netty.channel.Channel; 12 | 13 | /** 14 | * @ClassName: DrivingRecordToServerHandler 15 | * @Description: 行驶记录上传0x0700 16 | * @Company iot 17 | * @author 18 | * @version 1.0, 2017-3-21 下午3:25:50 19 | */ 20 | @Component(value = "p_driving_record_to_server") 21 | public class DrivingRecordToServerHandler extends AbstractDeviceCommandHandler { 22 | 23 | @Override 24 | public Map receive(JT808ProtocalPack message, Channel channel) throws Exception { 25 | Log.getLogger(this.getClass()).info("收到终端响应的信息:" + message.toHexString()); 26 | return null; 27 | } 28 | 29 | @Override 30 | public void send(JT808ProtocalPack message, Channel channel, Map resultMap) throws Exception { 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/response/DeviceParamToServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.response; 2 | 3 | import java.util.Map; 4 | 5 | import org.springframework.stereotype.Component; 6 | 7 | import com.mortals.iot.handler.protocol808.collect.commons.Log; 8 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 9 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 10 | 11 | import io.netty.channel.Channel; 12 | 13 | /** 14 | * @ClassName: DeviceparamResponseHandler 15 | * @Description: 查询终端参数应答0x0104:设备直接返回给服务端的信息 16 | * @Company iot 17 | * @author 18 | * @version 1.0, 2017-3-21 下午3:25:50 19 | */ 20 | @Component(value="p_device_param_to_server") 21 | public class DeviceParamToServerHandler extends AbstractDeviceCommandHandler{ 22 | 23 | @Override 24 | public Map receive(JT808ProtocalPack message, Channel channel) throws Exception { 25 | Log.getLogger(this.getClass()).info("收到终端响应的信息:" + message.toHexString()); 26 | return null; 27 | } 28 | 29 | @Override 30 | public void send(JT808ProtocalPack message, Channel channel,Map resultMap) throws Exception { 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/commons/ConfigUtils.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.commons; 2 | 3 | 4 | 5 | import java.io.IOException; 6 | import java.io.UnsupportedEncodingException; 7 | import java.util.Properties; 8 | 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | /** 13 | * @ClassName: ConfigUtils 14 | * @Description: 配置端口等信息工具 15 | * @author 16 | * @date 2017-12-31 下午2:16:45 17 | * 18 | */ 19 | public class ConfigUtils { 20 | 21 | private static final Properties props; 22 | 23 | private final static Logger logger = LoggerFactory.getLogger(ConfigUtils.class); 24 | 25 | static{ 26 | props = new Properties(); 27 | try { 28 | props.load(ConfigUtils.class.getClassLoader().getResourceAsStream("config.properties")); 29 | } catch (IOException e) { 30 | logger.error(e.getMessage(), e); 31 | } 32 | } 33 | 34 | private ConfigUtils(){} 35 | 36 | public static Object getValue(String name){ 37 | if(props.containsKey(name)){ 38 | try { 39 | return new String(props.get(name).toString().getBytes("ISO-8859-1"),"utf-8"); 40 | } catch (UnsupportedEncodingException e) { 41 | logger.error(e.getMessage(), e); 42 | return ""; 43 | } 44 | }else{ 45 | return ""; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/response/PositionToServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.response; 2 | 3 | import java.util.Map; 4 | 5 | import org.springframework.stereotype.Component; 6 | 7 | import com.mortals.iot.handler.protocol808.collect.commons.Log; 8 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 9 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 10 | import com.mortals.iot.protocol.jt808.entity.MessageID; 11 | 12 | import io.netty.channel.Channel; 13 | 14 | /** 15 | * @ClassName: PositionToServerHandler 16 | * @Description: 位置信息查询应答0x0201:终端直接响应服务端的请求 17 | * @Company iot 18 | * @author 19 | * @version 1.0, 2017-3-26 下午4:21:38 20 | */ 21 | @Component(value = "p_location_reply") 22 | public class PositionToServerHandler extends AbstractDeviceCommandHandler implements MessageID { 23 | 24 | @Override 25 | public Map receive(JT808ProtocalPack message, Channel channel) throws Exception { 26 | Log.getLogger(this.getClass()).info("收到终端响应的信息:" + message.toHexString()); 27 | return null; 28 | } 29 | 30 | @Override 31 | public void send(JT808ProtocalPack message, Channel channel, Map resultMap) throws Exception { 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/resources/protocol_analyst.properties: -------------------------------------------------------------------------------- 1 | #GPS status 2 | A=良好定位 3 | V=没有卫星定位 4 | 2=2D定位 5 | 3=3D定位 6 | 4=没有卫星定位与移动通讯信号 7 | 5=没有移动通讯信号 8 | 6=最后坐标 9 | 10 | 11 | # alarm 12 | alarm_00000000000000000000000000000000=null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null 13 | alarm_11111111111111111111111111111111=紧急报警,超速报警,疲劳驾驶,预警,GNSS模块发生故障,GNSS天线未接或被剪断,GNSS天线短路,终端主电源欠压,终端主电源掉电,终端LCD或显示器故障,TTS模块故障,摄像头故障,null,null,null,null,null,null,当天累计驾驶超时,超时停车,进出区域,进出路线,路线行驶时间不足/过长,路线偏离报警,车辆VSS故障,车辆油量异常,车辆被盗(通过车辆防盗器),车辆非法点火,车辆非法位移,碰撞侧翻报警,null,null 14 | 15 | # car status 16 | status_00000000000000000000000000000000=ACC关,未定位,北纬,东经,运营状态,经纬度未经保密插件加密,空车,null,null,null,车辆油路正常,车辆电路正常,车门解锁,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null 17 | status_11111111111111111111111111111111=ACC开,定位,南纬,西经,停运状态,经纬度已经保密插件加密,重车,null,null,null,车辆油路断开,车辆电路断开,车门加锁,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null 18 | 19 | 20 | # multi media 21 | media_type_0=图像 22 | media_type_1=音频 23 | media_type_2=视频 24 | 25 | media_format_0=JPEG 26 | media_format_1=TIF 27 | media_format_2=MP3 28 | media_format_3=WAV 29 | media_format_4=WMV 30 | 31 | media_eventcode_0=平台下发指令 32 | media_eventcode_1=定时动作 33 | media_eventcode_2=抢劫报警触发 34 | media_eventcode_3=碰撞侧翻报警触发 -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | jar 7 | iot-hander-receive 8 | iot-hander-receive 9 | 协议接收处理节点 10 | 11 | 12 | com.mortals.iot 13 | iot 14 | 0.0.1-SNAPSHOT 15 | 16 | 17 | 18 | 19 | org.springframework.kafka 20 | spring-kafka 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter 25 | 26 | 27 | com.alibaba 28 | druid-spring-boot-starter 29 | 30 | 31 | mysql 32 | mysql-connector-java 33 | 34 | 35 | com.mortals.iot 36 | iot-common 37 | 38 | 39 | junit 40 | junit 41 | test 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/response/CommonReplayHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.response; 2 | 3 | import java.util.Map; 4 | 5 | import org.springframework.stereotype.Component; 6 | 7 | import com.mortals.iot.handler.protocol808.collect.commons.Log; 8 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 9 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 10 | import com.mortals.iot.protocol.jt808.util.HexUtils; 11 | 12 | import io.netty.channel.Channel; 13 | 14 | /** 15 | * @ClassName: CommonReplayHandler 16 | * @Description: 终端通用应答0x0001:终端响应服务端的消息, 服务端处理并转发给请求端 17 | * @Company iot 18 | * @author 19 | * @version 1.0, 2017-3-20 上午10:59:00 20 | */ 21 | @Component(value = "p_device_common_replay") 22 | public class CommonReplayHandler extends AbstractDeviceCommandHandler { 23 | 24 | public Map receive(JT808ProtocalPack message, Channel tsession) throws Exception { 25 | String replyId = HexUtils.bytesToHexString(HexUtils.copyOfRange(message.getBody(), 2, 4)); 26 | // Log.getLogger(this.getClass()).info("测试成功~收到终端通用应答0x0001 应答ID为"+replyId); 27 | Log.getLogger(this.getClass()).info("应答ID:" + replyId); 28 | return null; 29 | } 30 | 31 | public void send(JT808ProtocalPack message, Channel tsession, Map reslutMap) throws Exception { 32 | 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/resources/protocol_mall_packet.properties: -------------------------------------------------------------------------------- 1 | #---------------------------------------- 2 | # S -> T 3 | #---------------------------------------- 4 | # 设置终端参数 5 | 8103=p_deviceparam_set_req_client 6 | 7 | # 查询终端参数 8 | 8104=p_device_param_req_client 9 | 10 | # 位置信息查询(点名定位) 11 | 8201=p_position_req_client 12 | 13 | # 查询驾驶员身份信息采集上报 14 | 8702=p_device_driver_req_client 15 | 16 | # 文本信息下发 17 | 8300=p_txt_send_req_client 18 | 19 | # 提问下发 20 | 8302=p_question_req_client 21 | 22 | # 电话回拨 23 | 8400=p_call_req_client 24 | 25 | # 设置电话本 26 | 8401=p_setting_phonebook_client 27 | 28 | # 立即拍摄 29 | 8801=p_shoot_immediately_client 30 | 31 | # 开始录音 32 | 8804=p_record_start_client 33 | 34 | # 透传消息 35 | 8900=p_unvarnished_transmite_client 36 | 37 | # 设置圆形区域 38 | 8600=p_set_Circular_Area_client 39 | 40 | # 删除圆形区域 41 | 8601=p_del_Circular_Area_client 42 | 43 | # 设置矩形区域 44 | 8602=p_set_Rectangular_Area_client 45 | 46 | # 删除矩形区域 47 | 8603=p_del_Rectangular_Area_client 48 | 49 | #设置多边形区域 50 | 8604=p_set_Polygon_Area_client 51 | 52 | #删除多边形区域 53 | 8605=p_del_Polygon_Area_client 54 | 55 | #人工确认报警消息 56 | 8203=p_Disarm_Alarm_client 57 | 58 | #设置路线 59 | 8606=p_Course_client 60 | 61 | #终端参数查询的响应 62 | 0104=p_device_param_req_client 63 | 64 | #位置信息查询应答 65 | 0201=p_position_req_client 66 | 67 | #行驶记录数据采集 68 | 69 | 8700=p_driving_record_req_client 70 | 71 | #行驶记录数据上传 72 | 0700=p_driving_record_req_client 73 | 74 | #终端控制 75 | 8105=p_device_controll_req_client 76 | -------------------------------------------------------------------------------- /src/main/resources/protocol_device_packet.properties: -------------------------------------------------------------------------------- 1 | 2 | 3 | # T : terminal 4 | # S : Server 5 | 6 | #------------------------------------------------------------- 7 | # Login, Logout, Register, HeartBeat Service 8 | #------------------------------------------------------------- 9 | 10 | #-------------------------------- 11 | # T -> S 12 | #-------------------------------- 13 | 14 | # 终端通用应答 15 | 0001=p_device_common_replay 16 | 17 | # 终端心跳 18 | 0002=p_heart 19 | 20 | # 终端注册 21 | 0100=p_device_regist 22 | 23 | # 终端注销 24 | 0101=p_device_unregist 25 | 0003=p_device_unregist 26 | 27 | # 终端鉴权 28 | 0102=p_device_auth 29 | 30 | # 位置信息汇报 31 | 0200=p_location 32 | 33 | # 位置信息查询应答 34 | 0201=p_location_reply 35 | 36 | # 提问应答 37 | 0302=p_quiz_relay 38 | 39 | # 透传消息上行 40 | 0900=p_unvarnished_transmite 41 | 42 | # 电子运单上报 43 | 0701=p_electronic_waybill 44 | 45 | 46 | # 电子运单上报:营业数据二次分发 47 | dc=p_electronic_waybill_business 48 | DC=p_electronic_waybill_business 49 | 50 | # 电子运单上报:通知出租车车载信息终端空车状态命令 51 | d3=p_electronic_waybill_empty 52 | D3=p_electronic_waybill_empty 53 | 54 | # 电子运单上报:通知出租车车载信息终端重车状态命令 55 | d4=p_electronic_waybill_weight 56 | D4=p_electronic_waybill_weight 57 | 58 | # 多媒体事件信息上传(意义:拍照完成通知) 59 | 0800=p_multimedia_event_info 60 | 61 | # 多媒体数据上传 62 | 0801=p_multimedia_upload 63 | 64 | # 终端参数查询的响应 65 | 0104=p_device_param_to_server 66 | 67 | # 事件报告 68 | 0301=p_event_report 69 | 70 | # 信息点播,取消 71 | 0303=p_infomation_subscribe_cancle 72 | 73 | # 行驶记录上传 74 | 0700=p_driving_record_to_server 75 | 76 | # 数据压缩上传 77 | 0901=p_compress_upload 78 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/framework/cfg/SpringBootVFS.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.framework.cfg; 2 | 3 | import java.io.IOException; 4 | import java.io.UncheckedIOException; 5 | import java.net.URL; 6 | import java.util.List; 7 | import java.util.stream.Collectors; 8 | import java.util.stream.Stream; 9 | 10 | import org.apache.ibatis.io.VFS; 11 | import org.springframework.core.io.Resource; 12 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; 13 | import org.springframework.core.io.support.ResourcePatternResolver; 14 | 15 | public class SpringBootVFS extends VFS 16 | { 17 | 18 | private final ResourcePatternResolver resourceResolver; 19 | 20 | public SpringBootVFS() { 21 | this.resourceResolver = new PathMatchingResourcePatternResolver(getClass().getClassLoader()); 22 | } 23 | 24 | 25 | public boolean isValid() { 26 | return true; 27 | } 28 | 29 | 30 | protected List list(URL url, String path) throws IOException { 31 | Resource[] resources = resourceResolver.getResources("classpath*:" + path + "/**/*.class"); 32 | return Stream.of(resources) 33 | .map(resource -> preserveSubpackageName(resource, path)) 34 | .collect(Collectors.toList()); 35 | } 36 | 37 | private static String preserveSubpackageName(final Resource resource, final String rootPath) { 38 | try { 39 | final String uriStr = resource.getURI().toString(); 40 | final int start = uriStr.indexOf(rootPath); 41 | return uriStr.substring(start); 42 | } catch (IOException e) { 43 | throw new UncheckedIOException(e); 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/mortals/iot/KafkaProducerTest.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.apache.kafka.clients.producer.ProducerConfig; 7 | import org.apache.kafka.common.serialization.StringSerializer; 8 | import org.springframework.kafka.core.DefaultKafkaProducerFactory; 9 | import org.springframework.kafka.core.KafkaTemplate; 10 | 11 | public class KafkaProducerTest { 12 | public static void main(String[] args) { 13 | Map props = new HashMap<>(); 14 | props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); 15 | props.put(ProducerConfig.RETRIES_CONFIG, 0); 16 | props.put(ProducerConfig.BATCH_SIZE_CONFIG, 4096); 17 | props.put(ProducerConfig.LINGER_MS_CONFIG, 1); 18 | props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, 40960); 19 | props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); 20 | props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); 21 | 22 | DefaultKafkaProducerFactory kafkaFctory = new DefaultKafkaProducerFactory<>(props); 23 | KafkaTemplate kafkaTemplate = new KafkaTemplate<>(kafkaFctory); 24 | 25 | String jsonData="{\r\n" + 26 | " \"action\": 33027,\r\n" + 27 | " \"devmark\": \"S60\",\r\n" + 28 | " \"serialNumber\": \"serialNumber\",\r\n" + 29 | " \"data\": {\r\n" + 30 | " \"5Y+C5pWw5oC75pWw\": 1,\r\n" + 31 | " \"5Y+C5pWw6aG55YiX6KGo\": [{\r\n" + 32 | " \"5Y+C5pWwSUQ=\": 1,\r\n" + 33 | " \"5Y+C5pWw6ZW/5bqm\": 4,\r\n" + 34 | " \"5Y+C5pWw5YC8\": 10\r\n" + 35 | " }]\r\n" + 36 | " }\r\n" + 37 | "}"; 38 | kafkaTemplate.send("commandreq", jsonData); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/DrivingRecordParam.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | import com.mortals.iot.protocol.jt808.util.HexUtils; 4 | 5 | /** 6 | *
  • 文件名称: DrivingRecordParam
  • 7 | *
  • 文件描述: 行驶记录参数下发实体类$
  • 8 | *
  • 内容摘要: 包括模块、函数及其功能的说明
  • 9 | *
  • 完成日期:2017-4-24
  • 10 | *
  • 修改记录1:iot
  • 11 | */ 12 | public class DrivingRecordParam { 13 | 14 | //终端手机号码 15 | private String deviceMobile; 16 | 17 | //命令字 18 | private int command; 19 | 20 | //数据块 21 | private String dataBlock; 22 | 23 | public DrivingRecordParam(String deviceMobile,byte[] body){ 24 | byte b_cmd=body[0]; 25 | byte [] b_data_block=HexUtils.copyOfRange(body, 1, body.length); 26 | 27 | this.deviceMobile = deviceMobile; 28 | this.command = HexUtils.byteBcdToInt(b_cmd); 29 | this.dataBlock = HexUtils.bytesToHexString(b_data_block); 30 | } 31 | 32 | public DrivingRecordParam(String deviceMobile, int command, String dataBlock) { 33 | this.deviceMobile = deviceMobile; 34 | this.command = command; 35 | this.dataBlock = dataBlock; 36 | } 37 | 38 | public String getDeviceMobile() { 39 | return deviceMobile; 40 | } 41 | 42 | public void setDeviceMobile(String deviceMobile) { 43 | this.deviceMobile = deviceMobile; 44 | } 45 | 46 | public int getCommand() { 47 | return command; 48 | } 49 | 50 | public void setCommand(int command) { 51 | this.command = command; 52 | } 53 | 54 | public String getDataBlock() { 55 | return dataBlock; 56 | } 57 | 58 | public void setDataBlock(String dataBlock) { 59 | this.dataBlock = dataBlock; 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/up/MultimediaUploadHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.up; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.mortals.framework.exception.AppException; 9 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 10 | import com.mortals.iot.protocol.jt808.constant.NumberConstants; 11 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 12 | 13 | import io.netty.channel.Channel; 14 | 15 | /** 16 | * @ClassName: MultimediaUploadHandler 17 | * @Description: 多媒体数据上传0x0801:终端上发给服务端的多媒体数据 18 | * @Company iot 19 | * @author 20 | * @version 1.0, 2017-3-28 下午4:25:37 21 | */ 22 | //@Component(value = "p_multimedia_upload") 23 | public class MultimediaUploadHandler extends AbstractDeviceCommandHandler { 24 | 25 | public Map receive(JT808ProtocalPack message, Channel channel) throws Exception { 26 | Map resultMap = new HashMap(); 27 | Integer result = NumberConstants._0; 28 | 29 | try { 30 | logger.info("多媒体数据上传:" + message.toHexString()); 31 | } catch (AppException e) { 32 | logger.error(e.getMessage()); 33 | result = NumberConstants._1; 34 | } catch (Exception e) { 35 | logger.error(e.getMessage(), e); 36 | result = NumberConstants._1; 37 | } 38 | 39 | resultMap.put("result", result); 40 | return resultMap; 41 | } 42 | 43 | // TODO bono: 分包处理 44 | public void send(JT808ProtocalPack message, Channel channel, Map reslutMap) throws Exception { 45 | 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/LinkMan.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | /** 4 | * @ClassName: Linkman 5 | * @Description: 联系人信息:联系人标志+号码长度+电话号码+联系人长度+联系人姓名 6 | * @Company iot 7 | * @author 8 | * @version 1.0, 2017-3-27 下午1:53:05 9 | */ 10 | public class LinkMan { 11 | 12 | // 联系人标志+号码长度+电话号码+联系人长度+联系人姓名 13 | 14 | 15 | // 1:呼入 16 | public static final int IN = 1; 17 | // 2:呼出 18 | public static final int OUT = 2; 19 | // 3:呼入/呼出 20 | public static final int INOUT = 3; 21 | 22 | private int flag; 23 | 24 | private String phoneNumber; 25 | 26 | private String linkName; 27 | 28 | public LinkMan(int flag, String phoneNumber, String linkName){ 29 | this.flag = flag; 30 | this.phoneNumber = phoneNumber; 31 | this.linkName = linkName; 32 | } 33 | 34 | /** 35 | * @return the flag 36 | */ 37 | public int getFlag() { 38 | return flag; 39 | } 40 | 41 | /** 42 | * @param flag the flag to set 43 | */ 44 | public void setFlag(int flag) { 45 | this.flag = flag; 46 | } 47 | 48 | /** 49 | * @return the phoneNumber 50 | */ 51 | public String getPhoneNumber() { 52 | return phoneNumber; 53 | } 54 | 55 | /** 56 | * @param phoneNumber the phoneNumber to set 57 | */ 58 | public void setPhoneNumber(String phoneNumber) { 59 | this.phoneNumber = phoneNumber; 60 | } 61 | 62 | /** 63 | * @return the linkName 64 | */ 65 | public String getLinkName() { 66 | return linkName; 67 | } 68 | 69 | /** 70 | * @param linkName the linkName to set 71 | */ 72 | public void setLinkName(String linkName) { 73 | this.linkName = linkName; 74 | } 75 | 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/commons/MyTest.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.commons; 2 | 3 | public class MyTest { 4 | 5 | public static String bytesToHexString(byte[] src){ 6 | StringBuilder stringBuilder = new StringBuilder(""); 7 | if (src == null || src.length <= 0) { 8 | return null; 9 | } 10 | for (int i = 0; i < src.length; i++) { 11 | int v = src[i] & 0xFF; 12 | String hv = Integer.toHexString(v); 13 | if (hv.length() < 2) { 14 | stringBuilder.append(0); 15 | } 16 | stringBuilder.append(hv); 17 | } 18 | return stringBuilder.toString(); 19 | } 20 | 21 | 22 | public static byte[] hexStringToBytes(String hexString) { 23 | if (hexString == null || hexString.equals("")) { 24 | return null; 25 | } 26 | hexString = hexString.toUpperCase(); 27 | int length = hexString.length() / 2; 28 | char[] hexChars = hexString.toCharArray(); 29 | byte[] d = new byte[length]; 30 | for (int i = 0; i < length; i++) { 31 | int pos = i * 2; 32 | d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); 33 | } 34 | return d; 35 | } 36 | 37 | public static byte charToByte(char c) { 38 | return (byte) "0123456789ABCDEF".indexOf(c); 39 | } 40 | 41 | 42 | /** 43 | * @param args 44 | */ 45 | public static void main(String[] args) { 46 | // TODO Auto-generated method stub 47 | byte b[]={0x7E, 00 ,02 }; 48 | System.out.println(bytesToHexString(b)); 49 | 50 | System.out.println(hexStringToBytes("126")); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/server/TCPServer.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.server; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import javax.annotation.PostConstruct; 6 | import javax.annotation.PreDestroy; 7 | 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.beans.factory.annotation.Qualifier; 12 | import org.springframework.stereotype.Component; 13 | 14 | import io.netty.bootstrap.ServerBootstrap; 15 | import io.netty.channel.ChannelFuture; 16 | 17 | @Component 18 | public class TCPServer { 19 | private Logger log = LoggerFactory.getLogger(TCPServer.class); 20 | 21 | @Autowired 22 | @Qualifier("serverBootstrap") 23 | private ServerBootstrap b; 24 | 25 | @Autowired 26 | @Qualifier("tcpSocketAddress") 27 | private InetSocketAddress tcpPort; 28 | 29 | private ChannelFuture serverChannelFuture; 30 | 31 | @PostConstruct 32 | public void start() throws Exception { 33 | try { 34 | serverChannelFuture = b.bind(tcpPort).sync(); 35 | log.info("protocol server is listing on:= {}",tcpPort.getPort()); 36 | } catch (Exception e) { 37 | log.error("protocol server start failed.>>{} {}",e.getMessage(),tcpPort); 38 | System.exit(-1); 39 | } 40 | } 41 | 42 | @PreDestroy 43 | public void stop() throws Exception { 44 | log.info("stop server at " + tcpPort); 45 | serverChannelFuture.channel().closeFuture().sync(); 46 | } 47 | 48 | public ServerBootstrap getB() { 49 | return b; 50 | } 51 | 52 | public void setB(ServerBootstrap b) { 53 | this.b = b; 54 | } 55 | 56 | public InetSocketAddress getTcpPort() { 57 | return tcpPort; 58 | } 59 | 60 | public void setTcpPort(InetSocketAddress tcpPort) { 61 | this.tcpPort = tcpPort; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/server/initializer/NettyServerInitializer.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.server.initializer; 2 | 3 | import java.util.concurrent.TimeUnit; 4 | 5 | import org.springframework.beans.factory.annotation.Qualifier; 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.mortals.iot.handler.protocol808.collect.protocol.codec.MessageDecoder; 9 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.DeviceMessageHandler; 10 | import com.mortals.iot.protocol.jt808.constant.SystemConstants; 11 | 12 | import io.netty.channel.ChannelInitializer; 13 | import io.netty.channel.ChannelPipeline; 14 | import io.netty.channel.socket.SocketChannel; 15 | import io.netty.handler.timeout.IdleStateHandler; 16 | 17 | /** 18 | * Just a dummy protocol mainly to show the ServerBootstrap being initialized. 19 | * 20 | * @author cjun 21 | * 22 | */ 23 | @Component 24 | @Qualifier("nettyServerInitializer") 25 | public class NettyServerInitializer extends ChannelInitializer { 26 | 27 | @Override 28 | protected void initChannel(SocketChannel ch) throws Exception { 29 | ChannelPipeline pipeline = ch.pipeline(); 30 | // 心跳检测 31 | pipeline.addLast("idleStateHandler", new IdleStateHandler(SystemConstants.TCP_CLIENT_IDLE_MINUTES, 0, 0, TimeUnit.MINUTES)); 32 | // 设置decoder用于记录日志 33 | // pipeline.addLast(new Decoder4LoggingOnly()); 34 | // 1024表示单条消息的最大长度,解码器在查找分隔符的时候,达到该长度还没找到的话会抛异常 35 | // pipeline.addLast( 36 | // new DelimiterBasedFrameDecoder(1024, Unpooled.copiedBuffer(new byte[] { 0x7e 37 | // }), 38 | // Unpooled.copiedBuffer(new byte[] { 0x7e, 0x7e }))); 39 | pipeline.addLast(new MessageDecoder()); 40 | pipeline.addLast(new DeviceMessageHandler()); 41 | // pipeline.addLast(new MessageEncoder()); 42 | // pipeline.addLast(tcpServerHandler); 43 | 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/resources/config/spring-config-druid.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | com.mortals.*.service.* 34 | com.mortals.*.dao.* 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/service/AbstractDeviceCommandHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.service; 2 | 3 | import java.util.Map; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 9 | import com.mortals.iot.protocol.jt808.util.HexUtils; 10 | 11 | import io.netty.buffer.Unpooled; 12 | import io.netty.channel.Channel; 13 | import io.netty.channel.ChannelFuture; 14 | 15 | /** 16 | * @ClassName: AbstractDeviceCommandHandler 17 | * @Description: 指令处理抽象类 18 | * @Company iot 19 | * @author 20 | * @date 2017-1 下午3:37:41 21 | * 22 | */ 23 | public abstract class AbstractDeviceCommandHandler { 24 | protected Logger logger = LoggerFactory.getLogger(this.getClass()); 25 | 26 | /** 27 | * 接受设备消息 28 | * 29 | * @param message 30 | * @param session 31 | * @return Map 32 | * @throws Exception 33 | */ 34 | public abstract Map receive(JT808ProtocalPack message, Channel channel) throws Exception; 35 | 36 | /** 37 | * 发送响应消息到设备 38 | * 39 | * @param message 40 | * @param modelMap 41 | * @param session 42 | * @throws Exception 43 | */ 44 | public abstract void send(JT808ProtocalPack message, Channel channel, Map reslutMap) throws Exception; 45 | 46 | /** 47 | * 发送数据到netty通道 48 | * 49 | * @param channel 50 | * @param message 51 | * @throws Exception 52 | */ 53 | public void sendMessage(Channel channel, JT808ProtocalPack message) { 54 | try { 55 | byte[] resultData = message.pack(); 56 | 57 | if (resultData != null && resultData.length > 0) { 58 | ChannelFuture channelFuture = channel.writeAndFlush(Unpooled.copiedBuffer(resultData)); 59 | if (!channelFuture.isSuccess()) { 60 | logger.error("发送jt808消息到设备出错:", channelFuture.cause()); 61 | } else { 62 | logger.info("发送jt808消息:" + HexUtils.bytesToHexString(resultData)); 63 | } 64 | } else { 65 | logger.info("jt808消息为空"); 66 | } 67 | } catch (Exception e) { 68 | logger.info("消息发送出错", e); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/AlarmMessage.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | 6 | import com.mortals.iot.protocol.jt808.util.DataHelper; 7 | 8 | /** 9 | * 人工确认报警消息 消息ID:0x8203 10 | * 11 | * @author 12 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.message.client 13 | * @copyright iot 14 | * @date:2017-4-18 上午9:08:14 15 | */ 16 | public class AlarmMessage { 17 | // 报警消息流水号 18 | private short alarmID; 19 | // 人工确认报警类型 20 | // 32位各代表各意思 21 | private int alarmType; 22 | 23 | /** 24 | * 编码方法 25 | * 26 | * @param out 27 | * @return 28 | * @throws IOException 29 | */ 30 | public OutputStream encoder(OutputStream out) throws IOException { 31 | int size = 0; 32 | size += DataHelper.getShort(out, alarmID); 33 | size += DataHelper.getInt(out, alarmType); 34 | if (size != 6) { 35 | return null; 36 | } 37 | 38 | return out; 39 | } 40 | 41 | public short getAlarmID() { 42 | return alarmID; 43 | } 44 | 45 | public void setAlarmID(short alarmID) { 46 | this.alarmID = alarmID; 47 | } 48 | 49 | public int getAlarmType() { 50 | return alarmType; 51 | } 52 | 53 | public void setAlarmType(int alarmType) { 54 | this.alarmType = alarmType; 55 | } 56 | 57 | @Override 58 | public int hashCode() { 59 | final int prime = 31; 60 | int result = 1; 61 | result = prime * result + alarmID; 62 | result = prime * result + alarmType; 63 | return result; 64 | } 65 | 66 | @Override 67 | public boolean equals(Object obj) { 68 | if (this == obj) 69 | return true; 70 | if (obj == null) 71 | return false; 72 | if (getClass() != obj.getClass()) 73 | return false; 74 | AlarmMessage other = (AlarmMessage) obj; 75 | if (alarmID != other.alarmID) 76 | return false; 77 | if (alarmType != other.alarmType) 78 | return false; 79 | return true; 80 | } 81 | 82 | @Override 83 | public String toString() { 84 | return "AlarmMessage [alarmID=" + alarmID + ", alarmType=" + alarmType 85 | + "]"; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/SetPolygonArea_T.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | 6 | import com.mortals.iot.protocol.jt808.util.DataHelper; 7 | 8 | /** 9 | * 设置多边形区域 10 | * 11 | * @author 12 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.message.client 13 | * @copyright iot 14 | * @date:2017-4-17 上午9:34:45 15 | */ 16 | public class SetPolygonArea_T { 17 | // 顶点纬度 18 | private int VertexLatitude; 19 | // 顶点经度 20 | private int VertexLongitude; 21 | 22 | /** 23 | * 编码方法 24 | * 25 | * @param out 26 | * @param size 27 | * @return 28 | * @throws IOException 29 | */ 30 | public int encoder(OutputStream out, int size) throws IOException { 31 | size += DataHelper.getInt(out, VertexLatitude); 32 | size += DataHelper.getInt(out, VertexLongitude); 33 | 34 | return size; 35 | } 36 | 37 | public int getVertexLatitude() { 38 | return VertexLatitude; 39 | } 40 | 41 | public void setVertexLatitude(int vertexLatitude) { 42 | VertexLatitude = vertexLatitude; 43 | } 44 | 45 | public int getVertexLongitude() { 46 | return VertexLongitude; 47 | } 48 | 49 | public void setVertexLongitude(int vertexLongitude) { 50 | VertexLongitude = vertexLongitude; 51 | } 52 | 53 | @Override 54 | public int hashCode() { 55 | final int prime = 31; 56 | int result = 1; 57 | result = prime * result + VertexLatitude; 58 | result = prime * result + VertexLongitude; 59 | return result; 60 | } 61 | 62 | @Override 63 | public boolean equals(Object obj) { 64 | if (this == obj) 65 | return true; 66 | if (obj == null) 67 | return false; 68 | if (getClass() != obj.getClass()) 69 | return false; 70 | SetPolygonArea_T other = (SetPolygonArea_T) obj; 71 | if (VertexLatitude != other.VertexLatitude) 72 | return false; 73 | if (VertexLongitude != other.VertexLongitude) 74 | return false; 75 | return true; 76 | } 77 | 78 | @Override 79 | public String toString() { 80 | return "SetPolygonArea_T [VertexLatitude=" + VertexLatitude 81 | + ", VertexLongitude=" + VertexLongitude + "]"; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/main/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/DrivingRecordReqHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import javax.annotation.Resource; 4 | 5 | import org.springframework.kafka.core.KafkaTemplate; 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.alibaba.fastjson.JSON; 9 | import com.alibaba.fastjson.JSONObject; 10 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 11 | import com.mortals.iot.protocol.jt808.constant.SystemConstants; 12 | import com.mortals.iot.protocol.jt808.entity.DrivingRecordEntity; 13 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 14 | import com.mortals.iot.protocol.jt808.entity.SessionManager; 15 | 16 | /** 17 | *
  • 文件名称: DrivingRecordReqHandler
  • 18 | *
  • 文件描述: 行驶记录参数下发处理类$
  • 19 | *
  • 内容摘要: 包括模块、函数及其功能的说明
  • 20 | *
  • 完成日期:2017-4-24
  • 21 | *
  • 修改记录1:iot
  • 22 | * 23 | */ 24 | @Component(value = "p_driving_record_req_client") 25 | public class DrivingRecordReqHandler extends AbstractMallCommandHandler { 26 | private SessionManager sessionManager = SessionManager.getInstance(); 27 | @Resource 28 | private KafkaTemplate kafkaTemplate; 29 | 30 | @Override 31 | public JT808ProtocalPack receive(String message) throws Exception { 32 | DrivingRecordEntity drivingRecordEntity = new DrivingRecordEntity(); 33 | JT808ProtocalPack jt808ProtocalPack = drivingRecordEntity.toJT808ProtocalPack(message); 34 | return jt808ProtocalPack; 35 | } 36 | 37 | @Override 38 | public void send(JT808ProtocalPack message) throws Exception { 39 | DrivingRecordEntity drivingRecordEntity = new DrivingRecordEntity(); 40 | drivingRecordEntity.setValues(message.getBody()); 41 | 42 | JSONObject resultData = new JSONObject(); 43 | resultData.put(SystemConstants.CODE_KEY, 0); 44 | String serialNumber = sessionManager.removeFlowIdSerialNumber(message.getChannelId() + "-" + drivingRecordEntity.getReplyFlowId()); 45 | resultData.put(SystemConstants.SERIAL_NUMBER_KEY, serialNumber == null ? "" : serialNumber); 46 | 47 | resultData.put(SystemConstants.DATA_KEY, JSON.toJSONString(drivingRecordEntity)); 48 | kafkaTemplate.send(kafakaTopicName, resultData.toJSONString()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/commons/SpringContextUtils.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.commons; 2 | 3 | 4 | 5 | 6 | import org.springframework.context.ApplicationContext; 7 | import org.springframework.context.ApplicationContextAware; 8 | import org.springframework.context.support.ClassPathXmlApplicationContext; 9 | import org.springframework.stereotype.Component; 10 | 11 | 12 | 13 | @Component 14 | public class SpringContextUtils implements ApplicationContextAware{ 15 | 16 | private static ApplicationContext applicationContext = null; 17 | 18 | /** 19 | * 实现ApplicationContextAware接口, 注入Context到静态变量中. 20 | */ 21 | @Override 22 | public void setApplicationContext(ApplicationContext applicationContext) { 23 | 24 | if (SpringContextUtils.applicationContext == null) { 25 | SpringContextUtils.applicationContext = applicationContext; //NOSONAR 26 | } 27 | 28 | } 29 | 30 | /** 31 | * 实现DisposableBean接口,在Context关闭时清理静态变量. 32 | */ 33 | public void destroy() { 34 | SpringContextUtils.clear(); 35 | } 36 | 37 | /** 38 | * 取得存储在静态变量中的ApplicationContext. 39 | */ 40 | public static ApplicationContext getApplicationContext() { 41 | assertContextInjected(); 42 | return applicationContext; 43 | } 44 | 45 | /** 46 | * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. 47 | */ 48 | @SuppressWarnings("unchecked") 49 | public static T getBean(String name) { 50 | assertContextInjected(); 51 | return (T) applicationContext.getBean(name); 52 | } 53 | 54 | /** 55 | * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. 56 | */ 57 | public static T getBean(Class requiredType) { 58 | assertContextInjected(); 59 | return applicationContext.getBean(requiredType); 60 | } 61 | 62 | /** 63 | * 清除SpringContextUtils中的ApplicationContext为Null. 64 | */ 65 | public static void clear() { 66 | applicationContext = null; 67 | } 68 | 69 | /** 70 | * 检查ApplicationContext不为空. 71 | */ 72 | private static void assertContextInjected() { 73 | if (applicationContext == null) { 74 | applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); 75 | //throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextUtils"); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/DeivceParamReqHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import javax.annotation.Resource; 4 | 5 | import org.springframework.kafka.core.KafkaTemplate; 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.alibaba.fastjson.JSON; 9 | import com.alibaba.fastjson.JSONObject; 10 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 11 | import com.mortals.iot.protocol.jt808.constant.SystemConstants; 12 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 13 | import com.mortals.iot.protocol.jt808.entity.MessageID; 14 | import com.mortals.iot.protocol.jt808.entity.SessionManager; 15 | import com.mortals.iot.protocol.jt808.entity.TerminalParameterQueryResponseEntity; 16 | 17 | /** 18 | * @ClassName: DeivceParamReqHandler 19 | * @Description: 查询终端参数0x8104:服务端处理来自客户端发送的请求 20 | * @Company iot 21 | * @author 22 | * @date 2017-9-28 下午3:55:57 23 | * 24 | */ 25 | @Component(value = "p_device_param_req_client") 26 | public class DeivceParamReqHandler extends AbstractMallCommandHandler { 27 | private SessionManager sessionManager = SessionManager.getInstance(); 28 | @Resource 29 | private KafkaTemplate kafkaTemplate; 30 | 31 | @Override 32 | public JT808ProtocalPack receive(String message) throws Exception { 33 | JT808ProtocalPack jt808ProtocalPack = new JT808ProtocalPack(); 34 | // 设置消息id 35 | jt808ProtocalPack.setId(MessageID.INQUIRY_DEVICE_PARAMETER); 36 | return jt808ProtocalPack; 37 | } 38 | 39 | @Override 40 | public void send(JT808ProtocalPack message) throws Exception { 41 | TerminalParameterQueryResponseEntity paramQueryResp = new TerminalParameterQueryResponseEntity(); 42 | paramQueryResp.setValues(message.getBody()); 43 | 44 | JSONObject resultData = new JSONObject(); 45 | resultData.put(SystemConstants.CODE_KEY, 0); 46 | String serialNumber = sessionManager.removeFlowIdSerialNumber(message.getChannelId() + "-" + paramQueryResp.getReplyFlowId()); 47 | resultData.put(SystemConstants.SERIAL_NUMBER_KEY, serialNumber == null ? "" : serialNumber); 48 | 49 | resultData.put(SystemConstants.DATA_KEY, JSON.toJSONString(paramQueryResp)); 50 | kafkaTemplate.send(kafakaTopicName, resultData.toJSONString()); 51 | } 52 | } -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/framework/cfg/KafkaProducerConfig.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.framework.cfg; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.apache.kafka.clients.producer.ProducerConfig; 7 | import org.apache.kafka.common.serialization.StringSerializer; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.springframework.beans.factory.annotation.Value; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.context.annotation.PropertySource; 14 | import org.springframework.kafka.annotation.EnableKafka; 15 | import org.springframework.kafka.core.DefaultKafkaProducerFactory; 16 | import org.springframework.kafka.core.KafkaTemplate; 17 | import org.springframework.kafka.core.ProducerFactory; 18 | 19 | /** 20 | * 21 | * Description:Kafka生产者 22 | * 23 | * 依赖: org.springframework.kafka 24 | * spring-kafka 25 | * 1.0.5.RELEASE 26 | * 27 | * 使用案例: 28 | * 29 | * @Resource 30 | * private KafkaTemplate kafkaTemplate; 31 | * 调用方法发送数据: kafkaTemplate.send(topic, msg); 32 | * 33 | */ 34 | @Configuration 35 | @EnableKafka 36 | @PropertySource("classpath:kafka.properties") 37 | public class KafkaProducerConfig { 38 | 39 | @Value("${kafka.broker.address}") 40 | private String brokerAddress; 41 | private Logger log = LoggerFactory.getLogger(KafkaProducerConfig.class); 42 | @Bean 43 | public Map producerConfigs() { 44 | Map props = new HashMap<>(); 45 | props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, this.brokerAddress); 46 | props.put(ProducerConfig.RETRIES_CONFIG, 0); 47 | props.put(ProducerConfig.BATCH_SIZE_CONFIG, 4096); 48 | props.put(ProducerConfig.LINGER_MS_CONFIG, 1); 49 | props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, 40960); 50 | props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); 51 | props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); 52 | return props; 53 | } 54 | 55 | /** 获取工厂 */ 56 | @Bean 57 | public ProducerFactory producerFactory() { 58 | return new DefaultKafkaProducerFactory<>(producerConfigs()); 59 | } 60 | 61 | /** 注册实例 */ 62 | @Bean(name = "kafkaTemplate") 63 | public KafkaTemplate kafkaTemplate() { 64 | log.info("加载kafka生产者配置"); 65 | return new KafkaTemplate<>(producerFactory()); 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/up/EventReport.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.up; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.mortals.framework.exception.AppException; 9 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 10 | import com.mortals.iot.protocol.jt808.constant.NumberConstants; 11 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 12 | import com.mortals.iot.protocol.jt808.entity.MessageID; 13 | 14 | import io.netty.buffer.ByteBuf; 15 | import io.netty.buffer.Unpooled; 16 | import io.netty.channel.Channel; 17 | 18 | /** 19 | * @ClassName: EventReport 20 | * @Description: 事件上报 21 | * @Company iot 22 | * @author 23 | * @date 2017-12-15 下午2:30:03 24 | * 25 | */ 26 | //@Component(value = "p_event_report") 27 | public class EventReport extends AbstractDeviceCommandHandler implements MessageID { 28 | 29 | public Map receive(JT808ProtocalPack message, Channel tsession) throws Exception { 30 | Map resultMap = new HashMap(); 31 | Integer result = NumberConstants._0; 32 | 33 | try { 34 | int eventId = message.getBody()[0]; 35 | logger.info("收到时间报告消息,事件id:" + eventId); 36 | } catch (AppException e) { 37 | logger.error(e.getMessage()); 38 | result = NumberConstants._1; 39 | } catch (Exception e) { 40 | logger.error(e.getMessage(), e); 41 | result = NumberConstants._1; 42 | } 43 | 44 | resultMap.put("result", result); 45 | return resultMap; 46 | } 47 | 48 | // 49 | public void send(JT808ProtocalPack message, Channel tsession, Map reslutMap) throws Exception { 50 | Integer result = (Integer) reslutMap.get("result"); 51 | // 响应的流水号 52 | byte[] serialnumber = JT808ProtocalPack.generateSerialNumber(tsession); 53 | 54 | JT808ProtocalPack fpp = new JT808ProtocalPack(); 55 | fpp.setId(P_PLATFORM_COMMON_REPLAY); 56 | fpp.setDeviceMobile(message.getDeviceMobile()); 57 | fpp.setSerialNumber(serialnumber); 58 | 59 | ByteBuf buf = Unpooled.buffer(5); 60 | buf.writeBytes(message.getSerialNumber()); 61 | buf.writeBytes(message.getId()); 62 | buf.writeByte(result == null ? NumberConstants._1 : result); 63 | fpp.setBody(buf.array()); 64 | 65 | sendMessage(tsession, fpp); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/commons/SpringContext.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.commons; 2 | 3 | 4 | 5 | import org.springframework.beans.BeansException; 6 | import org.springframework.beans.factory.DisposableBean; 7 | import org.springframework.context.ApplicationContext; 8 | import org.springframework.context.ApplicationContextAware; 9 | import org.springframework.context.support.ClassPathXmlApplicationContext; 10 | 11 | /** 12 | *
  • 文件名称: SpringContext
  • 文件描述: $
  • 内容摘要: 包括模块、函数及其功能的说明
  • 13 | *
  • 完成日期:2017-12-31
  • 修改记录1:user
  • 14 | * 15 | */ 16 | public class SpringContext implements ApplicationContextAware, DisposableBean 17 | { 18 | 19 | private static ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); //NOSONAR 20 | 21 | 22 | /** 23 | * 实现DisposableBean接口,在Context关闭时清理静态变量. 24 | */ 25 | public void destroy() throws Exception 26 | { 27 | SpringContext.clear(); 28 | } 29 | 30 | /** 31 | * 取得存储在静态变量中的ApplicationContext. 32 | */ 33 | public static ApplicationContext getApplicationContext() 34 | { 35 | return applicationContext; 36 | } 37 | 38 | /** 39 | * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. 40 | */ 41 | @SuppressWarnings("unchecked") 42 | public static T getBean(String name) 43 | { 44 | assertContextInjected(); 45 | return (T) applicationContext.getBean(name); 46 | } 47 | 48 | /** 49 | * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. 50 | */ 51 | public static T getBean(Class requiredType) 52 | { 53 | assertContextInjected(); 54 | return applicationContext.getBean(requiredType); 55 | } 56 | 57 | /** 58 | * 清除SpringContextUtils中的ApplicationContext为Null. 59 | */ 60 | public static void clear() 61 | { 62 | applicationContext = null; 63 | } 64 | 65 | /** 66 | * 检查ApplicationContext不为空. 67 | */ 68 | private static void assertContextInjected() 69 | { 70 | if (applicationContext == null) 71 | { 72 | throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextUtils"); 73 | } 74 | } 75 | 76 | /* (non-Javadoc) 77 | * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext) 78 | */ 79 | @Override 80 | public void setApplicationContext(ApplicationContext arg0) throws BeansException 81 | { 82 | // TODO Auto-generated method stub 83 | 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/LongPack.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity; 2 | 3 | import java.util.Arrays; 4 | 5 | import com.mortals.iot.protocol.jt808.util.DataHelper; 6 | 7 | /** 8 | * 长报文 9 | * @author 10 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.message 11 | * @copyright iot 12 | * @date:2017-5-4 上午11:18:54 13 | */ 14 | public class LongPack { 15 | /** 16 | * 消息总包数 17 | */ 18 | private int sun; 19 | /** 20 | * 包序号 21 | */ 22 | private int seqNumber; 23 | /** 24 | * 数据 25 | */ 26 | private byte[] body; 27 | /** 28 | * 29 | * @param data 30 | */ 31 | public void decoder(byte[] data){ 32 | this.sun=DataHelper.parseUint16(data, 0); 33 | this.seqNumber=DataHelper.parseUint16(data, 2); 34 | body=new byte[data.length-4]; 35 | System.arraycopy(data, 4, body, 0, data.length-4); 36 | } 37 | public int getSun() { 38 | return sun; 39 | } 40 | public void setSun(int sun) { 41 | this.sun = sun; 42 | } 43 | public int getSeqNumber() { 44 | return seqNumber; 45 | } 46 | public void setSeqNumber(int seqNumber) { 47 | this.seqNumber = seqNumber; 48 | } 49 | public byte[] getBody() { 50 | return body; 51 | } 52 | public void setBody(byte[] body) { 53 | this.body = body; 54 | } 55 | @Override 56 | public int hashCode() { 57 | final int prime = 31; 58 | int result = 1; 59 | result = prime * result + Arrays.hashCode(body); 60 | result = prime * result + seqNumber; 61 | result = prime * result + sun; 62 | return result; 63 | } 64 | @Override 65 | public boolean equals(Object obj) { 66 | if (this == obj) 67 | return true; 68 | if (obj == null) 69 | return false; 70 | if (getClass() != obj.getClass()) 71 | return false; 72 | LongPack other = (LongPack) obj; 73 | if (!Arrays.equals(body, other.body)) 74 | return false; 75 | if (seqNumber != other.seqNumber) 76 | return false; 77 | if (sun != other.sun) 78 | return false; 79 | return true; 80 | } 81 | @Override 82 | public String toString() { 83 | return "LongPack [sun=" + sun + ", seqNumber=" + seqNumber + ", body=" 84 | + Arrays.toString(body) + "]"; 85 | } 86 | public static void main(String[] args) { 87 | byte[] cc=new byte[]{(byte)0x00,(byte)0x05,(byte)0x00,(byte)0x01,(byte)0x01,(byte)0x02,(byte)0x03,(byte)0x04,(byte)0x05,(byte)0x06}; 88 | LongPack aa=new LongPack(); 89 | aa.decoder(cc); 90 | System.err.println(aa.toString()); 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/up/LocationHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.up; 2 | 3 | import java.util.Map; 4 | 5 | import org.springframework.stereotype.Component; 6 | 7 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 8 | import com.mortals.iot.protocol.jt808.constant.NumberConstants; 9 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 10 | import com.mortals.iot.protocol.jt808.entity.MessageID; 11 | import com.mortals.iot.protocol.jt808.entity.PositionEntity; 12 | 13 | import io.netty.buffer.ByteBuf; 14 | import io.netty.buffer.Unpooled; 15 | import io.netty.channel.Channel; 16 | 17 | /** 18 | * @ClassName: LocationHandler 19 | * @Description: 位置信息汇报0x0200:终端发给服务端的消息 20 | * @Company iot 21 | * @author 22 | * @version 1.0, 2017-4-6 下午2:40:52 23 | */ 24 | @Component(value = "p_location") 25 | public class LocationHandler extends AbstractDeviceCommandHandler implements MessageID { 26 | 27 | public Map receive(JT808ProtocalPack message, Channel tsession) throws Exception { 28 | // Map resultMap = new HashMap(); 29 | // Integer result = NumberConstants._0; 30 | // 31 | // try { 32 | PositionEntity position = new PositionEntity(message.getDeviceMobile(), message.getBody()); 33 | logger.info("收到位置上报消息," + position.toString()); 34 | // } catch (AppException e) { 35 | // logger.error(e.getMessage()); 36 | // result = NumberConstants._1; 37 | // } catch (Exception e) { 38 | // logger.error(e.getMessage(), e); 39 | // result = NumberConstants._1; 40 | // } 41 | // 42 | // resultMap.put("result", result); 43 | // return resultMap; 44 | return null; 45 | } 46 | 47 | public void send(JT808ProtocalPack message, Channel tsession, Map reslutMap) throws Exception { 48 | Integer result = 0; 49 | // 响应的流水号 50 | byte[] serialnumber = JT808ProtocalPack.generateSerialNumber(tsession); 51 | JT808ProtocalPack fpp = new JT808ProtocalPack(); 52 | fpp.setId(P_PLATFORM_COMMON_REPLAY); 53 | fpp.setDeviceMobile(message.getDeviceMobile()); 54 | fpp.setSerialNumber(serialnumber); 55 | 56 | ByteBuf buf = Unpooled.buffer(5); 57 | buf.writeBytes(message.getSerialNumber()); 58 | buf.writeBytes(message.getId()); 59 | buf.writeByte(result == null ? NumberConstants._1 : result); 60 | 61 | fpp.setBody(buf.array()); 62 | 63 | sendMessage(tsession, fpp); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/mall/PositionReqHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.mall; 2 | 3 | import javax.annotation.Resource; 4 | 5 | import org.springframework.kafka.core.KafkaTemplate; 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.alibaba.fastjson.JSON; 9 | import com.alibaba.fastjson.JSONObject; 10 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 11 | import com.mortals.iot.protocol.jt808.constant.SystemConstants; 12 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 13 | import com.mortals.iot.protocol.jt808.entity.MessageID; 14 | import com.mortals.iot.protocol.jt808.entity.PositionEntity; 15 | import com.mortals.iot.protocol.jt808.entity.SessionManager; 16 | import com.mortals.iot.protocol.jt808.util.HexUtils; 17 | 18 | /** 19 | * @ClassName: PositionReqHandler 20 | * @Description: 位置信息查询(点名定位)0x8201:服务端处理来自客户端发送的请求 21 | * @Company iot 22 | * @author 23 | * @version 1.0, 2017-3-26 下午4:18:30 24 | */ 25 | @Component(value = "p_position_req_client") 26 | public class PositionReqHandler extends AbstractMallCommandHandler { 27 | private SessionManager sessionManager = SessionManager.getInstance(); 28 | @Resource 29 | private KafkaTemplate kafkaTemplate; 30 | protected String kafakaTopicName = SystemConstants.KAFAKA_DEFAULT_TOPIC_NAME; 31 | 32 | @Override 33 | public JT808ProtocalPack receive(String message) throws Exception { 34 | JT808ProtocalPack jt808ProtocalPack = new JT808ProtocalPack(); 35 | // 设置消息id 36 | jt808ProtocalPack.setId(MessageID.INQUIRY_LOCATION_INFORMATION); 37 | return jt808ProtocalPack; 38 | } 39 | 40 | @Override 41 | public void send(JT808ProtocalPack message) throws Exception { 42 | byte[] messageBody = message.getBody(); 43 | int replyFlowId = HexUtils.bytesToInt2(HexUtils.copyOfRange(messageBody, 0, 2)); 44 | byte[] positionInfo = HexUtils.copyOfRange(messageBody, 2, messageBody.length); 45 | PositionEntity position = new PositionEntity(); 46 | position.setValues(positionInfo); 47 | 48 | JSONObject resultData = new JSONObject(); 49 | resultData.put(SystemConstants.CODE_KEY, 0); 50 | String serialNumber = sessionManager.removeFlowIdSerialNumber(message.getChannelId() + "-" + replyFlowId); 51 | resultData.put(SystemConstants.SERIAL_NUMBER_KEY, serialNumber == null ? "" : serialNumber); 52 | 53 | resultData.put(SystemConstants.DATA_KEY, JSON.toJSONString(position)); 54 | kafkaTemplate.send(kafakaTopicName, resultData.toJSONString()); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/codec/MessageEncoder.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.codec; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 9 | import com.mortals.iot.protocol.jt808.util.HexUtils; 10 | 11 | import io.netty.buffer.ByteBuf; 12 | import io.netty.buffer.Unpooled; 13 | import io.netty.channel.ChannelFuture; 14 | import io.netty.channel.ChannelHandlerContext; 15 | import io.netty.handler.codec.MessageToByteEncoder; 16 | 17 | @SuppressWarnings("rawtypes") 18 | public class MessageEncoder extends MessageToByteEncoder { 19 | 20 | private final Logger logger = LoggerFactory.getLogger(getClass()); 21 | 22 | @Override 23 | protected void encode(ChannelHandlerContext contex, Object message, ByteBuf out) throws Exception { 24 | try { 25 | if (message instanceof JT808ProtocalPack) { 26 | JT808ProtocalPack jt808Data = (JT808ProtocalPack) message; 27 | byte[] resultData = jt808Data.pack(); 28 | 29 | if (resultData != null && resultData.length > 0) { 30 | byte[] transferData = transfer(resultData, 1, resultData.length - 2); 31 | ChannelFuture channelFuture = contex.writeAndFlush(Unpooled.copiedBuffer(transferData)); 32 | if (!channelFuture.isSuccess()) { 33 | logger.error("发送jt808消息到设备出错", channelFuture.cause()); 34 | } else { 35 | logger.info("发送jt808消息:" + HexUtils.bytesToHexString(transferData)); 36 | } 37 | } else { 38 | logger.info("jt808消息为空"); 39 | } 40 | } 41 | } catch (Exception e) { 42 | logger.info("消息发送出错", e); 43 | } 44 | } 45 | 46 | public byte[] transfer(byte[] data, int start, int end) throws Exception { 47 | ByteArrayOutputStream baos = null; 48 | 49 | try { 50 | if (start < 0 || end > data.length) { 51 | return data; 52 | } 53 | 54 | baos = new ByteArrayOutputStream(); 55 | for (int i = 0; i < start; i++) { 56 | baos.write(data[i]); 57 | } 58 | for (int i = start; i < end; i++) { 59 | if (data[i] == 0x7d) { 60 | baos.write(0x7d); 61 | baos.write(0x01); 62 | } else if (data[i] == 0x7e) { 63 | baos.write(0x7d); 64 | baos.write(0x02); 65 | } else { 66 | baos.write(data[i]); 67 | } 68 | } 69 | for (int i = end; i < data.length; i++) { 70 | baos.write(data[i]); 71 | } 72 | return baos.toByteArray(); 73 | } catch (Exception e) { 74 | throw e; 75 | } finally { 76 | if (baos != null) { 77 | baos.close(); 78 | } 79 | } 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/up/InfomationSubscribeCancle.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.up; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.mortals.framework.exception.AppException; 9 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 10 | import com.mortals.iot.protocol.jt808.constant.NumberConstants; 11 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 12 | import com.mortals.iot.protocol.jt808.entity.MessageID; 13 | import com.mortals.iot.protocol.jt808.util.HexUtils; 14 | 15 | import io.netty.buffer.ByteBuf; 16 | import io.netty.buffer.Unpooled; 17 | import io.netty.channel.Channel; 18 | 19 | /** 20 | * @ClassName: InfomationSubscribeCancle 21 | * @Description: 信息点播取消 22 | * @Company iot 23 | * @author 24 | * @date 2017-12-15 下午2:30:03 25 | * 26 | */ 27 | //@Component(value = "p_infomation_subscribe_cancle") 28 | public class InfomationSubscribeCancle extends AbstractDeviceCommandHandler implements MessageID { 29 | 30 | public Map receive(JT808ProtocalPack message, Channel tsession) throws Exception { 31 | Map resultMap = new HashMap(); 32 | Integer result = NumberConstants._0; 33 | 34 | try { 35 | int type = message.getBody()[0]; 36 | int subscribeCancleFlag = message.getBody()[1]; 37 | logger.info("收到信息点播取消,消息类型:" + type + ",点播/取消标志:" + subscribeCancleFlag); 38 | } catch (AppException e) { 39 | logger.error(e.getMessage()); 40 | result = NumberConstants._1; 41 | } catch (Exception e) { 42 | logger.error(e.getMessage(), e); 43 | result = NumberConstants._1; 44 | } 45 | 46 | resultMap.put("result", result); 47 | return resultMap; 48 | } 49 | 50 | // 51 | public void send(JT808ProtocalPack message, Channel tsession, Map reslutMap) throws Exception { 52 | Integer result = (Integer) reslutMap.get("result"); 53 | // 响应的流水号 54 | byte[] serialnumber = JT808ProtocalPack.generateSerialNumber(tsession); 55 | 56 | JT808ProtocalPack fpp = new JT808ProtocalPack(); 57 | fpp.setId(P_PLATFORM_COMMON_REPLAY); 58 | fpp.setDeviceMobile(message.getDeviceMobile()); 59 | fpp.setSerialNumber(serialnumber); 60 | 61 | ByteBuf buf = Unpooled.buffer(5); 62 | buf.writeBytes(message.getSerialNumber()); 63 | buf.writeBytes(message.getId()); 64 | buf.writeByte(result == null ? NumberConstants._1 : result); 65 | 66 | fpp.setBody(buf.array()); 67 | fpp.setProperty(HexUtils.intToByteArray(buf.array().length)); 68 | 69 | sendMessage(tsession, fpp); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/DeviceParamSetting.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | /** 4 | * @ClassName: DeviceParamSetting 5 | * @Description: 设置设备参数实体 6 | * @Company iot 7 | * @author 8 | * @version 1.0, 2017-3-29 上午10:03:40 9 | */ 10 | public class DeviceParamSetting { 11 | 12 | // ID: 终端心跳发送间隔 13 | public static final int ID_HEART_INTERVAL = 0x00000001; 14 | // ID: 主服务器地址,IP或域名 15 | public static final int ID_MAINSERVER_ADDR = 0x00000013; 16 | // ID:备份服务器地址,IP或域名 17 | public static final int ID_BACKSERVER_ADDR = 0x00000017; 18 | // ID: 服务器TCP端口 19 | public static final int ID_SERVER_TCP_PORT = 0x00000018; 20 | //位置汇报策略 21 | public static final int locationType = 0x00000020; 22 | // ID: 休眠时汇报时间间隔 23 | public static final int ID_SLEEP_INTERVAL = 0x00000027; 24 | // ID: 紧急报警时汇报时间间隔 25 | public static final int ID_ALARM_INTERVAL = 0x00000028; 26 | //ID: 缺省时间汇报间隔,单位为秒>0 27 | public static final int ID_DEFAULT_INTERVAL =0x00000029; 28 | // ID: 监控平台电话号码 29 | public static final int ID_PLATFORM_MOBILE_INTERVAL = 0x00000040; 30 | // ID: 复位电话号码,可采用此电话号码拨打终端电话让终端复位 31 | public static final int ID_RESET_MOBILE = 0x00000041; 32 | // ID: 恢复出厂设置电话号码,可采用此电话号码拨打终端电话让终端恢复出厂设置 33 | public static final int ID_FACTORY_SET_MOBILE = 0x00000042; 34 | // ID: 监听电话号码 35 | public static final int ID_MONITOR_MOBILE = 0x00000048; 36 | // ID: 最高速度 37 | public static final int ID_MAX_SPEED = 0x00000055; 38 | // ID: 超速持续时间 39 | public static final int ID_OVERSPEED_TIME = 0x00000056; 40 | // ID: 连续驾驶时间门限,超时时间 41 | public static final int ID_DRIVE_TIME_VAL = 0x00000057; 42 | // ID: 车辆里程表读数 43 | public static final int ID_MILEAGE_VAL = 0x00000080; 44 | // ID: 车辆所在的省域ID 45 | public static final int ID_PROVINCE = 0x00000081; 46 | // ID: 车辆所在的市域ID 47 | public static final int ID_CITY = 0x00000082; 48 | // ID: 公安交通管理部门颁发的机动车号牌 49 | public static final int ID_PLATE_NUMBER = 0x00000083; 50 | // ID: 车牌颜色 51 | public static final int ID_PLATE_COLOR = 0x00000084; 52 | 53 | public DeviceParamSetting(int id, Object value){ 54 | this.id = id; 55 | this.value = value; 56 | } 57 | 58 | private int id; 59 | 60 | private Object value; 61 | 62 | /** 63 | * @return the id 64 | */ 65 | public int getId() { 66 | return id; 67 | } 68 | 69 | /** 70 | * @param id the id to set 71 | */ 72 | public void setId(int id) { 73 | this.id = id; 74 | } 75 | 76 | /** 77 | * @return the value 78 | */ 79 | public Object getValue() { 80 | return value; 81 | } 82 | 83 | /** 84 | * @param value the value to set 85 | */ 86 | public void setValue(Object value) { 87 | this.value = value; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/up/MultimediaEventInfoHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.up; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.mortals.framework.exception.AppException; 9 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 10 | import com.mortals.iot.protocol.jt808.constant.NumberConstants; 11 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 12 | import com.mortals.iot.protocol.jt808.entity.MessageID; 13 | import com.mortals.iot.protocol.jt808.entity.MultiMediaEventEntity; 14 | import com.mortals.iot.protocol.jt808.util.HexUtils; 15 | 16 | import io.netty.buffer.ByteBuf; 17 | import io.netty.buffer.Unpooled; 18 | import io.netty.channel.Channel; 19 | 20 | /** 21 | * @ClassName: MultimediaEventInfoHandler 22 | * @Description: 多媒体事件信息上传(意义:拍照完成通知)0800:终端在拍照完成后发的信息。 23 | * @Company iot 24 | * @author 25 | * @version 1.0, 2017-3-28 上午11:23:54 26 | */ 27 | //@Component(value = "p_multimedia_event_info") 28 | public class MultimediaEventInfoHandler extends AbstractDeviceCommandHandler implements MessageID { 29 | 30 | public Map receive(JT808ProtocalPack message, Channel tsession) throws Exception { 31 | Map resultMap = new HashMap(); 32 | Integer result = NumberConstants._0; 33 | 34 | try { 35 | MultiMediaEventEntity multiMediaEventInfo = new MultiMediaEventEntity(message.getDeviceMobile(), message.getBody()); 36 | logger.info(multiMediaEventInfo.toString()); 37 | } catch (AppException e) { 38 | logger.error(e.getMessage()); 39 | result = NumberConstants._1; 40 | } catch (Exception e) { 41 | logger.error(e.getMessage(), e); 42 | result = NumberConstants._1; 43 | } 44 | 45 | resultMap.put("result", result); 46 | return resultMap; 47 | } 48 | 49 | public void send(JT808ProtocalPack message, Channel tsession, Map reslutMap) throws Exception { 50 | Integer result = (Integer) reslutMap.get("result"); 51 | // 响应的流水号 52 | byte[] serialnumber = JT808ProtocalPack.generateSerialNumber(tsession); 53 | 54 | JT808ProtocalPack fpp = new JT808ProtocalPack(); 55 | fpp.setId(P_PLATFORM_COMMON_REPLAY); 56 | fpp.setDeviceMobile(message.getDeviceMobile()); 57 | fpp.setSerialNumber(serialnumber); 58 | 59 | ByteBuf buf = Unpooled.buffer(5); 60 | buf.writeBytes(message.getSerialNumber()); 61 | buf.writeBytes(message.getId()); 62 | buf.writeByte(result == null ? NumberConstants._1 : result); 63 | 64 | fpp.setBody(buf.array()); 65 | fpp.setProperty(HexUtils.intToByteArray(buf.array().length)); 66 | 67 | sendMessage(tsession, fpp); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/service/AbstractMallCommandHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.service; 2 | 3 | import javax.annotation.Resource; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.kafka.core.KafkaTemplate; 8 | 9 | import com.alibaba.fastjson.JSONObject; 10 | import com.mortals.iot.protocol.jt808.constant.SystemConstants; 11 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 12 | import com.mortals.iot.protocol.jt808.entity.MessageID; 13 | import com.mortals.iot.protocol.jt808.entity.SessionManager; 14 | import com.mortals.iot.protocol.jt808.util.HexUtils; 15 | 16 | /** 17 | * @ClassName: AbstractMallCommandHandler 18 | * @Description: 客户端请求处理器 19 | * @Company iot 20 | * @author 21 | * @date 2018-2-1 下午4:31:03 22 | * 23 | */ 24 | public abstract class AbstractMallCommandHandler { 25 | protected Logger logger = LoggerFactory.getLogger(this.getClass()); 26 | @Resource 27 | private KafkaTemplate kafkaTemplate; 28 | protected String kafakaTopicName = SystemConstants.KAFAKA_DEFAULT_TOPIC_NAME; 29 | private SessionManager sessionManager = SessionManager.getInstance(); 30 | 31 | /** 32 | * 解析json对象为协议对象 33 | * 34 | * @param message 35 | * @throws Exception 36 | */ 37 | public abstract JT808ProtocalPack receive(String message) throws Exception; 38 | 39 | /** 40 | * 发送数据到mall 41 | * 42 | * @param message 43 | * @throws Exception 44 | */ 45 | public void send(JT808ProtocalPack message) throws Exception { 46 | int messageId = HexUtils.bytesToInt2(message.getId()); 47 | // 设备通用应答 48 | if (MessageID.P_DEVICE_COMMON_RESP_SERVER == messageId) { 49 | // 应答流水号 50 | int replyFlowId = HexUtils.bytesToInt2(HexUtils.copyOfRange(message.getBody(), 0, 2)); 51 | // 应答消息id 52 | int replyMessageId = HexUtils.bytesToInt2(HexUtils.copyOfRange(message.getBody(), 2, 4)); 53 | // 结果,0:成功/确认;1:失败;2:消息有误;3:不支持 54 | int result = HexUtils.copyOfRange(message.getBody(), 4, 5)[0]; 55 | 56 | JSONObject resultData = new JSONObject(); 57 | resultData.put(SystemConstants.CODE_KEY, 0); 58 | String serialNumber = sessionManager.removeFlowIdSerialNumber(message.getChannelId() + "-" + replyFlowId); 59 | resultData.put(SystemConstants.SERIAL_NUMBER_KEY, serialNumber == null ? "" : serialNumber); 60 | 61 | JSONObject messageBody = new JSONObject(); 62 | // 应答流水号 63 | messageBody.put("5bqU562U5rWB5rC05Y+3", replyFlowId); 64 | // 应答id 65 | messageBody.put("5bqU562USUQ=", replyMessageId); 66 | // 结果 67 | messageBody.put("57uT5p6c", result); 68 | resultData.put(SystemConstants.DATA_KEY, messageBody.toJSONString()); 69 | 70 | kafkaTemplate.send(kafakaTopicName, resultData.toJSONString()); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/up/QuizRelayHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.up; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.mortals.framework.exception.AppException; 9 | import com.mortals.iot.handler.protocol808.collect.commons.Log; 10 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 11 | import com.mortals.iot.protocol.jt808.constant.NumberConstants; 12 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 13 | import com.mortals.iot.protocol.jt808.entity.MessageID; 14 | import com.mortals.iot.protocol.jt808.util.HexUtils; 15 | 16 | import io.netty.buffer.ByteBuf; 17 | import io.netty.buffer.Unpooled; 18 | import io.netty.channel.Channel; 19 | 20 | /** 21 | * @ClassName: QuizRelayHandler 22 | * @Description: 提问应答0x0302:终端返回给服务端的信息,问答题 23 | * @Company iot 24 | * @author 25 | * @version 1.0, 2017-3-28 上午10:25:56 26 | */ 27 | //@Component(value = "p_quiz_relay") 28 | public class QuizRelayHandler extends AbstractDeviceCommandHandler implements MessageID { 29 | 30 | public Map receive(JT808ProtocalPack message, Channel tsession) throws Exception { 31 | 32 | Map resultMap = new HashMap(); 33 | Integer result = NumberConstants._0; 34 | 35 | try { 36 | // 应答流水号 37 | int replyFlowId = HexUtils.bytesToShort(HexUtils.copyOfRange(message.getBody(), 0, 2)); 38 | // 答案ID 39 | int answerId = message.getBody()[2]; 40 | logger.info("收到提问应答,应答流水号:" + replyFlowId + "; 答案id:" + answerId); 41 | } catch (AppException e) { 42 | logger.error(e.getMessage()); 43 | result = NumberConstants._1; 44 | } catch (Exception e) { 45 | logger.error(e.getMessage(), e); 46 | result = NumberConstants._1; 47 | } 48 | 49 | resultMap.put("result", result); 50 | return resultMap; 51 | } 52 | 53 | public void send(JT808ProtocalPack message, Channel tsession, Map reslutMap) throws Exception { 54 | Integer result = (Integer) reslutMap.get("result"); 55 | // 响应的流水号 56 | byte[] serialnumber = JT808ProtocalPack.generateSerialNumber(tsession); 57 | 58 | JT808ProtocalPack fpp = new JT808ProtocalPack(); 59 | fpp.setId(P_PLATFORM_COMMON_REPLAY); 60 | fpp.setDeviceMobile(message.getDeviceMobile()); 61 | fpp.setSerialNumber(serialnumber); 62 | 63 | ByteBuf buf = Unpooled.buffer(5); 64 | buf.writeBytes(message.getSerialNumber()); 65 | buf.writeBytes(message.getId()); 66 | buf.writeByte(result == null ? NumberConstants._1 : result); 67 | 68 | fpp.setBody(buf.array()); 69 | 70 | Log.getLogger(this.getClass()).info("服务端对提问应答的应答:" + fpp.toHexString()); 71 | sendMessage(tsession, fpp); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/up/UnvarnishedTransmiteHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.up; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.mortals.framework.exception.AppException; 9 | import com.mortals.iot.handler.protocol808.collect.commons.Log; 10 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 11 | import com.mortals.iot.protocol.jt808.constant.NumberConstants; 12 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 13 | import com.mortals.iot.protocol.jt808.entity.MessageID; 14 | import com.mortals.iot.protocol.jt808.util.HexUtils; 15 | 16 | import io.netty.buffer.ByteBuf; 17 | import io.netty.buffer.Unpooled; 18 | import io.netty.channel.Channel; 19 | 20 | /** 21 | * @ClassName: UnvarnishedTransmiteHandler 22 | * @Description: 数据上行透传0x0900:0x8900的应答 23 | * @Company iot 24 | * @author 25 | * @version 1.0, 2017-3-28 上午10:11:15 26 | */ 27 | //@Component(value = "p_unvarnished_transmite") 28 | public class UnvarnishedTransmiteHandler extends AbstractDeviceCommandHandler implements MessageID { 29 | 30 | public Map receive(JT808ProtocalPack message, Channel tsession) throws Exception { 31 | Map resultMap = new HashMap(); 32 | Integer result = NumberConstants._0; 33 | 34 | try { 35 | int messageType = message.getBody()[0]; 36 | byte[] messageContent = HexUtils.copyOfRange(message.getBody(), 1, message.getBody().length); 37 | Log.getLogger(this.getClass()).info("收到的透传信息,messageType:" + messageType + "messageContent:" + HexUtils.bytesToHexString(messageContent)); 38 | } catch (AppException e) { 39 | logger.error(e.getMessage()); 40 | result = NumberConstants._1; 41 | } catch (Exception e) { 42 | logger.error(e.getMessage(), e); 43 | result = NumberConstants._1; 44 | } 45 | 46 | resultMap.put("result", result); 47 | return resultMap; 48 | 49 | } 50 | 51 | public void send(JT808ProtocalPack message, Channel tsession, Map reslutMap) throws Exception { 52 | Integer result = (Integer) reslutMap.get("result"); 53 | // 响应的流水号 54 | byte[] serialnumber = JT808ProtocalPack.generateSerialNumber(tsession); 55 | 56 | JT808ProtocalPack fpp = new JT808ProtocalPack(); 57 | fpp.setId(P_PLATFORM_COMMON_REPLAY); 58 | fpp.setDeviceMobile(message.getDeviceMobile()); 59 | fpp.setSerialNumber(serialnumber); 60 | 61 | ByteBuf buf = Unpooled.buffer(5); 62 | buf.writeBytes(message.getSerialNumber()); 63 | buf.writeBytes(message.getId()); 64 | buf.writeByte(result == null ? NumberConstants._1 : result); 65 | 66 | fpp.setBody(buf.array()); 67 | 68 | Log.getLogger(this.getClass()).info("透传消息上行应答:" + fpp.toHexString()); 69 | sendMessage(tsession, fpp); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/up/CompressUploadHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.up; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.mortals.framework.exception.AppException; 9 | import com.mortals.iot.handler.protocol808.collect.commons.Log; 10 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 11 | import com.mortals.iot.protocol.jt808.constant.NumberConstants; 12 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 13 | import com.mortals.iot.protocol.jt808.entity.MessageID; 14 | import com.mortals.iot.protocol.jt808.util.HexUtils; 15 | 16 | import io.netty.buffer.ByteBuf; 17 | import io.netty.buffer.Unpooled; 18 | import io.netty.channel.Channel; 19 | 20 | /** 21 | * @ClassName: CompressUploadHandler 22 | * @Description: 数据压缩上传0x0901 23 | * @Company iot 24 | * @author 25 | * @version 1.0, 2017-3-28 上午10:11:15 26 | */ 27 | //@Component(value = "p_compress_upload") 28 | public class CompressUploadHandler extends AbstractDeviceCommandHandler implements MessageID { 29 | 30 | public Map receive(JT808ProtocalPack message, Channel tsession) throws Exception { 31 | Map resultMap = new HashMap(); 32 | Integer result = NumberConstants._0; 33 | 34 | try { 35 | int messageLength = HexUtils.parseIntFromBytes(message.getBody(), 0, 4); 36 | byte[] messageContent = HexUtils.copyOfRange(message.getBody(), 1, message.getBody().length); 37 | Log.getLogger(this.getClass()) 38 | .info("收到压缩信息,messageLength:" + messageLength + "messageContent:" + HexUtils.bytesToHexString(messageContent)); 39 | } catch (AppException e) { 40 | logger.error(e.getMessage()); 41 | result = NumberConstants._1; 42 | } catch (Exception e) { 43 | logger.error(e.getMessage(), e); 44 | result = NumberConstants._1; 45 | } 46 | 47 | resultMap.put("result", result); 48 | return resultMap; 49 | 50 | } 51 | 52 | public void send(JT808ProtocalPack message, Channel tsession, Map reslutMap) throws Exception { 53 | Integer result = (Integer) reslutMap.get("result"); 54 | // 响应的流水号 55 | byte[] serialnumber = JT808ProtocalPack.generateSerialNumber(tsession); 56 | 57 | JT808ProtocalPack fpp = new JT808ProtocalPack(); 58 | fpp.setId(P_PLATFORM_COMMON_REPLAY); 59 | fpp.setDeviceMobile(message.getDeviceMobile()); 60 | fpp.setSerialNumber(serialnumber); 61 | 62 | ByteBuf buf = Unpooled.buffer(5); 63 | buf.writeBytes(message.getSerialNumber()); 64 | buf.writeBytes(message.getId()); 65 | buf.writeByte(result == null ? NumberConstants._1 : result); 66 | 67 | fpp.setBody(buf.array()); 68 | 69 | Log.getLogger(this.getClass()).info("透传消息上行应答:" + fpp.toHexString()); 70 | sendMessage(tsession, fpp); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/device/SaveMediaRep.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.device; 2 | 3 | import java.util.ArrayList; 4 | 5 | import com.mortals.iot.protocol.jt808.util.DataHelper; 6 | 7 | /** 8 | * 存储多媒体数据检索应答 消息ID:0x0802 9 | * 10 | * @author 11 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.message.device 12 | * @copyright iot 13 | * @date:2017-4-23 下午2:59:08 14 | */ 15 | public class SaveMediaRep { 16 | /** 17 | * 应答流水号 18 | */ 19 | private short serialNumber; 20 | /** 21 | * 多媒体数据总项数 22 | */ 23 | private short num; 24 | 25 | /** 26 | * 检索项 27 | */ 28 | private ArrayList events = new ArrayList(); 29 | 30 | /** 31 | * 初始化 32 | */ 33 | public SaveMediaRep() { 34 | 35 | } 36 | 37 | /** 38 | * 解码 39 | * 40 | * @param data 41 | */ 42 | public void decode(byte[] data) { 43 | this.serialNumber = DataHelper.parseUint16(data, 0); 44 | this.num = DataHelper.parseUint16(data, 2); 45 | int size = 0; 46 | for (int i = 0; i < num; i++) { 47 | SaveMediaRepT event = new SaveMediaRepT(); 48 | size += event.decode(data, 4 + size); 49 | events.add(event); 50 | 51 | } 52 | 53 | } 54 | 55 | public short getSerialNumber() { 56 | return serialNumber; 57 | } 58 | 59 | public void setSerialNumber(short serialNumber) { 60 | this.serialNumber = serialNumber; 61 | } 62 | 63 | public short getNum() { 64 | return num; 65 | } 66 | 67 | public void setNum(short num) { 68 | this.num = num; 69 | } 70 | 71 | public ArrayList getEvents() { 72 | return events; 73 | } 74 | 75 | public void setEvents(ArrayList events) { 76 | this.events = events; 77 | } 78 | 79 | @Override 80 | public int hashCode() { 81 | final int prime = 31; 82 | int result = 1; 83 | result = prime * result + ((events == null) ? 0 : events.hashCode()); 84 | result = prime * result + num; 85 | result = prime * result + serialNumber; 86 | return result; 87 | } 88 | 89 | @Override 90 | public boolean equals(Object obj) { 91 | if (this == obj) 92 | return true; 93 | if (obj == null) 94 | return false; 95 | if (getClass() != obj.getClass()) 96 | return false; 97 | SaveMediaRep other = (SaveMediaRep) obj; 98 | if (events == null) { 99 | if (other.events != null) 100 | return false; 101 | } else if (!events.equals(other.events)) 102 | return false; 103 | if (num != other.num) 104 | return false; 105 | if (serialNumber != other.serialNumber) 106 | return false; 107 | return true; 108 | } 109 | 110 | @Override 111 | public String toString() { 112 | return "SaveMediaRep [serialNumber=" + serialNumber + ", num=" + num 113 | + ", events=" + events + "]"; 114 | } 115 | 116 | 117 | } 118 | -------------------------------------------------------------------------------- /mybatis-3-config.dtd: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 32 | 33 | 34 | 38 | 39 | 40 | 41 | 42 | 46 | 47 | 48 | 49 | 50 | 54 | 55 | 56 | 57 | 58 | 63 | 64 | 65 | 68 | 69 | 70 | 73 | 74 | 75 | 76 | 77 | 80 | 81 | 82 | 85 | 86 | 87 | 90 | 91 | 92 | 95 | 96 | 97 | 100 | 101 | 102 | 103 | 104 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/up/DriverIdentityInfoHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.up; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.mortals.framework.exception.AppException; 9 | import com.mortals.iot.handler.protocol808.collect.commons.Log; 10 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 11 | import com.mortals.iot.protocol.jt808.constant.NumberConstants; 12 | import com.mortals.iot.protocol.jt808.entity.DriverIdentityEntity; 13 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 14 | import com.mortals.iot.protocol.jt808.entity.MessageID; 15 | import com.mortals.iot.protocol.jt808.util.HexUtils; 16 | 17 | import io.netty.buffer.ByteBuf; 18 | import io.netty.buffer.Unpooled; 19 | import io.netty.channel.Channel; 20 | 21 | /** 22 | *
  • 文件名称: DriverIdentityInfoHandler
  • 23 | *
  • 文件描述: 驾驶员身份信息采集上传业务处理类$
  • 24 | *
  • 内容摘要: 包括模块、函数及其功能的说明
  • 25 | *
  • 完成日期:2017-4-24
  • 26 | *
  • 修改记录1:iot
  • 27 | */ 28 | //@Component(value = "p_driverinfo_to_server") 29 | public class DriverIdentityInfoHandler extends AbstractDeviceCommandHandler implements MessageID { 30 | 31 | @Override 32 | public Map receive(JT808ProtocalPack message, Channel channel) throws Exception { 33 | Map resultMap = new HashMap(); 34 | Integer result = NumberConstants._0; 35 | 36 | try { 37 | DriverIdentityEntity driverInfo = new DriverIdentityEntity(message.getDeviceMobile(), message.getBody()); 38 | logger.info("收到驾驶员身份信息上报消息," + driverInfo.toString()); 39 | } catch (AppException e) { 40 | logger.error(e.getMessage()); 41 | result = NumberConstants._1; 42 | } catch (Exception e) { 43 | logger.error(e.getMessage(), e); 44 | result = NumberConstants._1; 45 | } 46 | 47 | resultMap.put("result", result); 48 | return resultMap; 49 | } 50 | 51 | @Override 52 | public void send(JT808ProtocalPack message, Channel session, Map resultMap) throws Exception { 53 | Integer result = (Integer) resultMap.get("result"); 54 | // 响应的流水号 55 | byte[] serialnumber = JT808ProtocalPack.generateSerialNumber(session); 56 | 57 | JT808ProtocalPack fpp = new JT808ProtocalPack(); 58 | fpp.setId(P_PLATFORM_COMMON_REPLAY); 59 | fpp.setDeviceMobile(message.getDeviceMobile()); 60 | fpp.setSerialNumber(serialnumber); 61 | 62 | ByteBuf buf = Unpooled.buffer(5); 63 | buf.writeBytes(message.getSerialNumber()); 64 | buf.writeBytes(message.getId()); 65 | buf.writeByte(result == null ? NumberConstants._1 : result); 66 | 67 | fpp.setBody(buf.array()); 68 | fpp.setProperty(HexUtils.intToByteArray(buf.array().length)); 69 | 70 | Log.getLogger(this.getClass()).info("驾驶员身份信息回复:" + fpp.toHexString()); 71 | sendMessage(session, fpp); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/framework/cfg/KafkaConsumerConfig.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.framework.cfg; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.apache.kafka.clients.consumer.ConsumerConfig; 7 | import org.apache.kafka.clients.producer.ProducerConfig; 8 | import org.apache.kafka.common.serialization.StringDeserializer; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.beans.factory.annotation.Value; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.context.annotation.PropertySource; 15 | import org.springframework.kafka.annotation.EnableKafka; 16 | import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; 17 | import org.springframework.kafka.config.KafkaListenerContainerFactory; 18 | import org.springframework.kafka.core.ConsumerFactory; 19 | import org.springframework.kafka.core.DefaultKafkaConsumerFactory; 20 | import org.springframework.kafka.listener.ConcurrentMessageListenerContainer; 21 | 22 | /** 23 | * 24 | * Description:Kafka消费者 25 | * 26 | * 依赖: org.springframework.kafka 27 | * spring-kafka 28 | * 1.0.5.RELEASE 29 | * 30 | * 使用案例: 31 | * 32 | * @KafkaListener(topics = { "taskCmd" }) public void taskCmd(ConsumerRecord 33 | * record) { Object message = record.value(); 34 | * logger.info("收到管理平台命令:" + message); } 35 | * 36 | */ 37 | @Configuration 38 | @EnableKafka 39 | @PropertySource("classpath:kafka.properties") 40 | public class KafkaConsumerConfig { 41 | @Value("${kafka.broker.address}") 42 | private String brokerAddress; 43 | private Logger log = LoggerFactory.getLogger(KafkaConsumerConfig.class); 44 | @Bean 45 | public Map consumerConfigs() { 46 | Map props = new HashMap<>(); 47 | props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, this.brokerAddress); 48 | props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false); 49 | props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "100"); 50 | props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, "15000"); 51 | props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); 52 | props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); 53 | props.put(ConsumerConfig.GROUP_ID_CONFIG, "Agent-Server-1.0.2"); 54 | props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); 55 | return props; 56 | } 57 | 58 | /** 获取工厂 */ 59 | @Bean 60 | public ConsumerFactory consumerFactory() { 61 | return new DefaultKafkaConsumerFactory<>(consumerConfigs()); 62 | } 63 | 64 | /** 获取实例 */ 65 | @Bean 66 | public KafkaListenerContainerFactory> kafkaListenerContainerFactory() { 67 | ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); 68 | log.info("加载kafka消费者"); 69 | factory.setConsumerFactory(consumerFactory()); 70 | factory.setConcurrency(3); 71 | factory.getContainerProperties().setPollTimeout(3000); 72 | return factory; 73 | } 74 | } -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/Recording.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | 6 | import com.mortals.iot.protocol.jt808.util.DataHelper; 7 | 8 | /** 9 | * 录音开始命令 消息ID:0x8804 10 | * 11 | * @author 12 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.message.client 13 | * @copyright iot 14 | * @date:2017-4-24 上午10:07:29 15 | */ 16 | public class Recording { 17 | /** 18 | * 录音命令 byte 19 | */ 20 | private int cmd; 21 | /** 22 | * 录音时间 short 23 | */ 24 | private short time; 25 | /** 26 | * 保存标志 byte 27 | */ 28 | private int save; 29 | /** 30 | * 音频采样率 byte 0:8K;1:11K;2:23K;3:32K;其他保留 31 | */ 32 | private int audioSamplingRate; 33 | 34 | /** 35 | * 初始化 36 | */ 37 | public Recording() { 38 | 39 | } 40 | 41 | /** 42 | * 编码 43 | * 44 | * @param out 45 | * @return 46 | * @throws IOException 47 | */ 48 | public OutputStream encoder(OutputStream out) throws IOException { 49 | int size = 0; 50 | size += DataHelper.getbyte(out, cmd); 51 | size += DataHelper.getShort(out, time); 52 | size += DataHelper.getbyte(out, save); 53 | size += DataHelper.getbyte(out, audioSamplingRate); 54 | if (size != 5) { 55 | return null; 56 | } 57 | 58 | return out; 59 | } 60 | 61 | public int getCmd() { 62 | return cmd; 63 | } 64 | 65 | public void setCmd(int cmd) { 66 | this.cmd = cmd; 67 | } 68 | 69 | public short getTime() { 70 | return time; 71 | } 72 | 73 | public void setTime(short time) { 74 | this.time = time; 75 | } 76 | 77 | public int getSave() { 78 | return save; 79 | } 80 | 81 | public void setSave(int save) { 82 | this.save = save; 83 | } 84 | 85 | public int getAudioSamplingRate() { 86 | return audioSamplingRate; 87 | } 88 | 89 | public void setAudioSamplingRate(int audioSamplingRate) { 90 | this.audioSamplingRate = audioSamplingRate; 91 | } 92 | 93 | @Override 94 | public int hashCode() { 95 | final int prime = 31; 96 | int result = 1; 97 | result = prime * result + audioSamplingRate; 98 | result = prime * result + cmd; 99 | result = prime * result + save; 100 | result = prime * result + time; 101 | return result; 102 | } 103 | 104 | @Override 105 | public boolean equals(Object obj) { 106 | if (this == obj) 107 | return true; 108 | if (obj == null) 109 | return false; 110 | if (getClass() != obj.getClass()) 111 | return false; 112 | Recording other = (Recording) obj; 113 | if (audioSamplingRate != other.audioSamplingRate) 114 | return false; 115 | if (cmd != other.cmd) 116 | return false; 117 | if (save != other.save) 118 | return false; 119 | if (time != other.time) 120 | return false; 121 | return true; 122 | } 123 | 124 | @Override 125 | public String toString() { 126 | return "Recording [cmd=" + cmd + ", time=" + time + ", save=" + save 127 | + ", audioSamplingRate=" + audioSamplingRate + "]"; 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/commons/SerialNumber.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.commons; 2 | 3 | /** 4 | * 主要用于各个发送类的SerialNumber统一管理 5 | * 6 | * @author 7 | * @package com.mortals.iot.handler.protocol808.collect.comm.commons 8 | * @copyright iot 9 | * @date:2017-4-9 上午9:18:54 10 | */ 11 | public interface SerialNumber { 12 | /** 13 | * 查询终端参数流水号0x00C3 14 | */ 15 | public static final byte[] queryPosition2SerialNumber = new byte[] { 0x00, 16 | (byte) 0xC3 }; 17 | /** 18 | * 查询终端参数流水号0x02BA 19 | */ 20 | public static final byte[] queryDeviceParamsSerialNumber = new byte[] { 21 | 0x02, (byte) 0xBA }; 22 | /** 23 | * 文本信息下发流水号 0x0000 24 | */ 25 | public static final byte[] sendTxtSerialNumber = new byte[] { 0x00, 26 | (byte) 0x00 }; 27 | /** 28 | * 位置信息查询流水号0x00C3 29 | */ 30 | public static final byte[] queryPositionSerialNumber = new byte[] { 0x00, 31 | (byte) 0xC3 }; 32 | /** 33 | * 电话回拨流水号 0x0001 34 | */ 35 | public static final byte[] callSerialNumber = new byte[] { 0x00, 36 | (byte) 0x01 }; 37 | /** 38 | * 设置电话本流水号0x0001 39 | */ 40 | public static final byte[] settingMobileListSerialNumber = new byte[] { 41 | 0x00, (byte) 0x01 }; 42 | /** 43 | * 摄像头立即拍摄命令流水号0x0001 44 | */ 45 | public static final byte[] shootImmediatelySerialNumber = new byte[] { 46 | 0x00, (byte) 0x01 }; 47 | /** 48 | * 数据下行透传流水号0x0001 49 | */ 50 | public static final byte[] unvarnishedTransmiteSerialNumber = new byte[] { 51 | 0x00, (byte) 0x01 }; 52 | /** 53 | * 录音开始命令流水号0x0001 54 | */ 55 | public static final byte[] recordSerialNumber = new byte[] { 0x00, 56 | (byte) 0x01 }; 57 | /** 58 | * 提问下发流水号0x0001 59 | */ 60 | public static final byte[] questionSerialNumber = new byte[] { 0x00, 61 | (byte) 0x01 }; 62 | /** 63 | * 设置终端参数流水号0x0001 64 | */ 65 | public static final byte[] setDeviceParamSerialNumber = new byte[] { 0x00, 66 | (byte) 0x01 }; 67 | 68 | /** 69 | * 设置圆形区域流水号0x8600 70 | */ 71 | public static final byte[] setCircularAreaSerialNumber=new byte[]{ 0x00, 72 | (byte) 0x01 }; 73 | 74 | /** 75 | * 设置矩形区域流水号0x8600 76 | */ 77 | public static final byte[] setRectangularAreaSerialNumber=new byte[]{ 0x00, 78 | (byte) 0x01 }; 79 | 80 | /** 81 | * 设置多边形区域流水号0x8600 82 | */ 83 | public static final byte[] setPolygonAreaSerialNumber=new byte[]{ 0x00, 84 | (byte) 0x01 }; 85 | 86 | /** 87 | * 人工消息确认流水号0x8203 88 | */ 89 | public static final byte[] setDisarmAlarmSerialNumber=new byte[]{ 0x00, 90 | (byte) 0x01 }; 91 | 92 | /** 93 | * 设置圆形区域流水号0x8600 94 | */ 95 | public static final byte[] delCircularAreaSerialNumber=new byte[]{ 0x00, 96 | (byte) 0x01 }; 97 | 98 | /** 99 | * 查询驾驶员身份信息请求流水号 0x8702 100 | */ 101 | public static final byte[] DriverIcSerialNumber=new byte[]{0x00,(byte)0x01}; 102 | 103 | /** 104 | * 设置流水号0x8600 105 | */ 106 | public static final byte[] setSerialNumber=new byte[]{ 0x00, 107 | (byte) 0x01 }; 108 | 109 | /** 110 | * body为空, 空包体 111 | */ 112 | 113 | 114 | public static final byte[] nullBody = new byte[] {}; 115 | 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/DeleteCircularArea.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStream; 6 | import java.io.Serializable; 7 | import java.util.ArrayList; 8 | 9 | import com.mortals.iot.protocol.jt808.util.DataHelper; 10 | 11 | /** 12 | * @MessageID 消息ID:0x8601 13 | * @author 14 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.message.client 15 | * @copyright iot 16 | * @date:2017-4-16 上午11:08:53 17 | */ 18 | public class DeleteCircularArea implements Serializable { 19 | 20 | private static final long serialVersionUID = 1L; 21 | // 删除圆形区域 22 | private int number; 23 | // 圆形区域ID 24 | private ArrayList id = new ArrayList(); 25 | 26 | /** 27 | * encoder the DeleteCircularArea 28 | * 29 | * @param out 30 | * @return 31 | * @throws IOException 32 | */ 33 | public OutputStream encoder(OutputStream out) throws IOException { 34 | int size = 0; 35 | if (this.number == 0) { 36 | return out; 37 | } 38 | size += DataHelper.getbyte(out, number); 39 | for (int i = 0; i < number; i++) { 40 | size += DataHelper.getInt(out, id.get(i)); 41 | } 42 | if (size < 4) { 43 | return null; 44 | } 45 | return out; 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return "DeleteCircularArea [number=" + number + ", id=" + id + "]"; 51 | } 52 | 53 | public int getNumber() { 54 | return number; 55 | } 56 | 57 | public void setNumber(int number) { 58 | this.number = number; 59 | } 60 | 61 | public ArrayList getId() { 62 | return id; 63 | } 64 | 65 | public void setId(ArrayList id) { 66 | this.id = id; 67 | } 68 | 69 | @Override 70 | public int hashCode() { 71 | final int prime = 31; 72 | int result = 1; 73 | result = prime * result + ((id == null) ? 0 : id.hashCode()); 74 | result = prime * result + number; 75 | return result; 76 | } 77 | 78 | @Override 79 | public boolean equals(Object obj) { 80 | if (this == obj) 81 | return true; 82 | if (obj == null) 83 | return false; 84 | if (getClass() != obj.getClass()) 85 | return false; 86 | DeleteCircularArea other = (DeleteCircularArea) obj; 87 | if (id == null) { 88 | if (other.id != null) 89 | return false; 90 | } else if (!id.equals(other.id)) 91 | return false; 92 | if (number != other.number) 93 | return false; 94 | return true; 95 | } 96 | 97 | public static void main(String[] args) throws IOException { 98 | ArrayList aa = new ArrayList<>(); 99 | 100 | aa.add(12); 101 | aa.add(333); 102 | aa.add(2564); 103 | aa.add(25462); 104 | // int[] aa=new int[]{12,33,44,22,55,66,994,1112,23412,2523}; 105 | DeleteCircularArea a = new DeleteCircularArea(); 106 | a.setNumber(aa.size()); 107 | a.setId(aa); 108 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 109 | a.encoder(out); 110 | System.err.println(a.toString()); 111 | System.err.println(DataHelper.DataToHexString(out.toByteArray())); 112 | System.err.println(out.size()); 113 | 114 | } 115 | 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/InfoMenuSettings_T.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStream; 6 | 7 | import com.mortals.iot.protocol.jt808.util.DataHelper; 8 | 9 | /** 10 | * 信息点播菜单设置 子结构 11 | 消息ID:0x8303。 12 | * @author 13 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.message.client 14 | * @copyright iot 15 | * @date:2017-4-18 上午9:19:58 16 | */ 17 | public class InfoMenuSettings_T { 18 | //信息类型 19 | private int MessageType; 20 | //信息名称长度 21 | private short MessageLength; 22 | //信息名称 23 | private String MessageName; 24 | /** 25 | * 26 | * @param out 27 | * @param size 28 | * @return 29 | * @throws IOException 30 | */ 31 | public int encoder(OutputStream out ,int size) throws IOException{ 32 | size+=DataHelper.getbyte(out, MessageType); 33 | size+=DataHelper.getShort(out, MessageLength); 34 | out.write(DataHelper.encodeGBK(MessageName)); 35 | size+=MessageLength; 36 | return size; 37 | } 38 | /** 39 | * get 结构长度 40 | * @return 41 | */ 42 | public int getLength(){ 43 | 44 | return 3+MessageLength; 45 | } 46 | 47 | 48 | public int getMessageType() { 49 | return MessageType; 50 | } 51 | public void setMessageType(int messageType) { 52 | MessageType = messageType; 53 | } 54 | public short getMessageLength() { 55 | return MessageLength; 56 | } 57 | public void setMessageLength(short messageLength) { 58 | MessageLength = messageLength; 59 | } 60 | public String getMessageName() { 61 | return MessageName; 62 | } 63 | public void setMessageName(String messageName) { 64 | MessageName = messageName; 65 | } 66 | @Override 67 | public int hashCode() { 68 | final int prime = 31; 69 | int result = 1; 70 | result = prime * result + MessageLength; 71 | result = prime * result 72 | + ((MessageName == null) ? 0 : MessageName.hashCode()); 73 | result = prime * result + MessageType; 74 | return result; 75 | } 76 | @Override 77 | public boolean equals(Object obj) { 78 | if (this == obj) 79 | return true; 80 | if (obj == null) 81 | return false; 82 | if (getClass() != obj.getClass()) 83 | return false; 84 | InfoMenuSettings_T other = (InfoMenuSettings_T) obj; 85 | if (MessageLength != other.MessageLength) 86 | return false; 87 | if (MessageName == null) { 88 | if (other.MessageName != null) 89 | return false; 90 | } else if (!MessageName.equals(other.MessageName)) 91 | return false; 92 | if (MessageType != other.MessageType) 93 | return false; 94 | return true; 95 | } 96 | @Override 97 | public String toString() { 98 | return "InfoMenuSettings_T [MessageType=" + MessageType 99 | + ", MessageLength=" + MessageLength + ", MessageName=" 100 | + MessageName + "]"; 101 | } 102 | 103 | public static void main(String[] args) throws IOException { 104 | InfoMenuSettings_T t=new InfoMenuSettings_T(); 105 | t.setMessageLength((short)33); 106 | t.setMessageType(1); 107 | t.setMessageName("asdsadsd"); 108 | ByteArrayOutputStream out=new ByteArrayOutputStream(); 109 | t.encoder(out, 0); 110 | System.err.println(DataHelper.DataToHexString(out.toByteArray())); 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/up/HeartHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.up; 2 | 3 | import java.util.Map; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 9 | import com.mortals.iot.module.device.service.DeviceService; 10 | import com.mortals.iot.protocol.jt808.constant.NumberConstants; 11 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 12 | import com.mortals.iot.protocol.jt808.entity.MessageID; 13 | import com.mortals.iot.protocol.jt808.util.HexUtils; 14 | 15 | import io.netty.buffer.ByteBuf; 16 | import io.netty.buffer.Unpooled; 17 | import io.netty.channel.Channel; 18 | 19 | /** 20 | * @ClassName: HeartHandler 21 | * @Description: 心跳0x0002 <-> 0x8001 22 | * @Company iot 23 | * @author 24 | * @date 2017-12-15 下午2:30:03 25 | * 26 | */ 27 | @Component(value = "p_heart") 28 | public class HeartHandler extends AbstractDeviceCommandHandler implements MessageID { 29 | private DeviceService deviceService; 30 | 31 | public Map receive(JT808ProtocalPack message, Channel tsession) throws Exception { 32 | // Map resultMap = new HashMap(); 33 | // Integer result = NumberConstants._0; 34 | // 35 | // try { 36 | // 根据channelid获取会话信息 37 | // Session session = 38 | // sessionManager.getChannelIdSession(tsession.id().asLongText()); 39 | // if (session == null || StringUtils.isEmpty(session.getDeviceId())) { 40 | // throw new AppException("netty会话信息异常" + (session != null ? ",sessionId is:" + 41 | // session.getId() : "")); 42 | // } 43 | // 44 | // // 更新设备的心跳信息 45 | // Map data = new HashMap(); 46 | // data.put("heartTime", new Date()); 47 | // Map condition = new HashMap(); 48 | // condition.put("deviceId", session.getDeviceId()); 49 | // deviceService.update(data, condition); 50 | // } catch (AppException e) { 51 | // logger.error(e.getMessage()); 52 | // result = NumberConstants._1; 53 | // } catch (Exception e) { 54 | // logger.error(e.getMessage(), e); 55 | // result = NumberConstants._1; 56 | // } 57 | 58 | // resultMap.put("result", result); 59 | // return resultMap; 60 | logger.info("收到心跳消息"); 61 | return null; 62 | } 63 | 64 | // 65 | public void send(JT808ProtocalPack message, Channel tsession, Map reslutMap) throws Exception { 66 | Integer result = 0; 67 | // 响应的流水号 68 | byte[] serialnumber = JT808ProtocalPack.generateSerialNumber(tsession); 69 | 70 | JT808ProtocalPack fpp = new JT808ProtocalPack(); 71 | fpp.setId(P_PLATFORM_COMMON_REPLAY); 72 | fpp.setDeviceMobile(message.getDeviceMobile()); 73 | fpp.setSerialNumber(serialnumber); 74 | 75 | ByteBuf buf = Unpooled.buffer(5); 76 | buf.writeBytes(message.getSerialNumber()); 77 | buf.writeBytes(message.getId()); 78 | buf.writeByte(result == null ? NumberConstants._1 : result); 79 | 80 | fpp.setBody(buf.array()); 81 | 82 | sendMessage(tsession, fpp); 83 | } 84 | 85 | public DeviceService getDeviceService() { 86 | return deviceService; 87 | } 88 | 89 | public void setDeviceService(DeviceService deviceService) { 90 | this.deviceService = deviceService; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/InfoMenuSettings.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStream; 6 | import java.util.ArrayList; 7 | 8 | import com.mortals.iot.protocol.jt808.util.DataHelper; 9 | 10 | /** 11 | * 信息点播菜单设置 12 | * 消息ID:0x8303。 13 | * @author 14 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.message.client 15 | * @copyright iot 16 | * @date:2017-4-18 上午9:17:48 17 | */ 18 | public class InfoMenuSettings { 19 | //设置类型 20 | private int Value; 21 | //信息项总数 22 | private int num; 23 | //信息项列表 24 | private ArrayList info=new ArrayList(); 25 | /** 26 | * 27 | * @param out 28 | * @return 29 | * @throws IOException 30 | */ 31 | public OutputStream encoder(OutputStream out) throws IOException{ 32 | int size =0; 33 | size+=DataHelper.getbyte(out, Value); 34 | if(num <=0){ 35 | return out; 36 | } 37 | size+=DataHelper.getbyte(out, num); 38 | for (InfoMenuSettings_T iterable_element : info) { 39 | size+=iterable_element.encoder(out, size); 40 | } 41 | return out; 42 | } 43 | 44 | public int getValue() { 45 | return Value; 46 | } 47 | public void setValue(int value) { 48 | Value = value; 49 | } 50 | public int getNum() { 51 | return num; 52 | } 53 | public void setNum(int num) { 54 | this.num = num; 55 | } 56 | public ArrayList getInfo() { 57 | return info; 58 | } 59 | 60 | public void setInfoList(InfoMenuSettings_T info){ 61 | this.info.add(info); 62 | } 63 | 64 | public void setInfo(ArrayList info) { 65 | this.info = info; 66 | } 67 | @Override 68 | public int hashCode() { 69 | final int prime = 31; 70 | int result = 1; 71 | result = prime * result + Value; 72 | result = prime * result + ((info == null) ? 0 : info.hashCode()); 73 | result = prime * result + num; 74 | return result; 75 | } 76 | @Override 77 | public boolean equals(Object obj) { 78 | if (this == obj) 79 | return true; 80 | if (obj == null) 81 | return false; 82 | if (getClass() != obj.getClass()) 83 | return false; 84 | InfoMenuSettings other = (InfoMenuSettings) obj; 85 | if (Value != other.Value) 86 | return false; 87 | if (info == null) { 88 | if (other.info != null) 89 | return false; 90 | } else if (!info.equals(other.info)) 91 | return false; 92 | if (num != other.num) 93 | return false; 94 | return true; 95 | } 96 | @Override 97 | public String toString() { 98 | return "InfoMenuSettings [Value=" + Value + ", num=" + num + ", info=" 99 | + info + "]"; 100 | } 101 | 102 | public static void main(String[] args) throws IOException { 103 | InfoMenuSettings aa=new InfoMenuSettings(); 104 | aa.Value=4; 105 | aa.num=2; 106 | for (int i = 0; i < 3; i++) { 107 | InfoMenuSettings_T c=new InfoMenuSettings_T(); 108 | c.setMessageType(4); 109 | c.setMessageLength((short)6); 110 | c.setMessageName("ajaj"); 111 | aa.setInfoList(c); 112 | 113 | } 114 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 115 | System.err.println(aa.toString()); 116 | aa.encoder(out); 117 | System.err.println(DataHelper.DataToHexString(out.toByteArray())); 118 | System.err.println(out.size()); 119 | 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/up/ElectronicWaybillHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.up; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.mortals.framework.exception.AppException; 9 | import com.mortals.iot.handler.protocol808.collect.commons.Log; 10 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 11 | import com.mortals.iot.protocol.jt808.constant.NumberConstants; 12 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 13 | import com.mortals.iot.protocol.jt808.entity.MessageID; 14 | import com.mortals.iot.protocol.jt808.util.HexUtils; 15 | 16 | import io.netty.buffer.ByteBuf; 17 | import io.netty.buffer.Unpooled; 18 | import io.netty.channel.Channel; 19 | 20 | /** 21 | * @ClassName: ElectronicWaybillHandler 22 | * @Description: 电子运单上报0x0701,具体运单内容看具体设备情况 23 | * @Company iot 24 | * @author 25 | * @version 1.0, 2017-3-28 上午10:35:25 26 | */ 27 | //@Component(value = "p_electronic_waybill") 28 | public class ElectronicWaybillHandler extends AbstractDeviceCommandHandler implements MessageID { 29 | 30 | public Map receive(JT808ProtocalPack message, Channel tsession) throws Exception { 31 | Map resultMap = new HashMap(); 32 | Integer result = NumberConstants._0; 33 | 34 | try { 35 | // 电子运单长度 36 | int length = HexUtils.bytesToInt4(HexUtils.copyOfRange(message.getBody(), 0, 4)); 37 | // 电子运单内容 38 | byte[] content = HexUtils.copyOfRange(message.getBody(), 4, 4 + length); 39 | logger.info("收到电子运单内容," + HexUtils.bytesToHexString(content)); 40 | 41 | // String cmdstr = HexUtils.copyToHexStr(b_content, 2, 1); 42 | // 由于计价器并非业内统一标准,所以下面并不适合转发指令情形,故改为if语句判断: 43 | // String beanName = (String) ServerPacketUtils.getValue(cmdstr); 44 | // IotDeviceCommandHandler handler = SpringContextUtils.getBean(beanName); 45 | // IoCommandContext context = new IoCommandContext(handler); 46 | // context.handle(message, tsession); 47 | 48 | // if ("dc".equalsIgnoreCase(cmdstr)) { 49 | // EletronicWaybill ewb = new EletronicWaybill(message.getDeviceMobile(), 50 | // b_content); 51 | // // CollectCallServiceImpl.getInstance().extdeviceMeterInfo(ewb); 52 | // Log.getLogger(this.getClass()).info("电子运单具体内容:" + ewb.toString()); 53 | // } 54 | } catch (AppException e) { 55 | logger.error(e.getMessage()); 56 | result = NumberConstants._1; 57 | } catch (Exception e) { 58 | logger.error(e.getMessage(), e); 59 | result = NumberConstants._1; 60 | } 61 | 62 | resultMap.put("result", result); 63 | return resultMap; 64 | } 65 | 66 | public void send(JT808ProtocalPack message, Channel tsession, Map reslutMap) throws Exception { 67 | Integer result = (Integer) reslutMap.get("result"); 68 | // 响应的流水号 69 | byte[] serialnumber = JT808ProtocalPack.generateSerialNumber(tsession); 70 | 71 | JT808ProtocalPack fpp = new JT808ProtocalPack(); 72 | fpp.setId(P_PLATFORM_COMMON_REPLAY); 73 | fpp.setDeviceMobile(message.getDeviceMobile()); 74 | fpp.setSerialNumber(serialnumber); 75 | 76 | ByteBuf buf = Unpooled.buffer(5); 77 | buf.writeBytes(message.getSerialNumber()); 78 | buf.writeBytes(message.getId()); 79 | buf.writeByte(result == null ? NumberConstants._1 : result); 80 | 81 | fpp.setBody(buf.array()); 82 | fpp.setProperty(HexUtils.intToByteArray(buf.array().length)); 83 | 84 | Log.getLogger(this.getClass()).info("电子运单应答:" + fpp.toHexString()); 85 | sendMessage(tsession, fpp); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/device/CameraShootRep.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.device; 2 | 3 | import java.util.ArrayList; 4 | 5 | import com.mortals.iot.protocol.jt808.util.DataHelper; 6 | 7 | /** 8 | * 摄像头立即拍摄命令应答 消息ID:0x0805。 9 | * 10 | * @author 11 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.message.device 12 | * @copyright iot 13 | * @date:2017-4-23 上午10:09:30 14 | */ 15 | public class CameraShootRep { 16 | /** 17 | * 手机号码 18 | */ 19 | private String mobile; 20 | 21 | /** 22 | * 应答流水号 23 | */ 24 | private short serialNumber; 25 | 26 | /** 27 | * 结果 byte 28 | */ 29 | private int result; 30 | /** 31 | * ]多媒体ID 个数 32 | */ 33 | private short Ids; 34 | /** 35 | * 多媒体ID 列表 36 | */ 37 | private ArrayList id; 38 | /** 39 | * 初始化 40 | */ 41 | public CameraShootRep(){ 42 | 43 | } 44 | 45 | /** 46 | * 解码过程 47 | */ 48 | public void decode(byte[] body, String mobile) { 49 | this.mobile = mobile; 50 | this.serialNumber = DataHelper.parseUint16(body, 0); 51 | this.result = DataHelper.parseUint8(body, 2); 52 | this.Ids = DataHelper.parseUint16(body, 3); 53 | for (int i = 0; i < Ids; i++) { 54 | id.add(DataHelper.parseUint32(body, i * 4)); 55 | } 56 | } 57 | 58 | public String getMobile() { 59 | return mobile; 60 | } 61 | 62 | public void setMobile(String mobile) { 63 | this.mobile = mobile; 64 | } 65 | 66 | public short getSerialNumber() { 67 | return serialNumber; 68 | } 69 | 70 | public void setSerialNumber(short serialNumber) { 71 | this.serialNumber = serialNumber; 72 | } 73 | 74 | public int getResult() { 75 | return result; 76 | } 77 | 78 | public void setResult(int result) { 79 | this.result = result; 80 | } 81 | 82 | public short getIds() { 83 | return Ids; 84 | } 85 | 86 | public void setIds(short ids) { 87 | Ids = ids; 88 | } 89 | 90 | public ArrayList getId() { 91 | return id; 92 | } 93 | 94 | public void setId(ArrayList id) { 95 | this.id = id; 96 | } 97 | 98 | @Override 99 | public int hashCode() { 100 | final int prime = 31; 101 | int result = 1; 102 | result = prime * result + Ids; 103 | result = prime * result + ((id == null) ? 0 : id.hashCode()); 104 | result = prime * result + ((mobile == null) ? 0 : mobile.hashCode()); 105 | result = prime * result + this.result; 106 | result = prime * result + serialNumber; 107 | return result; 108 | } 109 | 110 | @Override 111 | public boolean equals(Object obj) { 112 | if (this == obj) 113 | return true; 114 | if (obj == null) 115 | return false; 116 | if (getClass() != obj.getClass()) 117 | return false; 118 | CameraShootRep other = (CameraShootRep) obj; 119 | if (Ids != other.Ids) 120 | return false; 121 | if (id == null) { 122 | if (other.id != null) 123 | return false; 124 | } else if (!id.equals(other.id)) 125 | return false; 126 | if (mobile == null) { 127 | if (other.mobile != null) 128 | return false; 129 | } else if (!mobile.equals(other.mobile)) 130 | return false; 131 | if (result != other.result) 132 | return false; 133 | if (serialNumber != other.serialNumber) 134 | return false; 135 | return true; 136 | } 137 | 138 | @Override 139 | public String toString() { 140 | return "CameraShootRep [mobile=" + mobile + ", serialNumber=" 141 | + serialNumber + ", result=" + result + ", Ids=" + Ids 142 | + ", id=" + id + "]"; 143 | } 144 | 145 | } 146 | -------------------------------------------------------------------------------- /src/main/resources/config/spring-config-druid-datasource.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 21 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 77 | 78 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/SetCircularArea.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStream; 6 | import java.io.Serializable; 7 | import java.util.ArrayList; 8 | 9 | import com.mortals.iot.protocol.jt808.util.DataHelper; 10 | 11 | /** 12 | * 设置圆形区域 13 | * 14 | * @MessageID=0x8600 15 | * @author 16 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.message.device 17 | * @copyright iot 18 | * @date:2017-4-9 下午3:12:33 19 | */ 20 | public class SetCircularArea implements Serializable{ 21 | /** 22 | * 23 | */ 24 | private static final long serialVersionUID = 1L; 25 | // 0:更新区域; 26 | // 1:追加区域; 27 | // 2:修改区域 28 | private int value; 29 | // 设置区域总算 30 | private int number; 31 | // 数据包 32 | private ArrayList area=new ArrayList(); 33 | 34 | /** 35 | * 36 | * @param out 37 | * @return 38 | * @throws IOException 39 | */ 40 | public OutputStream encoder(OutputStream out) throws IOException { 41 | int size = 0; 42 | size += DataHelper.getbyte(out, value); 43 | size += DataHelper.getbyte(out, number); 44 | if (number != 0) { 45 | for (CircularArea_T iterable_element : area) { 46 | size += iterable_element.encoder(out, size); 47 | } 48 | } 49 | return out; 50 | } 51 | 52 | public void setAreaList(CircularArea_T area) { 53 | this.area.add(area); 54 | 55 | } 56 | 57 | public ArrayList getArea() { 58 | return area; 59 | } 60 | 61 | public void setArea(ArrayList area) { 62 | this.area = area; 63 | } 64 | 65 | public int getValue() { 66 | return value; 67 | } 68 | 69 | public void setValue(int value) { 70 | this.value = value; 71 | } 72 | 73 | public int getNumber() { 74 | return number; 75 | } 76 | 77 | public void setNumber(int number) { 78 | this.number = number; 79 | } 80 | 81 | @Override 82 | public int hashCode() { 83 | final int prime = 31; 84 | int result = 1; 85 | result = prime * result + ((area == null) ? 0 : area.hashCode()); 86 | result = prime * result + number; 87 | result = prime * result + value; 88 | return result; 89 | } 90 | 91 | @Override 92 | public boolean equals(Object obj) { 93 | if (this == obj) 94 | return true; 95 | if (obj == null) 96 | return false; 97 | if (getClass() != obj.getClass()) 98 | return false; 99 | SetCircularArea other = (SetCircularArea) obj; 100 | if (area == null) { 101 | if (other.area != null) 102 | return false; 103 | } else if (!area.equals(other.area)) 104 | return false; 105 | if (number != other.number) 106 | return false; 107 | if (value != other.value) 108 | return false; 109 | return true; 110 | } 111 | 112 | @Override 113 | public String toString() { 114 | return "SetCircularArea [value=" + value + ", number=" + number 115 | + ", area=" + area + "]"; 116 | } 117 | 118 | public static void main(String[] args) throws IOException { 119 | SetCircularArea aa = new SetCircularArea(); 120 | // CircularArea_T[] bb = new CircularArea_T[1]; 121 | aa.setNumber(2); 122 | aa.setValue(2); 123 | for (int i = 0; i < 2; i++) { 124 | CircularArea_T cc = new CircularArea_T(); 125 | cc.setAreaId(i); 126 | cc.setAreaValue(new byte[] { (byte) 0xff, (byte) 0xff }); 127 | cc.setBeginTime("0930"); 128 | cc.setEndTime("1800"); 129 | int a1=(int) (104.073487*Math.pow(10, 6)); 130 | cc.setLatitude(a1); 131 | int a2=(int) (30.600753*Math.pow(10, 6)); 132 | cc.setRadius(a2); 133 | int a3=(int) (50.600753*Math.pow(10, 6)); 134 | cc.setLongitude(a3); 135 | cc.setSpeed((short) 100); 136 | cc.setDuration((byte) 0xff); 137 | aa.setAreaList(cc); 138 | } 139 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 140 | aa.encoder(out); 141 | System.err.println(aa.toString()); 142 | System.err.println(DataHelper.DataToHexString(out.toByteArray())); 143 | System.err.println(out.size()); 144 | 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/SaveMedia.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStream; 6 | 7 | import com.mortals.iot.protocol.jt808.util.DataHelper; 8 | 9 | /** 10 | * 存储多媒体数据检索 11 | 消息ID:0x8802 12 | * @author 13 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.message.client 14 | * @copyright iot 15 | * @date:2017-4-23 上午10:53:54 16 | */ 17 | public class SaveMedia { 18 | 19 | /** 20 | * 多媒体类型 BYTE 21 | */ 22 | private int mediaValue; 23 | /** 24 | * 通道ID BYTE 25 | */ 26 | private int ID; 27 | /** 28 | * 事件项编码 BYTE 29 | */ 30 | private int event; 31 | /** 32 | * 起始时间BCD[6] YY-MM-DD-hh-mm-ss 33 | */ 34 | private String startTime; 35 | /** 36 | * 结束时间 BCD[6] YY-MM-DD-hh-mm-ss 37 | */ 38 | private String endTime; 39 | /** 40 | * 初始化 41 | */ 42 | public SaveMedia(){ 43 | this.startTime="100000000000"; 44 | this.endTime="100000000000"; 45 | } 46 | /** 47 | * 编码 48 | * @param out 49 | * @return 50 | * @throws IOException 51 | */ 52 | public OutputStream encoder(OutputStream out) throws IOException { 53 | int size=0; 54 | size+=DataHelper.getbyte(out, mediaValue); 55 | size+=DataHelper.getbyte(out, ID); 56 | size+=DataHelper.getbyte(out, event); 57 | out.write(DataHelper.string26Bcd(startTime)); 58 | size+=6; 59 | out.write(DataHelper.string26Bcd(endTime)); 60 | size+=6; 61 | if(size!=15){ 62 | return null; 63 | } 64 | 65 | return out; 66 | } 67 | 68 | public int getMediaValue() { 69 | return mediaValue; 70 | } 71 | public void setMediaValue(int mediaValue) { 72 | this.mediaValue = mediaValue; 73 | } 74 | public int getID() { 75 | return ID; 76 | } 77 | public void setID(int iD) { 78 | ID = iD; 79 | } 80 | public int getEvent() { 81 | return event; 82 | } 83 | public void setEvent(int event) { 84 | this.event = event; 85 | } 86 | public String getStartTime() { 87 | return startTime; 88 | } 89 | public void setStartTime(String startTime) { 90 | this.startTime = startTime; 91 | } 92 | public String getEndTime() { 93 | return endTime; 94 | } 95 | public void setEndTime(String endTime) { 96 | this.endTime = endTime; 97 | } 98 | @Override 99 | public int hashCode() { 100 | final int prime = 31; 101 | int result = 1; 102 | result = prime * result + ID; 103 | result = prime * result + ((endTime == null) ? 0 : endTime.hashCode()); 104 | result = prime * result + event; 105 | result = prime * result + mediaValue; 106 | result = prime * result 107 | + ((startTime == null) ? 0 : startTime.hashCode()); 108 | return result; 109 | } 110 | @Override 111 | public boolean equals(Object obj) { 112 | if (this == obj) 113 | return true; 114 | if (obj == null) 115 | return false; 116 | if (getClass() != obj.getClass()) 117 | return false; 118 | SaveMedia other = (SaveMedia) obj; 119 | if (ID != other.ID) 120 | return false; 121 | if (endTime == null) { 122 | if (other.endTime != null) 123 | return false; 124 | } else if (!endTime.equals(other.endTime)) 125 | return false; 126 | if (event != other.event) 127 | return false; 128 | if (mediaValue != other.mediaValue) 129 | return false; 130 | if (startTime == null) { 131 | if (other.startTime != null) 132 | return false; 133 | } else if (!startTime.equals(other.startTime)) 134 | return false; 135 | return true; 136 | } 137 | @Override 138 | public String toString() { 139 | return "SaveMedia [mediaValue=" + mediaValue + ", ID=" + ID 140 | + ", event=" + event + ", startTime=" + startTime 141 | + ", endTime=" + endTime + "]"; 142 | } 143 | 144 | public static void main(String[] args) throws IOException { 145 | SaveMedia a=new SaveMedia(); 146 | ByteArrayOutputStream out=new ByteArrayOutputStream(); 147 | a.encoder(out); 148 | System.err.println(DataHelper.DataToHexString(out.toByteArray())); 149 | System.err.println(out.size()); 150 | System.err.println(a.toString()); 151 | } 152 | 153 | } 154 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/SetRectangularArea.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStream; 6 | import java.io.Serializable; 7 | import java.util.ArrayList; 8 | 9 | import com.mortals.iot.protocol.jt808.util.DataHelper; 10 | 11 | /** 12 | * 设置矩形区域 13 | * 14 | * @MessageID 0x8602 15 | * @author 16 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.message.client 17 | * @copyright iot 18 | * @date:2017-4-10 下午3:42:49 19 | */ 20 | public class SetRectangularArea implements Serializable { 21 | /** 22 | * 23 | */ 24 | private static final long serialVersionUID = 1L; 25 | /** 26 | * 设置属性 0;1;2 27 | */ 28 | private int value; 29 | /** 30 | * 区域总数 31 | */ 32 | private int number; 33 | 34 | private ArrayList rectanggula = new ArrayList(); 35 | 36 | /** 37 | * 38 | * @param out 39 | * @return 40 | * @throws IOException 41 | */ 42 | public OutputStream encoder(OutputStream out) throws IOException { 43 | int size = 0; 44 | size += DataHelper.getbyte(out, value); 45 | size += DataHelper.getbyte(out, number); 46 | if (number != 0) { 47 | for (RectanggularArea_T iterable_element : rectanggula) { 48 | size += iterable_element.encoder(out, size); 49 | } 50 | } 51 | return out; 52 | } 53 | 54 | public void setAreaList(RectanggularArea_T rectanggula) { 55 | this.rectanggula.add(rectanggula); 56 | 57 | } 58 | 59 | public int getValue() { 60 | return value; 61 | } 62 | 63 | public void setValue(int value) { 64 | this.value = value; 65 | } 66 | 67 | public int getNumber() { 68 | return number; 69 | } 70 | 71 | public void setNumber(int number) { 72 | this.number = number; 73 | } 74 | 75 | public ArrayList getRectanggula() { 76 | return rectanggula; 77 | } 78 | 79 | public void setRectanggula(ArrayList rectanggula) { 80 | this.rectanggula = rectanggula; 81 | } 82 | 83 | @Override 84 | public int hashCode() { 85 | final int prime = 31; 86 | int result = 1; 87 | result = prime * result + number; 88 | result = prime * result 89 | + ((rectanggula == null) ? 0 : rectanggula.hashCode()); 90 | result = prime * result + value; 91 | return result; 92 | } 93 | 94 | @Override 95 | public boolean equals(Object obj) { 96 | if (this == obj) 97 | return true; 98 | if (obj == null) 99 | return false; 100 | if (getClass() != obj.getClass()) 101 | return false; 102 | SetRectangularArea other = (SetRectangularArea) obj; 103 | if (number != other.number) 104 | return false; 105 | if (rectanggula == null) { 106 | if (other.rectanggula != null) 107 | return false; 108 | } else if (!rectanggula.equals(other.rectanggula)) 109 | return false; 110 | if (value != other.value) 111 | return false; 112 | return true; 113 | } 114 | 115 | @Override 116 | public String toString() { 117 | return "SetRectangularArea [value=" + value + ", number=" + number 118 | + ", rectanggula=" + rectanggula + "]"; 119 | } 120 | 121 | public static void main(String[] args) throws IOException { 122 | SetRectangularArea aa = new SetRectangularArea(); 123 | // CircularArea_T[] bb = new CircularArea_T[1]; 124 | aa.setNumber(2); 125 | aa.setValue(2); 126 | for (int i = 0; i < 2; i++) { 127 | RectanggularArea_T cc = new RectanggularArea_T(); 128 | cc.setAreaId(i); 129 | cc.setAreaValue(new byte[] { (byte) 0, (byte) 1, (byte) 1, 130 | (byte) 1, (byte) 1, (byte) 0, (byte) 1, (byte) 0, (byte) 1, 131 | (byte) 1, (byte) 0, (byte) 1, (byte) 1, (byte) 1, (byte) 1, 132 | (byte) 1 }); 133 | cc.setBeginTime("000000093000"); 134 | cc.setEndTime("000000180000"); 135 | cc.setLULatitude(10); 136 | cc.setLULongitude(20); 137 | cc.setRDLatitude(30); 138 | cc.setRDLongitude(40); 139 | cc.setSpeed((short) 100); 140 | cc.setDuration((byte) 0xff); 141 | aa.setAreaList(cc); 142 | } 143 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 144 | aa.encoder(out); 145 | System.err.println(aa.toString()); 146 | System.err.println(DataHelper.DataToHexString(out.toByteArray())); 147 | System.err.println(out.size()); 148 | 149 | } 150 | 151 | } 152 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/commons/Log.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.commons; 2 | 3 | import java.text.MessageFormat; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | public class Log { 9 | 10 | private final Logger logger; 11 | 12 | private Log(Class clazz) { 13 | // logger = org.apache.log4j.Logger.getLogger(clazz); 14 | logger = LoggerFactory.getLogger(clazz); 15 | } 16 | 17 | private Log() { 18 | logger = LoggerFactory.getLogger(this.getClass()); 19 | } 20 | 21 | public static Log getLogger(Class clazz) { 22 | return new Log(clazz); 23 | } 24 | 25 | public static Log getRootLogger() { 26 | return new Log(); 27 | } 28 | 29 | public void trace(String message) { 30 | if (logger.isTraceEnabled()) { 31 | logger.trace(message); 32 | } 33 | } 34 | 35 | public void trace(String message, Throwable t) { 36 | if (logger.isTraceEnabled()) { 37 | logger.trace(message, t); 38 | } 39 | } 40 | 41 | public void trace(String pattern, Object... arguments) { 42 | if (logger.isTraceEnabled()) { 43 | logger.trace(format(pattern, arguments)); 44 | } 45 | } 46 | 47 | public void trace(String pattern, Throwable t, Object... arguments) { 48 | if (logger.isTraceEnabled()) { 49 | logger.trace(format(pattern, arguments), t); 50 | } 51 | } 52 | 53 | public void debug(String message) { 54 | if (logger.isDebugEnabled()) { 55 | logger.debug(message); 56 | } 57 | } 58 | 59 | public void debug(String message, Throwable t) { 60 | if (logger.isDebugEnabled()) { 61 | logger.debug(message, t); 62 | } 63 | } 64 | 65 | public void debug(String pattern, Object... arguments) { 66 | if (logger.isDebugEnabled()) { 67 | logger.debug(format(pattern, arguments)); 68 | } 69 | } 70 | 71 | public void debug(String pattern, Throwable t, Object... arguments) { 72 | if (logger.isDebugEnabled()) { 73 | logger.debug(format(pattern, arguments), t); 74 | } 75 | } 76 | 77 | public void info(String message) { 78 | if (logger.isInfoEnabled()) { 79 | logger.info(message); 80 | } 81 | } 82 | 83 | public void info(String message, Throwable t) { 84 | if (logger.isInfoEnabled()) { 85 | logger.info(message, t); 86 | } 87 | } 88 | 89 | public void info(String pattern, Object... arguments) { 90 | if (logger.isInfoEnabled()) { 91 | logger.info(format(pattern, arguments)); 92 | } 93 | } 94 | 95 | public void info(String pattern, Throwable t, Object... arguments) { 96 | if (logger.isInfoEnabled()) { 97 | logger.info(format(pattern, arguments), t); 98 | } 99 | } 100 | 101 | public void warn(String message) { 102 | if (logger.isWarnEnabled()) { 103 | logger.warn(message); 104 | } 105 | } 106 | 107 | public void warn(String message, Throwable t) { 108 | if (logger.isWarnEnabled()) { 109 | logger.warn(message, t); 110 | } 111 | } 112 | 113 | public void warn(String pattern, Object... arguments) { 114 | if (logger.isWarnEnabled()) { 115 | logger.warn(format(pattern, arguments)); 116 | } 117 | } 118 | 119 | public void warn(String pattern, Throwable t, Object... arguments) { 120 | if (logger.isWarnEnabled()) { 121 | logger.trace(format(pattern, arguments), t); 122 | } 123 | } 124 | 125 | public void error(String message) { 126 | if (logger.isErrorEnabled()) { 127 | logger.error(message); 128 | } 129 | } 130 | 131 | public void error(String message, Throwable t) { 132 | if (logger.isErrorEnabled()) { 133 | logger.error(message, t); 134 | } 135 | } 136 | 137 | public void error(String pattern, Object... arguments) { 138 | if (logger.isErrorEnabled()) { 139 | logger.error(format(pattern, arguments)); 140 | } 141 | } 142 | 143 | public void error(String pattern, Throwable t, Object... arguments) { 144 | if (logger.isErrorEnabled()) { 145 | logger.trace(format(pattern, arguments), t); 146 | } 147 | } 148 | 149 | 150 | public void assertLog(boolean assertion, String message) { 151 | if (!assertion) { 152 | logger.error(message); 153 | } 154 | } 155 | 156 | private static String format(String pattern, Object... arguments) { 157 | return MessageFormat.format(pattern, arguments); 158 | } 159 | 160 | @SuppressWarnings("unused") 161 | private static final String FQCN; 162 | 163 | static { 164 | FQCN = Log.class.getName(); 165 | } 166 | 167 | } -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/UpdataPack.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | import java.util.Arrays; 6 | 7 | import com.mortals.iot.handler.protocol808.collect.commons.Log; 8 | import com.mortals.iot.protocol.jt808.util.DataHelper; 9 | 10 | /** 11 | * 下发终端升级包 消息ID:0x8108。 12 | * 13 | * @author 14 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.message.client 15 | * @copyright iot 16 | * @date:2017-4-17 下午4:23:57 17 | */ 18 | public class UpdataPack { 19 | // 升级类型 0:终端,12:道路运输证IC 卡读卡器,52:iot 20 | // 卫星定位模块 21 | private int updataValue; 22 | // 制造商编号 23 | private String ManufacturersID; 24 | // 版本号长度 25 | private int verLength; 26 | // 版本号 27 | private String ver; 28 | // 升级数据包长度 29 | private int updataLength; 30 | // 升级数据包 31 | private byte[] data; 32 | 33 | /** 34 | * 35 | * @param out 36 | * @return 37 | * @throws IOException 38 | */ 39 | public OutputStream encoder(OutputStream out) throws IOException { 40 | int size = 0; 41 | size += DataHelper.getbyte(out, updataValue); 42 | out.write(DataHelper.string26Bcd(ManufacturersID)); 43 | size += 5; 44 | size += DataHelper.getbyte(out, verLength); 45 | out.write(DataHelper.string26Bcd(ver)); 46 | size += verLength; 47 | size += DataHelper.getInt(out, updataLength); 48 | out.write(data); 49 | if (size < 7 + verLength + updataLength) { 50 | Log.getLogger(this.getClass()).equals( 51 | "encoder is error:" + this.toString()); 52 | return null; 53 | } 54 | 55 | return out; 56 | } 57 | 58 | public int getUpdataValue() { 59 | return updataValue; 60 | } 61 | 62 | public void setUpdataValue(int updataValue) { 63 | this.updataValue = updataValue; 64 | } 65 | 66 | public String getManufacturersID() { 67 | return ManufacturersID; 68 | } 69 | 70 | public void setManufacturersID(String manufacturersID) { 71 | ManufacturersID = manufacturersID; 72 | } 73 | 74 | public int getVerLength() { 75 | return verLength; 76 | } 77 | 78 | public void setVerLength(int verLength) { 79 | this.verLength = verLength; 80 | } 81 | 82 | public String getVer() { 83 | return ver; 84 | } 85 | 86 | public void setVer(String ver) { 87 | this.ver = ver; 88 | } 89 | 90 | public int getUpdataLength() { 91 | return updataLength; 92 | } 93 | 94 | public void setUpdataLength(int updataLength) { 95 | this.updataLength = updataLength; 96 | } 97 | 98 | public byte[] getData() { 99 | return data; 100 | } 101 | 102 | public void setData(byte[] data) { 103 | this.data = data; 104 | } 105 | 106 | @Override 107 | public int hashCode() { 108 | final int prime = 31; 109 | int result = 1; 110 | result = prime * result 111 | + ((ManufacturersID == null) ? 0 : ManufacturersID.hashCode()); 112 | result = prime * result + Arrays.hashCode(data); 113 | result = prime * result + updataLength; 114 | result = prime * result + updataValue; 115 | result = prime * result + ((ver == null) ? 0 : ver.hashCode()); 116 | result = prime * result + verLength; 117 | return result; 118 | } 119 | 120 | @Override 121 | public boolean equals(Object obj) { 122 | if (this == obj) 123 | return true; 124 | if (obj == null) 125 | return false; 126 | if (getClass() != obj.getClass()) 127 | return false; 128 | UpdataPack other = (UpdataPack) obj; 129 | if (ManufacturersID == null) { 130 | if (other.ManufacturersID != null) 131 | return false; 132 | } else if (!ManufacturersID.equals(other.ManufacturersID)) 133 | return false; 134 | if (!Arrays.equals(data, other.data)) 135 | return false; 136 | if (updataLength != other.updataLength) 137 | return false; 138 | if (updataValue != other.updataValue) 139 | return false; 140 | if (ver == null) { 141 | if (other.ver != null) 142 | return false; 143 | } else if (!ver.equals(other.ver)) 144 | return false; 145 | if (verLength != other.verLength) 146 | return false; 147 | return true; 148 | } 149 | 150 | @Override 151 | public String toString() { 152 | return "UpdataPack [updataValue=" + updataValue + ", ManufacturersID=" 153 | + ManufacturersID + ", verLength=" + verLength + ", ver=" + ver 154 | + ", updataLength=" + updataLength + ", data=" 155 | + Arrays.toString(data) + "]"; 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/framework/cfg/SpringConfig.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.framework.cfg; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | import java.util.Set; 7 | 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.beans.factory.annotation.Qualifier; 10 | import org.springframework.beans.factory.annotation.Value; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.ComponentScan; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.context.annotation.ImportResource; 15 | import org.springframework.context.annotation.PropertySource; 16 | import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; 17 | 18 | import com.mortals.iot.server.initializer.NettyServerInitializer; 19 | 20 | import io.netty.bootstrap.ServerBootstrap; 21 | import io.netty.channel.ChannelOption; 22 | import io.netty.channel.nio.NioEventLoopGroup; 23 | import io.netty.channel.socket.nio.NioServerSocketChannel; 24 | import io.netty.handler.codec.string.StringDecoder; 25 | import io.netty.handler.codec.string.StringEncoder; 26 | 27 | /** 28 | * This class contains the bean definitions for this netty server. These beans 29 | * are autowired into the respective java classes in org.nerdronix.* packages 30 | * using component scan feature of spring. Properties are injected using the 31 | * PropertySource. For more information look here and here 36 | * 37 | * @author Abraham Menacherry 38 | * 39 | */ 40 | @Configuration 41 | @ComponentScan("com.mortals.iot") 42 | @PropertySource(value= {"classpath:netty-server.properties","classpath:important.properties"}) 43 | @ImportResource("classpath:config/spring-config.xml") 44 | public class SpringConfig { 45 | 46 | @Value("${boss.thread.count}") 47 | private int bossCount; 48 | 49 | @Value("${worker.thread.count}") 50 | private int workerCount; 51 | 52 | @Value("${tcp.port}") 53 | private int tcpPort; 54 | 55 | @Value("${so.keepalive}") 56 | private boolean keepAlive; 57 | 58 | @Value("${so.backlog}") 59 | private int backlog; 60 | 61 | @Value("${log4j.configuration}") 62 | private String log4jConfiguration; 63 | 64 | @Autowired 65 | @Qualifier("nettyServerInitializer") 66 | private NettyServerInitializer nettyServerInitializer; 67 | 68 | @SuppressWarnings("unchecked") 69 | @Bean(name = "serverBootstrap") 70 | public ServerBootstrap bootstrap() { 71 | ServerBootstrap b = new ServerBootstrap(); 72 | b.group(bossGroup(), workerGroup()).channel(NioServerSocketChannel.class).childHandler(nettyServerInitializer); 73 | Map, Object> tcpChannelOptions = tcpChannelOptions(); 74 | Set> keySet = tcpChannelOptions.keySet(); 75 | for (@SuppressWarnings("rawtypes") 76 | ChannelOption option : keySet) { 77 | b.option(option, tcpChannelOptions.get(option)); 78 | } 79 | return b; 80 | } 81 | 82 | @Bean(name = "bossGroup", destroyMethod = "shutdownGracefully") 83 | public NioEventLoopGroup bossGroup() { 84 | // 构造 可指定boss组启动线程数量,默认为cpu核心数*2 85 | return new NioEventLoopGroup(bossCount); 86 | } 87 | 88 | @Bean(name = "workerGroup", destroyMethod = "shutdownGracefully") 89 | public NioEventLoopGroup workerGroup() { 90 | return new NioEventLoopGroup(workerCount); 91 | } 92 | 93 | @Bean(name = "tcpSocketAddress") 94 | public InetSocketAddress tcpPort() { 95 | return new InetSocketAddress(tcpPort); 96 | } 97 | 98 | @Bean(name = "tcpChannelOptions") 99 | public Map, Object> tcpChannelOptions() { 100 | Map, Object> options = new HashMap, Object>(); 101 | options.put(ChannelOption.SO_KEEPALIVE, keepAlive); 102 | options.put(ChannelOption.SO_BACKLOG, backlog); 103 | return options; 104 | } 105 | 106 | @Bean(name = "stringEncoder") 107 | public StringEncoder stringEncoder() { 108 | return new StringEncoder(); 109 | } 110 | 111 | @Bean(name = "stringDecoder") 112 | public StringDecoder stringDecoder() { 113 | return new StringDecoder(); 114 | } 115 | 116 | /** 117 | * Necessary to make the Value annotations work. 118 | * 119 | * @return 120 | */ 121 | @Bean 122 | public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { 123 | return new PropertySourcesPlaceholderConfigurer(); 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/ShootParam.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | import org.apache.commons.lang.builder.HashCodeBuilder; 4 | import org.apache.commons.lang.builder.ToStringBuilder; 5 | 6 | /** 7 | * @ClassName: ShootParam 8 | * @Description: 拍摄参数 9 | * @Company iot 10 | * @author 11 | * @version 1.0, 2017-3-27 下午3:15:41 12 | */ 13 | public class ShootParam { 14 | 15 | // 通道ID 16 | private int channelId; 17 | 18 | // 拍摄命令 19 | private int shootCmd; 20 | 21 | // 拍照间隔/录像时间 22 | private int shootInterval; 23 | 24 | // 保存标志 25 | private int saveFlag; 26 | 27 | // 分辨率 28 | private int resolution; 29 | 30 | // 图像/视频质量 31 | private int videoQuality; 32 | 33 | // 亮度 34 | private int brightness; 35 | 36 | // 对比度 37 | private int contrast; 38 | 39 | // 饱和度 40 | private int saturation; 41 | 42 | // 色度 43 | private int chroma; 44 | 45 | public ShootParam() { 46 | this.channelId = 1; 47 | this.shootCmd = 1; 48 | this.shootInterval = 60; 49 | this.saveFlag = 0; 50 | this.resolution = 1; 51 | this.videoQuality = 2; 52 | this.brightness = 0; 53 | this.contrast = 0; 54 | this.saturation = 0; 55 | this.chroma = 0; 56 | } 57 | 58 | public ShootParam(int channelId, int shootCmd, int shootInterval, 59 | int saveFlag, int resolution, int videoQuality, int brightness, 60 | int contrast, int saturation, int chroma) { 61 | this.channelId = channelId; 62 | this.shootCmd = shootCmd; 63 | this.shootInterval = shootInterval; 64 | this.saveFlag = saveFlag; 65 | this.resolution = resolution; 66 | this.videoQuality = videoQuality; 67 | this.brightness = brightness; 68 | this.contrast = contrast; 69 | this.saturation = saturation; 70 | this.chroma = chroma; 71 | } 72 | 73 | @Override 74 | public String toString() { 75 | return ToStringBuilder.reflectionToString(this); 76 | } 77 | 78 | @Override 79 | public int hashCode() { 80 | return HashCodeBuilder.reflectionHashCode(this); 81 | } 82 | 83 | /** 84 | * @return 通道ID 85 | */ 86 | public int getChannelId() { 87 | return channelId; 88 | } 89 | 90 | /** 91 | * @param 通道ID 92 | */ 93 | public void setChannelId(int channelId) { 94 | this.channelId = channelId; 95 | } 96 | 97 | /** 98 | * @return 拍摄命令 99 | */ 100 | public int getShootCmd() { 101 | return shootCmd; 102 | } 103 | 104 | /** 105 | * @param 拍摄命令 106 | */ 107 | public void setShootCmd(int shootCmd) { 108 | this.shootCmd = shootCmd; 109 | } 110 | 111 | /** 112 | * @return 拍照间隔/录像时间 113 | */ 114 | public int getShootInterval() { 115 | return shootInterval; 116 | } 117 | 118 | /** 119 | * @param 拍照间隔/录像时间 120 | */ 121 | public void setShootInterval(int shootInterval) { 122 | this.shootInterval = shootInterval; 123 | } 124 | 125 | /** 126 | * @return 保存标志 127 | */ 128 | public int getSaveFlag() { 129 | return saveFlag; 130 | } 131 | 132 | /** 133 | * @param 保存标志 134 | */ 135 | public void setSaveFlag(int saveFlag) { 136 | this.saveFlag = saveFlag; 137 | } 138 | 139 | /** 140 | * @return 分辨率 141 | */ 142 | public int getResolution() { 143 | return resolution; 144 | } 145 | 146 | /** 147 | * @param 亮度 148 | */ 149 | public void setResolution(int resolution) { 150 | this.resolution = resolution; 151 | } 152 | 153 | /** 154 | * @return 图像/视频质量 155 | */ 156 | public int getVideoQuality() { 157 | return videoQuality; 158 | } 159 | 160 | /** 161 | * @param 图像/视频质量 162 | */ 163 | public void setVideoQuality(int videoQuality) { 164 | this.videoQuality = videoQuality; 165 | } 166 | 167 | /** 168 | * @return 亮度 169 | */ 170 | public int getBrightness() { 171 | return brightness; 172 | } 173 | 174 | /** 175 | * @param 亮度 176 | */ 177 | public void setBrightness(int brightness) { 178 | this.brightness = brightness; 179 | } 180 | 181 | /** 182 | * @return 对比度 183 | */ 184 | public int getContrast() { 185 | return contrast; 186 | } 187 | 188 | /** 189 | * @param 对比度 190 | */ 191 | public void setContrast(int contrast) { 192 | this.contrast = contrast; 193 | } 194 | 195 | /** 196 | * @return 饱和度 197 | */ 198 | public int getSaturation() { 199 | return saturation; 200 | } 201 | 202 | /** 203 | * @param 饱和度 204 | */ 205 | public void setSaturation(int saturation) { 206 | this.saturation = saturation; 207 | } 208 | 209 | /** 210 | * @return 色度 211 | */ 212 | public int getChroma() { 213 | return chroma; 214 | } 215 | 216 | /** 217 | * @param 色度 218 | */ 219 | public void setChroma(int chroma) { 220 | this.chroma = chroma; 221 | } 222 | 223 | 224 | } 225 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/SaveMediaUp.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStream; 6 | 7 | import com.mortals.iot.protocol.jt808.util.DataHelper; 8 | 9 | /** 10 | * 存储多媒体数据上传命令 消息ID:0x8803 11 | * 12 | * @author 13 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.message.client 14 | * @copyright iot 15 | * @date:2017-4-24 上午9:02:10 16 | */ 17 | public class SaveMediaUp { 18 | 19 | /** 20 | * 多媒体类型 byte 21 | */ 22 | private int MediaValue; 23 | /** 24 | * 通道ID byte 25 | */ 26 | private int channelID; 27 | /** 28 | * 事件项编码 byte 29 | */ 30 | private int event; 31 | /** 32 | * 起始时间 bcd[6] 33 | */ 34 | private String startTime; 35 | /** 36 | * 结束时间 bcd[6] 37 | */ 38 | private String endTime; 39 | /** 40 | * 删除标志 byte 41 | */ 42 | private int deleteMark; 43 | 44 | /** 45 | * 初始化 46 | */ 47 | public SaveMediaUp() { 48 | 49 | this.startTime="000000000000"; 50 | this.endTime="000000000000"; 51 | } 52 | 53 | /** 54 | * 编码 55 | * 56 | * @param out 57 | * @return 58 | * @throws IOException 59 | */ 60 | public OutputStream encoder(OutputStream out) throws IOException { 61 | int size = 0; 62 | size += DataHelper.getbyte(out, MediaValue); 63 | size += DataHelper.getbyte(out, channelID); 64 | size += DataHelper.getbyte(out, event); 65 | out.write(DataHelper.string26Bcd(startTime)); 66 | size += 6; 67 | out.write(DataHelper.string26Bcd(endTime)); 68 | size += 6; 69 | size += DataHelper.getbyte(out, deleteMark); 70 | if (size != 16) { 71 | return null; 72 | } 73 | 74 | return out; 75 | } 76 | 77 | public int getMediaValue() { 78 | return MediaValue; 79 | } 80 | 81 | public void setMediaValue(int mediaValue) { 82 | MediaValue = mediaValue; 83 | } 84 | 85 | public int getChannelID() { 86 | return channelID; 87 | } 88 | 89 | public void setChannelID(int channelID) { 90 | this.channelID = channelID; 91 | } 92 | 93 | public int getEvent() { 94 | return event; 95 | } 96 | 97 | public void setEvent(int event) { 98 | this.event = event; 99 | } 100 | 101 | public String getStartTime() { 102 | return startTime; 103 | } 104 | 105 | public void setStartTime(String startTime) { 106 | this.startTime = startTime; 107 | } 108 | 109 | public String getEndTime() { 110 | return endTime; 111 | } 112 | 113 | public void setEndTime(String endTime) { 114 | this.endTime = endTime; 115 | } 116 | 117 | public int getDeleteMark() { 118 | return deleteMark; 119 | } 120 | 121 | public void setDeleteMark(int deleteMark) { 122 | this.deleteMark = deleteMark; 123 | } 124 | 125 | @Override 126 | public int hashCode() { 127 | final int prime = 31; 128 | int result = 1; 129 | result = prime * result + MediaValue; 130 | result = prime * result + channelID; 131 | result = prime * result + deleteMark; 132 | result = prime * result + ((endTime == null) ? 0 : endTime.hashCode()); 133 | result = prime * result + event; 134 | result = prime * result 135 | + ((startTime == null) ? 0 : startTime.hashCode()); 136 | return result; 137 | } 138 | 139 | @Override 140 | public boolean equals(Object obj) { 141 | if (this == obj) 142 | return true; 143 | if (obj == null) 144 | return false; 145 | if (getClass() != obj.getClass()) 146 | return false; 147 | SaveMediaUp other = (SaveMediaUp) obj; 148 | if (MediaValue != other.MediaValue) 149 | return false; 150 | if (channelID != other.channelID) 151 | return false; 152 | if (deleteMark != other.deleteMark) 153 | return false; 154 | if (endTime == null) { 155 | if (other.endTime != null) 156 | return false; 157 | } else if (!endTime.equals(other.endTime)) 158 | return false; 159 | if (event != other.event) 160 | return false; 161 | if (startTime == null) { 162 | if (other.startTime != null) 163 | return false; 164 | } else if (!startTime.equals(other.startTime)) 165 | return false; 166 | return true; 167 | } 168 | 169 | @Override 170 | public String toString() { 171 | return "SaveMediaUp [MediaValue=" + MediaValue + ", channelID=" 172 | + channelID + ", event=" + event + ", startTime=" + startTime 173 | + ", endTime=" + endTime + ", deleteMark=" + deleteMark + "]"; 174 | } 175 | 176 | public static void main(String[] args) throws IOException { 177 | SaveMediaUp u=new SaveMediaUp(); 178 | ByteArrayOutputStream out=new ByteArrayOutputStream(); 179 | u.encoder(out); 180 | 181 | System.err.println(out.size()); 182 | System.err.println(DataHelper.DataToHexString(out.toByteArray())); 183 | 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/ConstantParams.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | 4 | 5 | /** 6 | * @ClassName: ConstantParams 7 | * @Description: 常量参数:文本信息、电话回拨、设置电话本、摄像头立即拍摄等参数 8 | * @Company iot 9 | * @author 10 | * @version 1.0, 2017-3-27 下午2:00:23 11 | */ 12 | public class ConstantParams { 13 | 14 | // -------------------------------------------------------- 15 | // 文本信息下发标志 16 | // -------------------------------------------------------- 17 | /** 18 | * 文本信息下发标志:紧急 19 | */ 20 | public static byte SENT_TXT_TYPE_EMERGENCY = 0x00; 21 | /** 22 | * 文本信息下发标志:终端显示器显示 23 | */ 24 | public static byte SENT_TXT_TYPE_SHOW = 2; 25 | /** 26 | * 文本信息下发标志:终端TTS播读 27 | */ 28 | public static byte SENT_TXT_TYPE_TTS = 3; 29 | /** 30 | * 文本信息下发标志:广告屏显示 31 | */ 32 | public static byte SENT_TXT_TYPE_AD = 4; 33 | /** 34 | * 文本信息下发标志:保留 35 | */ 36 | public static byte SENT_TXT_TYPE_1 = 1; 37 | /** 38 | * 文本信息下发标志:保留 39 | */ 40 | public static byte SENT_TXT_TYPE_5 = 5; 41 | /** 42 | * 文本信息下发标志:保留 43 | */ 44 | public static byte SENT_TXT_TYPE_6 = 6; 45 | /** 46 | * 文本信息下发标志:保留 47 | */ 48 | public static byte SENT_TXT_TYPE_7 = 7; 49 | 50 | // -------------------------------------------------------- 51 | // 电话回拨标志 52 | // -------------------------------------------------------- 53 | /** 54 | * 电话回拨标志:0:普通通话 55 | */ 56 | public static byte CALL_TYPE_COMMON = 0; 57 | /** 58 | * 电话回拨标志:0:普通通话 59 | */ 60 | public static byte CALL_TYPE_MONITOR = 1; 61 | 62 | // -------------------------------------------------------- 63 | // 设置电话本 64 | // -------------------------------------------------------- 65 | /** 66 | * 设置电话本 67 | * 删除终端上所有存储的联系人 68 | */ 69 | public static byte PHONEBOOK_TYPE_DEL = 0; 70 | /** 71 | * 更新电话本(删除终端中已有全部联系人并追加消息中的联系人); 72 | */ 73 | public static byte PHONEBOOK_TYPE_UPDATE = 1; 74 | /** 75 | * 追加电话本 76 | */ 77 | public static byte PHONEBOOK_TYPE_ADD = 2; 78 | /** 79 | * 修改电话本 80 | */ 81 | public static byte PHONEBOOK_TYPE_MODIFY = 3; 82 | 83 | // -------------------------------------------------------- 84 | // 摄像头立即拍摄参数 85 | // -------------------------------------------------------- 86 | /** 87 | * 拍摄命令:停止拍摄: 00 00 88 | */ 89 | public static int SHOOT_STOP = 0x0000; 90 | 91 | /** 92 | * 拍摄命令:录像 : FF FF 93 | */ 94 | public static int SHOOT_RECORD = (short) 0xFFFF; 95 | 96 | /** 97 | * 拍照间隔/录像时间 98 | */ 99 | public static int SHOOT_MIN_INTERVAL = 0x0000; 100 | 101 | /** 102 | * 保存标志:1 保存 103 | */ 104 | public static int SHOOT_FLAG_SAVE = 0x01; 105 | 106 | /** 107 | * 保存标志:0 实时上传 108 | */ 109 | public static int SHOOT_FLAG_REALTIME = 0x00; 110 | 111 | /** 112 | * 分辨率:320*240 113 | */ 114 | public static int SHOOT_RESOLUTION_320x240 = 0x01; 115 | 116 | /** 117 | * 分辨率:640*480 118 | */ 119 | public static int SHOOT_RESOLUTION_640x480 = 0x02; 120 | 121 | /** 122 | * 分辨率:800*600 123 | */ 124 | public static int SHOOT_RESOLUTION_800x600 = 0x03; 125 | 126 | /** 127 | * 分辨率:1024*768 128 | */ 129 | public static int SHOOT_RESOLUTION_1024x768 = 0x04; 130 | 131 | /** 132 | * 分辨率:176*144(qcif) 133 | */ 134 | public static int SHOOT_RESOLUTION_176x144_QCIF = 0x05; 135 | 136 | /** 137 | * 分辨率:352*288(cif) 138 | */ 139 | public static int SHOOT_RESOLUTION_352x288_CIF = 0x06; 140 | 141 | /** 142 | * 分辨率:704*288(HALF D1) 143 | */ 144 | public static int SHOOT_RESOLUTION_704x288_HALF_D1 = 0x07; 145 | 146 | /** 147 | * 分辨率:704*576(D1) 148 | */ 149 | public static int SHOOT_RESOLUTION_704x576_D1 = 0x08; 150 | 151 | /** 152 | * 图像/视频质量:01 153 | */ 154 | public static int SHOOT_VIDE_QUALITY_1 = 0x01; 155 | 156 | /** 157 | * 图像/视频质量:02 158 | */ 159 | public static int SHOOT_VIDE_QUALITY_2 = 0x02; 160 | 161 | /** 162 | * 图像/视频质量:03 163 | */ 164 | public static int SHOOT_VIDE_QUALITY_3 = 0x03; 165 | 166 | /** 167 | * 图像/视频质量:04 168 | */ 169 | public static int SHOOT_VIDE_QUALITY_4 = 0x04; 170 | 171 | /** 172 | * 图像/视频质量:05 173 | */ 174 | public static int SHOOT_VIDE_QUALITY_5 = 0x05; 175 | 176 | /** 177 | * 图像/视频质量:06 178 | */ 179 | public static int SHOOT_VIDE_QUALITY_6 = 0x06; 180 | 181 | /** 182 | * 图像/视频质量:07 183 | */ 184 | public static int SHOOT_VIDE_QUALITY_7 = 0x07; 185 | 186 | /** 187 | * 图像/视频质量:08 188 | */ 189 | public static int SHOOT_VIDE_QUALITY_8 = 0x08; 190 | 191 | /** 192 | * 图像/视频质量:09 193 | */ 194 | public static int SHOOT_VIDE_QUALITY_9 = 0x09; 195 | 196 | /** 197 | * 图像/视频质量:10 198 | */ 199 | public static int SHOOT_VIDE_QUALITY_10 = 0x0A; 200 | 201 | 202 | } 203 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/up/AuthenticHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.up; 2 | 3 | import java.util.Map; 4 | 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Component; 7 | 8 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 9 | import com.mortals.iot.module.device.service.DeviceJt808Service; 10 | import com.mortals.iot.module.device.service.DeviceService; 11 | import com.mortals.iot.protocol.jt808.constant.NumberConstants; 12 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 13 | import com.mortals.iot.protocol.jt808.entity.MessageID; 14 | 15 | import io.netty.buffer.ByteBuf; 16 | import io.netty.buffer.Unpooled; 17 | import io.netty.channel.Channel; 18 | 19 | /** 20 | * @ClassName: AuthenticHandler 21 | * @Description: 鉴权0x0102:终端主动上发给服务端的信息 22 | * @Company iot 23 | * @author 24 | * @version 1.0, 2017-3-20 上午10:39:31 25 | */ 26 | @Component(value = "p_device_auth") 27 | public class AuthenticHandler extends AbstractDeviceCommandHandler implements MessageID { 28 | 29 | private DeviceService deviceService; 30 | 31 | private DeviceJt808Service deviceJt808Service; 32 | 33 | public Map receive(JT808ProtocalPack message, Channel tsession) throws Exception { 34 | // Map resultMap = new HashMap(); 35 | // Integer authResult = NumberConstants._0; 36 | // 37 | // try { 38 | String authCode = new String(message.getBody(), "GBK"); 39 | logger.info("收到鉴权码:" + authCode); 40 | 41 | // String channelId = tsession.id().asLongText(); 42 | // Session session = sessionManager.getSession(channelId); 43 | // if (session == null) { 44 | // session = Session.buildSession(tsession, message.getDeviceMobile()); 45 | // sessionManager.putSession(channelId, session); 46 | // } 47 | // 48 | // DeviceJt808Query deviceJt808Query = new DeviceJt808Query(); 49 | // deviceJt808Query.setAuthorizationCode(authCode); 50 | // List deviceJt808EntityList = 51 | // deviceJt808Service.find(deviceJt808Query, null); 52 | // // 鉴权码不存在 53 | // if (deviceJt808EntityList == null || deviceJt808EntityList.size() <= 54 | // NumberConstants._0 55 | // || deviceJt808EntityList.get(NumberConstants._0) == null) { 56 | // throw new AppException("鉴权码:" + authCode + " ,不存在"); 57 | // } 58 | // 59 | // // 还要判断该鉴权码是否已经鉴过权 TODO bono:需要在应用重启的时候更新devcie表中的status状态为离线 60 | // DeviceEntity deviceEntity = 61 | // deviceService.get(deviceJt808EntityList.get(NumberConstants._0).getId(), 62 | // null); 63 | // if (deviceEntity == null) { 64 | // throw new AppException("鉴权码" + authCode + " ,对应设备信息不存在"); 65 | // } 66 | // if (deviceEntity.getStatus() == NumberConstants._0) { 67 | // throw new AppException("鉴权码:" + authCode + " ,已经鉴过权"); 68 | // } 69 | // 70 | // // 鉴权通过,保存鉴权通过会话信息 71 | // session.setDeviceId(deviceEntity.getDeviceId()); 72 | // session.setAuthenticated(true); 73 | // sessionManager.putAuthSession(deviceEntity.getDeviceId(), session); 74 | // 75 | // // 鉴权通过,更新设备状态为在线状态 76 | // Map data = new HashMap(); 77 | // data.put("status", NumberConstants._0); 78 | // Map condition = new HashMap(); 79 | // condition.put("id", deviceEntity.getId()); 80 | // deviceService.update(data, condition); 81 | // } catch (AppException e) { 82 | // logger.error(e.getMessage()); 83 | // authResult = NumberConstants._1; 84 | // } catch (Exception e) { 85 | // logger.error(e.getMessage(), e); 86 | // authResult = NumberConstants._1; 87 | // } 88 | // 89 | // resultMap.put("authResult", authResult); 90 | // return resultMap; 91 | return null; 92 | } 93 | 94 | public void send(JT808ProtocalPack message, Channel tsession, Map resultMap) throws Exception { 95 | Integer authResult = 0; 96 | // 响应的流水号 97 | byte[] serialnumber = JT808ProtocalPack.generateSerialNumber(tsession); 98 | 99 | JT808ProtocalPack fpp = new JT808ProtocalPack(); 100 | fpp.setId(P_PLATFORM_COMMON_REPLAY); 101 | fpp.setDeviceMobile(message.getDeviceMobile()); 102 | fpp.setSerialNumber(serialnumber); 103 | 104 | ByteBuf buf = Unpooled.buffer(5); 105 | buf.writeBytes(message.getSerialNumber()); 106 | buf.writeBytes(message.getId()); 107 | buf.writeByte(authResult == null ? NumberConstants._1 : authResult); 108 | 109 | fpp.setBody(buf.array()); 110 | sendMessage(tsession, fpp); 111 | } 112 | 113 | public DeviceService getDeviceService() { 114 | return deviceService; 115 | } 116 | 117 | public void setDeviceService(DeviceService deviceService) { 118 | this.deviceService = deviceService; 119 | } 120 | 121 | public DeviceJt808Service getDeviceJt808Service() { 122 | return deviceJt808Service; 123 | } 124 | 125 | public void setDeviceJt808Service(DeviceJt808Service deviceJt808Service) { 126 | this.deviceJt808Service = deviceJt808Service; 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/device/up/UnRegistHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler.device.up; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Component; 9 | 10 | import com.mortals.framework.exception.AppException; 11 | import com.mortals.framework.util.StringUtils; 12 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractDeviceCommandHandler; 13 | import com.mortals.iot.module.device.model.DeviceEntity; 14 | import com.mortals.iot.module.device.model.DeviceQuery; 15 | import com.mortals.iot.module.device.service.DeviceJt808Service; 16 | import com.mortals.iot.module.device.service.DeviceService; 17 | import com.mortals.iot.protocol.jt808.constant.NumberConstants; 18 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 19 | import com.mortals.iot.protocol.jt808.entity.MessageID; 20 | import com.mortals.iot.protocol.jt808.entity.Session; 21 | import com.mortals.iot.protocol.jt808.entity.SessionManager; 22 | import com.mortals.iot.protocol.jt808.util.HexUtils; 23 | 24 | import io.netty.buffer.ByteBuf; 25 | import io.netty.buffer.Unpooled; 26 | import io.netty.channel.Channel; 27 | 28 | /** 29 | * 30 | * @ClassName: UnregistHandler 31 | * @Description: 终端注销0x0101:服务端收到终端的注销信息 32 | * @Company iot 33 | * @author 34 | * @version 1.0, 2017-3-20 上午10:25:28 35 | */ 36 | //@Component(value = "p_device_unregist") 37 | public class UnRegistHandler extends AbstractDeviceCommandHandler implements MessageID { 38 | private SessionManager sessionManager = SessionManager.getInstance(); 39 | @Autowired 40 | private DeviceService deviceService; 41 | @Autowired 42 | private DeviceJt808Service deviceJt808Service; 43 | 44 | public Map receive(JT808ProtocalPack message, Channel channel) throws Exception { 45 | Map resultMap = new HashMap(); 46 | Integer unRegistResult = NumberConstants._0; 47 | 48 | try { 49 | String channelId = channel.id().asLongText(); 50 | 51 | // 删除会话信息 52 | Session session = sessionManager.getChannelIdSession(channelId); 53 | sessionManager.removeAuthSession(channelId); 54 | 55 | // 更改设备状态为离线 56 | if (session == null || StringUtils.isEmpty(session.getDeviceId())) { 57 | throw new AppException("设备会话信息异常,channelId:" + channelId + (session == null ? "" : ",deviceId:" + session.getDeviceId())); 58 | } 59 | DeviceQuery deviceQuery = new DeviceQuery(); 60 | deviceQuery.setDeviceId(session.getDeviceId()); 61 | List deviceList = deviceService.find(deviceQuery, null); 62 | // device信息为空 63 | if (deviceList == null || deviceList.size() <= 0 || deviceList.get(NumberConstants._0) == null 64 | || deviceList.get(NumberConstants._0).getId() == null) { 65 | throw new AppException("device信息为空,deviceId:" + session.getDeviceId()); 66 | } 67 | if (deviceList.size() > 1) { 68 | throw new AppException("device信息不唯一,deviceId:" + session.getDeviceId()); 69 | } 70 | Map data = new HashMap(); 71 | data.put("status", NumberConstants._1); 72 | Map condition = new HashMap(); 73 | condition.put("id", deviceList.get(NumberConstants._0).getId()); 74 | deviceService.update(data, condition); 75 | 76 | // 删除设备与车辆注册关系 77 | deviceJt808Service.remove(new Long[] { deviceList.get(NumberConstants._0).getId() }, null); 78 | } catch (AppException e) { 79 | logger.error(e.getMessage()); 80 | unRegistResult = NumberConstants._1; 81 | } catch (Exception e) { 82 | logger.error(e.getMessage(), e); 83 | unRegistResult = NumberConstants._1; 84 | } 85 | 86 | resultMap.put("unRegistResult", unRegistResult); 87 | return resultMap; 88 | } 89 | 90 | public void send(JT808ProtocalPack message, Channel tsession, Map resultMap) throws Exception { 91 | Integer unRegistResult = (Integer) resultMap.get("unRegistResult"); 92 | // 响应的流水号 93 | byte[] serialnumber = JT808ProtocalPack.generateSerialNumber(tsession); 94 | 95 | JT808ProtocalPack fpp = new JT808ProtocalPack(); 96 | fpp.setId(P_PLATFORM_COMMON_REPLAY); 97 | fpp.setDeviceMobile(message.getDeviceMobile()); 98 | fpp.setSerialNumber(serialnumber); 99 | 100 | ByteBuf buf = Unpooled.buffer(5); 101 | buf.writeBytes(message.getSerialNumber()); 102 | buf.writeBytes(message.getId()); 103 | buf.writeByte(unRegistResult); 104 | 105 | fpp.setBody(buf.array()); 106 | fpp.setProperty(HexUtils.intToByteArray(buf.array().length)); 107 | sendMessage(tsession, fpp); 108 | } 109 | 110 | public DeviceService getDeviceService() { 111 | return deviceService; 112 | } 113 | 114 | public void setDeviceService(DeviceService deviceService) { 115 | this.deviceService = deviceService; 116 | } 117 | 118 | public DeviceJt808Service getDeviceJt808Service() { 119 | return deviceJt808Service; 120 | } 121 | 122 | public void setDeviceJt808Service(DeviceJt808Service deviceJt808Service) { 123 | this.deviceJt808Service = deviceJt808Service; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/handler/MallMessageHandler.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.handler; 2 | 3 | import org.apache.kafka.clients.consumer.ConsumerRecord; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.kafka.annotation.KafkaListener; 8 | import org.springframework.stereotype.Component; 9 | 10 | import com.alibaba.fastjson.JSON; 11 | import com.alibaba.fastjson.JSONObject; 12 | import com.mortals.framework.exception.AppException; 13 | import com.mortals.framework.util.StringUtils; 14 | import com.mortals.iot.handler.protocol808.collect.commons.SpringContextUtils; 15 | import com.mortals.iot.handler.protocol808.collect.protocol.handler.service.AbstractMallCommandHandler; 16 | import com.mortals.iot.module.device.service.impl.DeviceServiceImpl; 17 | import com.mortals.iot.protocol.jt808.constant.SystemConstants; 18 | import com.mortals.iot.protocol.jt808.entity.JT808ProtocalPack; 19 | import com.mortals.iot.protocol.jt808.entity.Session; 20 | import com.mortals.iot.protocol.jt808.entity.SessionManager; 21 | import com.mortals.iot.protocol.jt808.util.HexUtils; 22 | import com.mortals.iot.protocol.jt808.util.MallPacketUtils; 23 | 24 | import io.netty.buffer.Unpooled; 25 | import io.netty.channel.Channel; 26 | import io.netty.channel.ChannelFuture; 27 | 28 | @Component 29 | public class MallMessageHandler { 30 | private final Logger logger = LoggerFactory.getLogger(MallMessageHandler.class); 31 | private SessionManager sessionManager = SessionManager.getInstance(); 32 | // @Autowired 33 | DeviceServiceImpl deviceServiceImpl; 34 | 35 | /** 36 | * 接收处理App端发到kafka的消息 37 | * 38 | * @param record 39 | */ 40 | @KafkaListener(topics = { "commandreq" }) 41 | public void appMessageRecievied(ConsumerRecord record) { 42 | try { 43 | String message = (String) record.value(); 44 | logger.info("收到Mall消息:" + message); 45 | JSONObject jsonObjectMessage = JSON.parseObject(message); 46 | Integer messageId = jsonObjectMessage.getInteger(SystemConstants.JSON_KEY_ACTION); 47 | 48 | // mall处理数据为协议数据 49 | JT808ProtocalPack pack = mallHander(message, messageId); 50 | // 对设备通道进行数据发送 51 | deviceHander(jsonObjectMessage, pack); 52 | } catch (AppException e) { 53 | logger.error("处理mall消息异常" + e.getMessage()); 54 | } catch (Exception e) { 55 | logger.error("处理mall消息异常" + e.getMessage(), e); 56 | } 57 | } 58 | 59 | private JT808ProtocalPack mallHander(String message, Integer messageId) throws Exception { 60 | String messageIdStringValue = messageId != null ? HexUtils.bytesToHexString(HexUtils.intToByte2Array(messageId)) : null; 61 | String handlerBeanName = StringUtils.isNotEmpty(messageIdStringValue) ? (String) MallPacketUtils.getValue(messageIdStringValue) : null; 62 | AbstractMallCommandHandler handler = StringUtils.isNotEmpty(handlerBeanName) ? SpringContextUtils.getBean(handlerBeanName) : null; 63 | if (handler == null) { 64 | throw new AppException("根据消息没有找到对应的消息处理器"); 65 | } 66 | 67 | // 返回协议对象 68 | JT808ProtocalPack jt808ProtocalPack = handler.receive(message); 69 | return jt808ProtocalPack; 70 | } 71 | 72 | private void deviceHander(JSONObject jsonObjectMessage, JT808ProtocalPack jt808ProtocalPack) { 73 | if (jt808ProtocalPack == null) { 74 | throw new AppException("转换后的jt808协议对象为空"); 75 | } 76 | String deviceId = jsonObjectMessage.getString(SystemConstants.JSON_KEY_DEVICE_ID); 77 | String serialNumber = jsonObjectMessage.getString(SystemConstants.JSON_KEY_SERIAL_NUMBER); 78 | 79 | // 根据设备id获取netty tcp连接 80 | if (StringUtils.isEmpty(deviceId)) { 81 | throw new AppException("终端Id信息为空"); 82 | } 83 | Session session = sessionManager.getDeviceIdSession(deviceId); 84 | if (session == null || session.getChannel() == null || StringUtils.isEmpty(session.getId())) { 85 | throw new AppException("终端会话信息不存在"); 86 | } 87 | if (!session.getChannel().isActive()) { 88 | throw new AppException("终端会话信息已断开"); 89 | } 90 | 91 | int currentFlowId = session.currentFlowId(); 92 | jt808ProtocalPack.setSerialNumber(HexUtils.intToByte2Array(currentFlowId)); 93 | jt808ProtocalPack.setDeviceMobile(sessionManager.getDeviceIdPhone(deviceId)); 94 | 95 | // 使用对应的device channel进行发送 96 | sendMessage(session.getChannel(), jt808ProtocalPack); 97 | 98 | // 存储jt808协议流水号与app端serialNumber映射关系 99 | if (StringUtils.isNotEmpty(serialNumber)) { 100 | sessionManager.putFlowIdSerialNumber(session.getId() + "-" + currentFlowId, serialNumber); 101 | } 102 | } 103 | 104 | /** 105 | * 发送数据到netty通道 106 | * 107 | * @param channel 108 | * @param message 109 | * @throws Exception 110 | */ 111 | public void sendMessage(Channel channel, JT808ProtocalPack message) { 112 | try { 113 | byte[] resultData = message.pack(); 114 | 115 | if (resultData != null && resultData.length > 0) { 116 | ChannelFuture channelFuture = channel.writeAndFlush(Unpooled.copiedBuffer(resultData)); 117 | if (!channelFuture.isSuccess()) { 118 | logger.error("发送jt808消息到设备出错:", channelFuture.cause()); 119 | } else { 120 | logger.info("发送jt808消息:" + HexUtils.bytesToHexString(resultData)); 121 | } 122 | } else { 123 | logger.info("jt808消息为空"); 124 | } 125 | } catch (Exception e) { 126 | logger.info("消息发送出错", e); 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/com/mortals/iot/handler/protocol808/collect/protocol/entity/client/Course.java: -------------------------------------------------------------------------------- 1 | package com.mortals.iot.handler.protocol808.collect.protocol.entity.client; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStream; 6 | import java.util.ArrayList; 7 | 8 | import com.mortals.iot.protocol.jt808.util.DataHelper; 9 | 10 | /** 11 | * 设置路线 消息ID:0x8606 12 | * 13 | * @author 14 | * @package com.mortals.iot.handler.protocol808.collect.comm.protocol.message.client 15 | * @copyright iot 16 | * @date:2017-4-18 上午11:03:15 17 | */ 18 | public class Course { 19 | // 路线ID 20 | private int courseID; 21 | /** 22 | * 路线属性 2 16位 2进制 23 | */ 24 | private String courseValue; 25 | /** 26 | * 起始时间 BCD[6] YY-MM-DD-hh-mm-ss 27 | */ 28 | private String startTime; 29 | /** 30 | * 结束时间 BCD[6] YY-MM-DD-hh-mm-ss 31 | */ 32 | private String endTime; 33 | /** 34 | * 路线总拐点数 2字节 不大于 32767 35 | */ 36 | private int InflectionNum; 37 | /** 38 | * 拐点项 39 | */ 40 | private ArrayList course = new ArrayList(); 41 | 42 | /** 43 | * 初始化 44 | */ 45 | public Course() { 46 | this.setStartTime("000000000000"); 47 | this.setEndTime("000000000000"); 48 | 49 | } 50 | 51 | /** 52 | * 53 | * @param out 54 | * @return 55 | * @throws IOException 56 | */ 57 | public OutputStream encoder(OutputStream out) throws IOException { 58 | int size = 0; 59 | size += DataHelper.getInt(out, courseID); 60 | int value = DataHelper.StringBinaryToInt(courseValue); 61 | size += DataHelper.getShort(out, (short) value); 62 | out.write(DataHelper.string26Bcd(startTime)); 63 | size += 6; 64 | out.write(DataHelper.string26Bcd(endTime)); 65 | size += 6; 66 | size += DataHelper.getShort(out, (short)InflectionNum); 67 | for (CourseT iterable_element : course) { 68 | size += iterable_element.encoder(out, size); 69 | } 70 | 71 | return out; 72 | } 73 | 74 | public void setCourseList(CourseT course) { 75 | this.course.add(course); 76 | } 77 | 78 | public int getCourseID() { 79 | return courseID; 80 | } 81 | 82 | public void setCourseID(int courseID) { 83 | this.courseID = courseID; 84 | } 85 | 86 | public String getStartTime() { 87 | return startTime; 88 | } 89 | 90 | public void setStartTime(String startTime) { 91 | this.startTime = startTime; 92 | } 93 | 94 | public String getEndTime() { 95 | return endTime; 96 | } 97 | 98 | public void setEndTime(String endTime) { 99 | this.endTime = endTime; 100 | } 101 | 102 | 103 | 104 | public int getInflectionNum() { 105 | return InflectionNum; 106 | } 107 | 108 | public void setInflectionNum(int inflectionNum) { 109 | InflectionNum = inflectionNum; 110 | } 111 | 112 | public ArrayList getCourse() { 113 | return course; 114 | } 115 | 116 | public void setCourse(ArrayList course) { 117 | this.course = course; 118 | } 119 | 120 | public String getCourseValue() { 121 | return courseValue; 122 | } 123 | 124 | public void setCourseValue(String courseValue) { 125 | this.courseValue = courseValue; 126 | } 127 | 128 | @Override 129 | public int hashCode() { 130 | final int prime = 31; 131 | int result = 1; 132 | result = prime * result + InflectionNum; 133 | result = prime * result + ((course == null) ? 0 : course.hashCode()); 134 | result = prime * result + courseID; 135 | result = prime * result 136 | + ((courseValue == null) ? 0 : courseValue.hashCode()); 137 | result = prime * result + ((endTime == null) ? 0 : endTime.hashCode()); 138 | result = prime * result 139 | + ((startTime == null) ? 0 : startTime.hashCode()); 140 | return result; 141 | } 142 | 143 | @Override 144 | public boolean equals(Object obj) { 145 | if (this == obj) 146 | return true; 147 | if (obj == null) 148 | return false; 149 | if (getClass() != obj.getClass()) 150 | return false; 151 | Course other = (Course) obj; 152 | if (InflectionNum != other.InflectionNum) 153 | return false; 154 | if (course == null) { 155 | if (other.course != null) 156 | return false; 157 | } else if (!course.equals(other.course)) 158 | return false; 159 | if (courseID != other.courseID) 160 | return false; 161 | if (courseValue == null) { 162 | if (other.courseValue != null) 163 | return false; 164 | } else if (!courseValue.equals(other.courseValue)) 165 | return false; 166 | if (endTime == null) { 167 | if (other.endTime != null) 168 | return false; 169 | } else if (!endTime.equals(other.endTime)) 170 | return false; 171 | if (startTime == null) { 172 | if (other.startTime != null) 173 | return false; 174 | } else if (!startTime.equals(other.startTime)) 175 | return false; 176 | return true; 177 | } 178 | 179 | @Override 180 | public String toString() { 181 | return "SetCourse [courseID=" + courseID + ", courseValue=" 182 | + courseValue + ", startTime=" + startTime + ", endTime=" 183 | + endTime + ", InflectionNum=" + InflectionNum + ", course=" 184 | + course + "]"; 185 | } 186 | 187 | public static void main(String[] args) throws IOException { 188 | Course cc = new Course(); 189 | cc.setCourseID(1); 190 | cc.setCourseValue("1111111111111111"); 191 | 192 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 193 | cc.encoder(out); 194 | System.err.println(DataHelper.DataToHexString(out.toByteArray())); 195 | 196 | } 197 | 198 | } 199 | --------------------------------------------------------------------------------