OSDN Git Service

単一メーカの複数デバイス対応の準備。(Panasonic)
authorMRSa <mrsa@myad.jp>
Sun, 30 Jan 2022 14:36:39 +0000 (23:36 +0900)
committerMRSa <mrsa@myad.jp>
Sun, 30 Jan 2022 14:36:39 +0000 (23:36 +0900)
app/src/main/java/jp/osdn/gokigen/gokigenassets/camera/vendor/CameraControlManager.kt
app/src/main/java/jp/osdn/gokigen/gokigenassets/camera/vendor/ICameraControlManager.kt
app/src/main/java/jp/osdn/gokigen/gokigenassets/camera/vendor/panasonic/connection/PanasonicCameraConnectSequence.kt
app/src/main/java/jp/osdn/gokigen/gokigenassets/camera/vendor/panasonic/connection/PanasonicCameraConnection.kt
app/src/main/java/jp/osdn/gokigen/gokigenassets/camera/vendor/panasonic/connection/PanasonicCameraDisconnectSequence.kt
app/src/main/java/jp/osdn/gokigen/gokigenassets/camera/vendor/panasonic/connection/PanasonicSsdpClient.kt
app/src/main/java/jp/osdn/gokigen/gokigenassets/camera/vendor/panasonic/liveview/PanasonicLiveViewControl.kt
app/src/main/java/jp/osdn/gokigen/gokigenassets/camera/vendor/panasonic/wrapper/PanasonicCameraControl.kt

index e6df1eb..503903d 100644 (file)
@@ -5,7 +5,7 @@ import jp.osdn.gokigen.gokigenassets.camera.vendor.panasonic.IPanasonicCamera
 
 class CameraControlManager : ICameraControlManager
 {
-    private val panasonicCameraDeviceMap = mutableMapOf<Int, IPanasonicCamera>()
+    private val panasonicCameraDeviceMap = mutableMapOf<Int, String>()
 
     override fun isAlreadyAssignedCameraControl(number: Int): Boolean
     {
@@ -32,12 +32,12 @@ class CameraControlManager : ICameraControlManager
         }
     }
 
-    override fun assignPanasonicCamera(number: Int, cameraDevice: IPanasonicCamera)
+    override fun assignCameraControl(number: Int, deviceId: String)
     {
         try
         {
-            Log.v(TAG, "assignPanasonicCamera($number, cameraDevice)")
-            panasonicCameraDeviceMap[number] = cameraDevice
+            Log.v(TAG, "assignPanasonicCamera($number, $deviceId)")
+            panasonicCameraDeviceMap[number] = deviceId
         }
         catch (e: Exception)
         {
@@ -45,11 +45,11 @@ class CameraControlManager : ICameraControlManager
         }
     }
 
