mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
add beginnings of radio interface service
This commit is contained in:
parent
5c9696588e
commit
559795b796
9 changed files with 203 additions and 90 deletions
|
|
@ -1,42 +1,45 @@
|
|||
package com.geeksville.mesh
|
||||
|
||||
import android.app.Service
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.os.IBinder
|
||||
import com.geeksville.android.Logging
|
||||
|
||||
|
||||
/**
|
||||
* Handles all the communication with android apps. Also keeps an internal model
|
||||
* of the network state.
|
||||
*
|
||||
* Note: this service will go away once all clients are unbound from it.
|
||||
*/
|
||||
class MeshService : Service(), Logging {
|
||||
|
||||
companion object {
|
||||
const val prefix = "com.geeksville.mesh"
|
||||
}
|
||||
|
||||
/*
|
||||
see com.geeksville.mesh broadcast intents
|
||||
// RECEIVED_OPAQUE for data received from other nodes
|
||||
// NODE_CHANGE for new IDs appearing or disappearing
|
||||
// CONNECTION_CHANGED for losing/gaining connection to the packet radio
|
||||
*/
|
||||
|
||||
/**
|
||||
* The RECEIVED_OPAQUE:
|
||||
* Payload will be the raw bytes which were contained within a MeshPacket.Opaque field
|
||||
* Sender will be a user ID string
|
||||
*/
|
||||
fun broadcastReceivedOpaque(senderId: String, payload: ByteArray) {
|
||||
val intent = Intent("$prefix.RECEIVED_OPAQUE")
|
||||
intent.putExtra("$prefix.Sender", senderId)
|
||||
intent.putExtra("$prefix.Payload", payload)
|
||||
intent.putExtra(EXTRA_SENDER, senderId)
|
||||
intent.putExtra(EXTRA_PAYLOAD, payload)
|
||||
sendBroadcast(intent)
|
||||
}
|
||||
|
||||
fun broadcastNodeChange(nodeId: String, isOnline: Boolean) {
|
||||
val intent = Intent("$prefix.NODE_CHANGE")
|
||||
intent.putExtra("$prefix.Id", nodeId)
|
||||
intent.putExtra("$prefix.Online", isOnline)
|
||||
sendBroadcast(intent)
|
||||
}
|
||||
|
||||
fun broadcastConnectionChanged(isConnected: Boolean) {
|
||||
val intent = Intent("$prefix.CONNECTION_CHANGED")
|
||||
intent.putExtra("$prefix.Connected", isConnected)
|
||||
intent.putExtra(EXTRA_ID, nodeId)
|
||||
intent.putExtra(EXTRA_ONLINE, isOnline)
|
||||
sendBroadcast(intent)
|
||||
}
|
||||
|
||||
|
|
@ -45,6 +48,30 @@ class MeshService : Service(), Logging {
|
|||
return binder
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
||||
val filter = IntentFilter(RadioInterfaceService.RECEIVE_FROMRADIO_ACTION)
|
||||
registerReceiver(radioInterfaceReceiver, filter)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
unregisterReceiver(radioInterfaceReceiver)
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives messages from our BT radio service and processes them to update our model
|
||||
* and send to clients as needed.
|
||||
*/
|
||||
private val radioInterfaceReceiver = object : BroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
val proto = MeshProtos.FromRadio.parseFrom(intent.getByteArrayExtra(EXTRA_PAYLOAD)!!)
|
||||
TODO("FIXME - update model and send messages as needed")
|
||||
}
|
||||
}
|
||||
|
||||
private val binder = object : IMeshService.Stub() {
|
||||
override fun setOwner(myId: String, longName: String, shortName: String) {
|
||||
error("TODO setOwner $myId : $longName : $shortName")
|
||||
|
|
|
|||
|
|
@ -2,4 +2,7 @@ package com.geeksville.mesh
|
|||
|
||||
import com.geeksville.android.GeeksvilleApplication
|
||||
|
||||
class MeshUtilApplication : GeeksvilleApplication(null, "58e72ccc361883ea502510baa46580e3")
|
||||
const val prefix = "com.geeksville.mesh"
|
||||
|
||||
class MeshUtilApplication : GeeksvilleApplication(null, "58e72ccc361883ea502510baa46580e3") {
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
package com.geeksville.mesh
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.core.app.JobIntentService
|
||||
import com.geeksville.android.Logging
|
||||
|
||||
const val EXTRA_CONNECTED = "$prefix.Connected"
|
||||
const val EXTRA_PAYLOAD = "$prefix.Payload"
|
||||
const val EXTRA_SENDER = "$prefix.Sender"
|
||||
const val EXTRA_ID = "$prefix.Id"
|
||||
const val EXTRA_ONLINE = "$prefix.Online"
|
||||
|
||||
/**
|
||||
* Handles the bluetooth link with a mesh radio device. Does not cache any device state,
|
||||
* just does bluetooth comms etc...
|
||||
*
|
||||
* This service is not exposed outside of this process.
|
||||
*
|
||||
* Note - this class intentionally dumb. It doesn't understand protobuf framing etc...
|
||||
* It is designed to be simple so it can be stubbed out with a simulated version as needed.
|
||||
*/
|
||||
class RadioInterfaceService : JobIntentService(), Logging {
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Unique job ID for this service. Must be the same for all work.
|
||||
*/
|
||||
private const val JOB_ID = 1001
|
||||
|
||||
/**
|
||||
* The SEND_TORADIO
|
||||
* Payload will be the raw bytes which were contained within a MeshProtos.ToRadio protobuf
|
||||
*/
|
||||
const val SEND_TORADIO_ACTION = "$prefix.SEND_TORADIO"
|
||||
|
||||
/**
|
||||
* The RECEIVED_FROMRADIO
|
||||
* Payload will be the raw bytes which were contained within a MeshProtos.FromRadio protobuf
|
||||
*/
|
||||
const val RECEIVE_FROMRADIO_ACTION = "$prefix.RECEIVE_FROMRADIO"
|
||||
|
||||
|
||||
/**
|
||||
* Convenience method for enqueuing work in to this service.
|
||||
*/
|
||||
fun enqueueWork(context: Context, work: Intent) {
|
||||
enqueueWork(
|
||||
context,
|
||||
RadioInterfaceService::class.java, JOB_ID, work
|
||||
)
|
||||
}
|
||||
|
||||
/// Helper function to send a packet to the radio
|
||||
fun sendToRadio(context: Context, a: ByteArray) {
|
||||
val i = Intent(SEND_TORADIO_ACTION)
|
||||
i.putExtra(EXTRA_PAYLOAD, a)
|
||||
enqueueWork(context, i)
|
||||
}
|
||||
}
|
||||
|
||||
private fun broadcastReceivedFromRadio(payload: ByteArray) {
|
||||
val intent = Intent(RECEIVE_FROMRADIO_ACTION)
|
||||
intent.putExtra("$prefix.Payload", payload)
|
||||
sendBroadcast(intent)
|
||||
}
|
||||
|
||||
fun broadcastConnectionChanged(isConnected: Boolean) {
|
||||
val intent = Intent("$prefix.CONNECTION_CHANGED")
|
||||
intent.putExtra(EXTRA_CONNECTED, isConnected)
|
||||
sendBroadcast(intent)
|
||||
}
|
||||
|
||||
/// Send a packet/command out the radio link
|
||||
private fun sendToRadio(p: ByteArray) {
|
||||
info("Simulating sending to radio size=$p.size")
|
||||
}
|
||||
|
||||
// Handle an incoming packet from the radio, broadcasts it as an android intent
|
||||
private fun handleFromRadio(p: ByteArray) {
|
||||
broadcastReceivedFromRadio(p)
|
||||
}
|
||||
|
||||
override fun onHandleWork(intent: Intent) { // We have received work to do. The system or framework is already
|
||||
// holding a wake lock for us at this point, so we can just go.
|
||||
debug("Executing work: $intent")
|
||||
when (intent.action) {
|
||||
SEND_TORADIO_ACTION -> sendToRadio(intent.getByteArrayExtra(EXTRA_PAYLOAD)!!)
|
||||
else -> TODO("Unhandled case")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -10,10 +10,7 @@ import android.bluetooth.le.ScanResult
|
|||
import android.bluetooth.le.ScanSettings
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Handler
|
||||
import android.os.ParcelUuid
|
||||
import android.os.SystemClock
|
||||
import android.widget.Toast
|
||||
import androidx.core.app.JobIntentService
|
||||
import com.geeksville.android.Logging
|
||||
import java.util.*
|
||||
|
|
@ -184,19 +181,7 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
connectToTestDevice() // FIXME, pass in as an intent arg instead
|
||||
startUpdate()
|
||||
}
|
||||
else -> logAssert(false)
|
||||
}
|
||||
|
||||
debug(
|
||||
"Completed service @ " + SystemClock.elapsedRealtime()
|
||||
)
|
||||
}
|
||||
|
||||
val mHandler = Handler()
|
||||
// Helper for showing tests
|
||||
fun toast(text: CharSequence?) {
|
||||
mHandler.post {
|
||||
Toast.makeText(this@SoftwareUpdateService, text, Toast.LENGTH_SHORT).show()
|
||||
else -> TODO("Unhandled case")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -204,10 +189,10 @@ class SoftwareUpdateService : JobIntentService(), Logging {
|
|||
/**
|
||||
* Unique job ID for this service. Must be the same for all work.
|
||||
*/
|
||||
const val JOB_ID = 1000
|
||||
private const val JOB_ID = 1000
|
||||
|
||||
val scanDevicesIntent = Intent("com.geeksville.com.geeeksville.mesh.SCAN_DEVICES")
|
||||
val startUpdateIntent = Intent("com.geeksville.com.geeeksville.mesh.START_UPDATE")
|
||||
val scanDevicesIntent = Intent("$prefix.SCAN_DEVICES")
|
||||
val startUpdateIntent = Intent("$prefix.START_UPDATE")
|
||||
|
||||
private const val SCAN_PERIOD: Long = 10000
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue