diff --git a/TODO.md b/TODO.md index 43d3ac85b..1bb2093d7 100644 --- a/TODO.md +++ b/TODO.md @@ -1,4 +1,6 @@ +* receive fake packets at power on to built initial state (for debugging, pretend there are a couple of nodes out there) +* learn our node number * test mesh service from activity * use android service from Signal * DONE handle failures in onCharWrite, instead of logAssert - because they can happen if device goes away diff --git a/app/src/main/java/com/geeksville/mesh/MeshService.kt b/app/src/main/java/com/geeksville/mesh/MeshService.kt index c82851d31..830b64f25 100644 --- a/app/src/main/java/com/geeksville/mesh/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/MeshService.kt @@ -11,6 +11,7 @@ import com.geeksville.mesh.MeshProtos.MeshPacket import com.geeksville.mesh.MeshProtos.ToRadio import com.geeksville.util.exceptionReporter import com.geeksville.util.exceptionsToStrings +import com.geeksville.util.toOneLineString import com.google.protobuf.ByteString import java.nio.charset.Charset @@ -131,7 +132,9 @@ class MeshService : Service(), Logging { nodeDBbyNodeNum.getOrPut(n) { -> NodeInfo(n) } /// Map a userid to a node/ node num, or throw an exception if not found - private fun toNodeInfo(id: String) = nodeDBbyID[id] ?: throw IdNotFoundException(id) + private fun toNodeInfo(id: String) = + nodeDBbyID[id] + ?: getOrCreateNodeInfo(10) // FIXME hack for now - throw IdNotFoundException(id) private fun toNodeNum(id: String) = toNodeInfo(id).num @@ -257,7 +260,7 @@ class MeshService : Service(), Logging { override fun onReceive(context: Context, intent: Intent) { val proto = MeshProtos.FromRadio.parseFrom(intent.getByteArrayExtra(EXTRA_PAYLOAD)!!) - info("Received from radio service: $proto") + info("Received from radio service: ${proto.toOneLineString()}") when (proto.variantCase.number) { MeshProtos.FromRadio.PACKET_FIELD_NUMBER -> handleReceivedMeshPacket(proto.packet) MeshProtos.FromRadio.NODE_INFO_FIELD_NUMBER -> handleReceivedNodeInfo(proto.nodeInfo) diff --git a/app/src/main/java/com/geeksville/mesh/RadioInterfaceService.kt b/app/src/main/java/com/geeksville/mesh/RadioInterfaceService.kt index 37a881c60..faa37e4d0 100644 --- a/app/src/main/java/com/geeksville/mesh/RadioInterfaceService.kt +++ b/app/src/main/java/com/geeksville/mesh/RadioInterfaceService.kt @@ -35,7 +35,7 @@ class RadioInterfaceService : JobIntentService(), Logging { * 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. */ @@ -55,6 +55,42 @@ class RadioInterfaceService : JobIntentService(), Logging { // for debug logging only private val jsonPrinter = JsonFormat.printer() + private val jsonParser = JsonFormat.parser() + + /** + * When simulating we parse these MeshPackets as if they arrived at startup + * Send broadcast them after we receive a ToRadio.WantNodes message. + * + * Our fake net has three nodes + * + * +16508675309, nodenum 9 - our node + * +16508675310, nodenum 10 - some other node, name Bob One/BO + * (eventually) +16508675311, nodenum 11 - some other node + */ + /* + +2020-01-25 11:02:05.279 1162-1280/com.geeksville.mesh D/com.geeksville.mesh.RadioInterfaceService: Executing work: Intent { act=com.geeksville.mesh.SEND_TORADIO (has extras) } +2020-01-25 11:02:05.282 1162-1273/com.geeksville.mesh D/EGL_emulation: eglMakeCurrent: 0xebb2b500: ver 2 0 (tinfo 0xc9748bc0) +2020-01-25 11:02:05.449 1162-1280/com.geeksville.mesh I/com.geeksville.mesh.RadioInterfaceService: TODO sending to radio: { "wantNodes": { } } +2020-01-25 11:02:05.452 1162-1280/com.geeksville.mesh D/com.geeksville.mesh.RadioInterfaceService: Executing work: Intent { act=com.geeksville.mesh.SEND_TORADIO (has extras) } +2020-01-25 11:02:05.479 1162-1280/com.geeksville.mesh I/com.geeksville.mesh.RadioInterfaceService: TODO sending to radio: { "setOwner": { "id": "+16508675309", "longName": "Kevin Xter", "shortName": "kx" } } +2020-01-25 11:02:05.480 1162-1280/com.geeksville.mesh D/com.geeksville.mesh.RadioInterfaceService: Executing work: Intent { act=com.geeksville.mesh.SEND_TORADIO (has extras) } +2020-01-25 11:02:05.504 1162-1280/com.geeksville.mesh I/com.geeksville.mesh.RadioInterfaceService: TODO sending to radio: { "packet": { "from": -1, "to": 10, "payload": { "subPackets": [{ "data": { "payload": "aGVsbG8gd29ybGQ=" } }] } } } +2020-01-25 11:02:05.505 1162-1280/com.geeksville.mesh D/com.geeksville.mesh.RadioInterfaceService: Executing work: Intent { act=com.geeksville.mesh.SEND_TORADIO (has extras) } +2020-01-25 11:02:05.510 1162-1280/com.geeksville.mesh I/com.geeksville.mesh.RadioInterfaceService: TODO sending to radio: { "packet": { "from": -1, "to": 10, "payload": { "subPackets": [{ "data": { "payload": "aGVsbG8gd29ybGQ=" } }] } } } +2020-01-25 11:02:08.232 1162-1273/com.geeksville.mesh D/EGL_emulation: eglMakeCurrent: 0xebb2b500: ver 2 0 (tinfo 0xc9748bc0) + + */ + val simInitPackets = + arrayOf( + """ { "from": 10, "to": 9, "payload": { "subPackets": [{ "user": { "id": "+16508675310", "longName": "Bob One", "shortName": "BO" }}]}} """, + """ { "from": 10, "to": 9, "payload": { "subPackets": [{ "data": { "payload": "aGVsbG8gd29ybGQ=", "typ": 0 }}]}} """, // SIGNAL_OPAQUE + """ { "from": 10, "to": 9, "payload": { "subPackets": [{ "data": { "payload": "aGVsbG8gd29ybGQ=", "typ": 1 }}]}} """, // CLEAR_TEXT + """ { "from": 10, "to": 9, "payload": { "subPackets": [{ "data": { "payload": "", "typ": 2 }}]}} """ // CLEAR_READACK + ) + + // FIXME, move into a subclass? + val isSimulating = true } lateinit var sentPacketsLog: DebugLogFile // inited in onCreate @@ -76,9 +112,21 @@ class RadioInterfaceService : JobIntentService(), Logging { // For debugging/logging purposes ONLY we convert back into a protobuf for readability val proto = MeshProtos.ToRadio.parseFrom(p) - info("TODO sending to radio: $proto") + val json = jsonPrinter.print(proto).replace('\n', ' ') + info("TODO sending to radio: $json") sentPacketsLog.log(json) + + if (isSimulating) + simInitPackets.forEach { json -> + val fromRadio = MeshProtos.FromRadio.newBuilder().apply { + packet = MeshProtos.MeshPacket.newBuilder().apply { + jsonParser.merge(json, this) + }.build() + }.build() + + broadcastReceivedFromRadio(fromRadio.toByteArray()) + } } // Handle an incoming packet from the radio, broadcasts it as an android intent