2323
2424local dbg = require " dbg"
2525local nixio = require " nixio"
26+ nixio .fs = require " nixio.fs"
2627local luci = require " luci"
2728luci .json = require " luci.json"
2829local uci = require " luci.model.uci" .cursor ()
@@ -48,10 +49,12 @@ local DEBUG = {
4849local DEVICE = uci :get_first (" system" , " system" , " device" )
4950local ULOOP_TIMEOUT_MS = 1e3
5051local O_RDWR_NONBLOCK = nixio .open_flags (" rdwr" , " nonblock" )
52+ local SLEEP_S , SLEEP_NS = 1 , 0
5153local TIMESTAMP_MIN = 1234567890
5254
5355local WW_STATISTICS_INFO_INTERVAL_S = 5
5456local WW_FLASH_CMD = " stm32flash -v -b 115200 -i 3,0,-0:-3,0,-0 -g 0x0 -w %s %s"
57+ local WW_UPGRADE_PATH = " /tmp/ww.hex"
5558
5659-- mosquitto client params
5760local MOSQ_ID = DAEMON
@@ -66,11 +69,22 @@ local MOSQ_QOS1 = 1
6669local MOSQ_RETAIN = true
6770local MOSQ_TOPIC_SENSOR_CONFIG = string.format (" /device/%s/config/sensor" , DEVICE )
6871local MOSQ_TOPIC_SENSOR = " /sensor/%s/%s"
72+ local MOSQ_TOPIC_WW_UPGRADE = " /device/%s/ww/upgrade"
73+
74+ local function merror (success , errno , err )
75+ -- TODO explicitely cancel the uloop on error
76+ if not success then error (MOSQ_ERROR :format (err )) end
77+ end
6978
7079-- connect to the MQTT broker
7180mosq .init ()
7281local mqtt = mosq .new (MOSQ_ID , MOSQ_CLN_SESSION )
73- mqtt :connect (MOSQ_HOST , MOSQ_PORT , MOSQ_KEEPALIVE )
82+ if not mqtt :connect (MOSQ_HOST , MOSQ_PORT , MOSQ_KEEPALIVE ) then
83+ repeat
84+ nixio .nanosleep (SLEEP_S , SLEEP_NS )
85+ until mqtt :reconnect ()
86+ end
87+ merror (mqtt :subscribe (MOSQ_TOPIC_WW_UPGRADE :format (DEVICE ), MOSQ_QOS0 ))
7488
7589local UART_DEV = " /dev/ttyS0"
7690local UART_BUFFER_SIZE = 4096
@@ -130,11 +144,11 @@ local UART_RX_ELEMENT = {
130144 event = " e_rx_embedded_system_status_update" ,
131145 fmt = " "
132146 },
133- [20 ] = { -- TODO
147+ [20 ] = {
134148 event = " e_rx_upgrade_confirm" ,
135149 fmt = " "
136150 },
137- [21 ] = { -- TODO
151+ [21 ] = {
138152 event = " e_rx_upgrade_reject" ,
139153 fmt = " "
140154 },
@@ -174,7 +188,7 @@ local UART_TX_ELEMENT = {
174188 typ = 15 ,
175189 fmt = " "
176190 },
177- upgrade_request = { -- TODO
191+ upgrade_request = {
178192 typ = 19 ,
179193 fmt = " "
180194 },
@@ -558,7 +572,7 @@ local sensor = {
558572}
559573
560574local ww = {
561- publish = function (self , elmnt )
575+ publish_version = function (self , elmnt )
562576 local data = { }
563577 vstruct .unpack (UART_RX_ELEMENT [elmnt .t ].fmt , elmnt .v , data )
564578 local topic = string.format (UART_RX_ELEMENT [elmnt .t ].topic , DEVICE )
@@ -657,7 +671,7 @@ local root = state {
657671
658672 version_info_response = state {
659673 entry = function ()
660- ww :publish (e_arg )
674+ ww :publish_version (e_arg )
661675 end
662676 },
663677
@@ -900,6 +914,23 @@ local event = {
900914 end
901915}
902916
917+ mqtt :set_callback (mosq .ON_MESSAGE , function (mid , topic , payload , qos , retain )
918+ if retain then return end
919+ nixio .fs .writefile (WW_UPGRADE_PATH , payload )
920+ event :process (" e_tx_upgrade_request" , {
921+ path = WW_UPGRADE_PATH ,
922+ fun = function () end
923+ })
924+ end )
925+
926+ local ufdr = uloop .fd (mqtt :socket (), uloop .READ , function (events )
927+ merror (mqtt :read (MOSQ_MAX_PKTS ))
928+ end )
929+
930+ local ufdw = uloop .fd (mqtt :socket (), uloop .WRITE , function (events )
931+ merror (mqtt :write (MOSQ_MAX_PKTS ))
932+ end )
933+
903934local ub_methods = {
904935 [" flukso.ww" ] = {
905936 debug = {
@@ -1016,9 +1047,7 @@ ut = uloop.timer(function()
10161047 event :process (" e_tx_statistics_info_request" )
10171048 end
10181049 -- service the mosquitto loop
1019- if not mqtt :loop (MOSQ_TIMEOUT , MOSQ_MAX_PKTS ) then
1020- mqtt :reconnect ()
1021- end
1050+ merror (mqtt :misc ())
10221051 end , ULOOP_TIMEOUT_MS )
10231052
10241053uart :flush ()
0 commit comments