|
@@ -0,0 +1,842 @@
|
|
|
+package com.wdkl.app.ncs.conversion_box.activity
|
|
|
+
|
|
|
+import android.app.AlarmManager
|
|
|
+import android.content.BroadcastReceiver
|
|
|
+import android.content.Context
|
|
|
+import android.content.Intent
|
|
|
+import android.content.IntentFilter
|
|
|
+import android.net.ConnectivityManager
|
|
|
+import android.os.*
|
|
|
+import android.support.v4.app.Fragment
|
|
|
+import android.text.TextUtils
|
|
|
+import android.util.Log
|
|
|
+import android.view.View
|
|
|
+import com.enation.javashop.android.jrouter.external.annotation.Router
|
|
|
+import com.enation.javashop.net.engine.model.NetState
|
|
|
+import com.google.gson.Gson
|
|
|
+import com.wdkl.app.ncs.conversion_box.BuildConfig
|
|
|
+import com.wdkl.app.ncs.conversion_box.R
|
|
|
+import com.wdkl.app.ncs.conversion_box.bean.SosItem
|
|
|
+import com.wdkl.app.ncs.conversion_box.databinding.OfflineMainActivityLayoutBinding
|
|
|
+import com.wdkl.app.ncs.conversion_box.fragment.OfflineMainFragment
|
|
|
+import com.wdkl.app.ncs.conversion_box.fragment.SipCallFragment
|
|
|
+import com.wdkl.app.ncs.conversion_box.helper.*
|
|
|
+import com.wdkl.app.ncs.conversion_box.launch.MainLaunch
|
|
|
+import com.wdkl.app.ncs.conversion_box.rtc.client.IUserState
|
|
|
+import com.wdkl.app.ncs.conversion_box.rtc.client.SocketManager
|
|
|
+import com.wdkl.app.ncs.conversion_box.settings.SettingConfig
|
|
|
+import com.wdkl.ncs.android.lib.base.BaseActivity
|
|
|
+import com.wdkl.ncs.android.lib.base.BaseApplication
|
|
|
+import com.wdkl.ncs.android.lib.utils.AppTool
|
|
|
+import com.wdkl.ncs.android.lib.utils.TimeHandle
|
|
|
+import com.wdkl.ncs.android.lib.utils.showMessage
|
|
|
+import com.wdkl.ncs.android.lib.vo.filter
|
|
|
+import com.wdkl.ncs.android.middleware.api.UrlManager
|
|
|
+import com.wdkl.ncs.android.middleware.common.Constant
|
|
|
+import com.wdkl.ncs.android.middleware.common.MessageEvent
|
|
|
+import com.wdkl.ncs.android.middleware.greendao.DaoManager
|
|
|
+import com.wdkl.ncs.android.middleware.logic.contract.conversion_box.MainActivityContract
|
|
|
+import com.wdkl.ncs.android.middleware.logic.presenter.conversion_box.MainActivityPresenter
|
|
|
+import com.wdkl.ncs.android.middleware.model.ServerInfo
|
|
|
+import com.wdkl.ncs.android.middleware.model.dos.AppVersionDO
|
|
|
+import com.wdkl.ncs.android.middleware.model.dos.PartSettingDO
|
|
|
+import com.wdkl.ncs.android.middleware.model.dto.TcpSeverDTO
|
|
|
+import com.wdkl.ncs.android.middleware.model.vo.DeviceNurseInfoVO
|
|
|
+import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.channel.OtherUtil
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.channel.VoiceUtil
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.dto.TcpModel
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.enums.DeviceTypeEnum
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpAction
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpType
|
|
|
+import com.wdkl.ncs.android.middleware.udp2.UdpIndex
|
|
|
+import com.wdkl.ncs.android.middleware.udp2.UdpItem
|
|
|
+import com.wdkl.ncs.android.middleware.udp2.UdpSendUtil
|
|
|
+import com.wdkl.ncs.android.middleware.utils.CommonUtils
|
|
|
+import com.wdkl.ncs.janus.rtc2.SkyEngineKit
|
|
|
+import kotlinx.android.synthetic.main.offline_main_activity_layout.*
|
|
|
+import kotlinx.android.synthetic.main.offline_main_activity_layout.view_title_layout_tv_hospital_name
|
|
|
+import kotlinx.android.synthetic.main.offline_main_activity_layout.view_title_layout_tv_no
|
|
|
+import kotlinx.android.synthetic.main.offline_main_activity_layout.view_title_layout_tv_point
|
|
|
+import kotlinx.android.synthetic.main.view_title_layout.*
|
|
|
+import org.greenrobot.eventbus.EventBus
|
|
|
+import org.greenrobot.eventbus.Subscribe
|
|
|
+import org.greenrobot.eventbus.ThreadMode
|
|
|
+import serialporttest.utils.SerialPort485Util
|
|
|
+import serialporttest.utils.SerialPortUtil
|
|
|
+import java.io.DataOutputStream
|
|
|
+import java.io.IOException
|
|
|
+import java.util.*
|
|
|
+import kotlin.collections.ArrayList
|
|
|
+
|
|
|
+@Router(path = "/conversion_box_offline/main")
|
|
|
+class OfflineMainActivity :BaseActivity<MainActivityPresenter, OfflineMainActivityLayoutBinding>(), MainActivityContract.View,
|
|
|
+ SerialPortUtil.ISerialPortBedOnclickEvent, SerialPort485Util.ISerialPortData, IUserState {
|
|
|
+ private val TAG = "OfflineMainActivity"
|
|
|
+
|
|
|
+ private lateinit var receiver: TimeReceiver
|
|
|
+ private lateinit var curFragment: String
|
|
|
+ //首页
|
|
|
+ private val mainFragment = "main_fragment"
|
|
|
+
|
|
|
+
|
|
|
+ private var clickTime : Long = 0
|
|
|
+ private var clickSosTime : Long = 0
|
|
|
+
|
|
|
+ //网络异常计数
|
|
|
+ private var netErrCount : Int = 0
|
|
|
+
|
|
|
+ private var isMacRegister: Boolean = false
|
|
|
+
|
|
|
+ private var showMcuVersion = false
|
|
|
+
|
|
|
+ //通话界面fragment
|
|
|
+ private var callFragment: Fragment? = null
|
|
|
+ private var targetSip = ""
|
|
|
+
|
|
|
+ //正在通话分机串口地址
|
|
|
+ private var curDeviceUart = ""
|
|
|
+ //当前呼叫或通话分机id
|
|
|
+ private var curDeviceId = -1
|
|
|
+ //当前通话InteractionVO
|
|
|
+ private var curInteractionVO: InteractionVO? = null
|
|
|
+ //对方设备id
|
|
|
+ var fromId: Int = -1
|
|
|
+
|
|
|
+ private var sosList = ArrayList<SosItem>()
|
|
|
+ private var outCallList = ArrayList<String>()
|
|
|
+ private var callingUart = ""
|
|
|
+
|
|
|
+ private var serverIp = ""
|
|
|
+ private var testing = false
|
|
|
+
|
|
|
+ private val handler by lazy { Handler(Looper.getMainLooper()) }
|
|
|
+
|
|
|
+ override fun getLayId(): Int {
|
|
|
+ return R.layout.offline_main_activity_layout
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun bindDagger() {
|
|
|
+ MainLaunch.component.inject(this)
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun init() {
|
|
|
+ //离线模式
|
|
|
+ CommonUtils.setStartMode(BaseApplication.appContext, 0)
|
|
|
+
|
|
|
+ //获取mac地址
|
|
|
+ Constant.LOCAL_MAC = NetHelper.getInstance().macAddress
|
|
|
+
|
|
|
+ //注册广播
|
|
|
+ regReceiver()
|
|
|
+
|
|
|
+ EventBus.getDefault().register(this)
|
|
|
+
|
|
|
+ //串口监听
|
|
|
+ setSerialListner()
|
|
|
+ SerialPortHelper.sipRegState("2")
|
|
|
+
|
|
|
+ //启动主fragment
|
|
|
+ switchFragment(R.id.conversion_main_frame, OfflineMainFragment(), mainFragment)
|
|
|
+
|
|
|
+ val buildUrl = UrlManager.build()
|
|
|
+ serverIp = buildUrl.buyer.substringAfterLast("//").substringBefore(":")
|
|
|
+
|
|
|
+ tv_mac_addr.setText("MAC: " + Constant.LOCAL_MAC + "\nIP: " + NetHelper.getInstance().localIP + ", server: " + serverIp + ", tcp: " + Constant.TCP_SERVER_URL)
|
|
|
+ tv_version.setText("V" + BuildConfig.VERSION_NAME + "_" + BuildConfig.VERSION_CODE)
|
|
|
+
|
|
|
+ //设置默认时区
|
|
|
+ val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
|
|
+ alarmManager.setTimeZone("Asia/Shanghai")
|
|
|
+
|
|
|
+ //打开网络调试
|
|
|
+ AppTool.Time.delay(120000) {
|
|
|
+ openNetwrokDebug()
|
|
|
+ }
|
|
|
+
|
|
|
+ val devices = DaoManager.getInstance().daoSession.deviceInfoBeanDao.loadAll()
|
|
|
+ if (devices != null && devices.size > 0) {
|
|
|
+ val deviceInfo = devices[0]
|
|
|
+ Constant.SIP_ID = deviceInfo.sipId
|
|
|
+ Constant.DEVICE_ID = deviceInfo.id
|
|
|
+ Constant.PART_ID = deviceInfo.partId
|
|
|
+ Constant.DEVICE_TYPE = deviceInfo.deviceType
|
|
|
+
|
|
|
+ view_title_layout_tv_hospital_name.text = deviceInfo.hospitalName + deviceInfo.partName + "--离线"
|
|
|
+ view_title_layout_tv_no.text = "设备ID: " + deviceInfo.id
|
|
|
+ }
|
|
|
+
|
|
|
+ AppTool.Time.delay(2000) {
|
|
|
+ if (!isMacRegister) {
|
|
|
+ isMacRegister = true
|
|
|
+ SerialPortHelper.changeRegisterState()
|
|
|
+ SerialPortHelper.changeCallingMode("0") //双工模式
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置登录状态回调
|
|
|
+ SocketManager.getInstance().addUserStateCallback(this)
|
|
|
+ //连接rtc服务器
|
|
|
+ connectRtcServer()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun connectRtcServer() {
|
|
|
+ val hostIP = CommonUtils.getHostIp(activity)
|
|
|
+ if (!TextUtils.isEmpty(Constant.SIP_ID) && !TextUtils.isEmpty(hostIP)) {
|
|
|
+ val wsUrl = "ws://" + hostIP + ":" + SkyEngineKit.signalPort
|
|
|
+ SocketManager.getInstance().connect(wsUrl, Constant.SIP_ID)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun userLogin() {
|
|
|
+ runOnUiThread {
|
|
|
+ view_title_layout_tv_point.setBackgroundResource(R.color.green)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun userLogout() {
|
|
|
+ runOnUiThread {
|
|
|
+ view_title_layout_tv_point.setBackgroundResource(R.color.red_color)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //开启网络调试
|
|
|
+ private fun openNetwrokDebug() {
|
|
|
+ val commands = arrayListOf(
|
|
|
+ "/system/bin/sh",
|
|
|
+ "setprop service.adb.tcp.port 5555",
|
|
|
+ "stop adbd",
|
|
|
+ "start adbd"
|
|
|
+ )
|
|
|
+ try {
|
|
|
+ RunAsRoot(commands)
|
|
|
+ } catch (e: IOException) {
|
|
|
+ e.printStackTrace()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private fun RunAsRoot(cmds: ArrayList<String>) {
|
|
|
+ val p = Runtime.getRuntime().exec("su")
|
|
|
+ val os = DataOutputStream(p.outputStream)
|
|
|
+ for (tmpCmd in cmds) {
|
|
|
+ os.writeBytes(
|
|
|
+ """
|
|
|
+ $tmpCmd
|
|
|
+
|
|
|
+ """.trimIndent()
|
|
|
+ )
|
|
|
+ }
|
|
|
+ os.writeBytes("exit\n")
|
|
|
+ os.flush()
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun showMsgMain(msg: String) {
|
|
|
+ runOnUiThread {
|
|
|
+ showMessage(msg)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun switchFragment(id: Int, fragment: Fragment, tag: String) {
|
|
|
+ supportFragmentManager.beginTransaction()
|
|
|
+ .replace(id, fragment, tag)
|
|
|
+ .commit()
|
|
|
+ curFragment = tag
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun bindEvent() {
|
|
|
+ //
|
|
|
+ }
|
|
|
+
|
|
|
+ //设置串口监听
|
|
|
+ private fun setSerialListner() {
|
|
|
+ SerialPortUtil.getInstance().setOnDataReceiveListener(this)
|
|
|
+ //开启串口心跳
|
|
|
+ SerialPortUtil.getInstance().startHeartBeat()
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ override fun destory() {
|
|
|
+ unRegReceiver()
|
|
|
+ EventBus.getDefault().unregister(this)
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
+ SerialPortUtil.getInstance().closeHeart()
|
|
|
+ SerialPortUtil.getInstance().closeSerialPort()
|
|
|
+
|
|
|
+ handler.removeCallbacksAndMessages(null)
|
|
|
+
|
|
|
+ DaoManager.getInstance().closeConnection()
|
|
|
+ }
|
|
|
+
|
|
|
+ //数据加载错误
|
|
|
+ override fun onError(message: String, type: Int) {
|
|
|
+ //
|
|
|
+ }
|
|
|
+
|
|
|
+ //没有网络
|
|
|
+ override fun onNoNet() {
|
|
|
+ //
|
|
|
+ }
|
|
|
+
|
|
|
+ //数据加载完成
|
|
|
+ override fun complete(message: String, type: Int) {
|
|
|
+ }
|
|
|
+
|
|
|
+ //开始获取数据
|
|
|
+ override fun start() {
|
|
|
+ }
|
|
|
+
|
|
|
+ //网络监听
|
|
|
+ override fun networkMonitor(state: NetState) {
|
|
|
+ state.filter(onMobile = {
|
|
|
+
|
|
|
+ },onWifi = {
|
|
|
+
|
|
|
+ },offline = {
|
|
|
+
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun setTcpServerHost(tcpSeverDTO: TcpSeverDTO) {
|
|
|
+ //
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun setServerInfo(data: ServerInfo) {
|
|
|
+ //
|
|
|
+ }
|
|
|
+
|
|
|
+ //显示设备信息
|
|
|
+ override fun showDeviceInfo(deviceInfo: DeviceNurseInfoVO) {
|
|
|
+ //
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ override fun setPartSettings(partSetting: PartSettingDO) {
|
|
|
+ //
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun loadAppVersion(appInfo: AppVersionDO) {
|
|
|
+ //
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun regReceiver() {
|
|
|
+ receiver = TimeReceiver()
|
|
|
+ var intentFilter = IntentFilter()
|
|
|
+ intentFilter.addAction(Intent.ACTION_TIME_TICK)
|
|
|
+ intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
|
|
|
+ registerReceiver(receiver, intentFilter)
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun unRegReceiver() {
|
|
|
+ unregisterReceiver(receiver)
|
|
|
+ }
|
|
|
+
|
|
|
+ override fun onSerialPortData(data: ByteArray) {
|
|
|
+ //val hexStr = SerialPort485Util.bytesToHexString(data)
|
|
|
+ //updateUart0Info(hexStr)
|
|
|
+ //Log.d("onSerialPortData", " rs485 data: $hexStr")
|
|
|
+ }
|
|
|
+
|
|
|
+ //串口处理
|
|
|
+ override fun serialPortBedOnclick(str: String) {
|
|
|
+ try {
|
|
|
+ val newStr: String = CutSerialPortUtil.delHeadAndEnd(str, "$", "#")
|
|
|
+ val content = newStr.split(",").toTypedArray()
|
|
|
+ Log.d("serialPortBedOnclick", "newStr==$newStr")
|
|
|
+ updateUartInfo(newStr)
|
|
|
+ if (isMacRegister) {
|
|
|
+ val addr = content[1].substring(0, content[1].length - 1)
|
|
|
+ Log.d("serialPortBedOnclick", "handle serialPort click: event=${content[0]}, addr=$addr")
|
|
|
+ when (content[0]) {
|
|
|
+ "A" -> {
|
|
|
+ if (Constant.CALL_STATE == Constant.CALL_INCOMING && addr.equals(callingUart, true)) {
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
+ SerialPortHelper.openSoundChannel(addr)
|
|
|
+ showCallFragment(1, "", "", addr)
|
|
|
+ } else {
|
|
|
+ //分机呼叫
|
|
|
+ startCall(addr)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ "B" -> {
|
|
|
+ //分机取消呼叫或拒接
|
|
|
+ outCallList.remove(addr.toUpperCase(Locale.ROOT))
|
|
|
+ if (Constant.CALL_STATE == Constant.CALL_INCOMING) {
|
|
|
+ if (addr.equals(callingUart, true)) {
|
|
|
+ updateCallText("待机中")
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
+ UdpSendUtil.getInstance().sendUdpData(UdpIndex.HOST_CALL_REJECT, "", "", addr, "", "", "", Constant.DEVICE_ID.toString(), Constant.PART_ID.toString())
|
|
|
+ SerialPortHelper.closeSoundChannel(addr)
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
+ } else {
|
|
|
+ cancelOutCall(addr, false)
|
|
|
+ }
|
|
|
+ } else if (Constant.CALL_STATE == Constant.CALL_CALLING) {
|
|
|
+ if (addr.equals(callingUart, true)) {
|
|
|
+ SerialPortHelper.closeSoundChannel(addr)
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
+ handoffCall(addr)
|
|
|
+ } else {
|
|
|
+ cancelOutCall(addr, false)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ cancelOutCall(addr, true)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ "C" -> {
|
|
|
+ synchronized(Unit) {
|
|
|
+ //紧急呼叫: 同一个按钮一定时间内重复多次按无效
|
|
|
+ val curTime = System.currentTimeMillis()
|
|
|
+ if (sosList.size > 0) {
|
|
|
+ val sosItem = sosList.stream().filter { addr.equals(it.addr, true) }.findFirst().orElse(null)
|
|
|
+ if (sosItem == null) {
|
|
|
+ //该按钮还没有呼叫过
|
|
|
+ //Log.e("serialport", "sosclick 111111111: " + addr)
|
|
|
+ val item = SosItem(addr, curTime)
|
|
|
+ sosList.add(item)
|
|
|
+ startSosCall(addr)
|
|
|
+ } else if (curTime - sosItem.time > 6000) {
|
|
|
+ //Log.e("serialport", "sosclick 222222222: " + addr)
|
|
|
+ //该紧急按钮按下距上次已超10s,重新呼叫
|
|
|
+ sosList.remove(sosItem)
|
|
|
+ val newItem = SosItem(addr, curTime)
|
|
|
+ sosList.add(newItem)
|
|
|
+ startSosCall(addr)
|
|
|
+ } /*else {
|
|
|
+ Log.e("serialport", "sosclick 重复呼叫,不处理: " + addr)
|
|
|
+ }*/
|
|
|
+ } else {
|
|
|
+ //Log.e("serialport", "sosclick 33333333: " + addr)
|
|
|
+ val item = SosItem(addr, curTime)
|
|
|
+ sosList.add(item)
|
|
|
+ startSosCall(addr)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ "D" -> {
|
|
|
+ //已废弃
|
|
|
+ }
|
|
|
+
|
|
|
+ "V" -> {
|
|
|
+ Constant.MCU_VERSION_NUMBER = content[1].substring(0, 17)
|
|
|
+ Log.d("serialPortBedOnclick","Constants.MCU_VERSION_NUMBER==" + Constant.MCU_VERSION_NUMBER)
|
|
|
+ if (!showMcuVersion) {
|
|
|
+ showMcuVersion = true
|
|
|
+ runOnUiThread {
|
|
|
+ tv_mcu.setText("MCU: " + Constant.MCU_VERSION_NUMBER)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //这里实际上是执行了“E”指令
|
|
|
+ /*if (content[1].length > 5) {
|
|
|
+ UdpSendUtil.sendOnlyId(content[1].substring(0, 4), content[1].substring(4, 19));//后来增加了字符
|
|
|
+ } else {
|
|
|
+ UdpSendUtil.sendRegister(content[1].substring(0, 4));
|
|
|
+ }*/
|
|
|
+
|
|
|
+ Log.d("serialPortBedOnclick", "isMacRegister is false: newStr==$newStr")
|
|
|
+ //上传分机设备地址及转换盒设备地址
|
|
|
+ if (content[1].length >= 5) {
|
|
|
+ val deviceMac = content[1].substring(0, 4)
|
|
|
+ if (Constant.PART_ID != null) {
|
|
|
+ presenter.setDeviceMac(deviceMac, Constant.LOCAL_MAC)
|
|
|
+ }
|
|
|
+
|
|
|
+ if (content[1].contains("MD")) {
|
|
|
+ startTestLight(deviceMac)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (e: java.lang.Exception) {
|
|
|
+ Log.d("serialPortBedOnclick", "Exception==")
|
|
|
+ e.printStackTrace()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun startTestLight(mac: String) {
|
|
|
+ if (!testing) {
|
|
|
+ testing = true
|
|
|
+ Thread{
|
|
|
+ try {
|
|
|
+ SerialPortHelper.closeDoorLight(mac)
|
|
|
+ Thread.sleep(500)
|
|
|
+ SerialPortHelper.testDoorLightAll(mac)
|
|
|
+ } catch (e: Exception) {
|
|
|
+ e.printStackTrace()
|
|
|
+ }
|
|
|
+
|
|
|
+ testing = false
|
|
|
+ }.start()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun startCall(uart: String) {
|
|
|
+ Log.d("serialPortBedOnclick", "startCall: $uart")
|
|
|
+ if (outCallList.contains(uart.toUpperCase(Locale.ROOT))) {
|
|
|
+ Log.d("serialPortBedOnclick", "$uart out call exist! return")
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ for (device in FrameHelper.offlineDevices) {
|
|
|
+ if (uart.equals(device.uartAddr, true)) {
|
|
|
+ //发送udp呼叫
|
|
|
+ outCallList.add(uart.toUpperCase(Locale.ROOT))
|
|
|
+ updateSendTcpInfo("udp call $uart")
|
|
|
+ updateCallText("正在呼叫-->$uart, ${device.fullName}")
|
|
|
+ //String index, String frameName, String patientName, String uartAddr, String myAddr, String targetAddr, String deviceId, String partId
|
|
|
+ UdpSendUtil.getInstance().sendUdpData(UdpIndex.BED_CALL_OUT, device.fullName, "", uart, "", "", "", Constant.DEVICE_ID.toString(), Constant.PART_ID.toString())
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun cancelOutCall(uart: String, resetCall: Boolean) {
|
|
|
+ SerialPortHelper.closeSoundChannel(uart)
|
|
|
+ for (device in FrameHelper.offlineDevices) {
|
|
|
+ if (uart.equals(device.uartAddr, true)) {
|
|
|
+ updateSendTcpInfo("udp cancel $uart")
|
|
|
+ updateCallText("取消呼叫-->$uart, ${device.fullName}")
|
|
|
+ UdpSendUtil.getInstance().sendUdpData(UdpIndex.BED_CALL_CANCEL, device.fullName, "", uart, "", "", "", Constant.DEVICE_ID.toString(), Constant.PART_ID.toString())
|
|
|
+ if (resetCall) {
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
+ }
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //关闭门灯
|
|
|
+ /*val doorAddr = getDoorLightAddr(uart)
|
|
|
+ if (!TextUtils.isEmpty(doorAddr)) {
|
|
|
+ SerialPortHelper.closeDoorLight(doorAddr)
|
|
|
+ }*/
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun startSosCall(uart: String) {
|
|
|
+ for (device in FrameHelper.offlineDevices) {
|
|
|
+ if (uart.equals(device.uartAddr, true)) {
|
|
|
+ updateSendTcpInfo("udp sos call $uart")
|
|
|
+ updateCallText("紧急呼叫-->$uart, ${device.fullName}")
|
|
|
+ UdpSendUtil.getInstance().sendUdpData(UdpIndex.SOS_CALL, device.fullName, "", uart, "", "", "", Constant.DEVICE_ID.toString(), Constant.PART_ID.toString())
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //开启门灯
|
|
|
+ /*val doorAddr = getDoorLightAddrBySos(uart)
|
|
|
+ if (!TextUtils.isEmpty(doorAddr)) {
|
|
|
+ SerialPortHelper.openDoorLightRed(doorAddr)
|
|
|
+ }*/
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun cancelSosCall(uart: String) {
|
|
|
+ if (!TextUtils.isEmpty(uart)) {
|
|
|
+ //关闭紧急按钮
|
|
|
+ SerialPortHelper.closeEmergency(uart)
|
|
|
+ //关闭门灯
|
|
|
+ /*val doorAddr = getDoorLightAddrBySos(uart)
|
|
|
+ if (!TextUtils.isEmpty(doorAddr)) {
|
|
|
+ SerialPortHelper.closeDoorLight(doorAddr)
|
|
|
+ }*/
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //通过床位分机查找所在房间的门灯
|
|
|
+ private fun getDoorLightAddr(bedAddr: String) : String? {
|
|
|
+ //首先找到分机所在床位层级,然后通过该bed frame的父级id(即房间层级)找到对应room frame,获得门灯设备信息
|
|
|
+ if (!TextUtils.isEmpty(bedAddr) && FrameHelper.frameDeviceList.size > 0) {
|
|
|
+ var roomId = -1
|
|
|
+ for (bedFrameDevice in FrameHelper.frameDeviceList) {
|
|
|
+ if (bedFrameDevice.device != null && bedAddr.equals(bedFrameDevice.device.ethMac, true)) {
|
|
|
+ roomId = bedFrameDevice.frame.parentId
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (roomId != -1) {
|
|
|
+ for (frameDevice in FrameHelper.frameDeviceList) {
|
|
|
+ if (frameDevice.frame != null && frameDevice.frame.id == roomId) {
|
|
|
+ if (frameDevice.device != null && frameDevice.device.deviceType == DeviceTypeEnum.SIMULATE_DOOR_LIGHT.value()) {
|
|
|
+ //找到对应门灯设备
|
|
|
+ return frameDevice.device.ethMac
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //没有找到对应门灯设备,返回null
|
|
|
+ return null
|
|
|
+ }
|
|
|
+
|
|
|
+ //通过紧急按钮地址查找门灯
|
|
|
+ private fun getDoorLightAddrBySos(sosAddr: String) : String? {
|
|
|
+ //首先找到分机所在床位层级,然后通过该bed frame的父级id(即房间层级)找到对应room frame,获得门灯设备信息
|
|
|
+ if (!TextUtils.isEmpty(sosAddr) && FrameHelper.frameDeviceList.size > 0) {
|
|
|
+ var roomId = -1
|
|
|
+ for (roomFrameDevice in FrameHelper.frameDeviceList) {
|
|
|
+ if (roomFrameDevice.device != null && sosAddr.equals(roomFrameDevice.device.ethMac, true)) {
|
|
|
+ roomId = roomFrameDevice.frame.id
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (roomId != -1) {
|
|
|
+ for (frameDevice in FrameHelper.frameDeviceList) {
|
|
|
+ if (frameDevice.frame != null && frameDevice.frame.id == roomId) {
|
|
|
+ if (frameDevice.device != null && frameDevice.device.deviceType == DeviceTypeEnum.SIMULATE_DOOR_LIGHT.value()) {
|
|
|
+ //找到对应门灯设备
|
|
|
+ return frameDevice.device.ethMac
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //没有找到对应门灯设备,返回null
|
|
|
+ return null
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun updateCallText(str: String) {
|
|
|
+ runOnUiThread {
|
|
|
+ tv_call_state.setText("呼叫状态: " + str)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun updateUart0Info(str: String) {
|
|
|
+ runOnUiThread {
|
|
|
+ tv_uart0_info.setText("串口0: $str")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun updateUartInfo(str: String) {
|
|
|
+ runOnUiThread {
|
|
|
+ val timeStr = TimeHandle.getDateTime(System.currentTimeMillis(), "HH:mm:ss")
|
|
|
+ tv_uart_info.setText("串口1: $str, $timeStr")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun updateTcpInfo(str: String) {
|
|
|
+ runOnUiThread {
|
|
|
+ tv_tcp_info.setText("Received TCP: $str")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun updateSendTcpInfo(str: String) {
|
|
|
+ runOnUiThread {
|
|
|
+ tv_send_tcp_info.setText("Send TCP: $str")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun updateNetState() {
|
|
|
+ /*
|
|
|
+ * 检查网络情况,若tcp断开连接多次且IP也是空的则网络异常,重启设备
|
|
|
+ * 仅对3128设备有效
|
|
|
+ */
|
|
|
+ if (Build.MODEL.equals("rk3128")) {
|
|
|
+ var count = SettingConfig.getNetErrResetCount(this)
|
|
|
+ if (SocketManager.getInstance().userState == 0 || TextUtils.isEmpty(NetHelper.getInstance().localIP)) {
|
|
|
+ netErrCount++
|
|
|
+ } else {
|
|
|
+ netErrCount = 0
|
|
|
+ if (count > 0) {
|
|
|
+ count = 0
|
|
|
+ SettingConfig.setNetErrResetCount(this, count)
|
|
|
+ }
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (netErrCount >= 5) {
|
|
|
+ //如果重启次数超过8次还是无网则不再重启
|
|
|
+ if (count < 8) {
|
|
|
+ count++
|
|
|
+ SettingConfig.setNetErrResetCount(this, count)
|
|
|
+ Handler().postDelayed({
|
|
|
+ AppUpdateHelper.reboot(this)
|
|
|
+ }, 5000)
|
|
|
+ } else {
|
|
|
+ WarningDialogHelper.showDialog(activity)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Subscribe(threadMode = ThreadMode.MAIN)
|
|
|
+ fun onMoonEvent(messageEvent: MessageEvent) {
|
|
|
+ //代码同步
|
|
|
+ synchronized(Unit) {
|
|
|
+ handleTcpModel(messageEvent)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun handleTcpModel(messageEvent: MessageEvent) {
|
|
|
+ when (messageEvent.getType()) {
|
|
|
+ //UDP消息处理
|
|
|
+ Constant.EVENT_UDP -> {
|
|
|
+ if (messageEvent.message is UdpItem) {
|
|
|
+ val udpItem = messageEvent.message as UdpItem
|
|
|
+ if (UdpIndex.SERVER_MODE_OFFLINE.equals(udpItem.index)) {
|
|
|
+ if (SocketManager.getInstance().userState == 0) {
|
|
|
+ connectRtcServer()
|
|
|
+ }
|
|
|
+ } else if (UdpIndex.BED_CALL_REJECT.equals(udpItem.index)) {
|
|
|
+ //主机拒接,从呼叫列表移除
|
|
|
+ outCallList.remove(udpItem.uartAddr.toUpperCase(Locale.ROOT))
|
|
|
+ updateCallText("对方拒绝: -->${udpItem.frameName}")
|
|
|
+ showMessage("对方拒绝")
|
|
|
+ SerialPortHelper.closeSoundChannel(udpItem.uartAddr.toUpperCase(Locale.ROOT))
|
|
|
+ } else if (UdpIndex.HOST_CALL_BED.equals(udpItem.index)) {
|
|
|
+ //当前有来电或正在通话则提示忙
|
|
|
+ if (Constant.CALL_STATE == Constant.CALL_INCOMING || Constant.CALL_STATE == Constant.CALL_CALLING) {
|
|
|
+ UdpSendUtil.getInstance().sendUdpData(UdpIndex.CALL_CALLING, udpItem.frameName, "", udpItem.uartAddr, "", "", "", Constant.DEVICE_ID.toString(), Constant.PART_ID.toString())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //主机呼叫分机
|
|
|
+ updateCallText("收到来电: <--${udpItem.frameName}")
|
|
|
+ Constant.CALL_STATE = Constant.CALL_INCOMING
|
|
|
+ if (CommonUtils.getAutoAnswer(activity)) {
|
|
|
+ //自动接听
|
|
|
+ SerialPortHelper.openSoundChannel(udpItem.uartAddr.toUpperCase(Locale.ROOT))
|
|
|
+ showCallFragment(1, "", "", udpItem.uartAddr)
|
|
|
+ } else {
|
|
|
+ callingUart = udpItem.uartAddr
|
|
|
+ SerialPortHelper.callInChannel(udpItem.uartAddr.toUpperCase(Locale.ROOT))
|
|
|
+ RingPlayHelper.playRingTone(activity, R.raw.ring_tone, true)
|
|
|
+ }
|
|
|
+
|
|
|
+ //关闭门灯
|
|
|
+ //val doorAddr = getDoorLightAddr(curDeviceUart)
|
|
|
+ //if (!TextUtils.isEmpty(doorAddr)) {
|
|
|
+ // SerialPortHelper.closeDoorLight(doorAddr)
|
|
|
+ //}
|
|
|
+ } else if (UdpIndex.BED_CALL_ACCEPT.equals(udpItem.index)) {
|
|
|
+ //主机接听,从呼叫列表移除
|
|
|
+ outCallList.remove(udpItem.uartAddr.toUpperCase(Locale.ROOT))
|
|
|
+ callingUart = udpItem.uartAddr
|
|
|
+
|
|
|
+ if (TextUtils.isEmpty(udpItem.data)) {
|
|
|
+ showMsgMain("没有目标sip id")
|
|
|
+ SerialPortHelper.closeSoundChannel(udpItem.uartAddr.toUpperCase(Locale.ROOT))
|
|
|
+ } else {
|
|
|
+ if (SocketManager.getInstance().userState == 1) {
|
|
|
+ //主机接听,开始通话
|
|
|
+ SerialPortHelper.openSoundChannel(udpItem.uartAddr.toUpperCase(Locale.ROOT))
|
|
|
+ showCallFragment(0, udpItem.frameName, udpItem.data, udpItem.uartAddr)
|
|
|
+ } else {
|
|
|
+ //socket未连接,挂断
|
|
|
+ SerialPortHelper.closeSoundChannel(udpItem.uartAddr.toUpperCase(Locale.ROOT))
|
|
|
+ showMsgMain("sip断开连接")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //关闭门灯
|
|
|
+ /*val doorAddr = getDoorLightAddr(curDeviceUart)
|
|
|
+ if (!TextUtils.isEmpty(doorAddr)) {
|
|
|
+ SerialPortHelper.closeDoorLight(doorAddr)
|
|
|
+ }*/
|
|
|
+ } else if (UdpIndex.HOST_CALL_CANCEL.equals(udpItem.index)) {
|
|
|
+ //主机取消呼叫分机
|
|
|
+ if (Constant.CALL_STATE == Constant.CALL_INCOMING) {
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
+ }
|
|
|
+ SerialPortHelper.closeSoundChannel(udpItem.uartAddr.toUpperCase(Locale.ROOT))
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
+ } else if (UdpIndex.BED_CALL_END.equals(udpItem.index)) {
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
+ EventBus.getDefault().post(MessageEvent("endcall", Constant.EVENT_END_CALL))
|
|
|
+ } else if (UdpIndex.SOS_CANCEL.equals(udpItem.index)) {
|
|
|
+ //紧急呼叫已处理
|
|
|
+ val addr = udpItem.uartAddr.toUpperCase(Locale.ROOT)
|
|
|
+ cancelSosCall(addr)
|
|
|
+ //删除sosList中对应item
|
|
|
+ var iterator = sosList.iterator()
|
|
|
+ while (iterator.hasNext()){
|
|
|
+ val it = iterator.next()
|
|
|
+ if (it.addr.equals(addr)) {
|
|
|
+ sosList.remove(it)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Constant.EVENT_RESTART_APP -> {
|
|
|
+ AppUpdateHelper.restartApp(activity)
|
|
|
+ }
|
|
|
+
|
|
|
+ Constant.EVENT_REMOVE_CALL_FRAGMENT -> {
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
+ updateCallText("待机中")
|
|
|
+
|
|
|
+ removeCallFragment()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fun inCalling() {
|
|
|
+ Constant.CALL_STATE = Constant.CALL_CALLING
|
|
|
+ updateCallText("通话中")
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun handoffCall(addr: String) {
|
|
|
+ RingPlayHelper.stopRingTone()
|
|
|
+ EventBus.getDefault().post(MessageEvent("handoff", Constant.EVENT_END_CALL))
|
|
|
+ UdpSendUtil.getInstance().sendUdpData(UdpIndex.BED_CALL_END, "", "", addr, "", "", "", Constant.DEVICE_ID.toString(), Constant.PART_ID.toString())
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun showCallFragment(state: Int, frame: String, target: String, addr: String) {
|
|
|
+ if (callFragment == null) {
|
|
|
+ var fragment = SipCallFragment()
|
|
|
+ var bundle = Bundle()
|
|
|
+ bundle.putInt("call_state", state)
|
|
|
+ bundle.putBoolean("audio_only", true)
|
|
|
+ bundle.putString("targetSip", target)
|
|
|
+ bundle.putString("frame", frame)
|
|
|
+ bundle.putString("uart_addr", addr)
|
|
|
+ fragment.arguments = bundle
|
|
|
+ addCallFragment(fragment)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun addCallFragment(fragment: Fragment) {
|
|
|
+ if (callFragment != null) {
|
|
|
+ supportFragmentManager.beginTransaction()
|
|
|
+ .remove(callFragment)
|
|
|
+ .commit()
|
|
|
+ callFragment = null
|
|
|
+ }
|
|
|
+
|
|
|
+ callFragment = fragment
|
|
|
+ supportFragmentManager.beginTransaction()
|
|
|
+ .add(R.id.call_frame, fragment)
|
|
|
+ .commit()
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun removeCallFragment() {
|
|
|
+ if (callFragment != null) {
|
|
|
+ supportFragmentManager.beginTransaction()
|
|
|
+ .remove(callFragment)
|
|
|
+ .commit()
|
|
|
+ callFragment = null
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ inner class TimeReceiver: BroadcastReceiver() {
|
|
|
+ override fun onReceive(context: Context, intent: Intent) {
|
|
|
+ if (intent.action == Intent.ACTION_TIME_TICK) {
|
|
|
+ if (SocketManager.getInstance().userState == 0) {
|
|
|
+ connectRtcServer()
|
|
|
+ }
|
|
|
+ updateNetState()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|