合并大唐高鸿obu,增加debug入口,去掉了vrMode按钮入口
This commit is contained in:
@@ -20,18 +20,22 @@ class ObuManager {
|
||||
|
||||
private lateinit var obu: IObu
|
||||
private lateinit var context: Context
|
||||
private var listener:IObuCallback? = null
|
||||
|
||||
fun init(context: Context) {
|
||||
Logger.d(TAG, "init=======")
|
||||
Logger.d(TAG, "init=======${DebugConfig.getObuType()}")
|
||||
this.context = context
|
||||
obu = if (DebugConfig.getObuType() == DebugConfig.OBU_TYPE_CIDI) {
|
||||
CidiObu()
|
||||
} else {
|
||||
HualiObu()
|
||||
obu = when (DebugConfig.getObuType()) {
|
||||
DebugConfig.OBU_TYPE_CIDI -> CidiObu()
|
||||
DebugConfig.OBU_TYPE_HUALI -> HualiObu()
|
||||
else -> NetCarObu()
|
||||
}
|
||||
obu.init()
|
||||
obu.init(context)
|
||||
|
||||
}
|
||||
|
||||
fun registerObuDataChangedListener(listener: IObuCallback?) {
|
||||
this.listener = listener
|
||||
if (listener != null) {
|
||||
obu.registerObuCallback(listener)
|
||||
if(DebugConfig.isUseMockObuData() ) {
|
||||
@@ -41,5 +45,9 @@ class ObuManager {
|
||||
}
|
||||
}
|
||||
|
||||
fun resetObuType(obuType: Int) {
|
||||
Logger.d(TAG, "resetObuType: $obuType")
|
||||
obu.release()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +1,16 @@
|
||||
package com.zhidao.mogo.module.obu.obu
|
||||
|
||||
import android.content.Context
|
||||
|
||||
abstract class BaseObu : IObu {
|
||||
var callback: IObuCallback? = null
|
||||
override fun init() {
|
||||
override fun init(context: Context) {
|
||||
}
|
||||
|
||||
override fun registerObuCallback(callback: IObuCallback) {
|
||||
this.callback = callback
|
||||
}
|
||||
|
||||
override fun release() {
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.zhidao.mogo.module.obu.obu
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Message
|
||||
import com.mogo.commons.debug.DebugConfig
|
||||
@@ -26,8 +27,8 @@ class CidiObu : BaseObu(), Handler.Callback, OnMessageReceiveListener {
|
||||
}
|
||||
|
||||
private val handler = Handler(this)
|
||||
override fun init() {
|
||||
super.init()
|
||||
override fun init(context: Context) {
|
||||
super.init(context)
|
||||
// 初始化sdk,注册数据回调等信息
|
||||
V2xController.getInstance().setMessageReceiveListener(this)
|
||||
V2xController.getInstance().init()
|
||||
@@ -120,4 +121,11 @@ class CidiObu : BaseObu(), Handler.Callback, OnMessageReceiveListener {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun release() {
|
||||
super.release()
|
||||
handler.removeMessages(MSG_MONITOR_OBU_STATUS)
|
||||
V2xController.getInstance().setMessageReceiveListener(null)
|
||||
V2xController.getInstance().release()
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.zhidao.mogo.module.obu.obu
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.SystemClock
|
||||
import android.util.ArrayMap
|
||||
@@ -62,8 +63,8 @@ class HualiObu : BaseObu(), IUdpSocketCallback {
|
||||
|
||||
private val handler = Handler()
|
||||
|
||||
override fun init() {
|
||||
super.init()
|
||||
override fun init(context: Context) {
|
||||
super.init(context)
|
||||
socketManager.connect(IP_ADDRESS, PORT)
|
||||
Logger.d(TAG, "init")
|
||||
}
|
||||
@@ -308,4 +309,9 @@ class HualiObu : BaseObu(), IUdpSocketCallback {
|
||||
private fun convertTwoUnSignInt(byteArray: ByteArray): Int =
|
||||
(byteArray[0].toInt() shl 24) or (byteArray[1].toInt() and 0xFF) or (byteArray[2].toInt() shl 8) or (byteArray[3].toInt() and 0xFF)
|
||||
|
||||
override fun release() {
|
||||
super.release()
|
||||
socketManager.release()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.zhidao.mogo.module.obu.obu
|
||||
|
||||
import android.content.Context
|
||||
|
||||
/**
|
||||
* Obu基本方法
|
||||
* @author tongchenfei
|
||||
@@ -8,11 +10,15 @@ interface IObu {
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
fun init()
|
||||
fun init(context: Context)
|
||||
|
||||
/**
|
||||
* 注册数据回调
|
||||
*/
|
||||
fun registerObuCallback(callback: IObuCallback)
|
||||
|
||||
/**
|
||||
* release
|
||||
*/
|
||||
fun release()
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
package com.zhidao.mogo.module.obu.obu
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Message
|
||||
import com.mogo.utils.logger.Logger
|
||||
import com.mogo.utils.network.utils.GsonUtil
|
||||
import com.zhidao.mogo.module.obu.ObuConstant.TYPE_OPTIMAL_SPEED_ADVISORY
|
||||
import com.zhidao.mogo.module.obu.ObuConstant.TYPE_ROAD_USER_COLLISION_WARNING
|
||||
import com.zhidao.mogo.module.obu.obu.bean.MogoObuEventInfo
|
||||
import com.zhidao.mogo.module.obu.obu.bean.MogoObuTrafficLightInfo
|
||||
import com.zhidao.mogo.module.obu.socket.IUdpSocketStatusCallback
|
||||
import com.zhidao.mogo.module.obu.socket.UdpSocketManager
|
||||
import org.json.JSONObject
|
||||
|
||||
/**
|
||||
* 大唐高鸿obu
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
class NetCarObu : BaseObu(), IUdpSocketStatusCallback, Handler.Callback {
|
||||
companion object {
|
||||
const val TAG = "NetCarObu"
|
||||
const val MSG_SEND_ACTIVATION_MSG = 1001
|
||||
const val MSG_RECONNECT = 1002
|
||||
const val SEND_ACTIVATION_MSG_DELAY = 4 * 1000L
|
||||
const val RECONNECT_DELAY = 10_000L
|
||||
const val TARGET_IP = "192.168.118.104"
|
||||
const val TARGET_PORT = 50500
|
||||
}
|
||||
|
||||
private lateinit var socketManager: UdpSocketManager
|
||||
|
||||
private val handler = Handler(this)
|
||||
|
||||
override fun init(context: Context) {
|
||||
super.init(context)
|
||||
Logger.d(TAG, "NetCar obu init")
|
||||
socketManager = UdpSocketManager(context = context, useDefaultAddress = true, callback = this)
|
||||
}
|
||||
|
||||
override fun isReady() {
|
||||
Logger.d(TAG, "udp is ready")
|
||||
// 1. 向obu注册
|
||||
sendRegisterMsg()
|
||||
}
|
||||
|
||||
private var unique: String = ""
|
||||
|
||||
override fun onMessageReceived(msg: ByteArray) {
|
||||
val response = String(msg)
|
||||
val json = JSONObject(response)
|
||||
Logger.d(TAG, "收到消息: $json")
|
||||
when (json.optInt("tag")) {
|
||||
1002 -> {
|
||||
// 查询状态成功,准备注册
|
||||
socketManager.defaultAddress?.let {
|
||||
socketManager.sendMsgTo(GsonUtil.jsonFromObject(Request(2001, NcsRegisteredData(it.ip, it.port))), TARGET_IP, TARGET_PORT)
|
||||
startReconnectTiming()
|
||||
}
|
||||
}
|
||||
2002 -> {
|
||||
// 响应注册
|
||||
val rsp = json.optInt("rsp", -1)
|
||||
if (rsp == 0) {
|
||||
// 注册成功, 等待激活
|
||||
unique = json.optString("unique", "")
|
||||
startActivationTiming()
|
||||
}
|
||||
}
|
||||
2004 -> {
|
||||
// 响应解除注册
|
||||
val rsp = json.optInt("rsp", -1)
|
||||
if (rsp == 0) {
|
||||
// 解除注册成功
|
||||
socketManager.release()
|
||||
}
|
||||
}
|
||||
2006 -> {
|
||||
// 响应激活
|
||||
val rsp = json.optInt("rsp", -1)
|
||||
if (rsp != 0) {
|
||||
// 激活失败,需要重新激活
|
||||
sendActivationMsg()
|
||||
} else {
|
||||
// 激活成功,重新计时
|
||||
startActivationTiming()
|
||||
}
|
||||
}
|
||||
2104 -> {
|
||||
// 红绿灯倒数秒数上报(车速引导)
|
||||
val dataJson = json.optJSONObject("data")
|
||||
if (dataJson != null) {
|
||||
// val lightInfo = dataJson.optJSONObject("phase")
|
||||
val lightInfoArray = dataJson.optJSONArray("phase")
|
||||
|
||||
if (lightInfoArray != null && lightInfoArray.length() > 0) {
|
||||
Logger.d(TAG, "lightInfo: $lightInfoArray")
|
||||
val lightInfo = lightInfoArray.getJSONObject(0)
|
||||
|
||||
val trafficLightInfo = MogoObuTrafficLightInfo()
|
||||
val color = lightInfo.optInt("color")
|
||||
if (color in 1..3) {
|
||||
// 有效颜色数据
|
||||
trafficLightInfo.lightStatus = when (color) {
|
||||
2 -> "R"
|
||||
3 -> "Y"
|
||||
else -> "G"
|
||||
}
|
||||
trafficLightInfo.surplusTime = lightInfo.optInt("time", 0).toString()
|
||||
callback?.onTrafficLightInfoCallback(trafficLightInfo)
|
||||
|
||||
// val end = lightInfo.optInt("guide_speed_max", -1)
|
||||
// val start = lightInfo.optInt("guide_speed_min", -1)
|
||||
// if (start != -1 && end != -1) {
|
||||
// val eventInfo = MogoObuEventInfo()
|
||||
// eventInfo.mogoEventId = TYPE_OPTIMAL_SPEED_ADVISORY
|
||||
// eventInfo.describe = "前方路口,建议车速 $start 到 $end km/h"
|
||||
// callback?.let {
|
||||
// handler.post {
|
||||
// it.onEventInfoCallback(eventInfo)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
} else {
|
||||
Logger.e(TAG, "红绿灯数据为空")
|
||||
}
|
||||
} else {
|
||||
Logger.e(TAG, "红绿灯数据为data空")
|
||||
}
|
||||
}
|
||||
2105 -> {
|
||||
// 事件上报
|
||||
val event = json.optJSONObject("data")
|
||||
if (event != null) {
|
||||
val type = event.optInt("type", 0) % 100000
|
||||
Logger.d(TAG, "事件id,取模后: $type")
|
||||
if (type == 4012) {
|
||||
// 前方行人预警
|
||||
val eventInfo = MogoObuEventInfo()
|
||||
eventInfo.mogoEventId = TYPE_ROAD_USER_COLLISION_WARNING
|
||||
handler.post {
|
||||
callback?.onEventInfoCallback(eventInfo)
|
||||
}
|
||||
} else if (type == 3005) {
|
||||
// 红绿灯变灯提醒
|
||||
val eventInfo = MogoObuEventInfo()
|
||||
eventInfo.type = "vip变灯提醒"
|
||||
eventInfo.typeCode = "vip变灯提醒"
|
||||
eventInfo.describe = "将为您变灯,vip车辆可优先通行"
|
||||
handler.post {
|
||||
callback?.onEventInfoCallback(eventInfo)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Logger.e(TAG, "事件数据为空")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendRegisterMsg() {
|
||||
socketManager.defaultAddress?.let {
|
||||
socketManager.sendMsgTo(GsonUtil.jsonFromObject(Request<NcsRegisteredData>(2001, NcsRegisteredData(it.ip, it.port))), TARGET_IP, TARGET_PORT)
|
||||
startReconnectTiming()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启激活计时
|
||||
*/
|
||||
private fun startActivationTiming() {
|
||||
handler.removeMessages(MSG_SEND_ACTIVATION_MSG)
|
||||
handler.removeMessages(MSG_RECONNECT)
|
||||
handler.sendEmptyMessageDelayed(MSG_SEND_ACTIVATION_MSG, SEND_ACTIVATION_MSG_DELAY)
|
||||
}
|
||||
|
||||
private fun startReconnectTiming() {
|
||||
handler.removeMessages(MSG_RECONNECT)
|
||||
handler.sendEmptyMessageDelayed(MSG_RECONNECT, RECONNECT_DELAY)
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送激活数据
|
||||
*/
|
||||
private fun sendActivationMsg() {
|
||||
Logger.d(TAG, "准备发送激活消息====")
|
||||
socketManager.sendMsgTo(GsonUtil.jsonFromObject(NcsActivationRequest(unique = unique)), TARGET_IP, TARGET_PORT)
|
||||
startReconnectTiming()
|
||||
}
|
||||
|
||||
override fun handleMessage(msg: Message): Boolean {
|
||||
return when (msg.what) {
|
||||
MSG_SEND_ACTIVATION_MSG -> {
|
||||
sendActivationMsg()
|
||||
true
|
||||
}
|
||||
MSG_RECONNECT -> {
|
||||
if (!handler.hasMessages(MSG_SEND_ACTIVATION_MSG)) {
|
||||
// 没有等待激活,就进行重试
|
||||
Logger.d(TAG, "准备重连===")
|
||||
sendRegisterMsg()
|
||||
}
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
val firstMsg = "{\"tag\":1001}"
|
||||
|
||||
override fun release() {
|
||||
super.release()
|
||||
// 解除注册
|
||||
socketManager.sendMsgTo(GsonUtil.jsonFromObject(NcsUnRegisteredRequest(unique = unique)), TARGET_IP, TARGET_PORT)
|
||||
}
|
||||
|
||||
data class Request<T>(val tag: Int, val data: T)
|
||||
|
||||
/**
|
||||
* 注册请求data
|
||||
*/
|
||||
data class NcsRegisteredData(val ip: String, val port: Int)
|
||||
|
||||
/**
|
||||
* 解注册请求request
|
||||
*/
|
||||
data class NcsUnRegisteredRequest(val tag: Int = 2003, val unique: String)
|
||||
|
||||
/**
|
||||
* 激活请求
|
||||
*/
|
||||
data class NcsActivationRequest(val tag: Int = 2005, val unique: String)
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.zhidao.mogo.module.obu.socket
|
||||
|
||||
/**
|
||||
* udp 数据回调
|
||||
*/
|
||||
interface ISocketMsgCallback {
|
||||
/**
|
||||
* udp过来的字节码数据,目前已知数据类型就是ByteArray
|
||||
*
|
||||
* @param msg udp发过来的数据
|
||||
*/
|
||||
fun onMessageReceived(msg: ByteArray)
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.zhidao.mogo.module.obu.socket
|
||||
|
||||
/**
|
||||
* udp状态回调
|
||||
*/
|
||||
interface IUdpSocketStatusCallback:ISocketMsgCallback {
|
||||
/**
|
||||
* udp连接准备完毕,指的是准备好接收数据了
|
||||
*/
|
||||
fun isReady()
|
||||
}
|
||||
@@ -72,4 +72,9 @@ class SimpleSocketManager(private val callback: IUdpSocketCallback? = null) {
|
||||
fun sendMessage(msg: String) {
|
||||
Logger.d(TAG, "暂不支持发送消息")
|
||||
}
|
||||
|
||||
fun release(){
|
||||
socket?.close()
|
||||
dataCacheHandler.looper.quitSafely()
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
package com.zhidao.mogo.module.obu.socket
|
||||
|
||||
import android.content.Context
|
||||
import android.net.wifi.WifiManager
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.util.ArrayMap
|
||||
import com.mogo.utils.NetworkUtils
|
||||
import com.mogo.utils.logger.Logger
|
||||
import java.lang.Thread.sleep
|
||||
import java.net.DatagramPacket
|
||||
import java.net.DatagramSocket
|
||||
import java.net.InetAddress
|
||||
@@ -12,9 +16,11 @@ import java.util.concurrent.Executors
|
||||
/**
|
||||
* udp socket 管理类,统一管理udp socket数据接收和发送
|
||||
*/
|
||||
class UdpSocketManager(private val callback: IUdpSocketCallback? = null) {
|
||||
class UdpSocketManager(val context: Context? = null, useDefaultAddress: Boolean = false, private val callback: IUdpSocketStatusCallback? = null) {
|
||||
companion object {
|
||||
const val TAG = "Mogo-UdpSocketManager"
|
||||
const val DEFAULT_PORT = 50501
|
||||
const val DEFAULT_IP = "192.168.8.169"
|
||||
}
|
||||
|
||||
private val socketMap = ArrayMap<SimpleAddress, DatagramSocket>()
|
||||
@@ -23,20 +29,66 @@ class UdpSocketManager(private val callback: IUdpSocketCallback? = null) {
|
||||
private val dataCacheThread = HandlerThread("obu-data-cache")
|
||||
private val dataCacheHandler: Handler
|
||||
|
||||
var defaultAddress:SimpleAddress? = null
|
||||
|
||||
init {
|
||||
dataCacheThread.start()
|
||||
dataCacheHandler = Handler(dataCacheThread.looper)
|
||||
if (useDefaultAddress) {
|
||||
// 获取连接的wifi的ip地址
|
||||
if (context == null) {
|
||||
throw IllegalArgumentException("do not find context at constructor")
|
||||
}else{
|
||||
// defaultAddress = SimpleAddress(DEFAULT_IP, DEFAULT_PORT)
|
||||
// receiveMsgFrom(DEFAULT_IP, DEFAULT_PORT)
|
||||
if (NetworkUtils.isConnectedWifi(context)) {
|
||||
// 已经判定连接到了wifi
|
||||
generateDefaultAddress()
|
||||
}else{
|
||||
// 还没连接到wifi,需要等待,此处采用每隔一秒检查一次,不用再注册相关监听广播
|
||||
dataCacheHandler.post {
|
||||
while (!NetworkUtils.isConnectedWifi(context)) {
|
||||
sleep(1000)
|
||||
}
|
||||
// 已经连接到wifi
|
||||
generateDefaultAddress()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Volatile
|
||||
private var isConnected = false
|
||||
|
||||
fun sendMsgTo(msg: String, ip: String, port: Int) {
|
||||
Logger.d(TAG, "sendMsg: $msg to $ip:$port")
|
||||
isConnected = true
|
||||
val address = SimpleAddress(ip, port)
|
||||
socketExecutor.execute(UdpSenderRunnable(address, msg))
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅获取连接wifi后的ip地址,使用默认端口进行数据接收
|
||||
*/
|
||||
private fun generateDefaultAddress(){
|
||||
context?.let {
|
||||
val wifiManager = it.getSystemService(Context.WIFI_SERVICE) as WifiManager
|
||||
val wifiInfo = wifiManager.connectionInfo
|
||||
val ip = intIp2StringIp(wifiInfo.ipAddress)
|
||||
Logger.d(TAG, "获取到本机ip地址: $ip")
|
||||
defaultAddress = SimpleAddress(ip, DEFAULT_PORT)
|
||||
// 生成了默认地址,开始准备接受数据
|
||||
receiveMsgFrom(ip, DEFAULT_PORT)
|
||||
}
|
||||
}
|
||||
|
||||
private fun intIp2StringIp(ip: Int):String {
|
||||
return "${ip and 0xff}.${(ip shr 8) and 0xff}.${(ip shr 16) and 0xff}.${(ip shr 24) and 0xff}"
|
||||
}
|
||||
|
||||
private var isReady = false
|
||||
|
||||
fun receiveMsgFrom(ip: String, port: Int) {
|
||||
isConnected = true
|
||||
val address = SimpleAddress(ip, port)
|
||||
@@ -78,6 +130,10 @@ class UdpSocketManager(private val callback: IUdpSocketCallback? = null) {
|
||||
if (socket.isClosed) {
|
||||
break
|
||||
}
|
||||
if (!isReady) {
|
||||
isReady = true
|
||||
callback?.isReady()
|
||||
}
|
||||
Logger.d(TAG, "准备接受消息====$address")
|
||||
socket.receive(packet)
|
||||
val msg = ByteArray(buffer.size)
|
||||
@@ -91,4 +147,5 @@ class UdpSocketManager(private val callback: IUdpSocketCallback? = null) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user