Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 34 additions & 10 deletions app/src/main/java/com/geeksville/mesh/service/MeshService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ class MeshService : Service() {
private const val DEFAULT_HISTORY_RETURN_WINDOW_MINUTES = 60 * 24
private const val DEFAULT_HISTORY_RETURN_MAX_MESSAGES = 100
private const val MAX_EARLY_PACKET_BUFFER = 128
private const val PRECISE_POSITION_BITS = 32

@VisibleForTesting
internal fun buildStoreForwardHistoryRequest(
Expand Down Expand Up @@ -2506,24 +2507,47 @@ class MeshService : Service() {
override fun requestPosition(destNum: Int, position: Position) = toRemoteExceptions {
if (destNum != myNodeNum) {
val provideLocation = meshPrefs.shouldProvideNodeLocation(myNodeNum)
val channel = nodeDBbyNodeNum[destNum]?.channel ?: 0
val channelSettingsList = [email protected]
val precision = channelSettingsList.getOrNull(channel)?.moduleSettings?.positionPrecision ?: 0

// default meshPosition to empty in case precision is 0 and this channel is not supposed to
// broadcast positions
var meshPosition = position {}
val currentPosition =
when {
provideLocation && position.isValid() -> position
else -> nodeDBbyNodeNum[myNodeNum]?.position?.let { Position(it) }?.takeIf { it.isValid() }
}
if (currentPosition == null) {
Timber.d("Position request skipped - no valid position available")
return@toRemoteExceptions
}
val meshPosition = position {
latitudeI = Position.degI(currentPosition.latitude)
longitudeI = Position.degI(currentPosition.longitude)
altitude = currentPosition.altitude
time = currentSecond()

if (precision > 0 && currentPosition != null) {
var latitude = Position.degI(currentPosition.latitude)
var longitude = Position.degI(currentPosition.longitude)

// Precision offset replicated from meshtastic firmware
if (precision < PRECISE_POSITION_BITS) {
val mask = -1 shl (PRECISE_POSITION_BITS - precision)
latitude = latitude and mask
longitude = longitude and mask

// We want the imprecise position to be the middle of the possible location, not the edge.
val offset = 1 shl (PRECISE_POSITION_BITS - 1 - precision)
latitude += offset
longitude += offset
}

meshPosition = position {
latitudeI = latitude
longitudeI = longitude
altitude = currentPosition.altitude
time = currentSecond()
precisionBits = precision
}
}

packetHandler.sendToRadio(
newMeshPacketTo(destNum).buildMeshPacket(
channel = nodeDBbyNodeNum[destNum]?.channel ?: 0,
channel = channel,
priority = MeshPacket.Priority.BACKGROUND,
) {
portnumValue = Portnums.PortNum.POSITION_APP_VALUE
Expand Down