|
@@ -5,10 +5,7 @@ import android.content.Context
|
|
|
import android.content.Intent
|
|
|
import android.content.IntentFilter
|
|
|
import android.net.ConnectivityManager
|
|
|
-import android.os.CountDownTimer
|
|
|
-import android.os.Handler
|
|
|
-import android.os.Message
|
|
|
-import android.os.SystemClock
|
|
|
+import android.os.*
|
|
|
import android.support.v4.app.Fragment
|
|
|
import android.support.v7.widget.LinearLayoutManager
|
|
|
import android.text.TextUtils
|
|
@@ -17,26 +14,33 @@ import android.view.View
|
|
|
import android.view.animation.AnimationUtils
|
|
|
import com.enation.javashop.android.jrouter.external.annotation.Router
|
|
|
import com.enation.javashop.net.engine.model.NetState
|
|
|
-import com.wdkl.app.ncs.callingbed.sip.SipHelper
|
|
|
-import com.wdkl.app.ncs.callingbed.sip.SipStatus
|
|
|
-import com.vvsip.ansip.IVvsipServiceListener
|
|
|
-import com.vvsip.ansip.VvsipCall
|
|
|
+import com.google.gson.Gson
|
|
|
+//import com.wdkl.app.ncs.callingbed.sip.SipHelper
|
|
|
+//import com.wdkl.app.ncs.callingbed.sip.SipStatus
|
|
|
+//import com.vvsip.ansip.IVvsipServiceListener
|
|
|
+//import com.vvsip.ansip.VvsipCall
|
|
|
import com.wdkl.app.ncs.callingbed.R
|
|
|
import com.wdkl.app.ncs.callingbed.adapter.NurseConfigAdpter
|
|
|
import com.wdkl.app.ncs.callingbed.databinding.CallingbedMainLayBinding
|
|
|
import com.wdkl.app.ncs.callingbed.fragment.*
|
|
|
-import com.wdkl.app.ncs.callingbed.helper.NetHelper
|
|
|
-import com.wdkl.app.ncs.callingbed.helper.SerialPortHelper
|
|
|
-import com.wdkl.app.ncs.callingbed.helper.SoundPoolHelper
|
|
|
+import com.wdkl.app.ncs.callingbed.helper.*
|
|
|
import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
|
|
|
+import com.wdkl.app.ncs.callingbed.settings.SettingConfig
|
|
|
import com.wdkl.app.ncs.callingbed2.agreement.CallingbedAgreement
|
|
|
+import com.wdkl.app.ncs.callingbed2.fragment.SkyCallFragment
|
|
|
+import com.wdkl.app.ncs.callingbed2.helper.ScreenManagerUtil
|
|
|
+import com.wdkl.core.consts.Urls
|
|
|
+import com.wdkl.core.socket.IUserState
|
|
|
+import com.wdkl.core.socket.SocketManager
|
|
|
//import com.wdkl.app.ncs.sip.service.SipService
|
|
|
import com.wdkl.ncs.android.lib.base.BaseActivity
|
|
|
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.lib.widget.MenuDialog
|
|
|
import com.wdkl.ncs.android.middleware.common.Constant
|
|
|
import com.wdkl.ncs.android.middleware.common.MessageEvent
|
|
|
+import com.wdkl.ncs.android.middleware.common.SipStatus
|
|
|
import com.wdkl.ncs.android.middleware.logic.contract.callingbed.CallingbedActivityContract
|
|
|
import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.CallingbedActivityPresenter
|
|
|
import com.wdkl.ncs.android.middleware.model.dos.PartSettingDO
|
|
@@ -44,8 +48,13 @@ import com.wdkl.ncs.android.middleware.model.dto.NurseConfigDto
|
|
|
import com.wdkl.ncs.android.middleware.model.dto.TcpSeverDTO
|
|
|
import com.wdkl.ncs.android.middleware.model.vo.BedDeviceInfoVO
|
|
|
import com.wdkl.ncs.android.middleware.model.vo.CustomerInfoVO
|
|
|
+import com.wdkl.ncs.android.middleware.model.vo.InteractionVO
|
|
|
import com.wdkl.ncs.android.middleware.tcp.TcpClient
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.channel.VideoUtil
|
|
|
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.TcpAction
|
|
|
+import com.wdkl.ncs.android.middleware.tcp.enums.TcpType
|
|
|
import kotlinx.android.synthetic.main.callingbed_main_lay.*
|
|
|
import kotlinx.android.synthetic.main.view_title_layout.*
|
|
|
import org.greenrobot.eventbus.EventBus
|
|
@@ -64,7 +73,7 @@ import java.lang.ref.WeakReference
|
|
|
|
|
|
@Router(path = "/callingbed/main")
|
|
|
class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMainLayBinding>(), CallingbedAgreement, CallingbedActivityContract.View, /*IVvsipServiceListener,*/
|
|
|
- SerialPortUtil.ISerialPortBedOnclickEvent, SerialPortUtil.ISerialPortBedOnclickString{
|
|
|
+ SerialPortUtil.ISerialPortBedOnclickEvent, SerialPortUtil.ISerialPortBedOnclickString, IUserState {
|
|
|
|
|
|
private lateinit var receiver: TimeReceiver
|
|
|
private lateinit var curFragment: String
|
|
@@ -78,9 +87,13 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
private lateinit var nurseConfigAdpter : NurseConfigAdpter
|
|
|
private var configList = ArrayList<NurseConfigDto>()
|
|
|
private var sipServiceRunning :Boolean = false
|
|
|
+ private var initialized :Boolean = false
|
|
|
|
|
|
- //呼叫倒计时
|
|
|
- lateinit var countDownTimer: CountDownTimer
|
|
|
+ //通话界面fragment
|
|
|
+ private var skyCallFragment: Fragment? = null
|
|
|
+
|
|
|
+ //网络异常计数
|
|
|
+ private var netErrCount : Int = 0
|
|
|
|
|
|
//主信息
|
|
|
private val mainFragment = "main_fragment"
|
|
@@ -120,8 +133,7 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
|
|
|
//sip初始化
|
|
|
//initSip()
|
|
|
- //显示日期时间
|
|
|
- updateDateTime()
|
|
|
+
|
|
|
//注册广播
|
|
|
regReceiver()
|
|
|
//串口监听
|
|
@@ -130,11 +142,16 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
SoundPoolHelper.getInstance().init(applicationContext)
|
|
|
//打开手柄mic
|
|
|
SerialPortHelper.setHandsMIC(true)
|
|
|
+ SerialPortHelper.setSosLight("0")
|
|
|
+
|
|
|
+ EventBus.getDefault().register(this)
|
|
|
|
|
|
- initCountDownTimer()
|
|
|
initNurseConfig()
|
|
|
updateNetState()
|
|
|
|
|
|
+ //添加webrtc登录回调
|
|
|
+ SocketManager.getInstance().addUserStateCallback(this)
|
|
|
+
|
|
|
initDevice()
|
|
|
|
|
|
//启动时间线程
|
|
@@ -149,35 +166,27 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
}
|
|
|
|
|
|
override fun destory() {
|
|
|
- countDownTimer.cancel()
|
|
|
SerialPortUtil.getInstance().closeHeart()
|
|
|
SerialPortUtil.getInstance().closeSerialPort()
|
|
|
- SipHelper.getInstance().unRegisterSip()
|
|
|
+ //SipHelper.getInstance().unRegisterSip()
|
|
|
SoundPoolHelper.getInstance().release()
|
|
|
+ EventBus.getDefault().unregister(this)
|
|
|
unRegReceiver()
|
|
|
handler.removeCallbacksAndMessages(null)
|
|
|
isTimeWorking = false
|
|
|
}
|
|
|
|
|
|
- fun initDevice() {
|
|
|
- if (!TextUtils.isEmpty(Constant.LOCAL_MAC)) {
|
|
|
- presenter.loadDeviceInfo(Constant.LOCAL_MAC)
|
|
|
- }
|
|
|
+ override fun userLogin() {
|
|
|
+ updateStatus(SipStatus.REGISTERCOM)
|
|
|
}
|
|
|
|
|
|
- fun initCountDownTimer() {
|
|
|
- countDownTimer = object: CountDownTimer(Constant.CALL_TIMEOUT*1000L, 1000) {
|
|
|
- override fun onTick(millisUntilFinished: Long) {
|
|
|
- //
|
|
|
- }
|
|
|
+ override fun userLogout() {
|
|
|
+ updateStatus(SipStatus.REGISTERFAIL)
|
|
|
+ }
|
|
|
|
|
|
- override fun onFinish() {
|
|
|
- //呼叫超时,返回到主界面
|
|
|
- showMessage("无人应答...")
|
|
|
- //MediaPlayHelper.getInstance().stopMusic()
|
|
|
- VoiceUtil.cancelAudioCall(Constant.DEVICE_ID)
|
|
|
- endCall()
|
|
|
- }
|
|
|
+ fun initDevice() {
|
|
|
+ if (!TextUtils.isEmpty(Constant.LOCAL_MAC)) {
|
|
|
+ presenter.loadDeviceInfo(Constant.LOCAL_MAC)
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -202,7 +211,7 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
//dismissDialog()
|
|
|
showMessage(message)
|
|
|
//加载失败,重置customid
|
|
|
- Constant.CUSTOM_ID = -1
|
|
|
+ //Constant.CUSTOM_ID = -1
|
|
|
}
|
|
|
|
|
|
//数据加载完成
|
|
@@ -220,7 +229,7 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
override fun onNoNet() {
|
|
|
showMessage("没有网络")
|
|
|
//加载失败,重置customid
|
|
|
- Constant.CUSTOM_ID = -1
|
|
|
+ //Constant.CUSTOM_ID = -1
|
|
|
}
|
|
|
|
|
|
//网络监听
|
|
@@ -241,24 +250,61 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
Constant.PART_ID = deviceInfo.partId
|
|
|
Constant.BED_NAME = deviceInfo.fullName
|
|
|
|
|
|
+ Constant.DEVICE_TYPE = deviceInfo.deviceType
|
|
|
+ Constant.DEVICE_CODE = deviceInfo.code
|
|
|
+ Constant.DEVICE_MODEL = deviceInfo.model
|
|
|
+ Constant.DEVICE_SOFT_VER = deviceInfo.softVer
|
|
|
+ Constant.DEVICE_HARD_VER = deviceInfo.hardVer
|
|
|
+ Constant.DEVICE_NAME = deviceInfo.name
|
|
|
+ if (deviceInfo.status != null) {
|
|
|
+ Constant.DEVICE_STATUS = deviceInfo.status
|
|
|
+ }
|
|
|
+
|
|
|
view_title_layout_tv_hospital_name.text = deviceInfo.hospitalName + deviceInfo.partName
|
|
|
+
|
|
|
if (deviceInfo.customerId != null) {
|
|
|
Constant.CUSTOM_ID = deviceInfo.customerId
|
|
|
- EventBus.getDefault().post(MessageEvent("updateCustom", Constant.EVENT_UPDATE_CUSTOM))
|
|
|
- presenter.loadPartSettings(Constant.PART_ID)
|
|
|
}
|
|
|
-
|
|
|
- //拿到sip账号之后再注册
|
|
|
- if (!sipServiceRunning && !TextUtils.isEmpty(Constant.SIP_ID)) {
|
|
|
- sipServiceRunning = true
|
|
|
- //startSipService()
|
|
|
- //StarRtcHelper.getInstance().initStarRtc()
|
|
|
- initSip(Constant.SIP_HOST, Constant.SIP_ID);
|
|
|
+ EventBus.getDefault().post(MessageEvent("updateCustom", Constant.EVENT_UPDATE_CUSTOM))
|
|
|
+
|
|
|
+ if (TextUtils.isEmpty(Constant.SIP_ID)) {
|
|
|
+ showMessage("SIP ID为空")
|
|
|
+ return
|
|
|
+ } else if (Constant.DEVICE_STATUS == 0) {
|
|
|
+ showMessage("设备未启用")
|
|
|
+ return
|
|
|
}
|
|
|
+
|
|
|
+ initialized = true
|
|
|
+ presenter.loadPartSettings(Constant.PART_ID)
|
|
|
+
|
|
|
+ connectRtcWebSocket()
|
|
|
}
|
|
|
|
|
|
override fun setPartSettings(partSetting: PartSettingDO) {
|
|
|
- //Constant.CALL_TIMEOUT = partSetting.sipOvertime
|
|
|
+ //设置白昼起止时间
|
|
|
+ SettingConfig.setInitialDayTime(this, partSetting.dayStart.substring(0,5))
|
|
|
+ SettingConfig.setEndOfDay(this,partSetting.nightStart.substring(0,5))
|
|
|
+
|
|
|
+ //分机白天夜晚亮度
|
|
|
+ SettingConfig.setExtensionDaytimeBrightness(this, partSetting.dayLight)
|
|
|
+ SettingConfig.setExtensionNightBrightness(this, partSetting.nightLight)
|
|
|
+
|
|
|
+ //分机白天夜晚护理灯 也就是LED灯的亮度
|
|
|
+ SettingConfig.setExtensionDaytimeLEDBrightness(this, partSetting.dayNurseLed)
|
|
|
+ SettingConfig.setExtensionNightLEDBrightness(this, partSetting.nightNurseLed)
|
|
|
+
|
|
|
+ //分机白天夜晚系统音量
|
|
|
+ SettingConfig.setExtensionDaytimeSystemVolume(this, partSetting.dayBedVol)
|
|
|
+ SettingConfig.setExtensionNightSystemVolume(this, partSetting.nightBedVol)
|
|
|
+
|
|
|
+ //分机通话音量 没做白昼区分
|
|
|
+ SettingConfig.setExtensionCallVolume(this, partSetting.dayBedVol)
|
|
|
+
|
|
|
+ SettingConfig.setSipOverTime(this, partSetting.sipOvertime)
|
|
|
+ SettingConfig.setSleepTime(this, partSetting.sleepSecondsBed)
|
|
|
+
|
|
|
+ updateSettings(true)
|
|
|
}
|
|
|
|
|
|
override fun setTcpServerHost(tcpSeverDTO: TcpSeverDTO) {
|
|
@@ -269,10 +315,23 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
//开启TCP连接
|
|
|
startTcp()
|
|
|
showMessage("tcp开始连接...host: " + Constant.TCP_SERVER_URL + ", port: " + Constant.TCP_PORT)
|
|
|
+
|
|
|
+ Thread(Runnable {
|
|
|
+ while (!initialized) {
|
|
|
+ runOnUiThread(Runnable {
|
|
|
+ initDevice()
|
|
|
+ })
|
|
|
+ try {
|
|
|
+ Thread.sleep(8000)
|
|
|
+ } catch (e: Exception) {
|
|
|
+ //
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }).start()
|
|
|
}
|
|
|
|
|
|
override fun updateNurseConfig(list: List<NurseConfigDto>) {
|
|
|
- if (list.size > 0) {
|
|
|
+ if (list.isNotEmpty()) {
|
|
|
for ((index, e) in list.withIndex()) {
|
|
|
configList.set(index, e)
|
|
|
}
|
|
@@ -280,14 +339,35 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- override fun onStart() {
|
|
|
- EventBus.getDefault().register(this)
|
|
|
- super.onStart()
|
|
|
+ private fun connectRtcWebSocket(){
|
|
|
+ //拿到sip账号之后再注册
|
|
|
+ if (!TextUtils.isEmpty(Constant.SIP_ID)) {
|
|
|
+ // 连接socket登录
|
|
|
+ SocketManager.getInstance().connect(Urls.WS, Constant.SIP_ID, 0)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- override fun onStop() {
|
|
|
- EventBus.getDefault().unregister(this)
|
|
|
- super.onStop()
|
|
|
+ fun addCallFragment(fragment: Fragment) {
|
|
|
+ //先切换到首页
|
|
|
+ if (!mainFragment.equals(curFragment)) {
|
|
|
+ switchToMainFragment()
|
|
|
+ }
|
|
|
+
|
|
|
+ skyCallFragment = fragment
|
|
|
+ supportFragmentManager.beginTransaction()
|
|
|
+ .setCustomAnimations(R.anim.slide_down_in, R.anim.slide_up_out)
|
|
|
+ .add(R.id.call_frame, fragment)
|
|
|
+ .commit()
|
|
|
+ }
|
|
|
+
|
|
|
+ fun removeCallFragment() {
|
|
|
+ if (skyCallFragment != null) {
|
|
|
+ supportFragmentManager.beginTransaction()
|
|
|
+ //.setCustomAnimations(R.anim.slide_down_in, R.anim.slide_down_out)
|
|
|
+ .remove(skyCallFragment)
|
|
|
+ .commit()
|
|
|
+ skyCallFragment = null
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
//切换fragment
|
|
@@ -327,6 +407,7 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
intentFilter.addAction(Intent.ACTION_TIME_TICK)
|
|
|
intentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED)
|
|
|
intentFilter.addAction(Intent.ACTION_TIME_CHANGED)
|
|
|
+ intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
|
|
|
registerReceiver(receiver, intentFilter)
|
|
|
}
|
|
|
|
|
@@ -334,11 +415,11 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
unregisterReceiver(receiver)
|
|
|
}
|
|
|
|
|
|
- private fun initSip(ipStr: String, id: String) {
|
|
|
+/* private fun initSip(ipStr: String, id: String) {
|
|
|
//=============================================SIP启动服务===================================//
|
|
|
- //SipHelper.getInstance().initSip(this@CallingbedActivity,ipStr, id, id)
|
|
|
- //SipHelper.getInstance().sipStartService()
|
|
|
- //SipHelper.getInstance().setSipListner(this)
|
|
|
+ SipHelper.getInstance().initSip(this@CallingbedActivity,ipStr, id, id)
|
|
|
+ SipHelper.getInstance().sipStartService()
|
|
|
+ SipHelper.getInstance().setSipListner(this)
|
|
|
}
|
|
|
|
|
|
fun sendSipCall(sipId: String) {
|
|
@@ -351,7 +432,7 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
SipHelper.getInstance().endCall()
|
|
|
}
|
|
|
|
|
|
- /*override fun onNewVvsipCallEvent(call: VvsipCall?) {
|
|
|
+ override fun onNewVvsipCallEvent(call: VvsipCall?) {
|
|
|
//Log.d("sip", "onNewVvsipCallEvent----")
|
|
|
if (call != null) {
|
|
|
SipHelper.getInstance().addCallObject(call)
|
|
@@ -402,49 +483,111 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
}
|
|
|
}*/
|
|
|
|
|
|
+ private fun updateSettings(forceSet: Boolean) {
|
|
|
+ val currentTimestamp = System.currentTimeMillis()
|
|
|
+
|
|
|
+ //白天起始时间戳
|
|
|
+ val date = TimeHandle.getDateTime("yyyy-MM-dd")
|
|
|
+ val dayStartTimeStamp = TimeHandle.dateToStamp(date+" "+SettingConfig.getInitialDayTime(this)+":00", "yyyy-MM-dd HH:mm:ss")
|
|
|
+ //白天结束时间戳
|
|
|
+ val endOfDayTimeStamp = TimeHandle.dateToStamp(date+" "+SettingConfig.getEndOfDay(this)+":00", "yyyy-MM-dd HH:mm:ss")
|
|
|
+
|
|
|
+ val curInday = dayStartTimeStamp < currentTimestamp && currentTimestamp < endOfDayTimeStamp
|
|
|
+
|
|
|
+ if (curInday) {
|
|
|
+ //当前是白天并且原来不是白天
|
|
|
+ if (Constant.day_state != 0 || forceSet) {
|
|
|
+ //设置白天亮度
|
|
|
+ ScreenManagerUtil().setScreenBrightness(
|
|
|
+ this,
|
|
|
+ Math.ceil(2.54 * SettingConfig.getExtensionDaytimeBrightness(this)).toInt()
|
|
|
+ )
|
|
|
+ //设置白天系统音量和响铃音
|
|
|
+ VoiceManagerUtil.setSystemVoice(
|
|
|
+ this,
|
|
|
+ SettingConfig.getExtensionDaytimeSystemVolume(this)
|
|
|
+ )
|
|
|
+ VoiceManagerUtil.setMusicVoice(
|
|
|
+ this,
|
|
|
+ SettingConfig.getExtensionDaytimeSystemVolume(this)
|
|
|
+ )
|
|
|
+ view_title_layout_iv_day_night.setImageResource(R.mipmap.ic_daylight)
|
|
|
+ }
|
|
|
+ Constant.day_state = 0
|
|
|
+ } else {
|
|
|
+ //当前是夜晚并且原来不是夜晚
|
|
|
+ if (Constant.day_state != 1 || forceSet) {
|
|
|
+ //设置晚上亮度
|
|
|
+ ScreenManagerUtil().setScreenBrightness(
|
|
|
+ this,
|
|
|
+ Math.ceil(2.54 * SettingConfig.getExtensionNightBrightness(this)).toInt()
|
|
|
+ )
|
|
|
+ //设置晚上系统音量和响铃音
|
|
|
+ VoiceManagerUtil.setSystemVoice(
|
|
|
+ this,
|
|
|
+ SettingConfig.getExtensionNightSystemVolume(this)
|
|
|
+ )
|
|
|
+ VoiceManagerUtil.setMusicVoice(
|
|
|
+ this,
|
|
|
+ SettingConfig.getExtensionNightSystemVolume(this)
|
|
|
+ )
|
|
|
+ view_title_layout_iv_day_night.setImageResource(R.mipmap.ic_night)
|
|
|
+ }
|
|
|
+ Constant.day_state = 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
override fun serialPortBedOnclick(buffer: ByteArray) {
|
|
|
Log.d("serialPortBedOnclick", "buffer[0]:" + buffer[0] + ", buffer[1]:" + buffer[1] + ", buffer[2]:" + buffer[2]
|
|
|
+ ", buffer[3]:" + buffer[3] + ", buffer[4]:" + buffer[4] + ", buffer[5]:" + buffer[5] + ", buffer[6]:" + buffer[6]
|
|
|
+ ", buffer[7]:" + buffer[7] + ", buffer[8]:" + buffer[8])
|
|
|
//首页
|
|
|
if (buffer[0].toInt() == 1 || buffer[0].toInt() == 2) {
|
|
|
- runOnUiThread {
|
|
|
- clickVHome()
|
|
|
+ if (skyCallFragment == null) {
|
|
|
+ runOnUiThread {
|
|
|
+ clickVHome()
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//费用
|
|
|
else if (buffer[1].toInt() == 1 || buffer[1].toInt() == 2) {
|
|
|
- runOnUiThread {
|
|
|
- clickVCost()
|
|
|
+ if (skyCallFragment == null) {
|
|
|
+ runOnUiThread {
|
|
|
+ clickVCost()
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//更多
|
|
|
else if (buffer[2].toInt() == 1 || buffer[2].toInt() == 2) {
|
|
|
- runOnUiThread {
|
|
|
- clickVQrcode()
|
|
|
+ if (skyCallFragment == null) {
|
|
|
+ runOnUiThread {
|
|
|
+ clickVQrcode()
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//增援
|
|
|
else if (buffer[3].toInt() == 1 || buffer[3].toInt() == 2) {
|
|
|
- runOnUiThread {
|
|
|
- clickVSupport()
|
|
|
+ if (skyCallFragment == null) {
|
|
|
+ runOnUiThread {
|
|
|
+ clickVSupport()
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//呼叫
|
|
|
else if (buffer[4].toInt() == 1 || buffer[4].toInt() == 2) {
|
|
|
runOnUiThread {
|
|
|
- clickVCall()
|
|
|
+ clickVCall(true)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//呼叫护士键短按或长按松开
|
|
|
else if (buffer[5].toInt() == 1 || buffer[5].toInt() == 2) {
|
|
|
runOnUiThread {
|
|
|
- clickCall()
|
|
|
+ clickVCall(false)
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -457,7 +600,15 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
}
|
|
|
|
|
|
override fun serialPortBedOnclickString(str: String) {
|
|
|
- //
|
|
|
+ try {
|
|
|
+ val newStr = str.substring(str.indexOf("$") + 1, str.indexOf("#"))
|
|
|
+ Log.d("serialPortBedOnclickString", "newStr==$newStr")
|
|
|
+ if (newStr.startsWith("V")) {
|
|
|
+ Constant.MCU_VERSION_NUMBER = newStr.substring(newStr.indexOf(",") + 1, 16)
|
|
|
+ }
|
|
|
+ } catch (e: Exception) {
|
|
|
+ e.printStackTrace()
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private fun isVisible(v: View) : Boolean {
|
|
@@ -526,7 +677,7 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
backTimeout = 0
|
|
|
if (isVisible(right_menu)) {
|
|
|
hideRightMenu(true)
|
|
|
- showMessage("增援请求已发送!")
|
|
|
+ //showMessage("增援请求已发送!")
|
|
|
//switchToFragment(R.id.callingbed_main_frame, SupportFragment(), supportFragment)
|
|
|
//SoundPoolHelper.getInstance().playSound(2)
|
|
|
} else {
|
|
@@ -534,28 +685,46 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private fun clickVCall() {
|
|
|
+ private fun clickVCall(checkMenu: Boolean) {
|
|
|
//重置超时时间
|
|
|
backTimeout = 0
|
|
|
//当前为待机状态,显示呼叫
|
|
|
if (Constant.CALL_STATE == Constant.CALL_STANDBY) {
|
|
|
- if (isVisible(right_menu)) {
|
|
|
- hideRightMenu(true)
|
|
|
- VoiceUtil.startAudioCall(Constant.DEVICE_ID)
|
|
|
- sendCall()
|
|
|
- //播放铃音
|
|
|
- //MediaPlayHelper.getInstance().playResMusic(R.raw.ringback, 1.0f, true)
|
|
|
- SoundPoolHelper.getInstance().playSound(2)
|
|
|
+ if (checkMenu) {
|
|
|
+ if (isVisible(right_menu)) {
|
|
|
+ hideRightMenu(true)
|
|
|
+ if (!TextUtils.isEmpty(Constant.SIP_ID)) {
|
|
|
+ //没有摄像头则只能拨打语音
|
|
|
+ startCall(Constant.VOICE_CALL)
|
|
|
+ } else {
|
|
|
+ showMessage("当前设备可能未办理入住,不能呼叫")
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ showRightMenu()
|
|
|
+ }
|
|
|
} else {
|
|
|
- showRightMenu()
|
|
|
+ if (isVisible(right_menu)) {
|
|
|
+ hideRightMenu(true)
|
|
|
+ }
|
|
|
+ if (!TextUtils.isEmpty(Constant.SIP_ID)) {
|
|
|
+ //没有摄像头则只能拨打语音
|
|
|
+ startCall(Constant.VOICE_CALL)
|
|
|
+ } else {
|
|
|
+ showMessage("当前设备可能未办理入住,不能呼叫")
|
|
|
+ }
|
|
|
}
|
|
|
} else if (Constant.CALL_STATE == Constant.CALL_CALLING) {
|
|
|
- //StarRtcHelper.getInstance().hangupAudioCall()
|
|
|
- //VoiceUtil.handoffAudioCall(Constant.DEVICE_ID, fromId, interactionId)
|
|
|
- endCall()
|
|
|
- } else {
|
|
|
- VoiceUtil.cancelAudioCall(Constant.DEVICE_ID)
|
|
|
- endCall()
|
|
|
+ //通话中挂断
|
|
|
+ EventBus.getDefault().post(MessageEvent("handoff", Constant.EVENT_SERIAL_EVENT))
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
+ } else if (Constant.CALL_STATE == Constant.CALL_OUTGOING) {
|
|
|
+ //呼叫取消
|
|
|
+ EventBus.getDefault().post(MessageEvent("cancel", Constant.EVENT_SERIAL_EVENT))
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
+ } else if (Constant.CALL_STATE == Constant.CALL_INCOMING) {
|
|
|
+ //来电接听
|
|
|
+ EventBus.getDefault().post(MessageEvent("accept", Constant.EVENT_SERIAL_EVENT))
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -567,18 +736,16 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
if (isVisible(right_menu)) {
|
|
|
hideRightMenu(true)
|
|
|
}
|
|
|
- VoiceUtil.startAudioCall(Constant.DEVICE_ID)
|
|
|
- sendCall()
|
|
|
- //播放铃音
|
|
|
- //MediaPlayHelper.getInstance().playResMusic(R.raw.ringback, 1.0f, true)
|
|
|
- SoundPoolHelper.getInstance().playSound(2)
|
|
|
- } else if (Constant.CALL_STATE == Constant.CALL_CALLING) {
|
|
|
- //StarRtcHelper.getInstance().hangupAudioCall()
|
|
|
- //VoiceUtil.handoffAudioCall(Constant.DEVICE_ID, fromId, interactionId)
|
|
|
- endCall()
|
|
|
- } else {
|
|
|
- VoiceUtil.cancelAudioCall(Constant.DEVICE_ID)
|
|
|
- endCall()
|
|
|
+ if (!TextUtils.isEmpty(Constant.SIP_ID)) {
|
|
|
+ //没有摄像头则只能拨打语音
|
|
|
+ startCall(Constant.VOICE_CALL)
|
|
|
+ } else {
|
|
|
+ showMessage("当前设备可能未办理入住,不能呼叫")
|
|
|
+ }
|
|
|
+ } else if (Constant.CALL_STATE == Constant.CALL_INCOMING) {
|
|
|
+ //来电接听
|
|
|
+ EventBus.getDefault().post(MessageEvent("accept", Constant.EVENT_SERIAL_EVENT))
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -603,40 +770,41 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
right_menu.setVisibility(View.GONE)
|
|
|
}
|
|
|
|
|
|
- //发起呼叫
|
|
|
- private fun sendCall() {
|
|
|
- Constant.CALL_STATE = Constant.CALL_OUTGOING
|
|
|
- ll_call_view.visibility = View.VISIBLE
|
|
|
- tv_call_bed_name.text = Constant.BED_NAME
|
|
|
- tv_call_state.text = "正在呼叫..."
|
|
|
- voice_call_timer_view.visibility = View.INVISIBLE
|
|
|
- countDownTimer.start()
|
|
|
- }
|
|
|
-
|
|
|
- //呼叫或通话结束
|
|
|
- private fun endCall() {
|
|
|
- voice_call_timer_view.base = SystemClock.elapsedRealtime()
|
|
|
- voice_call_timer_view.stop()
|
|
|
- ll_call_view.visibility = View.GONE
|
|
|
- Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
- countDownTimer.cancel()
|
|
|
+ //开始呼叫
|
|
|
+ fun startCall(type: Int) {
|
|
|
+ //通话之前先判断webrtc socket和tcp是否连接正常,否则不能建立通话
|
|
|
+ if (SocketManager.getInstance().socketOpen() && Constant.TCP_CONNECTED) {
|
|
|
+ //去电界面
|
|
|
+ Constant.CALL_TYPE = type
|
|
|
+ Constant.CALL_STATE = Constant.CALL_OUTGOING
|
|
|
+ var fragment = SkyCallFragment()
|
|
|
+ var bundle = Bundle()
|
|
|
+ bundle.putInt("call_state", 0)
|
|
|
+ fragment.arguments = bundle
|
|
|
+ addCallFragment(fragment)
|
|
|
+ } else {
|
|
|
+ showMessage("通话服务或网络未连接,请检查网络稍后再试")
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- //通话中
|
|
|
- private fun inCall() {
|
|
|
- ll_call_view.visibility = View.VISIBLE
|
|
|
- tv_call_bed_name.text = Constant.BED_NAME
|
|
|
- tv_call_state.text = "通话中..."
|
|
|
- voice_call_timer_view.visibility = View.VISIBLE
|
|
|
- voice_call_timer_view.base = SystemClock.elapsedRealtime()
|
|
|
- voice_call_timer_view.start()
|
|
|
- Constant.CALL_STATE = Constant.CALL_CALLING
|
|
|
- countDownTimer.cancel()
|
|
|
- }
|
|
|
|
|
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
|
|
fun onMoonEvent(messageEvent: MessageEvent) {
|
|
|
+ synchronized(Unit) {
|
|
|
+ handleTcpModel(messageEvent)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ fun handleTcpModel(messageEvent: MessageEvent) {
|
|
|
when (messageEvent.getType()) {
|
|
|
+ //退出通话界面
|
|
|
+ Constant.EVENT_REMOVE_CALL_FRAGMENT -> {
|
|
|
+ if (skyCallFragment != null) {
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
+ removeCallFragment()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
//Sip注册状态
|
|
|
Constant.EVENT_SIP_REGISTER_STATUS -> {
|
|
|
if (messageEvent.message is String) run {
|
|
@@ -645,20 +813,111 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
updateStatus(status)
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
//网络ping状态
|
|
|
- Constant.EVENT_INTERNETPING -> {
|
|
|
- SipHelper.getInstance().obtainSipInfo()
|
|
|
+ /*Constant.EVENT_INTERNETPING -> {
|
|
|
+ //SipHelper.getInstance().obtainSipInfo()
|
|
|
if (NetHelper.NetConn && NetHelper.getInstance().networkType == ConnectivityManager.TYPE_ETHERNET) {
|
|
|
view_title_layout_iv_ethernet.setImageResource(R.mipmap.ic_etherneted)
|
|
|
} else {
|
|
|
view_title_layout_iv_ethernet.setImageResource(R.mipmap.ic_no_ethernet)
|
|
|
}
|
|
|
view_title_layout_iv_wifi.setImageResource(R.mipmap.ic_wifi_nor)
|
|
|
- }
|
|
|
+ }*/
|
|
|
+
|
|
|
//返回主界面
|
|
|
Constant.EVENT_BACK_MAIN -> {
|
|
|
switchToMainFragment()
|
|
|
}
|
|
|
+
|
|
|
+ //TCP连接状态
|
|
|
+ Constant.EVENT_TCP_STATE -> {
|
|
|
+ updateTcpState()
|
|
|
+ }
|
|
|
+
|
|
|
+ //TCP消息处理
|
|
|
+ Constant.EVENT_TCP_MSG -> {
|
|
|
+ if (messageEvent.message is TcpModel) {
|
|
|
+ val tcpModel = messageEvent.message as TcpModel
|
|
|
+ Log.d("TCP", "received tcp action: " + tcpModel.action + ", type: " + tcpModel.type)
|
|
|
+ if (tcpModel.getType() == TcpType.VOICE) {
|
|
|
+ val interactionVO = Gson().fromJson(tcpModel.data.toString(), InteractionVO::class.java)
|
|
|
+ if (tcpModel.action == TcpAction.VoiceAction.CALL) {
|
|
|
+ Constant.fromId = tcpModel.fromId
|
|
|
+ Constant.interactionId = interactionVO.id
|
|
|
+ Constant.CALL_STATE = Constant.CALL_INCOMING
|
|
|
+ //通话之前先判断webrtc socket是否连接上,否则不能建立通话
|
|
|
+ if (SocketManager.getInstance().socketOpen()) {
|
|
|
+ //来电界面
|
|
|
+ var fragment = SkyCallFragment()
|
|
|
+ var bundle = Bundle()
|
|
|
+ bundle.putInt("call_state", 1)
|
|
|
+ bundle.putSerializable("tcp_model", tcpModel)
|
|
|
+ fragment.arguments = bundle
|
|
|
+ addCallFragment(fragment)
|
|
|
+ } else {
|
|
|
+ showMessage("通话服务还未建立连接,请稍后")
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
+ VoiceUtil.rejectAudioCall(Constant.DEVICE_ID, Constant.fromId, Constant.interactionId)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (tcpModel.type == TcpType.SOS) {
|
|
|
+ if (tcpModel.action == TcpAction.SOSAction.CANCEL) {
|
|
|
+ //紧急呼叫已处理
|
|
|
+ //SOSHelper.sosStop()
|
|
|
+ }
|
|
|
+ } else if (tcpModel.type == TcpType.DEVICE) {
|
|
|
+ //检查APP版本
|
|
|
+ if (tcpModel.getAction() == TcpAction.DeviceAction.APP_UPDATE) {
|
|
|
+ //checkAppVersion()
|
|
|
+ } else if (tcpModel.action == TcpAction.DeviceAction.RESTART) {
|
|
|
+ //收到重启app指令,若当前处于正常待机状态则直接重启app,否则等待通话结束再重启
|
|
|
+ if (Constant.CALL_STATE == Constant.CALL_STANDBY) {
|
|
|
+ AppUpdateHelper.restartApp(activity)
|
|
|
+ } else {
|
|
|
+ Constant.LATER_RESTART = true
|
|
|
+ }
|
|
|
+ } else if (tcpModel.action == TcpAction.DeviceAction.SYSTEM_SETTING) {
|
|
|
+ presenter.loadPartSettings(Constant.PART_ID)
|
|
|
+ }
|
|
|
+ } else if (tcpModel.action == TcpAction.DataAction.REFRESH) {
|
|
|
+ //重新加载数据,比如出院,入院等
|
|
|
+ initDevice()
|
|
|
+ }
|
|
|
+
|
|
|
+ //探视
|
|
|
+ if (tcpModel.type == TcpType.VIDEO) {
|
|
|
+ val interactionVO = Gson().fromJson(tcpModel.data.toString(), InteractionVO::class.java)
|
|
|
+ if (tcpModel.action == TcpAction.VideoAction.VIDEO_INVITE_JOIN) {
|
|
|
+ if (Constant.CALL_STATE != Constant.CALL_STANDBY) {
|
|
|
+ VideoUtil.videoInCalling(Constant.DEVICE_ID, tcpModel.fromId, interactionVO.id)
|
|
|
+ } else {
|
|
|
+ //收到探视请求,向探视机发起视频通话
|
|
|
+ Constant.interactionId = interactionVO.id
|
|
|
+ Constant.fromId = tcpModel.fromId
|
|
|
+ Constant.CALL_STATE = Constant.CALL_OUTGOING
|
|
|
+
|
|
|
+ //通话之前先判断webrtc socket是否连接上,否则不能建立通话
|
|
|
+ if (SocketManager.getInstance().socketOpen()) {
|
|
|
+ //探视界面
|
|
|
+ var fragment = SkyCallFragment()
|
|
|
+ var bundle = Bundle()
|
|
|
+ bundle.putInt("call_state", 2)
|
|
|
+ bundle.putSerializable("tcp_model", tcpModel)
|
|
|
+ fragment.arguments = bundle
|
|
|
+ addCallFragment(fragment)
|
|
|
+ } else {
|
|
|
+ showMessage("通话服务还未建立连接,请稍后")
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
+ VoiceUtil.rejectAudioCall(Constant.DEVICE_ID, Constant.fromId, Constant.interactionId)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (tcpModel.action == TcpAction.VideoAction.HANDOFF) {
|
|
|
+ Constant.CALL_STATE = Constant.CALL_STANDBY
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -683,10 +942,6 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private fun updateDateTime() {
|
|
|
- view_title_layout_tv_time.setText(TimeHandle.getDateTime("yyyy-MM-dd HH:mm E"));
|
|
|
- }
|
|
|
-
|
|
|
private fun updateNetState() {
|
|
|
if (NetHelper.getInstance().networkType == ConnectivityManager.TYPE_WIFI) {
|
|
|
view_title_layout_iv_wifi.visibility = View.VISIBLE
|
|
@@ -698,13 +953,54 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
view_title_layout_iv_wifi.visibility = View.GONE
|
|
|
}
|
|
|
|
|
|
- if (NetHelper.isBTConnected()) {
|
|
|
+ /*if (NetHelper.isBTConnected()) {
|
|
|
view_title_layout_iv_bt.visibility = View.VISIBLE
|
|
|
view_title_layout_iv_bt.setImageResource(R.mipmap.ic_bt_success)
|
|
|
} else {
|
|
|
view_title_layout_iv_bt.visibility = View.GONE
|
|
|
+ }*/
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 检查网络情况,若tcp断开连接多次且IP也是空的则网络异常,重启设备
|
|
|
+ * 仅对3128设备有效
|
|
|
+ */
|
|
|
+ if (Build.MODEL.equals("rk3128")) {
|
|
|
+ var count = SettingConfig.getNetErrResetCount(this)
|
|
|
+ if (!Constant.TCP_CONNECTED && TextUtils.isEmpty(NetHelper.getInstance().localIP)) {
|
|
|
+ netErrCount++
|
|
|
+ } else {
|
|
|
+ netErrCount = 0
|
|
|
+ if (count > 0) {
|
|
|
+ count = 0
|
|
|
+ SettingConfig.setNetErrResetCount(this, count)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (netErrCount >= 5) {
|
|
|
+ //如果重启次数超过8次还是无网则不再重启
|
|
|
+ if (count < 8) {
|
|
|
+ count++
|
|
|
+ SettingConfig.setNetErrResetCount(this, count)
|
|
|
+ Handler().postDelayed({
|
|
|
+ AppUpdateHelper.reboot(activity)
|
|
|
+ }, 5000)
|
|
|
+ } else {
|
|
|
+ WarningDialogHelper.showDialog(activity)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private fun updateTcpState() {
|
|
|
+ if (Constant.TCP_CONNECTED) {
|
|
|
+ view_title_layout_iv_tcp.setImageResource(R.mipmap.ic_tcp_success)
|
|
|
+ if (initialized && SocketManager.getInstance().userState == 0) {
|
|
|
+ //如果socket断开了则重连
|
|
|
+ connectRtcWebSocket()
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ view_title_layout_iv_tcp.setImageResource(R.mipmap.ic_tcp_fail)
|
|
|
}
|
|
|
- view_title_layout_iv_day_night.setImageResource(R.mipmap.ic_daylight)
|
|
|
}
|
|
|
|
|
|
inner class TimeReceiver: BroadcastReceiver() {
|
|
@@ -712,8 +1008,35 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
|
|
|
if (intent.action == Intent.ACTION_TIME_TICK
|
|
|
|| intent.action == Intent.ACTION_TIME_CHANGED
|
|
|
|| intent.action == Intent.ACTION_TIMEZONE_CHANGED) {
|
|
|
- updateDateTime()
|
|
|
- updateNetState()
|
|
|
+ //设备完成初始化才刷新
|
|
|
+ if (initialized) {
|
|
|
+ updateNetState()
|
|
|
+ updateSettings(false)
|
|
|
+ updateTcpState()
|
|
|
+
|
|
|
+ if (SocketManager.getInstance().userState == 1) {
|
|
|
+ view_title_layout_tv_point.setBackgroundResource(R.color.green)
|
|
|
+ } else {
|
|
|
+ view_title_layout_tv_point.setBackgroundResource(R.color.red_color)
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Constant.LATER_RESTART && Constant.CALL_STATE == Constant.CALL_STANDBY) {
|
|
|
+ AppUpdateHelper.restartApp(activity)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (intent.action == ConnectivityManager.CONNECTIVITY_ACTION) {
|
|
|
+ if (initialized) {
|
|
|
+ updateNetState()
|
|
|
+ if (NetHelper.getInstance().networkAvailable()) {
|
|
|
+ if (!Constant.TCP_CONNECTED) {
|
|
|
+ TcpClient.getInstance().doConnect()
|
|
|
+ }
|
|
|
+ if (SocketManager.getInstance().userState == 0) {
|
|
|
+ //如果socket断开了则重连
|
|
|
+ connectRtcWebSocket()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|