OSDN Git Service

Visionkids で、カメラIPアドレスを自動で設定できるようにした。
[gokigen/PKRemote.git] / app / src / main / java / net / osdn / gokigen / pkremote / camera / vendor / visionkids / wrapper / playback / VisionKidsCameraContentProvider.kt
1 package net.osdn.gokigen.pkremote.camera.vendor.visionkids.wrapper.playback
2
3 import android.content.Context
4 import android.net.ConnectivityManager
5 import android.net.RouteInfo
6 import android.os.Build
7 import android.util.Log
8 import androidx.appcompat.app.AppCompatActivity
9 import androidx.preference.PreferenceManager
10 import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContent
11 import net.osdn.gokigen.pkremote.camera.interfaces.playback.ICameraContentListCallback
12 import net.osdn.gokigen.pkremote.preference.IPreferencePropertyAccessor
13 import java.net.Inet6Address
14
15 class VisionKidsCameraContentProvider(private val context: AppCompatActivity) : IFtpServiceCallback
16 {
17     private val ftpClient = MyFtpClient(this)
18     private val preferences = PreferenceManager.getDefaultSharedPreferences(context)
19     private val cameraContentList = ArrayList<ICameraContent>()
20     private lateinit var callback : ICameraContentListCallback
21
22     fun getCameraContent(name: String) : ICameraContent?
23     {
24         try
25         {
26             for (cameraContent in cameraContentList)
27             {
28                 if (cameraContent.contentName == name)
29                 {
30                     return (cameraContent)
31                 }
32             }
33         }
34         catch (e: Exception)
35         {
36             e.printStackTrace()
37         }
38         return (null)
39     }
40
41     fun forceDisconnect()
42     {
43         try
44         {
45             ftpClient.enqueueCommand(FtpCommand("quit", "QUIT\r\n"))
46             try
47             {
48                 Thread.sleep(750)
49             }
50             catch (ee: Exception)
51             {
52                 ee.printStackTrace()
53             }
54             ftpClient.disconnect()
55         }
56         catch (e: Exception)
57         {
58             e.printStackTrace()
59         }
60     }
61
62     fun getHostAddress() : String
63     {
64         val autoHost = preferences.getBoolean(IPreferencePropertyAccessor.VISIONKIDS_AUTO_SET_HOST_IP, true)
65         var address = preferences.getString(IPreferencePropertyAccessor.VISIONKIDS_HOST_IP, IPreferencePropertyAccessor.VISIONKIDS_HOST_IP_DEFAULT_VALUE)?: IPreferencePropertyAccessor.VISIONKIDS_HOST_IP_DEFAULT_VALUE
66         try
67         {
68             if ((autoHost)&&(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M))
69             {
70                 val connectivityManager = context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
71                 val activeNetwork = connectivityManager.activeNetwork?: return (address)
72                 val routes: List<RouteInfo> = connectivityManager.getLinkProperties(activeNetwork)?.routes ?: return (address)
73                 for (route in routes)
74                 {
75                     val gateway = route.gateway
76                     if ((route.isDefaultRoute) && (!(gateway is Inet6Address))&&(gateway != null))
77                     {
78                         address = gateway.toString().replace("/","")
79                         Log.v(TAG, " --------- default Gateway : $address  --------- ")
80                         break
81                     }
82                 }
83             }
84         }
85         catch (e: Exception)
86         {
87             e.printStackTrace()
88         }
89         return (address)
90     }
91
92     fun getContentList(callback: ICameraContentListCallback)
93     {
94         try
95         {
96             val address = getHostAddress()
97             this.callback = callback
98             ftpClient.connect(address)
99         }
100         catch (e: Exception)
101         {
102             e.printStackTrace()
103         }
104     }
105
106     // IFtpServiceCallback
107     override fun onReceivedFtpResponse(command: String, code: Int, response: String)
108     {
109         try
110         {
111             if (code == 0)
112             {
113                 // 成功の応答の場合... FTPのシーケンスを進める
114                 when (command)
115                 {
116                     "connect" -> inputUser(response)
117                     "user" -> inputPass(response)
118                     "pass" -> changeCurrentWorkingDirectory(response)
119                     "cwd" -> setAsciiTransferMode(response)
120                     "ascii" -> setPassiveMode(response)
121                     "passive" -> checkPassivePort(response)
122                     "data_port" -> getFileList(response)
123                     "list" -> checkListCommand(response)
124                     "data" -> parseFileList(response)
125                     "quit" -> checkQuitResponse(response)
126                 }
127             }
128             else
129             {
130                 Log.v(TAG, " onReceivedFtpResponse($command/$code) [${response.length}] $response")
131                 when (command)
132                 {
133                     "receiveFromDevice(data)" -> onReceivedDataError(response)
134                 }
135             }
136         }
137         catch (e: Exception)
138         {
139             e.printStackTrace()
140         }
141     }
142
143     private fun onReceivedDataError(response: String)
144     {
145         try
146         {
147             // Occurs data receive timeout, so disconnect ftp
148             ftpClient.enqueueCommand(FtpCommand("quit", "QUIT\r\n"))
149         }
150         catch (e: Exception)
151         {
152             e.printStackTrace()
153         }
154     }
155
156     private fun inputUser(response: String)
157     {
158         try
159         {
160             if (response.startsWith("220"))
161             {
162                 val user = preferences.getString(IPreferencePropertyAccessor.VISIONKIDS_FTP_USER, IPreferencePropertyAccessor.VISIONKIDS_FTP_USER_DEFAULT_VALUE)?: IPreferencePropertyAccessor.VISIONKIDS_FTP_USER_DEFAULT_VALUE
163
164                 ftpClient.enqueueCommand(FtpCommand("user", "USER $user\r\n"))
165             }
166         }
167         catch (e: Exception)
168         {
169             e.printStackTrace()
170         }
171     }
172
173     private fun inputPass(response: String)
174     {
175         try
176         {
177             if (response.startsWith("331"))
178             {
179                 val pass = preferences.getString(IPreferencePropertyAccessor.VISIONKIDS_FTP_PASS, IPreferencePropertyAccessor.VISIONKIDS_FTP_PASS_DEFAULT_VALUE)?: IPreferencePropertyAccessor.VISIONKIDS_FTP_PASS_DEFAULT_VALUE
180                 ftpClient.enqueueCommand(FtpCommand("pass", "PASS $pass\r\n"))
181             }
182         }
183         catch (e: Exception)
184         {
185             e.printStackTrace()
186         }
187     }
188
189     private fun changeCurrentWorkingDirectory(response: String)
190     {
191         try
192         {
193             if (response.startsWith("230"))
194             {
195                 ftpClient.enqueueCommand(FtpCommand("cwd", "CWD /1/DCIM\r\n"))
196             }
197         }
198         catch (e: Exception)
199         {
200             e.printStackTrace()
201         }
202     }
203
204     private fun setAsciiTransferMode(response: String)
205     {
206         try
207         {
208             if (response.startsWith("250"))
209             {
210                 ftpClient.enqueueCommand(FtpCommand("ascii", "TYPE A\r\n"))
211             }
212         }
213         catch (e: Exception)
214         {
215             e.printStackTrace()
216         }
217     }
218
219     private fun setPassiveMode(response: String)
220     {
221         try
222         {
223             if (response.startsWith("200"))
224             {
225                 ftpClient.enqueueCommand(FtpCommand("passive", "PASV\r\n"))
226             }
227         }
228         catch (e: Exception)
229         {
230             e.printStackTrace()
231         }
232     }
233
234     private fun checkPassivePort(response: String)
235     {
236         try
237         {
238             if (response.startsWith("227"))
239             {
240                 ftpClient.decidePassivePort(response)
241             }
242         }
243         catch (e: Exception)
244         {
245             e.printStackTrace()
246         }
247     }
248     private fun getFileList(response: String)
249     {
250         try
251         {
252             ftpClient.openPassivePort(response)
253             ftpClient.enqueueCommand(FtpCommand("list", "LIST\r\n"))
254         }
255         catch (e: Exception)
256         {
257             e.printStackTrace()
258         }
259     }
260     private fun checkListCommand(response: String)
261     {
262         try
263         {
264             Log.v(TAG, "RESPONSE: $response")
265             if ((response.startsWith("226"))||((response.startsWith("150"))&&(response.contains("226"))))
266             {
267                 ftpClient.enqueueCommand(FtpCommand("quit", "QUIT\r\n"))
268             }
269             else if (response.startsWith("150"))
270             {
271                 Log.v(TAG, "RESP. 150")
272             }
273         }
274         catch (e: Exception)
275         {
276             e.printStackTrace()
277         }
278     }
279
280     private fun parseFileList(response: String)
281     {
282         try
283         {
284             cameraContentList.clear()
285             val fileList = response.split("\r\n")
286             for (files in fileList)
287             {
288                 val fileData = files.split(Regex("\\s+"))
289                 if (fileData.size > 8)
290                 {
291                     val imageFile = fileData[8]
292                     val imagePath = ""
293                     val imageDate = "${fileData[5]} ${fileData[6]} ${fileData[7]}" // MM DD YYYY
294                     cameraContentList.add(VisionKidsCameraContent(imageFile, imagePath, imageDate))
295                 }
296             }
297         }
298         catch (e: Exception)
299         {
300             e.printStackTrace()
301         }
302     }
303
304     private fun checkQuitResponse(response: String)
305     {
306         try
307         {
308             Log.v(TAG, "RESPONSE: $response")
309             ftpClient.disconnect()
310
311             // 取得した画像の一覧を応答する
312             callback.onCompleted(cameraContentList)
313         }
314         catch (e: Exception)
315         {
316             e.printStackTrace()
317         }
318     }
319
320     companion object
321     {
322         private val TAG = VisionKidsCameraContentProvider::class.java.simpleName
323     }
324 }