starting OTA without reconnecting the node, canceling OTA too… wow

This commit is contained in:
Laura Klünder 2023-12-01 16:39:27 +01:00
parent a3f763ad35
commit 0256c061ea
2 changed files with 30 additions and 1 deletions

View file

@ -16,7 +16,7 @@ from django.utils import timezone
from c3nav.mesh import messages
from c3nav.mesh.messages import (MESH_BROADCAST_ADDRESS, MESH_NONE_ADDRESS, MESH_ROOT_ADDRESS, OTA_CHUNK_SIZE,
MeshMessage, MeshMessageType, OTASettingMessage, OTAApplyMessage)
MeshMessage, MeshMessageType, OTAApplyMessage, OTASettingMessage)
from c3nav.mesh.models import MeshNode, MeshUplink, NodeMessage, OTARecipientStatus, OTAUpdate, OTAUpdateRecipient
from c3nav.mesh.utils import MESH_ALL_OTA_GROUP, MESH_ALL_UPLINKS_GROUP, UPLINK_PING, get_mesh_uplink_group
from c3nav.routing.rangelocator import RangeLocator
@ -176,6 +176,9 @@ class MeshConsumer(AsyncWebsocketConsumer):
# add signed in uplink node to broadcast group
await self.channel_layer.group_add(MESH_ALL_UPLINKS_GROUP, self.channel_name)
# OTA releases bluh bluh
await self.channel_layer.group_add(MESH_ALL_OTA_GROUP, self.channel_name)
# add this node as a destination that this uplink handles (duh)
await self.add_dst_nodes(nodes=(src_node, ))
self.dst_nodes[msg.src].last_msg[MeshMessageType.MESH_SIGNIN] = msg
@ -327,6 +330,14 @@ class MeshConsumer(AsyncWebsocketConsumer):
return
await self.send_msg(MeshMessage.fromjson(data["msg"]), data["sender"])
async def mesh_ota_recipients_changed(self, data):
addresses = set(data["addresses"]) - set(self.dst_nodes.keys())
print('recipients changed!')
if not addresses:
print('but none of ours')
return
await self.check_ota(addresses)
"""
helper functions
"""
@ -639,6 +650,16 @@ class MeshUIConsumer(AsyncJsonWebsocketConsumer):
update_id=recipient.update_id,
reboot=(ota == "reboot"),
).send()
elif ota == "cancel":
recipient.status = OTARecipientStatus.CANCELED
await recipient.send_status()
await OTAUpdateRecipient.objects.filter(pk=recipient.pk).aupdate(
status=OTARecipientStatus.CANCELED
)
self.channel_layer.group_send(MESH_ALL_OTA_GROUP, {
"type": "mesh.ota_recipients_changed",
"addresses": [recipient.node_id]
})
if "send_msg" in content:
msg_to_send = self.scope["session"].pop("mesh_msg_%s" % content["send_msg"], None)

View file

@ -5,6 +5,7 @@ from functools import cached_property
from itertools import chain
from typing import Any, Sequence
import channels
from asgiref.sync import async_to_sync
from django import forms
from django.core.exceptions import ValidationError
@ -17,6 +18,7 @@ from c3nav.mesh.dataformats import BoardConfig, BoardType, LedType, SerialLedTyp
from c3nav.mesh.messages import MESH_BROADCAST_ADDRESS, MESH_ROOT_ADDRESS, MeshMessage, MeshMessageType
from c3nav.mesh.models import (FirmwareBuild, HardwareDescription, MeshNode, OTARecipientStatus, OTAUpdate,
OTAUpdateRecipient)
from c3nav.mesh.utils import MESH_ALL_OTA_GROUP
class MeshMessageForm(forms.Form):
@ -380,6 +382,7 @@ class OTACreateForm(Form):
def save(self) -> list[OTAUpdate]:
updates = []
addresses = []
with transaction.atomic():
replaced_recipients = OTAUpdateRecipient.objects.filter(
node__in=chain(*self.selected_builds.values()),
@ -390,5 +393,10 @@ class OTACreateForm(Form):
update = OTAUpdate.objects.create(build=build)
for node in nodes:
update.recipients.create(node=node)
addresses.append(node.address)
updates.append(update)
async_to_sync(channels.layers.get_channel_layer().group_send)(MESH_ALL_OTA_GROUP, {
"type": "mesh.ota_recipients_changed",
"addresses": [addresses]
})
return updates