1919set -u
2020
2121# # Set version for each Production Release ##
22- readonly SCRIPT_VERSION=1.6.8
23- readonly SCRIPT_VERSTAG=" 26090718 "
22+ readonly SCRIPT_VERSION=1.6.9
23+ readonly SCRIPT_VERSTAG=" 26091601 "
2424readonly SCRIPT_NAME=" MerlinAU"
2525# # Set to "master" for Production Releases ##
26- SCRIPT_BRANCH=" master "
26+ SCRIPT_BRANCH=" dev "
2727
2828# #----------------------------------------##
2929# # Modified by Martinski W. [2024-Jul-03] ##
@@ -4335,7 +4335,7 @@ _ReEnableAsusTrendMicroProcesses_()
43354335}
43364336
43374337# #------------------------------------------##
4338- # # Modified by ExtremeFiretop [2024-Jan-26 ] ##
4338+ # # Modified by ExtremeFiretop [2025-Sep-16 ] ##
43394339# #------------------------------------------##
43404340_DoCleanUp_ ()
43414341{
@@ -4353,6 +4353,10 @@ _DoCleanUp_()
43534353 [ $# -gt 1 ] && [ " $2 " -eq 1 ] && keepZIPfile=true
43544354 [ $# -gt 2 ] && [ " $3 " -eq 1 ] && keepWfile=true
43554355
4356+ # Clear the volatile F/W-update guard used by AiMesh primaries. #
4357+ # This value is intentionally never committed to NVRAM. #
4358+ nvram unset merlinau_fw_update 2> /dev/null
4359+
43564360 # Stop the LEDs blinking #
43574361 _Reset_LEDs_ 1
43584362
@@ -5429,9 +5433,9 @@ _DoMeshNodeLogin_()
54295433 return " $? "
54305434}
54315435
5432- # #----------------------------------------##
5433- # # Modified by Martinski W. [2026-Jan-01 ] ##
5434- # #----------------------------------------##
5436+ # #------------------------------------------ ##
5437+ # # Modified by ExtremeFiretop [2026-Sep-16 ] ##
5438+ # #------------------------------------------ ##
54355439# Trigger the node "Check for updates" (no waiting here)
54365440_MeshNodeTriggerFWCheck_ ()
54375441{
@@ -5443,6 +5447,7 @@ _MeshNodeTriggerFWCheck_()
54435447 local safeID=" $( _MeshSafeID_ " $nodeIPv4addr " ) "
54445448 local nodeURL=" $( _GetNodeURL_ " $nodeIPv4addr " ) "
54455449 local cookieFile=" /tmp/${runID} .${safeID} .cookie"
5450+ local nodeBusy nodeBusyRC
54465451
54475452 # Check for Login Credentials #
54485453 credsENC=" $( Get_Custom_Setting credentials_base64) "
@@ -5463,6 +5468,30 @@ _MeshNodeTriggerFWCheck_()
54635468 return 1
54645469 fi
54655470
5471+ # Check if the AiMesh node is already performing a MerlinAU F/W update
5472+ # before triggering the built-in firmware update check.
5473+ nodeBusy=" $( curl -s -k " ${nodeURL} /appGet.cgi?hook=nvram_get(merlinau_fw_update)" \
5474+ -H ' User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' \
5475+ -H ' Accept: application/json,text/plain,*/*' \
5476+ -H ' Accept-Language: en-US,en;q=0.5' \
5477+ -H ' Connection: keep-alive' \
5478+ -H " Referer: ${nodeURL} /index.asp" \
5479+ --cookie " $cookieFile " \
5480+ --max-time 2 2> /dev/null) "
5481+ nodeBusyRC=" $? "
5482+
5483+ if [ " $nodeBusyRC " -eq 0 ] && echo " $nodeBusy " | grep -Eq ' "merlinau_fw_update"[[:space:]]*:[[:space:]]*"1"'
5484+ then
5485+ Say " AiMesh Node [$nodeIPv4addr ] entered an active MerlinAU F/W update before start_webs_update. Skipping firmware check."
5486+
5487+ # Best-effort logout of this primary-router session, then remove its cookie.
5488+ curl -s -k " ${nodeURL} /Logout.asp" \
5489+ --cookie " $cookieFile " \
5490+ --max-time 2 > /dev/null 2>&1
5491+ rm -f " $cookieFile "
5492+ return 0
5493+ fi
5494+
54665495 # Trigger firmware check (mimic WebUI "Check" button) #
54675496 curl -s -k " ${nodeURL} /start_apply.htm" \
54685497 --referer " ${nodeURL} /Advanced_FirmwareUpgrade_Content.asp" \
@@ -9755,11 +9784,15 @@ _Unmount_Eject_USB_Drives_()
97559784 " $ejectUSB_OK " && return 0 || return 1
97569785}
97579786
9758- # #----------------------------------------##
9759- # # Modified by Martinski W. [2026-Jan-01 ] ##
9760- # #----------------------------------------##
9787+ # #------------------------------------------ ##
9788+ # # Modified by ExtremeFiretop [2026-Sep-16 ] ##
9789+ # #------------------------------------------ ##
97619790_RunFirmwareUpdateNow_ ()
97629791{
9792+ local fwUploadResponseFile=" /tmp/upload_response.txt"
9793+ local fwUploadDiagFile=" ${SETTINGS_DIR} /last_fw_upload_response.txt"
9794+ local curlRC=0 uploadHTTPcode=" "
9795+
97639796 # Double-check the directory exists before using it #
97649797 [ ! -d " $FW_LOG_DIR " ] && mkdir -p -m 755 " $FW_LOG_DIR "
97659798
@@ -10219,6 +10252,15 @@ Please manually update to version ${GRNct}${MinSupportedFirmwareVers}${NOct} or
1021910252 fi
1022010253 fi
1022110254
10255+ # ------------------------------------------------------------------------#
10256+ # A volatile guard before restarting/logging into the WebGUI.
10257+ # Primary routers running MerlinAU can query this nvram value with appGet.cgi
10258+ # and avoid triggering start_webs_update on this router mid-flash.
10259+ # Do not commit this value since a reboot should clear it automatically.
10260+ # ------------------------------------------------------------------------#
10261+ nvram set merlinau_fw_update=1
10262+ rm -f " $fwUploadResponseFile " " $fwUploadDiagFile "
10263+
1022210264 # ------------------------------------------------------------#
1022310265 # Restart the WebGUI to make sure nobody else is logged in
1022410266 # so that the F/W Update can start without interruptions.
@@ -10311,7 +10353,8 @@ Please manually update to version ${GRNct}${MinSupportedFirmwareVers}${NOct} or
1031110353 Say " Flashing ${GRNct}${firmware_file}${NOct} ...\n${REDct} Please wait for reboot in about 4 minutes or less.${NOct} "
1031210354 echo
1031310355
10314- # *WARNING*: NO MORE logging at this point & beyond #
10356+ # Avoid persistent logging from this point during the normal flash path. #
10357+ # Failure diagnostics are written only if the router does not reboot. #
1031510358 sync ; sleep 2 ; echo 3 > /proc/sys/vm/drop_caches ; sleep 3
1031610359
1031710360 # #-------------------------------------##
@@ -10327,7 +10370,7 @@ Please manually update to version ${GRNct}${MinSupportedFirmwareVers}${NOct} or
1032710370 # the following 'Curl' command MUST always be the last step in this block.
1032810371 # Do NOT insert any commands after it! (unless you understand the implications).
1032910372 # ----------------------------------------------------------------------------------#
10330- nohup curl -k " ${routerURL} /upgrade.cgi" \
10373+ nohup curl -sS - k " ${routerURL} /upgrade.cgi" \
1033110374 --referer " ${routerURL} /Advanced_FirmwareUpgrade_Content.asp" \
1033210375 --user-agent ' Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' \
1033310376 -H ' Accept-Language: en-US,en;q=0.5' \
@@ -10340,7 +10383,9 @@ Please manually update to version ${GRNct}${MinSupportedFirmwareVers}${NOct} or
1034010383 -F ' preferred_lang=EN' \
1034110384 -F " firmver=${dottedVersion} " \
1034210385 -F " file=@${firmware_file} " \
10343- --cookie " $cookieFile " > /tmp/upload_response.txt 2>&1 &
10386+ --cookie " $cookieFile " \
10387+ --write-out ' \nMERLINAU_HTTP_CODE:%{http_code}\n' \
10388+ > " $fwUploadResponseFile " 2>&1 &
1034410389 curlPID=$!
1034510390
1034610391 # ----------------------------------------------------------#
@@ -10356,16 +10401,40 @@ Please manually update to version ${GRNct}${MinSupportedFirmwareVers}${NOct} or
1035610401 sleep 180
1035710402 if [ " $curlPID " -gt 0 ]
1035810403 then
10359- kill -EXIT $curlPID 2> /dev/null || return
10360- kill -TERM $curlPID 2> /dev/null
10404+ kill -EXIT " $curlPID " 2> /dev/null || return
10405+ kill -TERM " $curlPID " 2> /dev/null
1036110406 fi
1036210407 ) &
10363- wait $curlPID ; curlPID=0
10408+
10409+ # Preserve Curl's actual result instead of discarding it. #
10410+ wait " $curlPID "
10411+ curlRC=$?
10412+ curlPID=0
10413+ uploadHTTPcode=" $( sed -n ' s/^MERLINAU_HTTP_CODE://p' " $fwUploadResponseFile " 2> /dev/null | tail -n 1) "
10414+
1036410415 # ----------------------------------------------------------#
1036510416 # Let's wait for 3 minutes here. If the router does not
10366- # reboot by itself after the process returns, do it now.
10417+ # reboot by itself after the process returns,
10418+ # preserve any diagnostics then reboot.
10419+ # A successful flash reboots before this step.
1036710420 # ----------------------------------------------------------#
1036810421 sleep 180
10422+
10423+ {
10424+ echo " MerlinAU v$SCRIPT_VERSION firmware upload diagnostics"
10425+ echo " Timestamp: $( date ' +%Y-%m-%d %H:%M:%S %Z' ) "
10426+ echo " Router: $MODEL_ID "
10427+ echo " Firmware image: $firmware_file "
10428+ echo " Curl exit code: $curlRC "
10429+ echo " HTTP status: ${uploadHTTPcode:- UNKNOWN} "
10430+ echo " ------------------------------------------------------------"
10431+ [ -s " $fwUploadResponseFile " ] && cat " $fwUploadResponseFile "
10432+ } > " $fwUploadDiagFile " 2> /dev/null
10433+ chmod 600 " $fwUploadDiagFile " 2> /dev/null
10434+
10435+ _MsgToSysLog_ " F/W upload did not cause the router to reboot within 180 seconds. Curl exit code [$curlRC ], HTTP status [${uploadHTTPcode:- UNKNOWN} ]."
10436+ _MsgToSysLog_ " F/W upload diagnostics saved to [$fwUploadDiagFile ]."
10437+
1036910438 _ReleaseLock_
1037010439 /sbin/service reboot
1037110440 else
0 commit comments