From 90c14abd8b3c793c6de089d22e08c855c2dea22d Mon Sep 17 00:00:00 2001 From: xinfengkun Date: Tue, 27 Feb 2024 20:23:58 +0800 Subject: [PATCH] =?UTF-8?q?[630][adas]=20=E7=89=B9=E7=A7=8D=E8=BD=A6?= =?UTF-8?q?=E8=BE=86=E5=91=BD=E4=BB=A4=E4=B8=8B=E5=8F=91=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=9D=A5=E6=BA=90=EF=BC=8C=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=9B=9E=E6=89=A7=E5=8A=9F=E8=83=BD=EF=BC=8CMAP380=E5=BC=80?= =?UTF-8?q?=E5=A7=8B=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../autopilot/MoGoAutopilotControlProvider.kt | 48 ++- .../autopilot/adapter/MoGoAdasListenerImpl.kt | 11 + .../IMoGoReceiveReceivedAckListener.kt | 17 + ...CallerReceiveReceivedAckListenerManager.kt | 22 ++ .../zhjt/mogo/adas}/common/MessageType.java | 56 +-- .../zhjt/mogo/adas/data/bean/ReceivedAck.java | 85 +++++ .../src/main/proto/message_pad.proto | 81 ++-- .../src/main/proto/personal/adas.proto | 17 + .../main/proto/special_vehicle_task_cmd.proto | 1 + .../src/main/proto/vehicle_state.proto | 6 +- libraries/mogo-adas/build.gradle | 1 + .../zhidao/support/adas/high/AdasChannel.java | 224 +++++++---- .../zhidao/support/adas/high/AdasManager.java | 64 +++- .../zhidao/support/adas/high/AdasOptions.java | 357 ++++++++++++------ .../support/adas/high/IAdasNetCommApi.java | 10 +- .../support/adas/high/OnAdasListener.java | 11 +- .../adas/high/common/AppPreferenceHelper.java | 83 ---- .../support/adas/high/common/Constants.java | 43 +++ .../adas/high/common/CupidLogUtils.java | 14 +- .../adas/high/common/IPreferencesHelper.java | 39 -- .../support/adas/high/common/MMKVUtils.java | 156 ++++++++ .../adas/high/common/MessageIdGenerator.java | 125 ++++++ .../adas/high/common/ReceivedAckManager.java | 153 ++++++++ .../adas/high/msg/CarConfigRespMessage.java | 2 +- .../adas/high/msg/MyMessageFactory.java | 2 +- .../support/adas/high/protocol/RawPack.java | 28 +- .../support/adas/high/socket/FpgaSocket.java | 60 ++- .../high/subscribe/SubscribeInterface.java | 9 +- .../subscribe/SubscribeInterfaceOption.java | 49 +++ .../subscribe/SubscribeInterfaceOptions.java | 71 ---- 30 files changed, 1326 insertions(+), 519 deletions(-) create mode 100644 core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoReceiveReceivedAckListener.kt create mode 100644 core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/CallerReceiveReceivedAckListenerManager.kt rename libraries/{mogo-adas/src/main/java/com/zhidao/support/adas/high => mogo-adas-data/src/main/java/com/zhjt/mogo/adas}/common/MessageType.java (78%) create mode 100644 libraries/mogo-adas-data/src/main/java/com/zhjt/mogo/adas/data/bean/ReceivedAck.java create mode 100644 libraries/mogo-adas-data/src/main/proto/personal/adas.proto delete mode 100644 libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/AppPreferenceHelper.java delete mode 100644 libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/IPreferencesHelper.java create mode 100644 libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MMKVUtils.java create mode 100644 libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MessageIdGenerator.java create mode 100644 libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/ReceivedAckManager.java create mode 100644 libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/subscribe/SubscribeInterfaceOption.java delete mode 100644 libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/subscribe/SubscribeInterfaceOptions.java diff --git a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/MoGoAutopilotControlProvider.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/MoGoAutopilotControlProvider.kt index 77b154540b..b9f7aaaa4a 100644 --- a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/MoGoAutopilotControlProvider.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/MoGoAutopilotControlProvider.kt @@ -57,7 +57,7 @@ import com.zhidao.support.adas.high.chain.AdasChain import com.zhidao.support.adas.high.common.Constants import com.zhidao.support.adas.high.common.Constants.IPC_CONNECTION_STATUS import com.zhidao.support.adas.high.common.CupidLogUtils -import com.zhidao.support.adas.high.common.MessageType +import com.zhjt.mogo.adas.common.MessageType import com.zhjt.mogo.adas.data.AdasConstants import com.zhjt.mogo.adas.data.bean.MogoReport import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable @@ -98,6 +98,7 @@ class MoGoAutopilotControlProvider : override fun init(context: Context) { CallerLogger.i("$M_D_C$TAG", "初始化工控机连接……") mContext = context + AdasManager.getInstance().init(context) runCatching { // 初始化ADAS 域控制器 CupidLogUtils.setEnableLog(false) @@ -115,15 +116,15 @@ class MoGoAutopilotControlProvider : // .setMessageTypes(messageTypes).build() // "192.168.1.102" - val options = AdasOptions.Builder() - .setIpcConnectionMode(AdasOptions.IPC_CONNECTION_MODE.FIXATION) - .setIpcFixationIP(AdasManager.getInstance().getIPCFixationIPList(mContext)) - .setClient(false) + val options = AdasOptions.newBuilder() + .setConnectionMode(AdasOptions.IPC_CONNECTION_MODE.PING) + .setPingAddressList(AdasManager.getInstance().ipcFixationIPList) + .setPassenger(false) .setUnableLaunchAutopilotGear(FunctionBuildConfig.unableLaunchAutopilotGear) // .setSubscribeInterfaceOptions(subscribeInterfaceOptions)// .build() - AdasManager.getInstance().create(context, options, MoGoAdasMsgConnectStatusListenerImpl()) + AdasManager.getInstance().create(options, MoGoAdasMsgConnectStatusListenerImpl()) //////////////////////////////////注意先后顺序,AdasManager.getInstance().create后才可以设置监听///////////////////////////////////////////// // 监听ADAS-SDK获取到的工控机数据 AdasManager.getInstance().setOnAdasListener(MoGoAdasListenerImpl()) @@ -213,12 +214,12 @@ class MoGoAutopilotControlProvider : directConnect(context) } else { val options = AdasOptions - .Builder() - .setClient(true) + .newBuilder() + .setPassenger(true) .setUnableLaunchAutopilotGear(FunctionBuildConfig.unableLaunchAutopilotGear) .build() AdasManager.getInstance() - .create(context, options, MoGoAdasMsgConnectStatusListenerImpl()) + .create(options, MoGoAdasMsgConnectStatusListenerImpl()) // 监听ADAS-SDK获取到的工控机数据 AdasManager.getInstance().setOnAdasListener(MoGoAdasListenerImpl()) // 接收司机屏发过来的感知、定位等数据 @@ -243,13 +244,13 @@ class MoGoAutopilotControlProvider : private fun directConnect(context: Context) { val options = AdasOptions - .Builder() - .setIpcConnectionMode(AdasOptions.IPC_CONNECTION_MODE.FIXATION) - .setIpcFixationIP(AdasManager.getInstance().getIPCFixationIPList(mContext)) - .setClient(false)// 乘客端直连工控机改为false + .newBuilder() + .setConnectionMode(AdasOptions.IPC_CONNECTION_MODE.PING) + .setPingAddressList(AdasManager.getInstance().ipcFixationIPList) + .setPassenger(false)// 乘客端直连工控机改为false .setUnableLaunchAutopilotGear(FunctionBuildConfig.unableLaunchAutopilotGear) .build() - AdasManager.getInstance().create(context, options, MoGoAdasMsgConnectStatusListenerImpl()) + AdasManager.getInstance().create(options, MoGoAdasMsgConnectStatusListenerImpl()) //////////////////////////////////注意先后顺序,AdasManager.getInstance().create后才可以设置监听///////////////////////////////////////////// // 监听ADAS-SDK获取到的工控机数据 AdasManager.getInstance().setOnAdasListener(MoGoAdasListenerImpl()) @@ -303,12 +304,19 @@ class MoGoAutopilotControlProvider : SharedPrefsMgr.getInstance().putString(MoGoConfig.AUTOPILOT_IP, autoPilotIp) } // 设置IP地址 - AdasManager.getInstance().adasOptions.isClient = false - AdasManager.getInstance().adasOptions.ipcConnectionMode = - AdasOptions.IPC_CONNECTION_MODE.ASSIGN - AdasManager.getInstance().adasOptions.ipcAssignIP = autoPilotIp - // 打开通讯连接 - AdasManager.getInstance().connect() + val options = AdasOptions.newBuilder() + .setPassenger(false) + .setConnectionMode(AdasOptions.IPC_CONNECTION_MODE.SPECIFIED) + .setSpecifiedAddress(autoPilotIp) + .build() + AdasManager.getInstance().create(options, MoGoAdasMsgConnectStatusListenerImpl()) + +// AdasManager.getInstance().adasOptions.isClient = false +// AdasManager.getInstance().adasOptions.ipcConnectionMode = +// AdasOptions.IPC_CONNECTION_MODE.ASSIGN +// AdasManager.getInstance().adasOptions.ipcAssignIP = autoPilotIp +// // 打开通讯连接 +// AdasManager.getInstance().connect() return "" } diff --git a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/adapter/MoGoAdasListenerImpl.kt b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/adapter/MoGoAdasListenerImpl.kt index a8520859ea..d19aa5163e 100644 --- a/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/adapter/MoGoAdasListenerImpl.kt +++ b/core/function-impl/mogo-core-function-datacenter/src/main/java/com/mogo/eagle/core/function/datacenter/autopilot/adapter/MoGoAdasListenerImpl.kt @@ -60,6 +60,7 @@ import com.zhjt.mogo.adas.data.bean.AdasParam import com.zhidao.support.adas.high.common.ProtocolStatus import com.zhjt.mogo.adas.data.AiCloudTask import com.zhjt.mogo.adas.data.bean.AutopilotStatistics +import com.zhjt.mogo.adas.data.bean.ReceivedAck import com.zhjt.mogo.adas.data.bean.UnableLaunchData import com.zhjt.mogo.adas.data.bean.UnableLaunchReason import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable @@ -930,6 +931,16 @@ class MoGoAdasListenerImpl : OnAdasListener { CallerParallelDrivingActionsListenerManager.invokeParallelDrivingAbility(isParallelDrivingAbility) } + /** + * 回执消息 + * PAD发送数据到域控的回执消息,是否存在回执详情参见{@link MessageType} 枚举 TYPE_SEND_XXX_XXX 消息回执超时时间大于0的表示需要回执 + * + * @param receivedAck 回执 + */ + override fun onReceiveReceivedAck(receivedAck: ReceivedAck) { + CallerReceiveReceivedAckListenerManager.invokeReceiveReceivedAck(receivedAck) + } + @ChainLog( linkChainLog = CHAIN_TYPE_SOCKET_AUTOPILOT, linkCode = CHAIN_SOURCE_ADAS, diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoReceiveReceivedAckListener.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoReceiveReceivedAckListener.kt new file mode 100644 index 0000000000..4bf4d6d113 --- /dev/null +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/autopilot/IMoGoReceiveReceivedAckListener.kt @@ -0,0 +1,17 @@ +package com.mogo.eagle.core.function.api.autopilot + +import com.zhjt.mogo.adas.data.bean.ReceivedAck + +/** + * 回执消息 + * PAD发送数据到域控的回执消息,是否存在回执详情参见{@link MessageType} 枚举 TYPE_SEND_XXX_XXX 消息回执超时时间大于0的表示需要回执 + */ +interface IMoGoReceiveReceivedAckListener { + + /** + * 回执消息 + * + * @param receivedAck 回执 + */ + fun onReceiveReceivedAck(receivedAck: ReceivedAck) +} \ No newline at end of file diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/CallerReceiveReceivedAckListenerManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/CallerReceiveReceivedAckListenerManager.kt new file mode 100644 index 0000000000..046b8796ac --- /dev/null +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/autopilot/CallerReceiveReceivedAckListenerManager.kt @@ -0,0 +1,22 @@ +package com.mogo.eagle.core.function.call.autopilot + +import com.mogo.eagle.core.function.api.autopilot.IMoGoReceiveReceivedAckListener +import com.mogo.eagle.core.function.call.base.CallerBase +import com.zhjt.mogo.adas.data.bean.ReceivedAck + +/** + * 回执消息 + * PAD发送数据到域控的回执消息,是否存在回执详情参见{@link MessageType} 枚举 TYPE_SEND_XXX_XXX 消息回执超时时间大于0的表示需要回执 + */ +object CallerReceiveReceivedAckListenerManager : CallerBase() { + + /** + * 金旅M1 + */ + fun invokeReceiveReceivedAck(receivedAck: ReceivedAck) { + M_LISTENERS.forEach { + val listener = it.value + listener.onReceiveReceivedAck(receivedAck) + } + } +} \ No newline at end of file diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MessageType.java b/libraries/mogo-adas-data/src/main/java/com/zhjt/mogo/adas/common/MessageType.java similarity index 78% rename from libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MessageType.java rename to libraries/mogo-adas-data/src/main/java/com/zhjt/mogo/adas/common/MessageType.java index 9dc323cf05..79e7cf309e 100644 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MessageType.java +++ b/libraries/mogo-adas-data/src/main/java/com/zhjt/mogo/adas/common/MessageType.java @@ -1,13 +1,11 @@ -package com.zhidao.support.adas.high.common; +package com.zhjt.mogo.adas.common; import mogo.telematics.pad.MessagePad; /** * 工控机发送或接收的类型 - * 工控机接收接口必须包含:TYPE_RECEIVE - * 目前收发相同的Type: - * * MessagePad.MessageType.MsgTypeBagManagerCmd - * * MessagePad.MessageType.MsgTypeTaskCmd + * 工控机接收接口必须包含TYPE_RECEIVE + * 消息回执文档:http://wiki.zhidaohulian.com/pages/viewpage.action?pageId=119731359 * * @author nie yunlong * @description 请求值 @@ -35,14 +33,14 @@ public enum MessageType { TYPE_RECEIVE_BASIC_INFO_REQ(MessagePad.MessageType.MsgTypeBasicInfoReq, "自动驾驶设备基础信息请求"), TYPE_SEND_BASIC_INFO_RESP(MessagePad.MessageType.MsgTypeBasicInfoResp, "自动驾驶设备基础信息应答"), - TYPE_SEND_SET_AUTOPILOT_MODE_REQ(MessagePad.MessageType.MsgTypeSetAutopilotModeReq, "设置自动驾驶模式 启动自动驾驶"), - TYPE_SEND_SET_DEMO_MODE_REQ(MessagePad.MessageType.MsgTypeSetDemoModeReq, "设置演示模式"), + TYPE_SEND_SET_AUTOPILOT_MODE_REQ(MessagePad.MessageType.MsgTypeSetAutopilotModeReq, "设置自动驾驶模式 启动自动驾驶", 5000), + TYPE_SEND_SET_DEMO_MODE_REQ(MessagePad.MessageType.MsgTypeSetDemoModeReq, "设置演示模式", 5000), TYPE_SEND_CAR_CONFIG_REQ(MessagePad.MessageType.MsgTypeCarConfigReq, "车机基础信息请求"), TYPE_RECEIVE_CAR_CONFIG_RESP(MessagePad.MessageType.MsgTypeCarConfigResp, "车机基础信息应答"), TYPE_SEND_RECORD_CAUSE(MessagePad.MessageType.MsgTypeRecordCause, "记录人工接管原因"), TYPE_SEND_RECORD_DATA(MessagePad.MessageType.MsgTypeRecordData, "数据采集请求"), TYPE_RECEIVE_RECORD_RESULT(MessagePad.MessageType.MsgTypeRecordResult, "数据采集结果"), - TYPE_SEND_SET_AUTOPILOT_SPEED_REQ(MessagePad.MessageType.MsgTypeSetAutopilotSpeedReq, "设置自动驾驶最大速度"), + TYPE_SEND_SET_AUTOPILOT_SPEED_REQ(MessagePad.MessageType.MsgTypeSetAutopilotSpeedReq, "设置自动驾驶最大速度", 5000), TYPE_SEND_GLOBAL_PATH_REQ(MessagePad.MessageType.MsgTypeGlobalPathReq, "自动驾驶路径请求"), TYPE_RECEIVE_GLOBAL_PATH_RESP(MessagePad.MessageType.MsgTypeGlobalPathResp, "自动驾驶路径应答"), @Deprecated//MAP290开始此接口弃用 @@ -50,32 +48,38 @@ public enum MessageType { @Deprecated TYPE_RECEIVE_WARN(MessagePad.MessageType.MsgTypeWarn, "预警数据"), TYPE_RECEIVE_ARRIVAL_NOTIFICATION(MessagePad.MessageType.MsgTypeArrivalNotification, "到站提醒"), - TYPE_SEND_SYSTEM_CMD_REQ(MessagePad.MessageType.MsgTypeSystemCmdReq, "系统命令请求, 比如系统重启,启用新镜像"), - TYPE_SEND_TRAJECTORY_DOWNLOAD_REQ(MessagePad.MessageType.MsgTypeTrajectoryDownloadReq, "轨迹下载请求"), + TYPE_SEND_SYSTEM_CMD_REQ(MessagePad.MessageType.MsgTypeSystemCmdReq, "系统命令请求", 5000), + TYPE_SEND_TRAJECTORY_DOWNLOAD_REQ(MessagePad.MessageType.MsgTypeTrajectoryDownloadReq, "轨迹下载请求", 5000), + @Deprecated//HQ、M1 MAP350开始弃用,其他车型MAP360开始弃用 TYPE_SEND_STATUS_QUERY_REQ(MessagePad.MessageType.MsgTypeStatusQueryReq, "状态查询请求"), + @Deprecated//HQ、M1 MAP350开始弃用,其他车型MAP360开始弃用 TYPE_RECEIVE_STATUS_QUERY_RESP(MessagePad.MessageType.MsgTypeStatusQueryResp, "状态查询应答"), - TYPE_SEND_SET_RAIN_MODE_REQ(MessagePad.MessageType.MsgTypeSetRainModeReq, "设置雨天模式"), + TYPE_SEND_SET_RAIN_MODE_REQ(MessagePad.MessageType.MsgTypeSetRainModeReq, "设置雨天模式", 5000), TYPE_SEND_RECORD_DATA_CONFIG_REQ(MessagePad.MessageType.MsgTypeRecordDataConfigReq, "数据采集配置查询"), TYPE_RECEIVE_RECORD_DATA_CONFIG_RESP(MessagePad.MessageType.MsgTypeRecordDataConfigResp, "数据采集配置"), - TYPE_SEND_OPERATOR_CMD_REQ(MessagePad.MessageType.MsgTypeOperatorCmdReq, "操控指令"), - TYPE_SEND_SUBSCRIBE_DATA_REQ(MessagePad.MessageType.MsgTypeSubscribeDataReq, "数据订阅、取消订阅请求"), - TYPE_SEND_SPECIAL_VEHICLE_TASK_CMD(MessagePad.MessageType.MsgTypeSpecialVehicleTaskCmd, "特种车辆命令"), - TYPE_SEND_SET_PARAM_REQ(MessagePad.MessageType.MsgTypeSetParamReq, "设置参数命令"), + TYPE_SEND_OPERATOR_CMD_REQ(MessagePad.MessageType.MsgTypeOperatorCmdReq, "操控指令", 5000), + TYPE_SEND_SUBSCRIBE_DATA_REQ(MessagePad.MessageType.MsgTypeSubscribeDataReq, "数据订阅、取消订阅请求", 5000), + TYPE_SEND_SPECIAL_VEHICLE_TASK_CMD(MessagePad.MessageType.MsgTypeSpecialVehicleTaskCmd, "特种车辆命令", 5000), + TYPE_SEND_SET_PARAM_REQ(MessagePad.MessageType.MsgTypeSetParamReq, "设置参数命令", 5000), TYPE_SEND_TRIP_INFO_REQ(MessagePad.MessageType.MsgTypeTripInfoEvent, "行程信息"), TYPE_SEND_BAG_MANAGER_CMD(MessagePad.MessageType.MsgTypeBagManagerCmd, "Bag管理请求"), TYPE_RECEIVE_BAG_MANAGER_CMD(MessagePad.MessageType.MsgTypeBagManagerCmd, "Bag管理应答"), - TYPE_SEND_PLANNING_CMD(MessagePad.MessageType.MsgTypePlanningCmd, "给Planning指令"), - TYPE_SEND_SET_PARAM_REQ_V2(MessagePad.MessageType.MsgTypeSetParamReqV2, "设置参数命令V2"), + TYPE_SEND_PLANNING_CMD(MessagePad.MessageType.MsgTypePlanningCmd, "给Planning指令", 5000), + TYPE_SEND_SET_PARAM_REQ_V2(MessagePad.MessageType.MsgTypeSetParamReqV2, "设置参数命令V2", 5000), TYPE_RECEIVE_V2N_CONGESTION_EVENT(MessagePad.MessageType.MsgTypeV2nCongestionEvent, "主车附近事件推送"), TYPE_RECEIVE_V2N_GLOBAL_PATH_EVENTS(MessagePad.MessageType.MsgTypeV2nGlobalPathEvents, "主车路径全局事件推送"), TYPE_SEND_GET_PARAM_REQ(MessagePad.MessageType.MsgTypeGetParamReq, "参数获取请求"), TYPE_RECEIVE_GET_PARAM_RESP(MessagePad.MessageType.MsgTypeGetParamResp, "参数获取应答"), - TYPE_SEND_SWEEPER_CLOUD_TASK_CMD(MessagePad.MessageType.MsgTypeTaskCmd, "发送清扫车指令到云控"), - TYPE_RECEIVE_SWEEPER_CLOUD_TASK_CMD(MessagePad.MessageType.MsgTypeTaskCmd, "云控下发清扫车任务指令"), + TYPE_SEND_SWEEPER_CLOUD_TASK_CMD(MessagePad.MessageType.MsgTypeTaskCmd, "发送清扫车指令到云控", 5000), + TYPE_RECEIVE_SWEEPER_CLOUD_TASK_CMD(MessagePad.MessageType.MsgTypeTaskCmd, "云控下发清扫车任务指令", 5000), TYPE_SEND_FSM_STATUS_REASON_QUERY_REQ(MessagePad.MessageType.MsgTypeFSMStatusReasonQueryReq, "FSM状态原因查询"), TYPE_RECEIVE_FSM_STATUS_REASON_QUERY_RESP(MessagePad.MessageType.MsgTypeFSMStatusReasonQueryResp, "FSM状态原因查询应答"), - TYPE_SEND_PARALLEL_DRIVING_REQ(MessagePad.MessageType.MsgTypeParallelDrivingCmd, "平行驾驶请求"), - TYPE_RECEIVE_PARALLEL_DRIVING_STATUS(MessagePad.MessageType.MsgTypeParallelDrivingCmd, "平行驾驶状态"), + TYPE_SEND_GET_DEBUG_INFO_REQ(MessagePad.MessageType.MsgTypeGetDebugInfo, "Debug信息请求"), + TYPE_RECEIVE_GET_DEBUG_INFO_RESP(MessagePad.MessageType.MsgTypeGetDebugInfo, "Debug信息应答"), + TYPE_SEND_PARALLEL_DRIVING_REQ(MessagePad.MessageType.MsgTypeParallelDrivingCmd, "平行驾驶请求", 5000), + TYPE_RECEIVE_PARALLEL_DRIVING_STATUS(MessagePad.MessageType.MsgTypeParallelDrivingCmd, "平行驾驶状态", 5000), + TYPE_SEND_RECEIVED_ACK(MessagePad.MessageType.MsgTypeReceivedAck, "发送消息回执"), + TYPE_RECEIVE_RECEIVED_ACK(MessagePad.MessageType.MsgTypeReceivedAck, "接收消息回执"), //TODO 透传原始pb文件中不存在以下type。由于Java中无法强转,所以在mogo-adas-data/message_pad.proto中放开注释 TYPE_RECEIVE_PLANNING_DECISION_STATE(MessagePad.MessageType.MsgTypePlanningDecisionState, "Planning决策状态"), TYPE_RECEIVE_SWEEPER_TASK_INDEX_DATA(MessagePad.MessageType.MsgTypeSweeperTaskIndexData, "清扫车指标数据"), @@ -92,9 +96,19 @@ public enum MessageType { */ public final String desc; + /** + * 消息回执超时时间 毫秒 0:表示不需要回执 + */ + public final long timeoutMillis; + MessageType(MessagePad.MessageType typeCode, String desc) { + this(typeCode, desc, 0); + } + + MessageType(MessagePad.MessageType typeCode, String desc, long timeoutMillis) { this.typeCode = typeCode; this.desc = desc; + this.timeoutMillis = timeoutMillis; } diff --git a/libraries/mogo-adas-data/src/main/java/com/zhjt/mogo/adas/data/bean/ReceivedAck.java b/libraries/mogo-adas-data/src/main/java/com/zhjt/mogo/adas/data/bean/ReceivedAck.java new file mode 100644 index 0000000000..f7201f5d46 --- /dev/null +++ b/libraries/mogo-adas-data/src/main/java/com/zhjt/mogo/adas/data/bean/ReceivedAck.java @@ -0,0 +1,85 @@ +package com.zhjt.mogo.adas.data.bean; + + +import com.google.protobuf.TextFormat; +import com.zhjt.mogo.adas.common.MessageType; +import com.zhjt.mogo.adas.utils.ByteUtil; + +import mogo.telematics.pad.MessagePad; + +/** + * 消息回执 + */ +public class ReceivedAck { + /** + * 是否超时,如果超时 receiveTime和receivedAck不会被赋值 + * 超时时间定义在{@link MessageType}中,根据定义的超时时间实际返回的超时时间 ±1 秒内 + */ + private boolean isTimeout = false; + private final long sendTime;//数据发送时间 + private long receiveTime;//回执接收时间 + private final long msgId;//消息ID + private final MessageType messageType;//具体消息 + private final byte[] sendData;//发送的数据 + private MessagePad.ReceivedAck receivedAck;//回执的数据 + + public ReceivedAck(long sendTime, long msgId, MessageType messageType, byte[] sendData) { + this.sendTime = sendTime; + this.msgId = msgId; + this.messageType = messageType; + this.sendData = sendData; + } + + public boolean isTimeout() { + return isTimeout; + } + + public void setTimeout(boolean timeout) { + isTimeout = timeout; + } + + public long getSendTime() { + return sendTime; + } + + public long getReceiveTime() { + return receiveTime; + } + + public void setReceiveTime(long receiveTime) { + this.receiveTime = receiveTime; + } + + public long getMsgId() { + return msgId; + } + + public MessageType getMessageType() { + return messageType; + } + + public byte[] getSendData() { + return sendData; + } + + public MessagePad.ReceivedAck getReceivedAck() { + return receivedAck; + } + + public void setReceivedAck(MessagePad.ReceivedAck receivedAck) { + this.receivedAck = receivedAck; + } + + @Override + public String toString() { + return "{" + + "是否超时=" + isTimeout + + ", 发送时间=" + sendTime + + ", 接收时间=" + receiveTime + + ", 消息ID=" + msgId + + ", 消息类型=" + messageType + + ", 发送数据=" + (sendData == null ? null : ByteUtil.byteArrToHex(sendData)) + + ", 回执数据=" + (receivedAck == null ? null : TextFormat.printer().escapingNonAscii(false).printToString(receivedAck)) + + '}'; + } +} diff --git a/libraries/mogo-adas-data/src/main/proto/message_pad.proto b/libraries/mogo-adas-data/src/main/proto/message_pad.proto index 12f5704b7f..6ac64ee7a6 100644 --- a/libraries/mogo-adas-data/src/main/proto/message_pad.proto +++ b/libraries/mogo-adas-data/src/main/proto/message_pad.proto @@ -13,28 +13,30 @@ enum MessageType { MsgTypeDefault = 0; - MsgTypePlanningDecisionState = 0x00001; //planning决策状态, 透传 - MsgTypeSweeperTaskIndexData = 0x00002; //清扫车指标数据 - MsgTypeObuWarningData = 0x00003; //obu预警事件 + //透传消息列表,不需要明确消息定义, 仅作记录,供鹰眼使用 + MsgTypePlanningDecisionState = 0x00001; //planning决策状态, 透传 定频10hz + MsgTypeSweeperTaskIndexData = 0x00002; //清扫车指标数据 定频10hz + MsgTypeObuWarningData = 0x00003; //obu预警事件 不定频 - MsgTypeTrajectory = 0x10000; //局部轨迹,车前引导线 - MsgTypeTrackedObjects = 0x10001; //障碍物信息 - MsgTypeGnssInfo = 0x10002; //惯导信息 - MsgTypeVehicleState = 0x10003; //底盘信息, 透传底盘状态,pb参考底盘 - MsgTypeAutopilotState = 0x10004; //自动驾驶状态 - MsgTypeReportMessage = 0x10005; //监控事件报告 - MsgTypePerceptionTrafficLight = 0x10006; //感知红绿灯 - MsgTypePredictionObstacleTrajectory = 0x10007; //他车轨迹预测 - MsgTypePointCloud = 0x10008; //点云透传 - MsgTypePlanningObjects = 0x10009; //planning障碍物 - MsgTypeOBU = 0x1000a; //OBU - MsgTypeChassisStates = 0x1000b; //重构后的底盘状态, 透传 - MsgTypeFunctionStates = 0x1000c; //重构后的功能状态, 透传 - MsgTypeBackCameraVideo = 0x1000d; //后部摄像头视频 10hz - MsgTypeM1StitchedVideo = 0x1000e; //m1拼接视频 10hz - MsgTypeSSMState = 0x1000f; //ssm 系统状态 1hz hq m1 MAP350开始支持,其他车型MAP360开始支持 - MsgTypeFMState = 0x10010; //FM状态 1hz bus和清扫车是MAP370开始支持,其他车型MAP360开始支持 + MsgTypeTrajectory = 0x10000; //局部轨迹,车前引导线 定频10hz + MsgTypeTrackedObjects = 0x10001; //障碍物信息 定频10hz + MsgTypeGnssInfo = 0x10002; //惯导信息 定频20hz + MsgTypeVehicleState = 0x10003; //底盘信息, 透传底盘状态,pb参考底盘 定频20hz + MsgTypeAutopilotState = 0x10004; //自动驾驶状态 定频20hz + MsgTypeReportMessage = 0x10005; //系统事件 不定频 + MsgTypePerceptionTrafficLight = 0x10006; //感知红绿灯 定频10hz + MsgTypePredictionObstacleTrajectory = 0x10007; //他车轨迹预测 定频10hz + MsgTypePointCloud = 0x10008; //点云透传 定频1hz + MsgTypePlanningObjects = 0x10009; //planning障碍物 定频10hz + MsgTypeOBU = 0x1000a; //OBU红绿灯, 宜宾df专用, 非常态, 有则定频10hz + MsgTypeChassisStates = 0x1000b; //重构后的底盘状态, 透传 定频20hz + MsgTypeFunctionStates = 0x1000c; //重构后的功能状态, 透传 定频1hz + MsgTypeBackCameraVideo = 0x1000d; //清扫车后部摄像头视频 定频10hz + MsgTypeM1StitchedVideo = 0x1000e; //m1拼接视频 定频10hz + MsgTypeSSMState = 0x1000f; //ssm 系统状态 定频1hz hq m1 MAP350开始支持,其他车型MAP360开始支持 + MsgTypeFMState = 0x10010; //FM状态 定频1hz bus和清扫车是MAP370开始支持,其他车型MAP360开始支持 + //### 以下消息全部不定频 ### MsgTypeBasicInfoReq = 0x10100; //自动驾驶设备基础信息请求 MsgTypeBasicInfoResp = 0x10101; //自动驾驶设备基础信息应答 MsgTypeSetAutopilotModeReq = 0x10102; //设置自动驾驶模式 @@ -47,8 +49,8 @@ enum MessageType MsgTypeSetAutopilotSpeedReq = 0x10109; //设置自动驾驶最大速度 MsgTypeGlobalPathReq = 0x1010a; //自动驾驶路径请求 MsgTypeGlobalPathResp = 0x1010b; //自动驾驶路径应答 - MsgTypeTrafficLightData = 0x1010c; //发送红绿灯数据到工控机 - MsgTypeWarn = 0x1010d; //预警数据 + MsgTypeTrafficLightData = 0x1010c; //发送红绿灯数据到工控机 废弃 + MsgTypeWarn = 0x1010d; //预警数据 废弃 MsgTypeArrivalNotification = 0x1010e; //到站提醒 MsgTypeSystemCmdReq = 0x1010f; //系统命令请求, 比如系统重启,启用新镜像 MsgTypeTrajectoryDownloadReq = 0x10110; //轨迹下载请求 @@ -74,6 +76,7 @@ enum MessageType MsgTypeFSMStatusReasonQueryResp = 0x10124; //fsm状态原因查询应答 MsgTypeGetDebugInfo = 0x10125; //debug信息查询 pad->telematics MsgTypeParallelDrivingCmd = 0x10126; //无人化场景,平行驾驶请求相关指令及状态反馈, 云控<->鹰眼双向透传 + MsgTypeReceivedAck = 0x10127; //消息接收ack, 表示消息已接收到 } message Header @@ -82,6 +85,13 @@ message Header MessageType msgType = 2; //消息类型 double timestamp = 3; //消息发送时间, 单位:秒 double sourceTimestamp = 4; //数据源消息发送时间, 单位:秒 + uint32 needAck = 5; //是否需要接收回执,仅重要消息使用 0: 不需要 1: 需要 +} + +// message definition for MsgTypeReceivedAck +message ReceivedAck +{ + repeated uint64 msgids = 1; //确认收到的msgid列表 } // message definition for MsgTypeTrajectory @@ -111,13 +121,14 @@ enum AdditionalAttribute ATTR_ROAD_CONSTRUCTION = 2; // 道路施工区域 ATTR_STATIC = 3; // 静止障碍物 ATTR_ACCIDENT = 4; // 事故车 + ATTR_ROAD_CONGESTION = 5; // 车辆拥堵 } // message definition for MsgTypeTrackedObjects message SubSource { uint32 source = 1; // TrackedSource=1:1-lidar 2-camera 3-radar 4-vidar 5-falcon - // TrackedSource=2:1-v2v_bsm 2-v2i_rsm 3-v2v_ssm 4-v2n_rsm 5-v2n_rsi 6-v2i_ssm + // TrackedSource=2:1-v2v_bsm 2-v2i_rsm 3-v2v_ssm 4-v2n_rsm 5-v2n_rsi 6-v2i_ssm 7-v2i_rsi string id = 2; //HEX_string -bsm_id } @@ -132,7 +143,8 @@ message TrackedObject uint32 type = 1; //物体类型, 0:Background, 1:Person, 2:Bicycle, 3:Car, 4:MotorCycle, //5:TrafficSign, 6:Bus, 7:CellPhone, 8:Truck, 9:Bottle, 10:TrafficLight, //11:Rider, 12:TriangleRoadblock, 13:WarningTriangle, 100:Unknown, - //501:RoadWork_occupy_0501, 502:RoadWork_break_0502 + //447:TAILBACK 501:RoadWork_occupy_0501, 502:RoadWork_break_0502, + //707:ROAD_CONGESTION double longitude = 2; //经度 double latitude = 3; //纬度 double altitude = 4; //海拔 @@ -155,7 +167,8 @@ message TrackedObject } -message LocalizationInfo{ +message LocalizationInfo +{ double stamp = 1; //seconds float longitude = 2; float latitude = 3; @@ -175,6 +188,7 @@ message TrackedObjects { repeated TrackedObject objs = 1; BlindAreaData blindAreaData = 2; + uint32 collision_risk = 3; //0: no risk 1: risk with a < -5m/s2 2: collision detected } // message definition for MsgTypeGnssInfo @@ -228,7 +242,7 @@ message PlanningObject message PlanningObjects { - repeated PlanningObject objs = 1; + repeated PlanningObject objs = 1; } // message definition for MessageType: MsgTypeOBU @@ -437,11 +451,15 @@ enum SystemCmdType { SYSTEMCMD_NONE = 0; SYSTEMCMD_REBOOT = 1; + SYSTEMCMD_START_NODE = 2; + SYSTEMCMD_STOP_NODE = 3; + SYSTEMCMD_POWER_OFF = 4;//MAP 410上线 } message SystemCmdReq { - SystemCmdType cmdType = 1; // + SystemCmdType cmdType = 1; + uint32 node = 2; //0: default, 1: 前向camera 30 2: lidar 3: 左前radar 4: calib_check node(MAP 410上线) } // message definition for MsgTypeStatusQueryReq @@ -544,6 +562,8 @@ enum DrivingState LANE_AVOID_LEFT_RSI_TRIANGLE = 29; //V2N 三角锥主动向左绕行状态: driving_action:1 表示触发绕行;driving_action:2 表示执行绕行;driving_action:3 表示绕行取消;driving_action:4 表示绕行完成 LANE_AVOID_RIGHT_RSI_TRIANGLE = 30; //V2N 三角锥主动向右绕行状态: driving_action:1 表示触发绕行;driving_action:2 表示执行绕行;driving_action:3 表示绕行取消;driving_action:4 表示绕行完成 WAITING_RSI_TRIANGLE = 31; //V2N 三角锥正在等待变道避让施工场景/静止障碍物: driving_action:1 表示正在等待;driving_action:2 表示等待超时请求平行驾驶 + + OUT_OF_ODD = 32; //超出设计运行范围(北京牌照考试): driving_action:1 表示红灯ODD(快速路信号灯)和绕障ODD(静止车占用部分车道,对向车辆借道行驶) } enum DrivingAction @@ -604,7 +624,7 @@ message PlanningActionMsg //message definition for MsgTypeSetParamReq message SetOneParam { - uint32 type = 1; // 0:default 1:绕障类功能开关(bool) 2:变道绕障的目标障碍物速度阈值(double, m/s) + uint32 type = 1; // 0:default 1:绕障类功能开关(bool) 2:变道绕障的目标障碍物速度阈值(double, m/s),针对低速绕行功能的 // 3:AEB开关(bool) 0:关闭自动紧急制动功能 1:启用自动紧急制动功能 // 4:限制绕障开关(bool) 0:正常绕障 1:限制绕障 默认0 // 5:停车让行线前避让等待开关(bool) 0:停车让行线前无需等待 1:停车让行线前需要等待 默认0 @@ -617,8 +637,9 @@ message SetOneParam // 12: 融合v2n开关(bool) 0:不发给PnC 1:发给Pnc /telematics/fusion/v2n_flag // 13: 融合v2i开关(bool) 0:不发给PnC和鹰眼 1:发给Pnc和鹰眼,默认0 /telematics/fusion/v2i_flag // 14: 融合模式(int) 1:全融合模式 2:盲区模式 3:超视距模式 4:透传模式 5:纯路侧模式,默认1 /telematics/fusion/fusion_mode - // 15: 座椅状态(int) 0:表示仅主驾位有人,1:表示仅副驾位有人,2:表示主驾和副驾同时有人,3:表示仅后排有人,4:表示主驾有人+后排有人,5:表示副驾有人+后排有人,6:表示主驾和副驾同时有人+后排有人,7: 所有座位都无人, 255:缺省 - // 16: 超车的最大速度阈值(double, m/s, 范围[3, 12.5]) + // 15:座椅状态(int) 0:表示仅主驾位有人,1:表示仅副驾位有人,2:表示主驾和副驾同时有人,3:表示仅后排有人,4:表示主驾有人+后排有人,5:表示副驾有人+后排有人,6:表示主驾和副驾同时有人+后排有人,7: 所有座位都无人, 255:缺省 + // 16: 超车的最大速度阈值(double, m/s) T1/T2: 范围[3, 12.5], 默认值10 + // 17: 故障模拟指令(int) default:0, 1:线控失效 string value = 2; // 转成字符串的值 } diff --git a/libraries/mogo-adas-data/src/main/proto/personal/adas.proto b/libraries/mogo-adas-data/src/main/proto/personal/adas.proto new file mode 100644 index 0000000000..63d5a4191c --- /dev/null +++ b/libraries/mogo-adas-data/src/main/proto/personal/adas.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; +package mogo.telematics.pad; +option java_package = "com.zhjt.mogo.adas.data"; + +import "message_pad.proto"; + +//发送的数据ID持久化,只保留最后一条的消息id,每天重新累计 +message LastMessage{ + uint64 msgID = 1; //消息唯一id + uint64 timestamp = 2;//消息发送时间 单位:毫秒 + mogo.telematics.pad.MessageType msgType = 3;//消息类型 +} + + +message MessageIdInfo{ + map lastMessages = 1;// key:data(日期) value:数据 +} diff --git a/libraries/mogo-adas-data/src/main/proto/special_vehicle_task_cmd.proto b/libraries/mogo-adas-data/src/main/proto/special_vehicle_task_cmd.proto index eb8ff009a2..9f4f7d48fb 100644 --- a/libraries/mogo-adas-data/src/main/proto/special_vehicle_task_cmd.proto +++ b/libraries/mogo-adas-data/src/main/proto/special_vehicle_task_cmd.proto @@ -51,4 +51,5 @@ message SpecialVehicleTaskCmd { optional RoboSweeperFuTianTaskCmd robo_sweeper_futian_task_cmd = 2; // 福田清扫车业务指令 optional RoboVanSkywellTaskCmd robo_van_skywell_task_cmd = 3; // 开沃小巴业务指令 optional RoboBusJinlvM1Cmd robo_bus_jinlv_m1_cmd = 4; //金旅定制车m1指令 + optional uint32 source = 5; //消息来源, 0:鹰眼, 1:云端 } diff --git a/libraries/mogo-adas-data/src/main/proto/vehicle_state.proto b/libraries/mogo-adas-data/src/main/proto/vehicle_state.proto index d33fc8b26e..caee5a97e8 100644 --- a/libraries/mogo-adas-data/src/main/proto/vehicle_state.proto +++ b/libraries/mogo-adas-data/src/main/proto/vehicle_state.proto @@ -76,7 +76,7 @@ message DoorState { message DoorStateV2 { optional DoorNumber number = 1; // 车门编号 - optional uint32 status = 2; // 车门开闭状态(0-关, 1-开) + optional uint32 status = 2; // 车门开闭状态(0-关, 1-开, 2-unknown 底盘通信有问题) } message LightState { @@ -121,13 +121,13 @@ message VehicleState { optional bool steer_inference = 23 [default = false]; //方向盘干预 optional bool brake_inference = 24 [default = false]; //制动踏板干预 optional bool accel_inference = 25 [default = false]; //加速踏板干预 - optional bool gear_switch_inference = 26 [default = false]; //档位切换干预 + optional bool gear_switch_inference = 26 [default = false]; //档位切换干预 optional bool location_missing = 27 [default = false]; //未收到定位 optional bool trajectory_missing = 28 [default = false]; //未收到轨迹 optional bool chassis_status_missing = 29 [default = false]; //未收到车辆底盘反馈信息 optional bool brake_light_status = 30 [default = false]; //自驾模式下制动灯状态 optional bool pilot_mode_condition_met = 31 [default = false]; - + optional float steeringSpd = 32 [default = 0]; // steering angle speed in degrees/s optional float leftFrontWheelAngle = 33 [default = 0];//左前轮角度(deg),左负右正 diff --git a/libraries/mogo-adas/build.gradle b/libraries/mogo-adas/build.gradle index 703d837083..52e20e4a23 100644 --- a/libraries/mogo-adas/build.gradle +++ b/libraries/mogo-adas/build.gradle @@ -85,6 +85,7 @@ dependencies { implementation rootProject.ext.dependencies.mogoservicebiz //okhttp3的依赖 implementation 'com.squareup.okhttp3:okhttp:3.12.3' + implementation 'com.tencent:mmkv:1.2.14' implementation project(':libraries:mogo-adas-data') } diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasChannel.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasChannel.java index 8956740bb5..2fc6690469 100644 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasChannel.java +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasChannel.java @@ -23,15 +23,14 @@ import androidx.annotation.Nullable; import com.google.protobuf.InvalidProtocolBufferException; import com.zhidao.support.adas.high.bean.VersionCompatibility; import com.zhidao.support.adas.high.common.AutopilotReview; -import com.zhjt.mogo.adas.utils.ByteUtil; import com.zhidao.support.adas.high.common.Constants; import com.zhidao.support.adas.high.common.CupidLogUtils; import com.zhidao.support.adas.high.common.Define; import com.zhidao.support.adas.high.common.IPCFixationIPHelper; -import com.zhidao.support.adas.high.common.MessageType; import com.zhidao.support.adas.high.common.ParallelDrivingManager; import com.zhidao.support.adas.high.common.ProtocolStatus; import com.zhidao.support.adas.high.common.ReceiveTimeoutManager; +import com.zhidao.support.adas.high.common.ReceivedAckManager; import com.zhidao.support.adas.high.common.RegexUtils; import com.zhidao.support.adas.high.common.autopilot.ability.AutopilotAbilityManager; import com.zhidao.support.adas.high.msg.IMsg; @@ -43,18 +42,21 @@ import com.zhidao.support.adas.high.queue.WSByteQueueManager; import com.zhidao.support.adas.high.queue.WebSocketQueueManager; import com.zhidao.support.adas.high.socket.FpgaSocket; import com.zhidao.support.adas.high.subscribe.SubscribeInterface; -import com.zhidao.support.adas.high.subscribe.SubscribeInterfaceOptions; +import com.zhidao.support.adas.high.subscribe.SubscribeInterfaceOption; import com.zhidao.support.adas.high.thread.DispatchHandler; +import com.zhjt.mogo.adas.common.MessageType; import com.zhjt.mogo.adas.data.AdasConstants; import com.zhjt.mogo.adas.data.AiCloudTask; import com.zhjt.mogo.adas.data.bean.AdasParam; import com.zhjt.mogo.adas.data.bean.AutopilotStatistics; +import com.zhjt.mogo.adas.data.bean.ReceivedAck; import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable; import com.zhjt.mogo.adas.data.sweeper.task.SweeperTask; import com.zhjt.mogo.adas.data.sweeper.task.cloud.s_r.SweeperTaskCloudSuspendResume; import com.zhjt.mogo.adas.data.sweeper.task.confirm.SweeperTaskConfirm; import com.zhjt.mogo.adas.data.sweeper.task.s_r.SweeperTaskSuspendResume; import com.zhjt.mogo.adas.data.sweeper.task.stop.SweeperTaskStop; +import com.zhjt.mogo.adas.utils.ByteUtil; import com.zhjt.service.chain.ChainLog; import java.util.HashMap; @@ -67,6 +69,7 @@ import java.util.TimerTask; import java.util.concurrent.atomic.AtomicInteger; import bag_manager.BagManagerOuterClass; +import chassis.Chassis; import chassis.SpecialVehicleTaskCmdOuterClass; import common.HeaderOuterClass; import function_state_management.FSMStatusReasonQueryOuterClass; @@ -123,7 +126,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec /** * 工控机连接配置 */ - private final AdasOptions adasOptions; + private AdasOptions adasOptions; /** * 已经链接成功的工控机IP 未连接未null @@ -146,6 +149,8 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec private Timer carConfigReqTimer;//车辆基础信息请求 多次请求防止无法收到基础信息情况出现 private Context context; + private final ReceivedAckManager receivedAckManager = new ReceivedAckManager();//消息回执 + public void setOnMultiDeviceListener(OnMultiDeviceListener onMultiDeviceListener) { this.onMultiDeviceListener = onMultiDeviceListener; } @@ -174,27 +179,41 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec * 创建对象时会自动连接工控机,如果使用setListener 会出现 listener=null而调用回调的情况,所以将所使用到的接口 * * @param options - * @param onAdasConnectStatusListener + * @param listener */ - AdasChannel(Context context, AdasOptions options, OnAdasConnectStatusListener onAdasConnectStatusListener) { + AdasChannel(Context context, @Nullable AdasOptions options, @Nullable OnAdasConnectStatusListener listener) { this.context = context; - this.adasConnectStatusListener = onAdasConnectStatusListener; + this.adasConnectStatusListener = listener; + setAdasOptions(options); + initData(); + if (!adasOptions.isPassenger() && listener != null) + connect(); + } + + public void setAdasOptions(AdasOptions options) { //配置为null默认是乘客屏幕 if (options == null) { - this.adasOptions = new AdasOptions.Builder().setClient(true).build(); + buildAdasOptions(AdasOptions.newBuilder()); } else { this.adasOptions = options; } - initData(); - if (!adasOptions.isClient()) { - initSocket(); - } + ReceiveTimeoutManager.getInstance().setEnable(adasOptions.isEnableTimeoutDetection(), getIpcConnectionStatus()); + setUnableLaunchAutopilotGear(adasOptions.getUnableLaunchAutopilotGear()); + } + + /** + * 构建 AdasOptions + * + * @param builder builder + */ + private void buildAdasOptions(@NonNull AdasOptions.Builder builder) { + this.adasOptions = builder.build(); } private void initData() { //原始数据解析类 rawUnpack = new RawUnpack(); - rawPack = new RawPack(); + rawPack = new RawPack(receivedAckManager); autopilotReview = new AutopilotReview(onAutopilotReviewListener); //消息工厂 myMessageFactory = new MyMessageFactory(autopilotReview); @@ -207,6 +226,19 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec statusQueryRespDispatchHandler.start(); } }); + receivedAckManager.setListener(new ReceivedAckManager.OnReceivedAckListener() { + @Override + public void onReceiveReceivedAck(@NonNull ReceivedAck receivedAck) { + if (mAdasListener != null) { + mAdasListener.onReceiveReceivedAck(receivedAck); + } + } + + @Override + public void onSendReceivedAck(MessageType messageType, byte[] bytes) { + sendPBMessage(messageType, bytes); + } + }); } /** @@ -287,16 +319,18 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec nodeAliasCode = CHAIN_CODE_ADAS_INIT, paramIndexes = {-1}) private void initSocket() { - mSocket = new FpgaSocket(context); - context = null; - mSocket.setWebSocketListener(this); - if (isUseQueue) { - WebSocketQueueManager.getInstance().registerWebSocketListener(this); - WebSocketQueueManager.getInstance().initDector(); - WSByteQueueManager.getInstance().registerWebSocketListener(this); - WSByteQueueManager.getInstance().initDector(); + if (mSocket == null) { + mSocket = new FpgaSocket(context); + context = null; + mSocket.setWebSocketListener(this); + if (isUseQueue) { + WebSocketQueueManager.getInstance().registerWebSocketListener(this); + WebSocketQueueManager.getInstance().initDector(); + WSByteQueueManager.getInstance().registerWebSocketListener(this); + WSByteQueueManager.getInstance().initDector(); + } } - connect(); +// mSocket.setReconnectCount(adasOptions.getReconnectCount()); } @ChainLog(linkChainLog = CHAIN_TYPE_INIT_STATUS, @@ -329,6 +363,16 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec return usedSsmSource; } + @Override + public void setUnableLaunchAutopilotGear(Set unableLaunchAutopilotGear) { + AutopilotAbilityManager.getInstance().setUnableLaunchAutopilotGear(unableLaunchAutopilotGear); + } + + public void setSupportReceivedAck(int version) { + receivedAckManager.setSupport(version); + + } + /** * 发送ws消息 * @@ -345,16 +389,19 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec * @param data 数据 * @return boolean */ - private boolean sendPBMessage(MessagePad.MessageType msgType, byte[] data) { + private boolean sendPBMessage(MessageType msgType, byte[] data) { if (rawPack != null) { - byte[] bytes = rawPack.pack(msgType, data); //司机屏工控机数据转发 - if (adasOptions.isClient()) { - if (onMultiDeviceListener != null) - onMultiDeviceListener.onForwardingPassengerIPCMessage(bytes); + if (adasOptions.isPassenger()) { + if (onMultiDeviceListener != null) { + onMultiDeviceListener.onForwardingPassengerIPCMessage(rawPack.pack(msgType, data)); + } return true; } else { - return sendWsMessage(bytes); + if (mSocket == null || !mSocket.isConnected()) { + return false; + } + return sendWsMessage(rawPack.pack(msgType, data)); } } return false; @@ -362,7 +409,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec @Override public boolean sendWsMessage(byte[] bytes) { - if (mSocket == null || bytes == null || bytes.length <= 0) { + if (mSocket == null || !mSocket.isConnected() || bytes == null || bytes.length == 0) { return false; } ByteString byteString = ByteString.of(bytes); @@ -399,8 +446,12 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec if (raw.getProtocolStatus() == ProtocolStatus.SUCCEED) { MessagePad.Header header = MessagePad.Header.parser().parseFrom(byteString.toByteArray(), raw.getOutHeaderLength(), raw.getOffsetValue() - raw.getOutHeaderLength()); raw.setHeader(header); + if (header.getNeedAck() == 1) { + //需要回执 + receivedAckManager.sendReceivedAck(header.getMsgID()); + } //司机端刷新心跳 - if (!adasOptions.isClient()) + if (!adasOptions.isPassenger()) ReceiveTimeoutManager.getInstance().refreshLast(header.getTimestamp()); // CupidLogUtils.w("--->websocket byte read header = " + messageType.toString()); MessagePad.MessageType messageType = header.getMsgType(); @@ -481,12 +532,19 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec if (raw.getProtocolStatus() == ProtocolStatus.SUCCEED) { MessagePad.Header header = raw.getHeader(); MessagePad.MessageType messageType = header.getMsgType(); - IMsg iMsg = myMessageFactory.createMessage(messageType); - if (iMsg == null) { - callError(ProtocolStatus.MESSAGE_TYPE_UNKNOWN, raw.originalData.toByteArray()); - return; + if (messageType == MessageType.TYPE_RECEIVE_RECEIVED_ACK.typeCode) { + //消息回执 + long time = System.currentTimeMillis(); + MessagePad.ReceivedAck ack = MessagePad.ReceivedAck.parser().parseFrom(raw.originalData.toByteArray(), raw.getOffsetValue(), raw.getPackageLengthValue() - raw.getOffsetValue()); + receivedAckManager.receiveReceivedAck(time, ack); + } else { + IMsg iMsg = myMessageFactory.createMessage(messageType); + if (iMsg == null) { + callError(ProtocolStatus.MESSAGE_TYPE_UNKNOWN, raw.originalData.toByteArray()); + return; + } + iMsg.handlerMsg(raw, mAdasListener); } - iMsg.handlerMsg(raw, mAdasListener); } else { callError(raw.getProtocolStatus(), raw.originalData.toByteArray()); } @@ -504,7 +562,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec @Override public AdasOptions getAdasOptions() { - return adasOptions == null ? new AdasOptions.Builder().build() : adasOptions; + return adasOptions; } /** @@ -513,15 +571,16 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec @Override public void connect() { //当是司机屏才启用 - if (!adasOptions.isClient()) { + if (!adasOptions.isPassenger()) { + initSocket(); if (ipcConnectionStatus.get() == Constants.IPC_CONNECTION_STATUS.DISCONNECTED || ipcConnectionStatus.get() == Constants.IPC_CONNECTION_STATUS.NOT_FOUND_ADDRESS) { - switch (adasOptions.getIpcConnectionMode()) { - case AdasOptions.IPC_CONNECTION_MODE.FIXATION: - ipcFixationIPHelper(adasOptions.getIpcFixationIP()); + switch (adasOptions.getConnectionMode()) { + case AdasOptions.IPC_CONNECTION_MODE.PING: + ipcFixationIPHelper(adasOptions.getPingAddressList()); break; - case AdasOptions.IPC_CONNECTION_MODE.ASSIGN: - onConnectionAddress(adasOptions.getIpcAssignIP()); + case AdasOptions.IPC_CONNECTION_MODE.SPECIFIED: + onConnectionAddress(adasOptions.getSpecifiedAddress()); break; } } @@ -536,7 +595,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec if (ipcFixationIPHelper != null) { ipcFixationIPHelper.stop(); } - if (!adasOptions.isClient()) { + if (!adasOptions.isPassenger()) { if (mSocket != null) mSocket.closeWebSocket(); if (isUseQueue) { @@ -561,9 +620,18 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec updateConnectStatus(Constants.IPC_CONNECTION_STATUS.CONNECTED, "已连接"); //根据连接配置 进行接口订阅或取消订阅配置 if (adasOptions != null) { - SubscribeInterfaceOptions options = adasOptions.getSubscribeInterfaceOptions(); - if (options != null && options.getMessageTypes() != null && !options.getMessageTypes().isEmpty()) { - subscribeInterface.subscribeInterface(options.getRole(), options.getType(), options.getMessageTypes()); + Set options = adasOptions.getSubscribeInterfaceOptions(); + if (options != null && !options.isEmpty()) { + for (SubscribeInterfaceOption option : options) { + MessageType messageType = option.getMessageType(); + if (messageType != null) { + subscribeInterface.subscribeInterface(option.getRole(), option.getType(), messageType); + } + Set messageTypes = option.getMessageTypes(); + if (messageTypes != null) { + subscribeInterface.subscribeInterface(option.getRole(), option.getType(), messageTypes); + } + } } } } @@ -575,6 +643,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec subscribeInterface = null; usedChassisSource = AdasConstants.ChassisSource.CHASSIS_UNKNOWN; usedSsmSource = AdasConstants.SsmSource.SSM_UNKNOWN; + receivedAckManager.stop(); updateConnectStatus(Constants.IPC_CONNECTION_STATUS.DISCONNECTED, t == null ? "" : t); } @@ -598,7 +667,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec nowTime = SystemClock.elapsedRealtime(); decoderRaw(receiveTime, bytes); //司机屏工控机数据转发 - if (!adasOptions.isClient() && onMultiDeviceListener != null) { + if (!adasOptions.isPassenger() && onMultiDeviceListener != null) { onMultiDeviceListener.onForwardingDriverIPCMessage(bytes.toByteArray()); } calculateTimeConsumingOnMessage(nowTime); @@ -876,7 +945,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec builder.setCertification(com.google.protobuf.ByteString.copyFrom(certification)); } MessagePad.BasicInfoResp resp = builder.build(); - return sendPBMessage(MessageType.TYPE_SEND_BASIC_INFO_RESP.typeCode, resp.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_BASIC_INFO_RESP, resp.toByteArray()); } /** @@ -896,7 +965,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec builder.setRouteInfo(routeInfo); MessagePad.SetAutopilotModeReq req = builder.build(); if (autopilotReview != null) autopilotReview.onAutopilotCommandTrigger(req); - return sendPBMessage(MessageType.TYPE_SEND_SET_AUTOPILOT_MODE_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_SET_AUTOPILOT_MODE_REQ, req.toByteArray()); } /** @@ -911,7 +980,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec .newBuilder() .setEnable(enable) .build(); - return sendPBMessage(MessageType.TYPE_SEND_SET_DEMO_MODE_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_SET_DEMO_MODE_REQ, req.toByteArray()); } /** @@ -924,7 +993,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec MessagePad.CarConfigReq req = MessagePad.CarConfigReq .newBuilder() .build(); - return sendPBMessage(MessageType.TYPE_SEND_CAR_CONFIG_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_CAR_CONFIG_REQ, req.toByteArray()); } /** @@ -954,7 +1023,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec .setReason(reason) .setReasonID(reasonID) .build(); - return sendPBMessage(MessageType.TYPE_SEND_RECORD_CAUSE.typeCode, resp.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_RECORD_CAUSE, resp.toByteArray()); } @Override @@ -1028,7 +1097,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec builder.addAllTopics(topics); } MessagePad.RecordData req = builder.build(); - return sendPBMessage(MessageType.TYPE_SEND_RECORD_DATA.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_RECORD_DATA, req.toByteArray()); } /** @@ -1043,7 +1112,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec .newBuilder() .setSpeedLimit(speedLimit) .build(); - return sendPBMessage(MessageType.TYPE_SEND_SET_AUTOPILOT_SPEED_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_SET_AUTOPILOT_SPEED_REQ, req.toByteArray()); } /** @@ -1062,7 +1131,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec MessagePad.GlobalPathReq req = MessagePad.GlobalPathReq .newBuilder() .build(); - return sendPBMessage(MessageType.TYPE_SEND_GLOBAL_PATH_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_GLOBAL_PATH_REQ, req.toByteArray()); } /** @@ -1110,7 +1179,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec builder.setLaneDetail(laneDetail); builder.setTimestamp(timestamp); MessagePad.TrafficLightData req = builder.build(); - return sendPBMessage(MessageType.TYPE_SEND_TRAFFIC_LIGHT_DATA.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_TRAFFIC_LIGHT_DATA, req.toByteArray()); } /** @@ -1132,7 +1201,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec MessagePad.SystemCmdReq.Builder builder = MessagePad.SystemCmdReq.newBuilder(); builder.setCmdType(type); MessagePad.SystemCmdReq req = builder.build(); - return sendPBMessage(MessageType.TYPE_SEND_SYSTEM_CMD_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_SYSTEM_CMD_REQ, req.toByteArray()); } /** @@ -1157,7 +1226,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec builder.setDownloadType(downloadType); } MessagePad.TrajectoryDownloadReq req = builder.build(); - return sendPBMessage(MessageType.TYPE_SEND_TRAJECTORY_DOWNLOAD_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_TRAJECTORY_DOWNLOAD_REQ, req.toByteArray()); } /** @@ -1178,7 +1247,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec MessagePad.StatusQueryReq req = MessagePad.StatusQueryReq .newBuilder() .build(); - return sendPBMessage(MessageType.TYPE_SEND_STATUS_QUERY_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_STATUS_QUERY_REQ, req.toByteArray()); } @@ -1194,7 +1263,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec .newBuilder() .setEnable(enable) .build(); - return sendPBMessage(MessageType.TYPE_SEND_SET_RAIN_MODE_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_SET_RAIN_MODE_REQ, req.toByteArray()); } /** @@ -1214,13 +1283,13 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec if (topicsNeedToCache != null && !topicsNeedToCache.isEmpty()) builder.addAllTopicsNeedToCache(topicsNeedToCache); MessagePad.RecordDataConfigReq req = builder.build(); - return sendPBMessage(MessageType.TYPE_SEND_RECORD_DATA_CONFIG_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_RECORD_DATA_CONFIG_REQ, req.toByteArray()); } /**************************************注册接口相关*******************************************/ @Override public boolean onSendSubscribe(byte[] bytes) { - return sendPBMessage(MessageType.TYPE_SEND_SUBSCRIBE_DATA_REQ.typeCode, bytes); + return sendPBMessage(MessageType.TYPE_SEND_SUBSCRIBE_DATA_REQ, bytes); } /** @@ -1328,7 +1397,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec build.setLaneChangeCmd(MessagePad.LaneChangeCmd.newBuilder().setCmd(laneChangeCmd)); } MessagePad.PlanningCmd planningCmd = build.build(); - return sendPBMessage(MessageType.TYPE_SEND_PLANNING_CMD.typeCode, planningCmd.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_PLANNING_CMD, planningCmd.toByteArray()); } /** @@ -1481,8 +1550,9 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec .setFrameId("special_vehicle_task_cmd") .setModuleName("EagleEye") .build(); - cmdBuild.setHeader(header); - return sendPBMessage(MessageType.TYPE_SEND_SPECIAL_VEHICLE_TASK_CMD.typeCode, cmdBuild.build().toByteArray()); + cmdBuild.setHeader(header) + .setSource(0); + return sendPBMessage(MessageType.TYPE_SEND_SPECIAL_VEHICLE_TASK_CMD, cmdBuild.build().toByteArray()); } @@ -1498,7 +1568,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec .setCmdType(MessagePad.OperatorCmdType.OPERATOR_CMD_CHANGE_LANE) .setValue(1) .build(); - return sendPBMessage(MessageType.TYPE_SEND_OPERATOR_CMD_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_OPERATOR_CMD_REQ, req.toByteArray()); } /** @@ -1513,7 +1583,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec .setCmdType(MessagePad.OperatorCmdType.OPERATOR_CMD_CHANGE_LANE) .setValue(2) .build(); - return sendPBMessage(MessageType.TYPE_SEND_OPERATOR_CMD_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_OPERATOR_CMD_REQ, req.toByteArray()); } /** @@ -1529,7 +1599,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec .setCmdType(MessagePad.OperatorCmdType.OPERATOR_CMD_SET_ACCELERATED_SPEED) .setValue(acc) .build(); - return sendPBMessage(MessageType.TYPE_SEND_OPERATOR_CMD_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_OPERATOR_CMD_REQ, req.toByteArray()); } /** @@ -1545,7 +1615,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec .setCmdType(MessagePad.OperatorCmdType.OPERATOR_CMD_SET_HORN) .setValue(value) .build(); - return sendPBMessage(MessageType.TYPE_SEND_OPERATOR_CMD_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_OPERATOR_CMD_REQ, req.toByteArray()); } /** @@ -1583,7 +1653,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec .newBuilder() .addReqs(oneParam) .build(); - return sendPBMessage(MessageType.TYPE_SEND_SET_PARAM_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_SET_PARAM_REQ, req.toByteArray()); } /** @@ -1600,7 +1670,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec builder.setBoolValue((Boolean) value); } ParamSetCmdOuterClass.ParamSetCmd req = builder.build(); - return sendPBMessage(MessageType.TYPE_SEND_SET_PARAM_REQ_V2.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_SET_PARAM_REQ_V2, req.toByteArray()); } /** @@ -1647,7 +1717,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec } if (builder.getReqsCount() > 0) { MessagePad.SetParamReq req = builder.build(); - isV1 = sendPBMessage(MessageType.TYPE_SEND_SET_PARAM_REQ.typeCode, req.toByteArray()); + isV1 = sendPBMessage(MessageType.TYPE_SEND_SET_PARAM_REQ, req.toByteArray()); } return isV1 && isV2BlindArea && isV2V2N && isV2V2NI; } @@ -1861,7 +1931,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec } req = builder.build(); } - return sendPBMessage(MessageType.TYPE_SEND_GET_PARAM_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_GET_PARAM_REQ, req.toByteArray()); } /** @@ -1894,7 +1964,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec } } MessagePad.TripInfoEvent req = builder.build(); - return sendPBMessage(MessageType.TYPE_SEND_TRIP_INFO_REQ.typeCode, req.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_TRIP_INFO_REQ, req.toByteArray()); } /** @@ -1905,7 +1975,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec */ @Override public boolean sendBagManagerCmd(BagManagerOuterClass.BagManager bagManager) { - return sendPBMessage(MessageType.TYPE_SEND_BAG_MANAGER_CMD.typeCode, bagManager.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_BAG_MANAGER_CMD, bagManager.toByteArray()); } /** @@ -1921,7 +1991,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec FSMStatusReasonQueryOuterClass.FSMStatusReasonQuery query = FSMStatusReasonQueryOuterClass.FSMStatusReasonQuery.newBuilder() .setType(type) .build(); - return sendPBMessage(MessageType.TYPE_SEND_FSM_STATUS_REASON_QUERY_REQ.typeCode, query.toByteArray()); + return sendPBMessage(MessageType.TYPE_SEND_FSM_STATUS_REASON_QUERY_REQ, query.toByteArray()); } /** @@ -1944,7 +2014,7 @@ public class AdasChannel implements IAdasNetCommApi, FpgaSocket.IWebSocketConnec builder.setPayload(payload); } AiCloudTask.AiCloudPadMessage message = builder.build(); - return sendPBMessage(padMessageType.typeCode, message.toByteArray()); + return sendPBMessage(padMessageType, message.toByteArray()); } /** diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasManager.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasManager.java index 42ead547b3..9dcd1600e5 100644 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasManager.java +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasManager.java @@ -6,12 +6,15 @@ import android.text.TextUtils; import androidx.annotation.NonNull; import com.zhidao.support.adas.high.bean.VersionCompatibility; -import com.zhidao.support.adas.high.common.AppPreferenceHelper; import com.zhidao.support.adas.high.common.Constants; import com.zhidao.support.adas.high.common.CupidLogUtils; import com.zhidao.support.adas.high.common.Define; -import com.zhidao.support.adas.high.common.MessageType; +import com.zhidao.support.adas.high.common.MMKVUtils; +import com.zhidao.support.adas.high.common.MessageIdGenerator; import com.zhidao.support.adas.high.common.ReceiveTimeoutManager; +import com.zhidao.support.adas.high.common.autopilot.ability.AutopilotAbilityManager; +import com.zhjt.mogo.adas.common.MessageType; +import com.zhjt.mogo.adas.data.Adas; import com.zhjt.mogo.adas.data.AdasConstants; import com.zhjt.mogo.adas.data.bean.AdasParam; import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable; @@ -30,6 +33,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import bag_manager.BagManagerOuterClass; +import chassis.Chassis; import chassis.SpecialVehicleTaskCmdOuterClass; import mogo.telematics.pad.MessagePad; import mogo.yycp.paralleldriving.protocol.ParallelDrivingRequest; @@ -57,6 +61,7 @@ public class AdasManager implements IAdasNetCommApi { private final Pattern pattern = Pattern.compile("\\d+\\.\\d+\\.\\d+"); private AdasChannel mChannel; + private Context context;//不持有,create之后会置null public static AdasManager getInstance() { if (ourInstance == null) { @@ -75,6 +80,9 @@ public class AdasManager implements IAdasNetCommApi { public synchronized void setCarConfig(MessagePad.CarConfigResp carConfig) { this.carConfig = carConfig; + if (carConfig != null && mChannel != null) { + mChannel.setSupportReceivedAck(carConfig.getMapVersion()); + } } /** @@ -99,20 +107,31 @@ public class AdasManager implements IAdasNetCommApi { } } + /** + * 初始化 + * TODO 必须在调用任意方法之前初始化 + * + * @param context + */ + public void init(Context context) { + this.context = context; + MMKVUtils.getInstance().init(context); + } + /** * 创建一个连接 * * @param options 连接参数 * @param onAdasConnectStatusListener 连接状态监听 */ - public synchronized void create(Context context, AdasOptions options, OnAdasConnectStatusListener onAdasConnectStatusListener) { + public synchronized void create(AdasOptions options, OnAdasConnectStatusListener onAdasConnectStatusListener) { if (mChannel != null) { mChannel.disconnect(); carConfig = null; mChannel = null; } mChannel = new AdasChannel(context, options, onAdasConnectStatusListener); - + context = null; } /** @@ -295,6 +314,16 @@ public class AdasManager implements IAdasNetCommApi { return mChannel == null ? AdasConstants.SsmSource.SSM_UNKNOWN : mChannel.getUsedSsmSource(); } + /** + * 设置不能启动自动驾驶的档位 + * + * @param unableLaunchAutopilotGear 不能起自驾档位 + */ + @Override + public void setUnableLaunchAutopilotGear(Set unableLaunchAutopilotGear) { + AutopilotAbilityManager.getInstance().setUnableLaunchAutopilotGear(unableLaunchAutopilotGear); + } + /** * 自动驾驶设备基础信息应答 * @@ -1234,8 +1263,8 @@ public class AdasManager implements IAdasNetCommApi { * * @return 返回默认工控机IP列表 */ - public HashSet getIPCFixationIPList(Context context) { - return AppPreferenceHelper.getInstance(context).getIPCFixationIPList(); + public HashSet getIPCFixationIPList() { + return Constants.getIPCFixationIPList(); } /** @@ -1243,8 +1272,8 @@ public class AdasManager implements IAdasNetCommApi { * * @param ipcIP IP */ - public boolean addIPCFixationIP(Context context, String ipcIP) { - return AppPreferenceHelper.getInstance(context).addIPCFixationIP(ipcIP); + public boolean addIPCFixationIP(String ipcIP) { + return Constants.addIPCFixationIP(ipcIP); } /** @@ -1252,15 +1281,26 @@ public class AdasManager implements IAdasNetCommApi { * * @param ipcIP IP */ - public boolean delIPCFixationIP(Context context, String ipcIP) { - return AppPreferenceHelper.getInstance(context).delIPCFixationIP(ipcIP); + public boolean delIPCFixationIP(String ipcIP) { + return Constants.delIPCFixationIP(ipcIP); } /** * 删除所有工控机固定IP */ - public void delIPCFixationIP(Context context) { - AppPreferenceHelper.getInstance(context).delIPCFixationIP(); + public void delIPCFixationIP() { + Constants.delIPCFixationIP(); + } + + + /** + * 获取全部已存储的消息ID + * LastMessage中的msgID如果是0表明今日还未下发任何数据 + * + * @return key:日期毫秒值 value:最后一条消息的相关信息 + */ + public Map getAllSendMessageId() { + return MessageIdGenerator.getInstance().getAllSendMessageId(); } /** diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasOptions.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasOptions.java index dcdc047c72..92459f3953 100644 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasOptions.java +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/AdasOptions.java @@ -1,7 +1,6 @@ package com.zhidao.support.adas.high; -import com.zhidao.support.adas.high.common.autopilot.ability.AutopilotAbilityManager; -import com.zhidao.support.adas.high.subscribe.SubscribeInterfaceOptions; +import com.zhidao.support.adas.high.subscribe.SubscribeInterfaceOption; import java.util.HashSet; import java.util.Set; @@ -14,117 +13,289 @@ import chassis.Chassis; * 更换链接方式必须先断开与工控机的连接 */ public class AdasOptions { + public interface DEFAULT { + boolean IS_PASSENGER = true;//默认乘客端 + int CONNECTION_MODE = IPC_CONNECTION_MODE.PING;//默认PING方式 + boolean IS_ENABLE_TIMEOUT_DETECTION = true;//默认启动超时检测 + int RECONNECT_COUNT = 0;//默认无限重连 -1:用不重连;0:无限重连;非0正整数:指定重连次数 + boolean IS_CERTIFICATION = false;//默认不启用证书 + boolean IS_AUTO_CONNECT = true;//默认自动连接(调用初始化后自动连接) + } + /** * 链接方式 */ public interface IPC_CONNECTION_MODE { /** - * 固定IP 根据存储的IP进行轮询 + * 提供一个地址列表,通过PING的方式进行选择 + * 主要作用是存在不同网段 */ - int FIXATION = 0; + int PING = 0; /** - * 指定IP + * 指定地址方式 */ - int ASSIGN = 1; + int SPECIFIED = 1; } - /** - * 是否是客户端 true:客户度(乘客屏) false:服务端(司机屏) - * 当是乘客端的情况下 ipcConnectionMode ipcAssignIP ipcFixationIPSet 均无效 - */ - private boolean isClient; + private final boolean isPassenger; + private final int connectionMode; + private final String specifiedAddress; + private final HashSet pingAddressList; + private final boolean isEnableTimeoutDetection; + private final int reconnectCount; + private final boolean isCertification; + private final String rootCrt; + private final boolean isAutoConnect; + private final Set subscribeInterfaceOptions; + private final Set unableLaunchAutopilotGear; - /** - * 链接工控机方式 - * 如果是司机屏默认 固定IP方式 - */ - private int ipcConnectionMode = IPC_CONNECTION_MODE.FIXATION; - /** - * 指定工控机IP - */ - private String ipcAssignIP; - /** - * 工控机固定IP集合 通过Ping方式尝试 - */ - private HashSet ipcFixationIP; - /** - * 订阅相关配置 - */ - private SubscribeInterfaceOptions subscribeInterfaceOptions; - - private AdasOptions() { + private AdasOptions(Builder builder) { + this.isPassenger = builder.isPassenger; + this.connectionMode = builder.connectionMode; + this.specifiedAddress = builder.specifiedAddress; + this.pingAddressList = builder.pingAddressList; + this.isEnableTimeoutDetection = builder.isEnableTimeoutDetection; + this.reconnectCount = builder.reconnectCount; + this.isCertification = builder.isCertification; + this.rootCrt = builder.rootCrt; + this.isAutoConnect = builder.isAutoConnect; + this.subscribeInterfaceOptions = builder.subscribeInterfaceOptions; + this.unableLaunchAutopilotGear = builder.unableLaunchAutopilotGear; } + public boolean isPassenger() { + return isPassenger; + } + + public String getSpecifiedAddress() { + return specifiedAddress; + } + + public int getConnectionMode() { + return connectionMode; + } + + public HashSet getPingAddressList() { + return pingAddressList; + } + + public boolean isEnableTimeoutDetection() { + return isEnableTimeoutDetection; + } + + public int getReconnectCount() { + return reconnectCount; + } + + public boolean isCertification() { + return isCertification; + } + + public String getRootCrt() { + return rootCrt; + } + + public boolean isAutoConnect() { + return isAutoConnect; + } + + public Set getSubscribeInterfaceOptions() { + return subscribeInterfaceOptions; + } + + public Set getUnableLaunchAutopilotGear() { + return unableLaunchAutopilotGear; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder(this); + } + + /** * 静态内部类 */ public static class Builder { - AdasOptions options; + private boolean isPassenger = DEFAULT.IS_PASSENGER; + private int connectionMode = DEFAULT.CONNECTION_MODE; + private String specifiedAddress; + private HashSet pingAddressList; + private boolean isEnableTimeoutDetection = DEFAULT.IS_ENABLE_TIMEOUT_DETECTION; + private int reconnectCount = DEFAULT.RECONNECT_COUNT; + private boolean isCertification = DEFAULT.IS_CERTIFICATION; + private String rootCrt; + private boolean isAutoConnect = DEFAULT.IS_AUTO_CONNECT; + private Set subscribeInterfaceOptions; + private Set unableLaunchAutopilotGear; - // 首先获得一个默认的配置 - public Builder() { - this(getDefaultOptions()); + + private Builder() { } - public Builder(AdasOptions defaultOptions) { - options = defaultOptions; + private Builder(AdasOptions options) { + this.isPassenger = options.isPassenger; + this.connectionMode = options.connectionMode; + this.specifiedAddress = options.specifiedAddress; + this.pingAddressList = options.pingAddressList; + this.isEnableTimeoutDetection = options.isEnableTimeoutDetection; + this.reconnectCount = options.reconnectCount; + this.isCertification = options.isCertification; + this.rootCrt = options.rootCrt; + this.isAutoConnect = options.isAutoConnect; + this.subscribeInterfaceOptions = options.subscribeInterfaceOptions; + this.unableLaunchAutopilotGear = options.unableLaunchAutopilotGear; } + /** - * 设置当前是客户端还是服务端 + * 设置当前是司机端还是乘客端 + * 默认乘客端 + * 当乘客端时以下参数均无效: + * *ipcConnectionMode + * *ipcAssignIP + * *ipcFixationIP + * *isEnableTimeoutDetection + * *reconnectCount + * *isCertification + * *rootCrt + * *isAutoConnect + * *subscribeInterfaceOptions + * *unableLaunchAutopilotGear * - * @param isClient true:客户度 false:服务端 - * @return + * @param isPassenger true:乘客端 false:司机端 + * @return Builder */ - public Builder setClient(boolean isClient) { - options.isClient = isClient; + public Builder setPassenger(boolean isPassenger) { + this.isPassenger = isPassenger; return this; } /** - * 配置连接方式 + * 配置工控机连接方式 + * isPassenger=false 时默认是固定IP方式{@link IPC_CONNECTION_MODE#PING} + * * + * 配置固定IP方式{@link IPC_CONNECTION_MODE#PING}时必须配置工控机IP地址列表{@link Builder#setPingAddressList(HashSet)} + * 配置指定IP方式{@link IPC_CONNECTION_MODE#SPECIFIED}时必须配置工控机IP地址{@link Builder#setSpecifiedAddress(String)} * - * @param ipcConnectionMode - * @return + * @param connectionMode 连接方式 + * @return Builder */ - public Builder setIpcConnectionMode(int ipcConnectionMode) { - options.ipcConnectionMode = ipcConnectionMode; + public Builder setConnectionMode(int connectionMode) { + this.connectionMode = connectionMode; return this; } /** * 设置IPC主机地址 * - * @param ipcAssignIP - * @return + * @param specifiedAddress ip + * @return Builder */ - public Builder setIpcAssignIP(String ipcAssignIP) { - options.ipcAssignIP = ipcAssignIP; + public Builder setSpecifiedAddress(String specifiedAddress) { + this.specifiedAddress = specifiedAddress; return this; } /** - * 设置IPC 固定IP + * 设置工控机固定IP * 通过ping方式逐一检查连通性 * - * @param ipcFixationIP - * @return + * @param pingAddressList 固定IP列表 + * @return Builder */ - public Builder setIpcFixationIP(HashSet ipcFixationIP) { - options.ipcFixationIP = ipcFixationIP; + public Builder setPingAddressList(HashSet pingAddressList) { + this.pingAddressList = pingAddressList; return this; } /** - * 接口注册参数 + * 是否启用超时检测 + * 默认启用 * - * @param subscribeInterfaceOptions - * @return + * @return Builder */ - public Builder setSubscribeInterfaceOptions(SubscribeInterfaceOptions subscribeInterfaceOptions) { - options.subscribeInterfaceOptions = subscribeInterfaceOptions; + public Builder setEnableTimeoutDetection(boolean enable) { + this.isEnableTimeoutDetection = enable; + return this; + } + + /** + * 重连次数 + * -1:不重连 + * 0:无限重连 + * >0:重连指定次数 + * 默认:0 + * + * @return Builder + */ + public Builder setReconnectCount(int count) { + this.reconnectCount = count; + return this; + } + + /** + * 是否启用SSL认证 + * 目前默认禁用 + * + * @return Builder + */ + public Builder setEnableCertification(boolean enable) { + this.isCertification = enable; + return this; + } + + /** + * ROOT证书 + * 启用认证必须传 + * + * @param rootCrt root证书 + * @return Builder + */ + public Builder setRootCrt(String rootCrt) { + this.rootCrt = rootCrt; + return this; + } + + /** + * 是否自动连接 + * create之后是否自动连接域控 + * + * @param isAutoConnect 是否自动连接 + * @return Builder + */ + public Builder setAutoConnect(boolean isAutoConnect) { + this.isAutoConnect = isAutoConnect; + return this; + } + + /** + * 接口订阅参数 + * + * @param subscribeInterfaceOption 订阅参数 + * @return Builder + */ + public Builder addSubscribeInterfaceOption(SubscribeInterfaceOption subscribeInterfaceOption) { + if (subscribeInterfaceOptions == null) { + subscribeInterfaceOptions = new HashSet<>(); + } + subscribeInterfaceOptions.add(subscribeInterfaceOption); + return this; + } + + /** + * 接口订阅参数 + * + * @param subscribeInterfaceOptions 订阅参数 + * @return Builder + */ + public Builder setSubscribeInterfaceOptions(Set subscribeInterfaceOptions) { + this.subscribeInterfaceOptions = subscribeInterfaceOptions; return this; } @@ -132,75 +303,15 @@ public class AdasOptions { * 不能启动自驾的档位 * * @param unableLaunchAutopilotGear 档位 - * @return + * @return Builder */ public Builder setUnableLaunchAutopilotGear(Set unableLaunchAutopilotGear) { - options.setUnableLaunchAutopilotGear(unableLaunchAutopilotGear); + this.unableLaunchAutopilotGear = unableLaunchAutopilotGear; return this; } public AdasOptions build() { - return options; + return new AdasOptions(this); } } - - /** - * 获取默认的配置 - * 默认配置是乘客端 - * - * @return - */ - public static AdasOptions getDefaultOptions() { - AdasOptions options = new AdasOptions(); - options.isClient = true; - options.ipcAssignIP = null; - options.ipcFixationIP = null; - options.subscribeInterfaceOptions = null; - options.setUnableLaunchAutopilotGear(null); - return options; - } - - public boolean isClient() { - return isClient; - } - - public String getIpcAssignIP() { - return ipcAssignIP; - } - - public int getIpcConnectionMode() { - return ipcConnectionMode; - } - - public HashSet getIpcFixationIP() { - return ipcFixationIP; - } - - public SubscribeInterfaceOptions getSubscribeInterfaceOptions() { - return subscribeInterfaceOptions; - } - - public void setIpcAssignIP(String ipcAssignIP) { - this.ipcAssignIP = ipcAssignIP; - } - - public void setClient(boolean client) { - isClient = client; - } - - public void setIpcConnectionMode(int ipcConnectionMode) { - this.ipcConnectionMode = ipcConnectionMode; - } - - public void setIpcFixationIP(HashSet ipcFixationIP) { - this.ipcFixationIP = ipcFixationIP; - } - - public void setSubscribeInterfaceOptions(SubscribeInterfaceOptions subscribeInterfaceOptions) { - this.subscribeInterfaceOptions = subscribeInterfaceOptions; - } - - public void setUnableLaunchAutopilotGear(Set unableLaunchAutopilotGear) { - AutopilotAbilityManager.getInstance().setUnableLaunchAutopilotGear(unableLaunchAutopilotGear); - } } diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/IAdasNetCommApi.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/IAdasNetCommApi.java index c395f8224d..9e0495efe8 100644 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/IAdasNetCommApi.java +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/IAdasNetCommApi.java @@ -5,7 +5,7 @@ import androidx.annotation.NonNull; import com.zhidao.support.adas.high.bean.VersionCompatibility; import com.zhidao.support.adas.high.common.Constants; import com.zhidao.support.adas.high.common.Define; -import com.zhidao.support.adas.high.common.MessageType; +import com.zhjt.mogo.adas.common.MessageType; import com.zhjt.mogo.adas.data.AdasConstants; import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable; import com.zhjt.mogo.adas.data.sweeper.task.SweeperTask; @@ -19,6 +19,7 @@ import java.util.Map; import java.util.Set; import bag_manager.BagManagerOuterClass; +import chassis.Chassis; import chassis.SpecialVehicleTaskCmdOuterClass; import mogo.telematics.pad.MessagePad; import mogo.yycp.paralleldriving.protocol.ParallelDrivingRequest; @@ -83,6 +84,13 @@ public interface IAdasNetCommApi { */ AdasConstants.SsmSource getUsedSsmSource(); + /** + * 设置不能启动自动驾驶的档位 + * + * @param unableLaunchAutopilotGear 不能起自驾档位 + */ + void setUnableLaunchAutopilotGear(Set unableLaunchAutopilotGear); + /** * 自动驾驶设备基础信息应答 * diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnAdasListener.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnAdasListener.java index f5e77e84b6..1f405257a4 100644 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnAdasListener.java +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/OnAdasListener.java @@ -4,12 +4,13 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.mogo.support.obu.ObuScene; -import com.zhidao.support.adas.high.common.MessageType; import com.zhidao.support.adas.high.common.ProtocolStatus; +import com.zhjt.mogo.adas.common.MessageType; import com.zhjt.mogo.adas.data.AdasConstants; import com.zhjt.mogo.adas.data.AiCloudTask; import com.zhjt.mogo.adas.data.bean.AdasParam; import com.zhjt.mogo.adas.data.bean.AutopilotStatistics; +import com.zhjt.mogo.adas.data.bean.ReceivedAck; import com.zhjt.mogo.adas.data.bean.UnableLaunchData; import com.zhjt.mogo.adas.data.bean.UnableLaunchReason; import com.zhjt.mogo.adas.data.sweeper.bootable.SweeperBootable; @@ -483,6 +484,14 @@ public interface OnAdasListener { */ void onParallelDrivingAbility(boolean isParallelDrivingAbility); + /** + * 回执消息 + * PAD发送数据到域控的回执消息,是否存在回执详情参见{@link MessageType} 枚举 TYPE_SEND_XXX_XXX 消息回执超时时间大于0的表示需要回执 + * + * @param receivedAck 回执 + */ + void onReceiveReceivedAck(@NonNull ReceivedAck receivedAck); + /** * 启动自动驾驶失败回调 * 根据MAP 系统监控状态返回过滤 diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/AppPreferenceHelper.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/AppPreferenceHelper.java deleted file mode 100644 index 209d58a5a6..0000000000 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/AppPreferenceHelper.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.zhidao.support.adas.high.common; - -import android.content.Context; -import android.content.SharedPreferences; - -import com.google.gson.reflect.TypeToken; - -import java.util.HashSet; - -/** - * Created by nie yunlong on 2018/4/13. - * sharePreference 操作 - * 根据 具体情况来写 - */ - -public class AppPreferenceHelper implements IPreferencesHelper { - - public static AppPreferenceHelper appPreferenceHelper; - /** - * 保存deviceId 文件名称 - */ - private final static String SP_NAME = "adas_config"; - - /** - * 手机Id - */ - private SharedPreferences ipcPre; - - - private HashSet ipcFixationIPSet;//工控机固定IP列表 - - public static AppPreferenceHelper getInstance(Context context) { - if (appPreferenceHelper == null) { - appPreferenceHelper = new AppPreferenceHelper(context.getApplicationContext()); - } - return appPreferenceHelper; - } - - private AppPreferenceHelper(Context context) { - ipcPre = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE); - getIPCFixationIPList(); - } - - - - @Override - public HashSet getIPCFixationIPList() { - if (ipcFixationIPSet == null || ipcFixationIPSet.isEmpty()) { - String json = ipcPre.getString("ipc_fixation_ip", Constants.DEFAULT_IPC_FIXATION_IP); - ipcFixationIPSet = JsonUtil.fromJson(json, new TypeToken>() { - }.getType()); - - } - return ipcFixationIPSet; - } - - @Override - public boolean addIPCFixationIP(String ipcIP) { - if (ipcFixationIPSet == null) - ipcFixationIPSet = new HashSet<>(); - if (!ipcFixationIPSet.contains(ipcIP)) { - ipcFixationIPSet.add(ipcIP); - ipcPre.edit().putString("ipc_fixation_ip", JsonUtil.toJson(ipcFixationIPSet)).apply(); - return true; - } - return false; - } - - @Override - public boolean delIPCFixationIP(String ipcIP) { - if (ipcFixationIPSet != null && ipcFixationIPSet.contains(ipcIP)) { - ipcFixationIPSet.remove(ipcIP); - ipcPre.edit().putString("ipc_fixation_ip", JsonUtil.toJson(ipcFixationIPSet)).apply(); - return true; - } - return false; - } - - @Override - public void delIPCFixationIP() { - ipcPre.edit().remove("ipc_fixation_ip").apply(); - } -} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/Constants.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/Constants.java index f45e3eab00..68772d15fb 100644 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/Constants.java +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/Constants.java @@ -1,5 +1,9 @@ package com.zhidao.support.adas.high.common; +import com.google.gson.reflect.TypeToken; + +import java.util.HashSet; + /** * @ProjectName: lib-adas-fpga * @Package: PACKAGE_NAME @@ -132,4 +136,43 @@ public class Constants { */ int MO_FANG = 3; } + + private static HashSet ipcFixationIPSet;//工控机固定IP列表 + + public static HashSet getIPCFixationIPList() { + if (ipcFixationIPSet == null || ipcFixationIPSet.isEmpty()) { + String json = MMKVUtils.getInstance().getString("ipc_fixation_ip", Constants.DEFAULT_IPC_FIXATION_IP); + ipcFixationIPSet = JsonUtil.fromJson(json, new TypeToken>() { + }.getType()); + + } + return ipcFixationIPSet; + } + + public static boolean addIPCFixationIP(String ipcIP) { + if (ipcFixationIPSet == null) { + getIPCFixationIPList(); + } + if (ipcFixationIPSet == null) { + ipcFixationIPSet = new HashSet<>(); + } + if (!ipcFixationIPSet.contains(ipcIP)) { + ipcFixationIPSet.add(ipcIP); + return MMKVUtils.getInstance().put("ipc_fixation_ip", JsonUtil.toJson(ipcFixationIPSet)); + } + return false; + } + + public static boolean delIPCFixationIP(String ipcIP) { + if (ipcFixationIPSet != null && ipcFixationIPSet.contains(ipcIP)) { + ipcFixationIPSet.remove(ipcIP); + return MMKVUtils.getInstance().put("ipc_fixation_ip", JsonUtil.toJson(ipcFixationIPSet)); + } + return false; + } + + public static void delIPCFixationIP() { + MMKVUtils.getInstance().removeKey("ipc_fixation_ip"); + } + } diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/CupidLogUtils.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/CupidLogUtils.java index cfdfa667e0..485b30b7c7 100644 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/CupidLogUtils.java +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/CupidLogUtils.java @@ -53,17 +53,7 @@ public class CupidLogUtils { Log.e("[tag=" + tag + "]", "[data=" + msg + "]"); } - public static void e(String msg) { - if (!mIsEnableLog) { - return; - } - Log.e("[tag=elita_lib]", "[data=" + msg + "]"); - } - - public static void w(String msg) { - if (!mIsEnableLog) { - return; - } - Log.e("[tag=elita_lib]", "[data=" + msg + "]"); + public static void log(String tag, String msg) { + Log.i("[tag=" + tag + "]", "[data= " + msg + "]"); } } diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/IPreferencesHelper.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/IPreferencesHelper.java deleted file mode 100644 index 53eacdb744..0000000000 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/IPreferencesHelper.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.zhidao.support.adas.high.common; - - -import java.util.HashSet; - -/** - * Created by nie yunlong on 2018/4/13. - */ - -public interface IPreferencesHelper { - - - /** - * 获取工控机固定IP列表 - * - * @return - */ - HashSet getIPCFixationIPList(); - - /** - * 增加工控机固定IP - * - * @param ipcIP - */ - boolean addIPCFixationIP(String ipcIP); - - /** - * 删除指定的工控机固定IP - * - * @param ipcIP - */ - boolean delIPCFixationIP(String ipcIP); - - /** - * 删除所有工控机固定IP - */ - void delIPCFixationIP(); - -} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MMKVUtils.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MMKVUtils.java new file mode 100644 index 0000000000..957d0572d9 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MMKVUtils.java @@ -0,0 +1,156 @@ +package com.zhidao.support.adas.high.common; + +import android.content.Context; +import android.os.Parcelable; + +import com.tencent.mmkv.MMKV; + +import java.util.Collections; +import java.util.Set; + + +/** + * MMKV Utils + */ +public class MMKVUtils { + + private static volatile MMKV mmkv; + private static volatile MMKVUtils INSTANCE; + + private MMKVUtils() { + } + + public static MMKVUtils getInstance() { + if (INSTANCE == null) { + synchronized (MMKVUtils.class) { + if (INSTANCE == null) { + INSTANCE = new MMKVUtils(); + } + } + } + return INSTANCE; + } + + public void init(Context context) { + if (mmkv == null) { + MMKV.initialize(context); +// mmkv = MMKV.defaultMMKV(MMKV.MULTI_PROCESS_MODE, null);//多进程模式 + mmkv = MMKV.defaultMMKV(); + } + } + + /** + * 写入基本数据类型缓存 + * + * @param key 键 + * @param object 值 + */ + public boolean put(String key, Object object) { + if (object instanceof String) { + return mmkv.encode(key, (String) object); + } else if (object instanceof Integer) { + return mmkv.encode(key, (Integer) object); + } else if (object instanceof Boolean) { + return mmkv.encode(key, (Boolean) object); + } else if (object instanceof Float) { + return mmkv.encode(key, (Float) object); + } else if (object instanceof Long) { + return mmkv.encode(key, (Long) object); + } else if (object instanceof Double) { + return mmkv.encode(key, (Double) object); + } else if (object instanceof byte[]) { + return mmkv.encode(key, (byte[]) object); + } else { + return mmkv.encode(key, object.toString()); + } + } + + + public void putSet(String key, Set sets) { + mmkv.encode(key, sets); + } + + public void putParcelable(String key, Parcelable obj) { + mmkv.encode(key, obj); + } + + public Integer getInt(String key) { + return mmkv.decodeInt(key, 0); + } + + public Integer getInt(String key, int defaultValue) { + return mmkv.decodeInt(key, defaultValue); + } + + public Double getDouble(String key) { + return mmkv.decodeDouble(key, 0.00); + } + + public Double getDouble(String key, double defaultValue) { + return mmkv.decodeDouble(key, defaultValue); + } + + public Long getLong(String key) { + return mmkv.decodeLong(key, 0L); + } + + public Long getLong(String key, long defaultValue) { + return mmkv.decodeLong(key, defaultValue); + } + + public Boolean getBoolean(String key) { + return mmkv.decodeBool(key, false); + } + + public Boolean getBoolean(String key, boolean defaultValue) { + return mmkv.decodeBool(key, defaultValue); + } + + public Float getFloat(String key) { + return mmkv.decodeFloat(key, 0F); + } + + public Float getFloat(String key, float defaultValue) { + return mmkv.decodeFloat(key, defaultValue); + } + + public byte[] getBytes(String key) { + return mmkv.decodeBytes(key); + } + + public byte[] getBytes(String key, byte[] defaultValue) { + return mmkv.decodeBytes(key, defaultValue); + } + + public String getString(String key) { + return mmkv.decodeString(key, ""); + } + + public String getString(String key, String defaultValue) { + return mmkv.decodeString(key, defaultValue); + } + + public Set getStringSet(String key) { + return mmkv.decodeStringSet(key, Collections.emptySet()); + } + + public Parcelable getParcelable(String key) { + return mmkv.decodeParcelable(key, null); + } + + /** + * 移除某个key对 + * + * @param key + */ + public void removeKey(String key) { + mmkv.removeValueForKey(key); + } + + /** + * 清除所有key + */ + public void clearAll() { + mmkv.clearAll(); + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MessageIdGenerator.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MessageIdGenerator.java new file mode 100644 index 0000000000..a66594da76 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/MessageIdGenerator.java @@ -0,0 +1,125 @@ +package com.zhidao.support.adas.high.common; + +import com.google.protobuf.InvalidProtocolBufferException; +import com.zhjt.mogo.adas.data.Adas; + +import java.util.Calendar; +import java.util.Collections; +import java.util.Map; + +import mogo.telematics.pad.MessagePad; + +/** + * 发送数据时ID生成器 + * 每天生成的ID重1开始自增,也可以表示为发送的数量 + */ +public class MessageIdGenerator { + private static final String TAG = "MessageIdGenerator"; + private static volatile MessageIdGenerator INSTANCE; + private final static int DEFAULT_COUNT = 30;//默认保留数量 + private final static String KEY_NAME = "send_message_id";//序列化名称 + + private final Adas.MessageIdInfo.Builder messageIdInfoBuilder; + private Adas.LastMessage lastMessage = null; + private final long data;//日期long值 + + + public static MessageIdGenerator getInstance() { + if (INSTANCE == null) { + synchronized (MessageIdGenerator.class) { + if (INSTANCE == null) { + INSTANCE = new MessageIdGenerator(); + } + } + } + return INSTANCE; + } + + private MessageIdGenerator() { + Calendar calendar = Calendar.getInstance(); + // 设置时间为当天的 00:00:00 + calendar.set(Calendar.HOUR_OF_DAY, 0); + calendar.set(Calendar.MINUTE, 0); + calendar.set(Calendar.SECOND, 0); + calendar.set(Calendar.MILLISECOND, 0); + data = calendar.getTimeInMillis(); + + Adas.MessageIdInfo messageIdInfo = null; + byte[] bytes = MMKVUtils.getInstance().getBytes(KEY_NAME); + if (bytes != null) { + try { + messageIdInfo = Adas.MessageIdInfo.parseFrom(bytes); + } catch (InvalidProtocolBufferException e) { + e.printStackTrace(); + } + } + if (messageIdInfo == null) { + messageIdInfoBuilder = Adas.MessageIdInfo.newBuilder(); + } else { + messageIdInfoBuilder = messageIdInfo.toBuilder(); + if (messageIdInfoBuilder.getLastMessagesCount() >= DEFAULT_COUNT) { + long minValue = Collections.min(messageIdInfoBuilder.getLastMessagesMap().keySet()); + messageIdInfoBuilder.removeLastMessages(minValue); + save(); + } + } + initLastMessageData(); + } + + /** + * 获取全部已存储的消息ID + * LastMessage中的msgID如果是0表明今日还未下发任何数据 + * + * @return key:日期毫秒值 value:最后一条消息的相关信息 + */ + + public Map getAllSendMessageId() { + return messageIdInfoBuilder.getLastMessagesMap(); + } + +// private void test() { +// SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()); +// +// for (long l : messageIdInfoBuilder.getLastMessagesMap().keySet()) { +// Log.i("ddddddddddd", "====" + formatter.format(new Date(l))); +// } +// Log.i("ddddddddddd", "==========================="); +// +//// Log.i("ddddddddddd", "日期=" + formatter.format(new Date(data))); +//// lastMessage = messageIdInfoBuilder.getLastMessagesOrDefault(data, null); +//// if (lastMessage != null) { +//// Log.i("ddddddddddd", "消息ID=" + lastMessage.getMsgID()); +//// Log.i("ddddddddddd", "消息类型=" + (lastMessage.getMsgType() == null ? null : lastMessage.getMsgType().name())); +//// Log.i("ddddddddddd", "发送时间=" + (lastMessage.getTimestamp() == 0 ? null : formatter.format(new Date(lastMessage.getTimestamp())))); +//// } +// } + + private void initLastMessageData() { + lastMessage = messageIdInfoBuilder.getLastMessagesOrDefault(data, null); + if (lastMessage == null) { + lastMessage = Adas.LastMessage.newBuilder().setMsgID(0).build(); + messageIdInfoBuilder.putLastMessages(data, lastMessage); + } + } + + private void save() { + MMKVUtils.getInstance().put(KEY_NAME, messageIdInfoBuilder.build().toByteArray()); + } + + /** + * TODO 10000次存储平均耗时=0.2036132830000002毫秒 + * + * @param timestamp + * @param type + * @return + */ + public long getId(long timestamp, MessagePad.MessageType type) { + long id = lastMessage.getMsgID() + 1; + CupidLogUtils.i(TAG, "自增ID=" + id); + lastMessage = lastMessage.toBuilder().setTimestamp(timestamp).setMsgType(type).setMsgID(id).build(); + messageIdInfoBuilder.putLastMessages(data, lastMessage); + save(); +// test(); + return id; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/ReceivedAckManager.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/ReceivedAckManager.java new file mode 100644 index 0000000000..aec7fc9893 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/common/ReceivedAckManager.java @@ -0,0 +1,153 @@ +package com.zhidao.support.adas.high.common; + +import androidx.annotation.NonNull; + +import com.zhjt.mogo.adas.common.MessageType; +import com.zhjt.mogo.adas.data.bean.ReceivedAck; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.atomic.AtomicBoolean; + +import mogo.telematics.pad.MessagePad; + +/** + * 回执消息管理 + */ +public class ReceivedAckManager { + private static final String TAG = ReceivedAckManager.class.getSimpleName(); + private volatile Timer timer; + + private final List list = Collections.synchronizedList(new ArrayList<>()); + private final AtomicBoolean isSupport = new AtomicBoolean(false);//是否支持回执功能 + private OnReceivedAckListener listener; + + public void setListener(OnReceivedAckListener listener) { + this.listener = listener; + } + + public interface OnReceivedAckListener { + /** + * 回执消息 + * + * @param receivedAck 回执 + */ + void onReceiveReceivedAck(@NonNull ReceivedAck receivedAck); + + /** + * 发送回执消息 + * + * @param bytes + */ + void onSendReceivedAck(MessageType messageType, byte[] bytes); + } + + public void setSupport(int version) { + isSupport.set(version >= 30800); + CupidLogUtils.log(TAG, version + " 是否支持回执功能=" + isSupport.get()); + if (!isSupport.get()) { + stop(); + } + } + + /** + * 添加需要回执的消息 + * + * @param sendTime + * @param msgId + * @param messageType + * @param sendData + */ + public void addNeedAckData(long sendTime, long msgId, MessageType messageType, byte[] sendData) { + if (isSupport.get()) { + start(); + list.add(new ReceivedAck(sendTime, msgId, messageType, sendData)); + } else { + stop(); + } + } + + /** + * 接收到回执 + * + * @param time 接收时间 + * @param receivedAck 回执数据 + */ + public void receiveReceivedAck(long time, MessagePad.ReceivedAck receivedAck) { + int count = receivedAck.getMsgidsCount(); + if (!list.isEmpty() && count > 0) { + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + ReceivedAck ack = iterator.next(); + for (int i = 0; i < count; i++) { + long msgId = receivedAck.getMsgids(i); + if (msgId == ack.getMsgId()) { + iterator.remove(); + ack.setTimeout(false); + ack.setReceiveTime(time); + ack.setReceivedAck(receivedAck); + if (listener != null) { + listener.onReceiveReceivedAck(ack); + } + break; + } + } + } + } + } + + + private synchronized void start() { + if (timer == null) { + timer = new Timer(); + timer.schedule(new TimerTask() { + @Override + public void run() { + if (!list.isEmpty()) { + long time = System.currentTimeMillis(); + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + ReceivedAck ack = iterator.next(); + if (time - ack.getSendTime() > ack.getMessageType().timeoutMillis) { + //超时 + iterator.remove(); + ack.setTimeout(true); + if (listener != null) { + listener.onReceiveReceivedAck(ack); + } + } + } + } + } + }, 2000L, 1000L); + } + } + + public void stop() { + if (!list.isEmpty()) { + list.clear(); + } + if (timer != null) { + timer.cancel(); + timer = null; + } + } + + /** + * 打包回执数据 + * + * @param msgID 要回复的消息ID + */ + public void sendReceivedAck(long msgID) { + MessagePad.ReceivedAck receivedAck = MessagePad.ReceivedAck.newBuilder() + .addMsgids(msgID) + .build(); + if (listener != null) { + listener.onSendReceivedAck(MessageType.TYPE_SEND_RECEIVED_ACK, receivedAck.toByteArray()); + } + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/CarConfigRespMessage.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/CarConfigRespMessage.java index f4a0eafc1c..36e0fb2fea 100644 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/CarConfigRespMessage.java +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/CarConfigRespMessage.java @@ -34,7 +34,7 @@ public class CarConfigRespMessage extends MyAbstractMessageHandler { adasListener.onCarConfigResp(raw.getHeader(), carConfigResp); } AdasChannel.calculateTimeConsumingBusiness("车机基础信息应答", nowTime); - CupidLogUtils.e("车机基础信息应答--->" + carConfigResp); + CupidLogUtils.e("CarConfigRespMessage", "车机基础信息应答--->" + carConfigResp); } /** diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/MyMessageFactory.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/MyMessageFactory.java index 0e8824fa9c..4c87b3583b 100644 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/MyMessageFactory.java +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/msg/MyMessageFactory.java @@ -1,7 +1,7 @@ package com.zhidao.support.adas.high.msg; import com.zhidao.support.adas.high.common.AutopilotReview; -import com.zhidao.support.adas.high.common.MessageType; +import com.zhjt.mogo.adas.common.MessageType; import mogo.telematics.pad.MessagePad; diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/protocol/RawPack.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/protocol/RawPack.java index 0a2154162b..a045467a98 100644 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/protocol/RawPack.java +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/protocol/RawPack.java @@ -1,9 +1,10 @@ package com.zhidao.support.adas.high.protocol; -import com.zhjt.mogo.adas.utils.ByteUtil; import com.zhidao.support.adas.high.common.Constants; - -import java.util.concurrent.atomic.AtomicLong; +import com.zhidao.support.adas.high.common.MessageIdGenerator; +import com.zhidao.support.adas.high.common.ReceivedAckManager; +import com.zhjt.mogo.adas.common.MessageType; +import com.zhjt.mogo.adas.utils.ByteUtil; import mogo.telematics.pad.MessagePad; @@ -17,24 +18,30 @@ import mogo.telematics.pad.MessagePad; public class RawPack { private static final String TAG = RawPack.class.getSimpleName(); private final DefaultMessageProtocol messageProtocol; - private final AtomicLong msgID = new AtomicLong(0L); + private final ReceivedAckManager receivedAckManager; - public RawPack() { + public RawPack(ReceivedAckManager receivedAckManager) { + this.receivedAckManager = receivedAckManager; messageProtocol = new DefaultMessageProtocol(); } - public synchronized byte[] pack(MessagePad.MessageType msgType, byte[] data) { + public synchronized byte[] pack(MessageType msgType, byte[] data) { if (msgType == null) { return null; } - double time = System.currentTimeMillis() / 1000.0; + long timeMillis = System.currentTimeMillis(); + MessagePad.MessageType type = msgType.typeCode; + double time = timeMillis / 1000.0; + boolean isNeedAck = msgType.timeoutMillis > 0; + long msgId = MessageIdGenerator.getInstance().getId(timeMillis, type); //封装Header MessagePad.Header.Builder headerBuilder = MessagePad.Header.newBuilder(); - headerBuilder.setMsgID(msgID.incrementAndGet());//消息唯一ID,生成数据累加。从1开始,连接未重新初始化就一直累加 - headerBuilder.setMsgType(msgType); + headerBuilder.setMsgID(msgId);//消息唯一ID,生成数据累加。从1开始,连接未重新初始化就一直累加 + headerBuilder.setMsgType(type); headerBuilder.setTimestamp(time); headerBuilder.setSourceTimestamp(time); + headerBuilder.setNeedAck(isNeedAck ? 1 : 0); MessagePad.Header headerPb = headerBuilder.build(); int lengthValue = messageProtocol.getOutHeaderLength() + headerPb.getSerializedSize();//数据总长度 byte[] offset = getOffset(lengthValue); @@ -56,6 +63,9 @@ public class RawPack { if (data != null && data.length > 0) { System.arraycopy(data, 0, msg, messageProtocol.getOutHeaderLength() + header.length, data.length); } + if (isNeedAck) { + receivedAckManager.addNeedAckData(timeMillis, msgId, msgType, msg); + } return msg; } diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/FpgaSocket.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/FpgaSocket.java index 6b0039dcca..efcb7fec65 100644 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/FpgaSocket.java +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/socket/FpgaSocket.java @@ -15,12 +15,12 @@ import androidx.annotation.NonNull; import com.google.protobuf.InvalidProtocolBufferException; import com.zhidao.support.adas.high.AdasChannel; -import com.zhjt.mogo.adas.utils.ByteUtil; import com.zhidao.support.adas.high.common.CupidLogUtils; import com.zhidao.support.adas.high.common.ReceiveTimeoutManager; import com.zhidao.support.adas.high.common.ReconnectManager; import com.zhidao.support.adas.high.queue.WSByteQueueManager; import com.zhidao.support.adas.high.queue.WebSocketQueueManager; +import com.zhjt.mogo.adas.utils.ByteUtil; import com.zhjt.service.chain.ChainLog; import java.util.Locale; @@ -61,7 +61,7 @@ public class FpgaSocket implements IWebSocket { private String wsHost; private String ipAddress; private int port; - + private boolean isEnableReconnect = true;//是否启用重连机制 /** * 是否是用户主动关闭socket */ @@ -79,12 +79,18 @@ public class FpgaSocket implements IWebSocket { * 接收数据超时原因 null时表示不是接收数据超时的原因 */ private volatile String receiveTimeoutReason = null; + private Context context; public FpgaSocket(Context context) { - init(context); + this.context = context; + init(); } - private void init(Context context) { + public boolean isConnected() { + return isConnected.get(); + } + + private void init() { listener = new EchoWebSocketListener(); OkHttpClient.Builder okBuilder = new OkHttpClient.Builder(); okBuilder.writeTimeout(4, TimeUnit.SECONDS) @@ -97,15 +103,29 @@ public class FpgaSocket implements IWebSocket { onPassiveClose(1001, receiveTimeoutReason); } }); - reconnectManager = new ReconnectManager(context, new ReconnectManager.OnReconnectListener() { - @Override - public void onReconnection(String tag) { - connect("重连中(" + tag + ")"); - } - }); client = okBuilder.build(); } + //配置是否启用重连 + public void setEnableReconnect(boolean enableReconnect) { + isEnableReconnect = enableReconnect; + Log.i(TAG, "是否启动自动重连=" + enableReconnect); + if (isEnableReconnect) { + if (reconnectManager == null) + reconnectManager = new ReconnectManager(context, new ReconnectManager.OnReconnectListener() { + @Override + public void onReconnection(String tag) { + connect("重连中(" + tag + ")"); + } + }); + } else { + if (reconnectManager != null) { + reconnectManager.stop(); + reconnectManager = null; + } + } + } + @Override public void connectWebSocket(String address, int port) { this.ipAddress = address; @@ -124,18 +144,30 @@ public class FpgaSocket implements IWebSocket { Request request = new Request.Builder() .url(wsHost) .build(); - mWebSocket = new RealWebSocket(request, listener, new Random(), 0); + mWebSocket = new RealWebSocket(request, listener, new Random(), client.pingIntervalMillis()); mWebSocket.connect(client); // mWebSocket = client.newWebSocket(request, listener); } } + private void reconnectCmd(boolean isStart) { + if (reconnectManager != null) { + if (isStart) { + if (isEnableReconnect) { + reconnectManager.start(); + } + } else { + reconnectManager.stop(); + } + } + } + /** * 重连 */ private void reconnect() { if (!isUserClose.get()) { - reconnectManager.start(); + reconnectCmd(true); } else { isUserClose.set(false); } @@ -149,7 +181,7 @@ public class FpgaSocket implements IWebSocket { } isUserClose.set(true); isPassiveClose.set(false); - reconnectManager.stop(); + reconnectCmd(false); if (mWebSocket != null) { close(true, 1000); } else { @@ -214,7 +246,7 @@ public class FpgaSocket implements IWebSocket { if (!isConnect) { onPassiveClose(1001, "協議不匹配"); } else { - reconnectManager.stop(); + reconnectCmd(false); ReceiveTimeoutManager.getInstance().start(); CupidLogUtils.i(TAG, "WebSocket 连接成功"); if (mWebSocketConnectListener != null) diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/subscribe/SubscribeInterface.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/subscribe/SubscribeInterface.java index db142ba712..3c3d4cc24f 100644 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/subscribe/SubscribeInterface.java +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/subscribe/SubscribeInterface.java @@ -1,10 +1,11 @@ package com.zhidao.support.adas.high.subscribe; + import androidx.annotation.NonNull; import com.zhidao.support.adas.high.common.Constants; import com.zhidao.support.adas.high.common.Define; -import com.zhidao.support.adas.high.common.MessageType; +import com.zhjt.mogo.adas.common.MessageType; import java.util.HashMap; import java.util.Map; @@ -36,6 +37,7 @@ public class SubscribeInterface { public SubscribeInterface(@NonNull OnSubscribeInterfaceListener listener) { this.listener = listener; + if (listener == null) throw new RuntimeException(); init(); } @@ -61,8 +63,10 @@ public class SubscribeInterface { * @param role 角色 详情参见{@link Constants.TERMINAL_ROLE} * @param type 注册类型 详情参见{@link Constants.SUBSCRIBE_TYPE} * @param messageTypes 要操作的接口 + * @return */ public boolean subscribeInterface(@Define.TerminalRole int role, @Define.SubscribeType int type, @NonNull Set messageTypes) { + if (messageTypes == null) return false; MessagePad.SubscribeDataReq.Builder builder = MessagePad.SubscribeDataReq.newBuilder(); builder.setRole(role).setReqType(type); Map temp = new HashMap<>(); @@ -86,6 +90,8 @@ public class SubscribeInterface { } } } + + return isSendSucceed; } @@ -98,6 +104,7 @@ public class SubscribeInterface { * @return 是否加入ws发送队列 */ public boolean subscribeInterface(@Define.TerminalRole int role, @Define.SubscribeType int type, @NonNull MessageType messageType) { + if (messageType == null) return false; MessagePad.SubscribeDataReq.Builder builder = MessagePad.SubscribeDataReq.newBuilder(); builder.setRole(role).setReqType(type).addDataTypes(messageType.typeCode.getNumber()); boolean isSendSucceed = listener.onSendSubscribe(builder.build().toByteArray()); diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/subscribe/SubscribeInterfaceOption.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/subscribe/SubscribeInterfaceOption.java new file mode 100644 index 0000000000..fd013b9c51 --- /dev/null +++ b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/subscribe/SubscribeInterfaceOption.java @@ -0,0 +1,49 @@ +package com.zhidao.support.adas.high.subscribe; + +import androidx.annotation.NonNull; + +import com.zhidao.support.adas.high.common.Constants; +import com.zhidao.support.adas.high.common.Define; +import com.zhjt.mogo.adas.common.MessageType; + +import java.util.Set; + +/** + * 订阅参数 + */ +public class SubscribeInterfaceOption { + @Define.TerminalRole + private int role = Constants.TERMINAL_ROLE.DRIVER; + @Define.SubscribeType + private int type = Constants.SUBSCRIBE_TYPE.UNSUBSCRIBE; + private MessageType messageType = null;//操作一个接口 + private Set messageTypes = null;//操作多个接口 + + public SubscribeInterfaceOption(@Define.TerminalRole int role, @Define.SubscribeType int type, @NonNull MessageType messageType) { + this.role = role; + this.type = type; + this.messageType = messageType; + } + + public SubscribeInterfaceOption(@Define.TerminalRole int role, @Define.SubscribeType int type, @NonNull Set messageTypes) { + this.role = role; + this.type = type; + this.messageTypes = messageTypes; + } + + public int getRole() { + return role; + } + + public int getType() { + return type; + } + + public MessageType getMessageType() { + return messageType; + } + + public Set getMessageTypes() { + return messageTypes; + } +} diff --git a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/subscribe/SubscribeInterfaceOptions.java b/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/subscribe/SubscribeInterfaceOptions.java deleted file mode 100644 index 7d133a5723..0000000000 --- a/libraries/mogo-adas/src/main/java/com/zhidao/support/adas/high/subscribe/SubscribeInterfaceOptions.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.zhidao.support.adas.high.subscribe; - -import com.zhidao.support.adas.high.common.Constants; -import com.zhidao.support.adas.high.common.Define; -import com.zhidao.support.adas.high.common.MessageType; - -import java.util.Set; - -/** - * 订阅参数 - */ -public class SubscribeInterfaceOptions { - @Define.TerminalRole - private int role = Constants.TERMINAL_ROLE.DRIVER; - @Define.SubscribeType - private int type = Constants.SUBSCRIBE_TYPE.UNSUBSCRIBE; - private Set messageTypes; - - private SubscribeInterfaceOptions() { - } - - public int getRole() { - return role; - } - - public int getType() { - return type; - } - - public Set getMessageTypes() { - return messageTypes; - } - - public static Builder newBuilder() { - return new Builder(); - } - - public static class Builder { - @Define.TerminalRole - private int role; - @Define.SubscribeType - private int type; - private Set messageTypes; - - private Builder() { - } - - public Builder setRole(@Define.TerminalRole int role) { - this.role = role; - return this; - } - - public Builder setType(@Define.SubscribeType int type) { - this.type = type; - return this; - } - - public Builder setMessageTypes(Set messageTypes) { - this.messageTypes = messageTypes; - return this; - } - - public SubscribeInterfaceOptions build() { - SubscribeInterfaceOptions options = new SubscribeInterfaceOptions(); - options.role = role; - options.type = type; - options.messageTypes = messageTypes; - return options; - } - } -}