-    override fun isAssignedPanasonicCamera(cameraDevice: IPanasonicCamera): Boolean
+    override fun isAssignedCameraControl(deviceId: String): Boolean
     {
         try
         {
-            return (panasonicCameraDeviceMap.containsValue(cameraDevice))
+            return (panasonicCameraDeviceMap.containsValue(deviceId))
         }
         catch (e: Exception)
         {
index c08b7cc..aa6aa08 100644 (file)
@@ -1,12 +1,10 @@
 package jp.osdn.gokigen.gokigenassets.camera.vendor
 
-import jp.osdn.gokigen.gokigenassets.camera.vendor.panasonic.IPanasonicCamera
-
 interface ICameraControlManager
 {
     fun isAlreadyAssignedCameraControl(number: Int) : Boolean
     fun releaseCameraControl(number: Int)
 
-    fun assignPanasonicCamera(number: Int, cameraDevice: IPanasonicCamera)
-    fun isAssignedPanasonicCamera(cameraDevice: IPanasonicCamera) : Boolean
+    fun assignCameraControl(number: Int, deviceId: String)
+    fun isAssignedCameraControl(deviceId: String) : Boolean
 }
index 9ff2d0c..140eba8 100644 (file)
@@ -6,19 +6,20 @@ import jp.osdn.gokigen.gokigenassets.camera.interfaces.ICameraConnection
 import jp.osdn.gokigen.gokigenassets.camera.interfaces.ICameraConnectionStatus
 import jp.osdn.gokigen.gokigenassets.camera.interfaces.ICameraStatusReceiver
 import jp.osdn.gokigen.gokigenassets.camera.interfaces.ICameraChangeListener
+import jp.osdn.gokigen.gokigenassets.camera.vendor.ICameraControlManager
 import jp.osdn.gokigen.gokigenassets.camera.vendor.panasonic.IPanasonicCamera
 import jp.osdn.gokigen.gokigenassets.camera.vendor.panasonic.IPanasonicCameraHolder
 import jp.osdn.gokigen.gokigenassets.constants.ICameraConstantConvert
 import jp.osdn.gokigen.gokigenassets.constants.ICameraConstantConvert.Companion.ID_STRING_CONNECT_CAMERA_DETECTED
 import jp.osdn.gokigen.gokigenassets.constants.ICameraConstantConvert.Companion.ID_STRING_CONNECT_START
 
-class PanasonicCameraConnectSequence(private val context: AppCompatActivity, private val cameraStatusReceiver: ICameraStatusReceiver, private val cameraConnection: ICameraConnection, private val cameraHolder: IPanasonicCameraHolder, private val listener: ICameraChangeListener) : Runnable, PanasonicSsdpClient.ISearchResultCallback
+class PanasonicCameraConnectSequence(private val context: AppCompatActivity, private val cameraStatusReceiver: ICameraStatusReceiver, private val cameraConnection: ICameraConnection, private val cameraHolder: IPanasonicCameraHolder, private val listener: ICameraChangeListener, cameraManager: ICameraControlManager, number : Int) : Runnable, PanasonicSsdpClient.ISearchResultCallback
 {
     companion object
     {
         private val TAG = PanasonicCameraConnectSequence::class.java.simpleName
     }
-    private val client = PanasonicSsdpClient(context, this, cameraStatusReceiver, 1)
+    private val client = PanasonicSsdpClient(context, this, cameraStatusReceiver, cameraManager, number, 1)
 
     override fun run()
     {
index f7dffd4..8dc5ea7 100644 (file)
@@ -12,7 +12,6 @@ import jp.osdn.gokigen.gokigenassets.camera.interfaces.ICameraConnectionStatus.C
 import jp.osdn.gokigen.gokigenassets.camera.interfaces.ICameraStatusReceiver
 import jp.osdn.gokigen.gokigenassets.camera.interfaces.ILiveViewController
 import jp.osdn.gokigen.gokigenassets.camera.interfaces.ICameraChangeListener
-import jp.osdn.gokigen.gokigenassets.camera.vendor.CameraControlManager
 import jp.osdn.gokigen.gokigenassets.camera.vendor.ICameraControlManager
 import jp.osdn.gokigen.gokigenassets.camera.vendor.panasonic.IPanasonicCameraHolder
 import jp.osdn.gokigen.gokigenassets.constants.ICameraConstantConvert
@@ -208,7 +207,7 @@ class PanasonicCameraConnection(private val context: AppCompatActivity, private
         Log.v(TAG, "disconnectFromCamera() $powerOff")
         try
         {
-            cameraExecutor.execute(PanasonicCameraDisconnectSequence(context, powerOff))
+            cameraExecutor.execute(PanasonicCameraDisconnectSequence(context, powerOff, cameraManager, number))
         }
         catch (e: Exception)
         {
@@ -230,7 +229,9 @@ class PanasonicCameraConnection(private val context: AppCompatActivity, private
                     statusReceiver,
                     this,
                     cameraHolder,
-                    listener
+                    listener,
+                    cameraManager,
+                    number
                 )
             )
         } catch (e: Exception) {
index 558da62..cd4757c 100644 (file)
@@ -2,12 +2,22 @@ package jp.osdn.gokigen.gokigenassets.camera.vendor.panasonic.connection
 
 import android.util.Log
 import androidx.appcompat.app.AppCompatActivity
+import jp.osdn.gokigen.gokigenassets.camera.vendor.ICameraControlManager
 
-class PanasonicCameraDisconnectSequence(private val context: AppCompatActivity, private val powerOff: Boolean) : Runnable
+class PanasonicCameraDisconnectSequence(private val context: AppCompatActivity, private val powerOff: Boolean, private val cameraManager: ICameraControlManager, private val number : Int) : Runnable
 {
     override fun run()
     {
         // カメラをPowerOffして接続を切る
         Log.v(PanasonicCameraDisconnectSequence::class.java.simpleName, " Disconnect from Panasonic.")
+        try
+        {
+            // カメラとの接続を切る
+            cameraManager.releaseCameraControl(number)
+        }
+        catch (e: Exception)
+        {
+            e.printStackTrace()
+        }
     }
 }
index dcc2f14..257527c 100644 (file)
@@ -3,6 +3,7 @@ package jp.osdn.gokigen.gokigenassets.camera.vendor.panasonic.connection
 import android.content.Context
 import android.util.Log
 import jp.osdn.gokigen.gokigenassets.camera.interfaces.ICameraStatusReceiver
+import jp.osdn.gokigen.gokigenassets.camera.vendor.ICameraControlManager
 import jp.osdn.gokigen.gokigenassets.camera.vendor.panasonic.IPanasonicCamera
 import jp.osdn.gokigen.gokigenassets.camera.vendor.panasonic.wrapper.PanasonicCameraDeviceProvider
 import jp.osdn.gokigen.gokigenassets.constants.ICameraConstantConvert.Companion.ID_STRING_CAMERA_NOT_FOUND
@@ -20,7 +21,7 @@ import java.nio.charset.Charset
 import kotlin.collections.ArrayList
 
 
-class PanasonicSsdpClient(private val context: Context, private val callback: ISearchResultCallback, private val cameraStatusReceiver: ICameraStatusReceiver, private var sendRepeatCount: Int = 0)
+class PanasonicSsdpClient(private val context: Context, private val callback: ISearchResultCallback, private val cameraStatusReceiver: ICameraStatusReceiver, private val cameraManager: ICameraControlManager, private val number : Int, private var sendRepeatCount: Int = 0)
 {
     companion object
     {
@@ -95,18 +96,19 @@ class PanasonicSsdpClient(private val context: Context, private val callback: IS
                 socket.soTimeout = SSDP_RECEIVE_TIMEOUT
                 socket.receive(receivePacket)
                 val ssdpReplyMessage = String(receivePacket.getData(), 0, receivePacket.length, Charset.forName("UTF-8"))
-                var ddUsn: String?
+                var ddUsn: String
                 if (ssdpReplyMessage.contains("HTTP/1.1 200"))
                 {
                     ddUsn = findParameterValue(ssdpReplyMessage, "USN")
+                    Log.v(TAG, "- - - - - - - USN : $ddUsn")
                     cameraStatusReceiver.onStatusNotify(context.getString(ID_STRING_CONNECT_CAMERA_RECEIVED_REPLY))
-                    if (!foundDevices.contains(ddUsn))
+                    if ((ddUsn.isNotEmpty())&&(!foundDevices.contains(ddUsn))&&(!cameraManager.isAssignedCameraControl(ddUsn)))
                     {
                         val ddLocation = findParameterValue(ssdpReplyMessage, "LOCATION")
                         foundDevices.add(ddUsn)
 
                         //// Fetch Device Description XML and parse it.
-                        if (ddLocation != null)
+                        if (ddLocation.isNotEmpty())
                         {
                             val http = SimpleHttpClient()
                             cameraStatusReceiver.onStatusNotify("LOCATION : $ddLocation")
@@ -119,8 +121,7 @@ class PanasonicSsdpClient(private val context: Context, private val callback: IS
                                 var retryTimeout = 3
                                 val registUrl =
                                     device.getCmdUrl() + "cam.cgi?mode=accctrl&type=req_acc&value=" + device.getClientDeviceUuId() + "&value2=GOKIGEN_a01Series"
-                                var reply: String =
-                                    http.httpGet(registUrl, SSDP_RECEIVE_TIMEOUT)
+                                var reply: String = http.httpGet(registUrl, SSDP_RECEIVE_TIMEOUT)
                                 while (retryTimeout > 0 && reply.contains("ok_under_research_no_msg")) {
                                     try
                                     {
@@ -136,8 +137,10 @@ class PanasonicSsdpClient(private val context: Context, private val callback: IS
                                 }
                                 if (reply.contains("ok"))
                                 {
+                                    cameraManager.assignCameraControl(number, ddUsn)
                                     callback.onDeviceFound(device)
                                     // カメラと接続できた場合は breakする
+                                    Log.v(TAG, "  assignCameraControl execution Result: " + cameraManager.isAssignedCameraControl(ddUsn))
                                     break
                                 }
                                 // 接続(デバイス登録)エラー...
@@ -187,7 +190,7 @@ class PanasonicSsdpClient(private val context: Context, private val callback: IS
         callback.onFinished()
     }
 
-    private fun findParameterValue(ssdpMessage: String, paramName: String): String?
+    private fun findParameterValue(ssdpMessage: String, paramName: String): String
     {
         var name = paramName
         if (!name.endsWith(":"))
@@ -208,7 +211,7 @@ class PanasonicSsdpClient(private val context: Context, private val callback: IS
                 e.printStackTrace()
             }
         }
-        return null
+        return ("")
     }
 
     /**
index 509455b..e12cf4f 100644 (file)
@@ -7,11 +7,10 @@ import jp.osdn.gokigen.gokigenassets.liveview.image.CameraLiveViewListenerImpl
 import jp.osdn.gokigen.gokigenassets.utils.communication.SimpleHttpClient
 import java.net.DatagramPacket
 import java.net.DatagramSocket
-import java.util.*
 
-
-class PanasonicLiveViewControl(private val liveViewListener : CameraLiveViewListenerImpl, private val camera: IPanasonicCamera, private val eventObserver: ICameraEventObserver)
+class PanasonicLiveViewControl(private val liveViewListener : CameraLiveViewListenerImpl, private val camera: IPanasonicCamera, private val eventObserver: ICameraEventObserver, number: Int)
 {
+    private val liveViewPortNumber = 49151 + number   // Base : 49152
     private var receiverSocket: DatagramSocket? = null
     private var whileStreamReceive = false
     private var errorOccur = 0
@@ -23,16 +22,15 @@ class PanasonicLiveViewControl(private val liveViewListener : CameraLiveViewList
         private const val ERROR_MAX = 30
         private const val RECEIVE_BUFFER_SIZE = 1024 * 1024 * 4
         private const val TIMEOUT_MS = 1500
-        private const val LIVEVIEW_PORT = 49152
-        private const val LIVEVIEW_START_REQUEST = "cam.cgi?mode=startstream&value=49152"
+        //private const val LIVEVIEW_PORT = 49152
+        //private const val LIVEVIEW_START_REQUEST = "cam.cgi?mode=startstream&value=49152"
+        private const val LIVEVIEW_START_REQUEST = "cam.cgi?mode=startstream&value="
         private const val LIVEVIEW_STOP_REQUEST = "cam.cgi?mode=stopstream"
     }
 
-    fun changeLiveViewSize(size: String?) {}
-
     fun startLiveView()
     {
-        Log.v(TAG, "startLiveView()")
+        Log.v(TAG, "startLiveView() port: $liveViewPortNumber")
         try
         {
             val thread = Thread(Runnable {
@@ -45,7 +43,7 @@ class PanasonicLiveViewControl(private val liveViewListener : CameraLiveViewList
                         return@Runnable
                     }
                     val http = SimpleHttpClient()
-                    val requestUrl = camera.getCmdUrl() + LIVEVIEW_START_REQUEST
+                    val requestUrl = camera.getCmdUrl() + LIVEVIEW_START_REQUEST + liveViewPortNumber
                     val reply: String = http.httpGet(requestUrl, TIMEOUT_MS)
                     if (!reply.contains("<result>ok</result>"))
                     {
@@ -124,6 +122,7 @@ class PanasonicLiveViewControl(private val liveViewListener : CameraLiveViewList
         }
     }
 
+    fun changeLiveViewSize(size: String?) {}
     fun updateDigitalZoom() {}
     fun updateMagnifyingLiveViewScale(isChangeScale: Boolean) {}
     fun getMagnifyingLiveViewScale(): Float { return 1.0f }
@@ -140,7 +139,7 @@ class PanasonicLiveViewControl(private val liveViewListener : CameraLiveViewList
         // ソケットをあける (UDP)
         try
         {
-            receiverSocket = DatagramSocket(LIVEVIEW_PORT)
+            receiverSocket = DatagramSocket(liveViewPortNumber)
             whileStreamReceive = true
         }
         catch (e: Exception)
@@ -168,24 +167,24 @@ class PanasonicLiveViewControl(private val liveViewListener : CameraLiveViewList
         var searchIndex = 0
         var startPosition = 0
         //val startmarker = intArrayOf(0xff, 0xd8)
-        val startmarker = byteArrayOf(0xff.toByte(), 0xd8.toByte())
+        val startMarker = byteArrayOf(0xff.toByte(), 0xd8.toByte())
         val receivedData: ByteArray = packet.data
-        if (receivedData == null)
-        {
-            // 受信データが取れなかったので終了する
-            Log.v(TAG, "RECEIVED DATA IS NULL...")
-            return
-        }
+        //if (receivedData == null)
+        //{
+        //    // 受信データが取れなかったので終了する
+        //    Log.v(TAG, "RECEIVED DATA IS NULL...")
+        //    return
+        //}
         // Log.v(TAG, "RECEIVED PACKET : " + dataLength);
         while (startPosition < dataLength)
         {
             // 先頭のjpegマーカーが出てくるまで読み飛ばす
             try
             {
-                if (receivedData[startPosition++] == startmarker[searchIndex])
+                if (receivedData[startPosition++] == startMarker[searchIndex])
                 {
                     searchIndex++
-                    if (searchIndex >= startmarker.size)
+                    if (searchIndex >= startMarker.size)
                     {
                         break
                     }
@@ -201,7 +200,7 @@ class PanasonicLiveViewControl(private val liveViewListener : CameraLiveViewList
                 return
             }
         }
-        val offset = startPosition - startmarker.size
+        val offset = startPosition - startMarker.size
         if (offset > 0)
         {
             eventObserver.receivedEvent(receivedData.copyOfRange(0, offset))
@@ -217,12 +216,12 @@ class PanasonicLiveViewControl(private val liveViewListener : CameraLiveViewList
         {
             try
             {
-                val receive_packet = DatagramPacket(buffer, buffer.size)
+                val receivePacket = DatagramPacket(buffer, buffer.size)
                 if (receiverSocket != null)
                 {
                     receiverSocket?.soTimeout = TIMEOUT_MS
-                    receiverSocket?.receive(receive_packet)
-                    checkReceiveImage(receive_packet)
+                    receiverSocket?.receive(receivePacket)
+                    checkReceiveImage(receivePacket)
                     exceptionCount = 0
                 }
                 else
@@ -241,7 +240,7 @@ class PanasonicLiveViewControl(private val liveViewListener : CameraLiveViewList
                         Log.v(TAG, "LV : RETRY REQUEST")
                         exceptionCount = 0
                         val http = SimpleHttpClient()
-                        val reply: String = http.httpGet(camera.getCmdUrl() + LIVEVIEW_START_REQUEST, TIMEOUT_MS)
+                        val reply: String = http.httpGet(camera.getCmdUrl() + LIVEVIEW_START_REQUEST + liveViewPortNumber, TIMEOUT_MS)
                         if (!reply.contains("ok"))
                         {
                             Log.v(TAG, "LV : RETRY COMMAND FAIL...")
index 5f09feb..5a55683 100644 (file)
@@ -10,7 +10,6 @@ import jp.osdn.gokigen.gokigenassets.camera.interfaces.ICameraChangeListener
 import jp.osdn.gokigen.gokigenassets.camera.vendor.panasonic.IPanasonicCamera
 import jp.osdn.gokigen.gokigenassets.camera.vendor.panasonic.IPanasonicCameraHolder
 import jp.osdn.gokigen.gokigenassets.camera.vendor.panasonic.connection.PanasonicCameraConnection
-import jp.osdn.gokigen.gokigenassets.camera.vendor.CameraControlManager
 import jp.osdn.gokigen.gokigenassets.camera.vendor.ICameraControlManager
 import jp.osdn.gokigen.gokigenassets.camera.vendor.panasonic.liveview.PanasonicLiveViewControl
 import jp.osdn.gokigen.gokigenassets.camera.vendor.panasonic.operation.PanasonicCameraCaptureControl
@@ -66,7 +65,7 @@ class PanasonicCameraControl(private val context: AppCompatActivity, private val
                 }
                 if (liveViewControl == null)
                 {
-                    liveViewControl = PanasonicLiveViewControl(liveViewListener, panasonicCamera, statusChecker.getCameraStatusEventObserver())
+                    liveViewControl = PanasonicLiveViewControl(liveViewListener, panasonicCamera, statusChecker.getCameraStatusEventObserver(), number)
                 }
                 focusControl?.setCamera(panasonicCamera)
                 captureControl?.setCamera(panasonicCamera)