RobinTan1024 4 лет назад
Родитель
Сommit
e020d81ff4

+ 2 - 0
.idea/dictionaries/11017950.xml

@@ -3,8 +3,10 @@
     <words>
       <w>currentbu</w>
       <w>doverfuelingsolutions</w>
+      <w>errcd</w>
       <w>gson</w>
       <w>issp</w>
+      <w>noperm</w>
       <w>snackbar</w>
     </words>
   </dictionary>

+ 5 - 0
.idea/misc.xml

@@ -1,5 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
+  <component name="EntryPointsManager">
+    <list size="1">
+      <item index="0" class="java.lang.String" itemvalue="androidx.lifecycle.OnLifecycleEvent" />
+    </list>
+  </component>
   <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="JDK" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/build/classes" />
   </component>

+ 3 - 0
app/build.gradle

@@ -61,6 +61,9 @@ dependencies {
     implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion"
     implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutineVersion"
 
+    def work_version = "2.4.0"
+    implementation "androidx.work:work-runtime-ktx:$work_version"
+
     implementation 'androidx.startup:startup-runtime:1.0.0'
 
     implementation 'com.youth.banner:banner:2.1.0'

+ 1 - 0
app/src/main/java/com/doverfuelingsolutions/issp/api/WayneApi.kt

@@ -157,6 +157,7 @@ object WayneApi {
                 if (code != 200 || body.isNullOrEmpty() || body[0].value.isBlank()) {
                     it.resume(DFSResult.fail(R.string.return_data_error))
                 } else {
+                    // TODO 需要优化
                     GlobalScope.launch(Dispatchers.IO) {
                         try {
                             val file = File(DFSApplication.instance.applicationContext.filesDir, body[0].name)

+ 11 - 0
app/src/main/java/com/doverfuelingsolutions/issp/fusion/FusionConstants.kt

@@ -0,0 +1,11 @@
+package com.doverfuelingsolutions.issp.fusion
+
+class FusionConstants {
+
+    companion object {
+
+        const val CODE_SUCCESS = "ERRCD_OK"
+        // ERRCD_NOPERM means unsuccessful LogOn request, may cause by previous unfinished session, trying LogOff and LogOn again
+        const val CODE_NOPERM = "ERRCD_NOPERM"
+    }
+}

+ 78 - 25
app/src/main/java/com/doverfuelingsolutions/issp/fusion/FusionManager.kt

@@ -4,6 +4,7 @@ import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleObserver
 import androidx.lifecycle.OnLifecycleEvent
 import com.doverfuelingsolutions.issp.data.DataStore
+import com.doverfuelingsolutions.issp.fusion.callback.OnFusionEvent
 import com.doverfuelingsolutions.issp.utils.log.DFSLog
 import com.doverfuelingsolutions.issp.utils.sp.SPKeys
 import com.doverfuelingsolutions.issp.utils.sp.SPUtil
@@ -16,49 +17,46 @@ import com.wayne.www.waynelib.fdc.message.ServiceResponse
 import com.wayne.www.waynelib.fdc.message.ServiceResponseLogOn
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlin.coroutines.resume
+import kotlin.coroutines.suspendCoroutine
 
 object FusionManager : LifecycleObserver, OnFdcClientStateChangedListener,
     OnFdcServiceResponseReceivedListener,
     OnFdcMessageReceivedListener {
 
+    private var stateFusion: FdcClient.FdcClientState = FdcClient.FdcClientState.Stopped
+
     private val coroutineIO = CoroutineScope(Dispatchers.IO)
 
+    var onFusionEvent: OnFusionEvent? = null
+
     override fun onFdcClientStateChanged(sender: FdcClient?, state: FdcClient.FdcClientState?) {
-        DFSLog.i("onFdcClientStateChanged: ${state?.name}")
+        DFSLog.i("Fusion: state = ${state?.name}")
         if (sender == null || state == null) return
 
+        stateFusion = state
         when (state) {
-            FdcClient.FdcClientState.Connected -> {
-                // TODO 获取油站相关信息
-                val port = SPUtil.getString(SPKeys.MIDDLE_PORT).toInt()
-                DFSLog.d("try login in Fusion")
-                sender.sendLogonRequestAsync(port, port, "00.07", OnFdcServiceResponseReceivedListener { _, response ->
-                    DFSLog.d("login Fusion respond")
-                    if (response == null || response !is ServiceResponseLogOn) return@OnFdcServiceResponseReceivedListener
-                    DFSLog.d(response.requestID, response.requestType, response.singleFdcData.fdcStatus)
-                    if (response.singleFdcData.fdcStatus.equals("ERRCD_NOPERM", true)) {
-                        DFSLog.w("Unsuccessful LogOn request, may cause by previous unfinished session, trying LogOff and LogOn again...")
-                        FdcClient.getDefault().sendLogOffRequestAsync({ _, _ ->
-                            sender.sendLogonRequestAsync(port, port, "00.07", null, 60000)
-                        }, 0)
-                    }
-                }, 60000)
-            }
+            FdcClient.FdcClientState.Connected -> loginFetchInfo()
             else -> {}
         }
     }
 
     override fun onServiceResponseReceived(sender: FdcClient?, serviceResponse: ServiceResponse?) {
-        DFSLog.d("onServiceResponseReceived")
+        if (sender == null || serviceResponse == null) return
+
+        DFSLog.v("onServiceResponseReceived")
     }
 
     override fun onFdcMessageReceived(sender: FdcClient?, fdcMessage: FdcMessage?) {
-        DFSLog.d("onFdcMessageReceived")
+        if (sender == null || fdcMessage == null) return
+
+        DFSLog.v("onFdcMessageReceived")
     }
 
     @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
     fun initialize() {
-        DFSLog.i("initialize")
         FdcClient.getDefault().addOnFdcClientStateChangedListeners(this)
         FdcClient.getDefault().addOnFdcServiceResponseReceivedListeners(this)
         FdcClient.getDefault().addOnFdcMessageReceivedListeners(this)
@@ -73,10 +71,65 @@ object FusionManager : LifecycleObserver, OnFdcClientStateChangedListener,
 
     @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
     fun close() {
-        DFSLog.i("close")
-        FdcClient.getDefault().removeOnFdcClientStateChangedListeners(this)
-        FdcClient.getDefault().removeOnFdcServiceResponseReceivedListeners(this)
-        FdcClient.getDefault().removeOnFdcMessageReceivedListeners(this)
-        FdcClient.getDefault().stop()
+        val manager = this
+        coroutineIO.launch {
+            logout()
+            FdcClient.getDefault().removeOnFdcClientStateChangedListeners(manager)
+            FdcClient.getDefault().removeOnFdcServiceResponseReceivedListeners(manager)
+            FdcClient.getDefault().removeOnFdcMessageReceivedListeners(manager)
+            FdcClient.getDefault().stop()
+        }
+    }
+
+    // TODO 获取油站相关信息
+    private fun loginFetchInfo() {
+        coroutineIO.launch {
+            // retry if failed
+            val success = if (login()) true else {
+                DFSLog.d("Fusion: retry login after logout")
+                logout()
+                delay(10000)
+                login()
+            }
+            if (!success) {
+                onFusionEvent?.onLogin(false)
+                return@launch
+            } else {
+                onFusionEvent?.onLogin(true)
+            }
+
+            // TODO station info
+        }
+    }
+
+    private suspend fun login() = suspendCoroutine<Boolean> {
+        val port = SPUtil.getString(SPKeys.MIDDLE_PORT).toInt()
+        FdcClient.getDefault().sendLogonRequestAsync(port, port, "00.07", { _, response ->
+            if (response != null && response is ServiceResponseLogOn) {
+                val status = response.singleFdcData.fdcStatus
+                DFSLog.d("Fusion: try login response = $status")
+                if (status.equals(FusionConstants.CODE_SUCCESS, true)) {
+                    DFSLog.d("Fusion: login succeeded")
+                    it.resume(true)
+                } else {
+                    DFSLog.d("Fusion: login failed")
+                    it.resume(false)
+                }
+            }
+        }, 10000)
+    }
+
+    private suspend fun logout() = suspendCoroutine<Boolean> {
+        FdcClient.getDefault().sendLogOffRequestAsync({ _, response ->
+            val status = response.singleFdcData.fdcStatus
+            DFSLog.d("Fusion: try logout response = $status")
+            if (status.equals(FusionConstants.CODE_SUCCESS, true)) {
+                DFSLog.d("Fusion: logout succeeded")
+                it.resume(true)
+            } else {
+                DFSLog.d("Fusion: logout failed")
+                it.resume(false)
+            }
+        }, 10000)
     }
 }

+ 6 - 0
app/src/main/java/com/doverfuelingsolutions/issp/fusion/callback/OnFusionEvent.kt

@@ -0,0 +1,6 @@
+package com.doverfuelingsolutions.issp.fusion.callback
+
+interface OnFusionEvent {
+
+    fun onLogin(success: Boolean, msg: String = "")
+}