Add support for WPS in repeater

This commit is contained in:
Mygod
2018-01-13 16:08:44 +08:00
parent aeab1059b4
commit 5e97e3d9ae
5 changed files with 81 additions and 8 deletions

View File

@@ -13,16 +13,18 @@ import android.os.IBinder
import android.support.v4.app.Fragment
import android.support.v4.content.ContextCompat
import android.support.v4.content.LocalBroadcastManager
import android.support.v7.app.AlertDialog
import android.support.v7.app.AppCompatDialog
import android.support.v7.widget.DefaultItemAnimator
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.support.v7.widget.Toolbar
import android.view.*
import android.widget.EditText
import be.mygod.vpnhotspot.databinding.FragmentRepeaterBinding
import be.mygod.vpnhotspot.databinding.ListitemClientBinding
class RepeaterFragment : Fragment(), ServiceConnection {
class RepeaterFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClickListener {
inner class Data : BaseObservable() {
val switchEnabled: Boolean
@Bindable get() = when (binder?.service?.status) {
@@ -71,7 +73,7 @@ class RepeaterFragment : Fragment(), ServiceConnection {
fun fetchClients() {
val binder = binder
if (binder?.service?.status == RepeaterService.Status.ACTIVE) {
if (binder?.active == true) {
owner = binder.service.group.owner
clients = binder.service.group.clientList
arpCache = NetUtils.arp(binder.service.routing?.downstream)
@@ -113,6 +115,8 @@ class RepeaterFragment : Fragment(), ServiceConnection {
binding.clients.itemAnimator = animator
binding.clients.adapter = adapter
binding.swipeRefresher.setOnRefreshListener { adapter.fetchClients() }
binding.toolbar.inflateMenu(R.menu.repeater)
binding.toolbar.setOnMenuItemClickListener(this)
return binding.root
}
@@ -143,4 +147,21 @@ class RepeaterFragment : Fragment(), ServiceConnection {
LocalBroadcastManager.getInstance(context!!).unregisterReceiver(data.statusListener)
data.onStatusChanged()
}
override fun onMenuItemClick(item: MenuItem) = when (item.itemId) {
R.id.wps -> if (binder?.active == true) {
val dialog = AlertDialog.Builder(context!!)
.setTitle("Enter PIN")
.setView(R.layout.dialog_wps)
.setPositiveButton(android.R.string.ok, { dialog, _ -> binder?.startWps((dialog as AppCompatDialog)
.findViewById<EditText>(android.R.id.edit)!!.text.toString()) })
.setNegativeButton(android.R.string.cancel, null)
.setNeutralButton("Push Button", { _, _ -> binder?.startWps(null) })
.create()
dialog.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE)
dialog.show()
true
} else false
else -> false
}
}

View File

@@ -5,6 +5,7 @@ import android.app.Service
import android.content.Context
import android.content.Intent
import android.net.NetworkInfo
import android.net.wifi.WpsInfo
import android.net.wifi.p2p.WifiP2pGroup
import android.net.wifi.p2p.WifiP2pInfo
import android.net.wifi.p2p.WifiP2pManager
@@ -37,6 +38,18 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
* https://android.googlesource.com/platform/frameworks/base.git/+/220871a/core/java/android/net/NetworkInfo.java#415
*/
private val patternNetworkInfo = "^mNetworkInfo .* (isA|a)vailable: (true|false)".toPattern(Pattern.MULTILINE)
/**
* Available since Android 4.3.
*
* Source: https://android.googlesource.com/platform/frameworks/base/+/android-4.3_r0.9/wifi/java/android/net/wifi/p2p/WifiP2pManager.java#958
*/
private val startWpsMethod = WifiP2pManager::class.java.getDeclaredMethod("startWps",
WifiP2pManager.Channel::class.java, WpsInfo::class.java, WifiP2pManager.ActionListener::class.java)
private fun WifiP2pManager.startWps(c: WifiP2pManager.Channel, wps: WpsInfo,
listener: WifiP2pManager.ActionListener) {
startWpsMethod.invoke(this, c, wps, listener)
}
}
enum class Status {
@@ -46,6 +59,23 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
inner class HotspotBinder : Binder() {
val service get() = this@RepeaterService
var data: RepeaterFragment.Data? = null
val active get() = status == Status.ACTIVE
fun startWps(pin: String? = null) {
if (status != Status.ACTIVE) return
val wps = WpsInfo()
if (pin == null) wps.setup = WpsInfo.PBC else {
wps.setup = WpsInfo.KEYPAD
wps.pin = pin
}
p2pManager.startWps(channel, wps, object : WifiP2pManager.ActionListener {
override fun onSuccess() = Toast.makeText(this@RepeaterService,
if (pin == null) "Please use WPS push button within the next 2 minutes to connect your device."
else "PIN registered.", Toast.LENGTH_SHORT).show()
override fun onFailure(reason: Int) = Toast.makeText(this@RepeaterService,
"Failed to start WPS (reason: ${formatReason(reason)})", Toast.LENGTH_SHORT).show()
})
}
fun shutdown() {
if (status == Status.ACTIVE) removeGroup()