Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- ============================================
- -- == Utilities
- -- ============================================
- local function fileReadAll(filePath)
- local hFile = fs.open(filePath, "r")
- if nil == hFile then
- return nill
- end
- local txt = hFile.readAll()
- hFile.close()
- return txt
- end
- local function fileOverwrite(filePath, text)
- local hFile = fs.open(filePath, "w")
- hFile.writeLine(text)
- hFile.close()
- end
- local function saveFile(filePath, data)
- fileOverwrite(filePath, textutils.serialize(data))
- end
- local function loadFile(filePath)
- local dat = fileReadAll(filePath)
- if nil == dat then
- return nil
- end
- return textutils.unserialize(dat)
- end
- local function deleteWhenExists(filePath)
- if fs.exists(filePath) then
- fs.delete(filePath)
- end
- end
- local function startsWith(subject, keyword)
- if nil == subject then
- return false
- end
- if nil == keyword then
- return false
- end
- if string.len(subject) < string.len(keyword) then
- return false
- end
- if string.sub(subject, 1, string.len(keyword)) == keyword then
- return true
- else
- return false
- end
- end
- local function split(sbj, splitter)
- local rslt = { }
- local i = 0
- while true do
- local idx = string.find(sbj, splitter, i, true)
- if nil == idx then
- table.insert(rslt, string.sub(sbj, i))
- return rslt
- else
- table.insert(rslt, string.sub(sbj, i, idx - 1))
- i = idx + 1
- end
- end
- end
- LOG_FILE_NAME = "debug.log"
- local function debug(txt)
- print(txt)
- local hFile
- if fs.exists(LOG_FILE_NAME) then
- hFile = fs.open(LOG_FILE_NAME, "a")
- else
- hFile = fs.open(LOG_FILE_NAME, "w")
- end
- hFile.writeLine(txt)
- hFile.close()
- end
- local function splitCommand(line)
- local tmp = string.gsub(line, "[ ]+", "\t")
- return split(tmp, "\t")
- end
- -- ============================================
- -- == Configuration
- -- ============================================
- local APP_FILE_PATH = "/atupd5"
- local THE_CHANNEL = 3951
- local MSG_SIGNATURE = "kssr3951's network system"
- local BASE_DIRECTORY = "/network/"
- local STATUS_DIRECTORY = BASE_DIRECTORY .. "status" .. "/"
- local PING_DIRECTORY = BASE_DIRECTORY .. "ping" .. "/"
- local ROUTE_DIRECTORY = BASE_DIRECTORY .. "route" .. "/"
- local REBOOT_DIRECTORY = BASE_DIRECTORY .. "reboot" .. "/"
- local REBOOT_HISTORY_DIRECTORY = BASE_DIRECTORY .. "rebootHistory" .. "/"
- local LOG_DIRECTORY = BASE_DIRECTORY .. "logs" .. "/"
- local TASK_DIRECTORY = BASE_DIRECTORY .. "tasks" .. "/"
- local PING_DIRECTORY = BASE_DIRECTORY .. "ping" .. "/"
- local ROUTE_FILENAME = ROUTE_DIRECTORY .. "routeData"
- local PING_TIMEOUT = 1
- -- LOGGING
- LOG_FILE_NAME = LOG_DIRECTORY .. "debug.log"
- -- ============================================
- -- == Application Utilities
- -- ============================================
- local function serializeMessage(msg)
- return MSG_SIGNATURE .. textutils.serialize(msg)
- end
- local function unserializeMessage(msg)
- if false == startsWith(msg, MSG_SIGNATURE) then
- return nil
- else
- return textutils.unserialize(string.sub(msg, string.len(MSG_SIGNATURE) + 1))
- end
- end
- -- ============================================
- -- == Application Common
- -- ============================================
- local modems = { }
- local timers = { }
- local function setTimer(time, fileName)
- local timerId = os.startTimer(time)
- timers[timerId] = fileName
- end
- Timestamp = { }
- Timestamp.new = function()
- return
- {
- day = os.day(),
- time = os.time(),
- clock = os.clock()
- }
- end
- Timestamp.tostring = function(timestamp)
- return tostring(timestamp.day) .. "-"
- .. tostring(timestamp.time) .. "-"
- .. tostring(timestamp.clock)
- end
- Timestamp.doSort = function(directory, ascFlg)
- local list = fs.list(directory)
- local tmpList = { }
- for i, v in ipairs(list) do
- if not fs.isDir(v) then
- sp = split(v, "-")
- if 3 <= table.maxn(sp) then
- local elm = { }
- elm.day = sp[1]
- elm.time = sp[2]
- elm.clock = sp[3]
- elm.fileName = v
- table.insert(tmpList, elm)
- end
- end
- end
- if true == ascFlg then
- table.sort(tmpList, Timestamp.compareAscFunc)
- else
- table.sort(tmpList, Timestamp.compareDescFunc)
- end
- local rslt = { }
- for i, v in ipairs(tmpList) do
- table.insert(rslt, v.fileName)
- end
- return rslt
- end
- Timestamp.sortAscByTimestamp = function(directory)
- return Timestamp.doSort(directory, true)
- end
- Timestamp.sortDescByTimestamp = function(directory)
- return Timestamp.doSort(directory, false)
- end
- Timestamp.getNewestFile = function(directory)
- if not (fs.exists(directory) and fs.isDir(directory)) then
- return nil
- end
- local list = Timestamp.sortDescByTimestamp(directory)
- if 1 <= #list then
- return list[1]
- else
- return nil
- end
- end
- Timestamp.compareAscFunc = function(a, b)
- if a.day ~= b.day then
- return tonumber(a.day) < tonumber(b.day)
- elseif a.time ~= b.time then
- return tonumber(a.time) < tonumber(b.time)
- elseif a.clock ~= b.clock then
- return tonumber(a.clock) < tonumber(b.clock)
- end
- end
- Timestamp.compareDescFunc = function(a, b)
- if a.day ~= b.day then
- return tonumber(a.day) > tonumber(b.day)
- elseif a.time ~= b.time then
- return tonumber(a.time) > tonumber(b.time)
- elseif a.clock ~= b.clock then
- return tonumber(a.clock) > tonumber(b.clock)
- end
- end
- RouteInfo = { }
- RouteInfo.update = function(pingInfo)
- -- 自PCのping結果をrouteDataに変換して保存する
- -- 自PCに隣接しているPCのIDをappendListに追加する
- local myPing = Ping.loadLatestPingData(os.getComputerID())
- local routeData = { }
- local appendList = { }
- for key, val in pairs(myPing) do
- table.insert(appendList, { nodeId = key, stepCount = 2 })
- local tmpDat = { }
- for i, val2 in ipairs(val) do
- if nil == tmpDat[val2.side] then
- tmpDat[val2.side] = { }
- tmpDat[val2.side].multiplicity = 0
- tmpDat[val2.side].maxDistance = val2.distance
- tmpDat[val2.side].minDistance = val2.distance
- tmpDat[val2.side].stepCount = 1
- end
- tmpDat[val2.side].multiplicity = tmpDat[val2.side].multiplicity + 1
- tmpDat[val2.side].maxDistance = math.max(tmpDat[val2.side].maxDistance, val2.distance)
- tmpDat[val2.side].minDistance = math.min(tmpDat[val2.side].minDistance, val2.distance)
- end
- routeData[key] = tmpDat
- end
- -- appendListをループする
- for _, appendData in ipairs(appendList) do
- -- appendData.nodeIdに対応するping情報が有るか確認
- local baseDir2 = ROUTE_DIRECTORY .. tostring(appendData.nodeId) .. "/"
- local newest2 = Timestamp.getNewestFile(baseDir2)
- if nil == newest2 then
- -- 無い場合
- debug(" no ping data for " .. tostring(appendData.nodeId))
- else
- -- 有る場合
- -- appendData.nodeIdに対応するping情報をsbjPingにロード
- local sbjPing = loadFile(baseDir2 .. newest2)
- if nil ~= sbjPing then
- -- appendData.nodeIdに対応するrouteDataをループする
- for parentSide, parentData in pairs(routeData[appendData.nodeId]) do
- local parentPing = Ping.loadLatestPingData(appendData.nodeId)
- for sbjId, sbjDataList in pairs(sbjPing) do
- if sbjId == os.getComputerID() then
- else
- for _, sbjData in ipairs(sbjDataList) do
- if nil == routeData[sbjId] then
- table.insert(appendList, { nodeId = sbjId, stepCount = appendData.stepCount + 1 })
- routeData[sbjId] = { }
- end
- if nil == routeData[sbjId][parentSide] then
- routeData[sbjId][parentSide] = { }
- routeData[sbjId][parentSide].multiplicity = 0
- routeData[sbjId][parentSide].maxDistance = parentData.maxDistance + sbjData.distance
- routeData[sbjId][parentSide].minDistance = parentData.minDistance + sbjData.distance
- routeData[sbjId][parentSide].stepCount = appendData.stepCount
- end
- routeData[sbjId][parentSide].multiplicity = routeData[sbjId][parentSide].multiplicity + 1
- routeData[sbjId][parentSide].maxDistance = math.max(routeData[sbjId][parentSide].maxDistance, parentData.maxDistance + sbjData.distance)
- routeData[sbjId][parentSide].minDistance = math.min(routeData[sbjId][parentSide].minDistance, parentData.minDistance + sbjData.distance)
- end
- end
- end
- end
- end
- end
- end
- saveFile(ROUTE_FILENAME, routeData)
- end
- RouteInfo.findSide = function(targetId)
- local routeData = loadFile(ROUTE_FILENAME)
- if nil == routeData then
- return nil
- end
- if nil == routeData[targetId] then
- return nil
- else
- for key, val in pairs(routeData[targetId]) do
- return key -- とりあえず1件目を返す
- end
- end
- end
- RouteInfo.new = function(data)
- local this = { }
- return this
- end
- -- ==============================================
- -- CommonMessage
- -- ==============================================
- CommonMessage = {}
- CommonMessage.new = function(typeName)
- local rslt =
- {
- messageId,
- typeName = typeName,
- timestamp = Timestamp.new(),
- commanderId = "",
- targetId = "",
- reply = false,
- fileName,
- timeout = nil,
- senderId
- }
- rslt.fileName = CommonMessage.getFileName(rslt)
- return rslt
- end
- CommonMessage.getFileName = function(message)
- return Timestamp.tostring(message.timestamp) .. "-" .. message.typeName
- end
- -- ==============================================
- -- Ping
- -- ==============================================
- Ping = { }
- Ping.TYPE_NAME = "PING"
- Ping.loadLatestPingData = function(nodeId)
- local baseDir = ROUTE_DIRECTORY .. tostring(nodeId) .. "/"
- local newest = Timestamp.getNewestFile(baseDir)
- if nil == newest then
- return nil
- end
- return loadFile(baseDir .. newest)
- end
- Ping.savePingInfo = function(action, modemSide, senderDistance)
- local pingInfo = { }
- local pingFolder = ROUTE_DIRECTORY .. action.message.targetId .. "/"
- fs.makeDir(pingFolder)
- if fs.exists(pingFolder .. action.message.fileName) then
- pingInfo = loadFile(pingFolder .. action.message.fileName)
- end
- if nil == pingInfo[action.message.senderId] then
- pingInfo[action.message.senderId] = { }
- end
- local found = false
- for i, v in ipairs(pingInfo[action.message.senderId]) do
- if v.side == modemSide and v.distance == senderDistance then
- found = true
- break
- end
- end
- if not found then
- table.insert(pingInfo[action.message.senderId],
- { side = modemSide, distance = senderDistance, label = action.message.resultPCsLabel })
- end
- saveFile(pingFolder .. action.message.fileName, pingInfo)
- end
- Ping.isPingResultExists = function(action)
- local pingFolder = ROUTE_DIRECTORY .. action.message.targetId .. "/"
- if fs.exists(pingFolder .. action.message.fileName) then
- return true
- else
- return false
- end
- end
- Ping.savePingResult = function(action)
- local pingFolder = ROUTE_DIRECTORY .. action.message.targetId .. "/"
- fs.makeDir(pingFolder)
- fileOverwrite(pingFolder .. action.message.fileName, action.message.pingResult)
- end
- Ping.getPingResultSummary = function(pingResultData)
- local rslt = { }
- if nil == pingResultData then
- return rslt
- end
- for computerId, dataList in pairs(pingResultData) do
- for _, data in ipairs(dataList) do
- if nil == rslt[computerId] then
- rslt[computerId] = { }
- rslt[computerId].minDistance = data.distance
- rslt[computerId].maxDistance = data.distance
- rslt[computerId].label = data.label
- end
- rslt[computerId].minDistance = math.min(rslt[computerId].minDistance, data.distance)
- rslt[computerId].maxDistance = math.max(rslt[computerId].minDistance, data.distance)
- end
- end
- return rslt
- end
- Ping.outputPingResultSummary = function(pingResultData, debugFlg)
- local pingRslt = Ping.getPingResultSummary(pingResultData)
- if true == debugFlg then
- debug("ID distance label")
- else
- print("ID distance label")
- end
- for key, data in pairs(pingRslt) do
- if true == debugFlg then
- debug(key .. " " .. tostring(data.minDistance) .. " " .. tostring(data.label))
- else
- print(key .. " " .. tostring(data.minDistance) .. " " .. tostring(data.label))
- end
- end
- end
- Ping.debugPingResultSummary = function(pingResultData)
- Ping.outputPingResultSummary(pingResultData, true)
- end
- Ping.printPingResultSummary = function(pingResultData)
- Ping.outputPingResultSummary(pingResultData, false)
- end
- Ping.new = function(message)
- local obj = { }
- if nil ~= message then
- obj.message = message
- else
- obj.message = CommonMessage.new(Ping.TYPE_NAME)
- obj.message.mode = ""
- obj.message.pingResult = { }
- obj.message.senderDirection = ""
- obj.message.resultPCsLabel = ""
- end
- obj.OnReceive = function(self, modemSide, senderChannel, replyChannel, senderDistance)
- debug("[ping]OnReceive from " .. tostring(self.message.senderId))
- if "REQUEST" == self.message.mode then
- if self.message.senderId == self.message.targetId then
- self.message.mode = "REPLY"
- self.message.senderId = os.getComputerID()
- self.message.resultPCsLabel = os.getComputerLabel()
- --saveFile(TASK_DIRECTORY .. self.message.fileName, self.message)
- modems[modemSide].transmit(THE_CHANNEL, THE_CHANNEL, serializeMessage(self.message))
- end
- elseif "REPLY" == self.message.mode then
- if self.message.senderId ~= os.getComputerID() and self.message.targetId == os.getComputerID() then
- Ping.savePingInfo(self, modemSide, senderDistance)
- end
- elseif "RESULT" == self.message.mode then
- if not Ping.isPingResultExists(self) then
- if self.message.commanderId == os.getComputerID() and self.message.targetId ~= os.getComputerID() then
- -- ping結果がpingを発行したpcに帰ってきた場合
- Ping.printPingResultSummary(textutils.unserialize(self.message.pingResult))
- Ping.savePingResult(self)
- -- ping対象が自分以外の場合、ping結果が到着したタイミングでルート情報を再構築する
- RouteInfo.update()
- else
- local tmpMsg = loadFile(TASK_DIRECTORY .. self.message.fileName)
- if nil ~= tmpMsg and nil ~= tmpMsg.senderDirection then
- -- 行き(往路)でこのpcを通過していれば、保存されたメッセージのsenderDirectionを使ってcommanderのほうに返せるので送信する
- modems[tmpMsg.senderDirection].transmit(THE_CHANNEL, THE_CHANNEL, serializeMessage(self.message))
- end
- -- ping結果を中継するpcもping結果を保存し、ルート情報を再構築する
- Ping.savePingResult(self)
- RouteInfo.update()
- end
- end
- else
- if not fs.exists(TASK_DIRECTORY .. self.message.fileName) then
- self.message.senderDirection = modemSide
- saveFile(TASK_DIRECTORY .. self.message.fileName, self.message)
- if self.message.targetId == os.getComputerID() then
- -- このPCがping対象である場合
- setTimer(self.message.timeout, self.message.fileName)
- self.message.mode = "REQUEST"
- self.message.senderId = os.getComputerID()
- for _, mdm in pairs(modems) do
- mdm.transmit(THE_CHANNEL, THE_CHANNEL, serializeMessage(self.message))
- end
- else
- local side = RouteInfo.findSide(self.message.targetId)
- if nil ~= side then
- modems[side].transmit(THE_CHANNEL, THE_CHANNEL, serializeMessage(self.message))
- end
- end
- end
- end
- end
- obj.OnTimer = function(self)
- if self.message.commanderId ~= os.getComputerID() then
- self.message.mode = "RESULT"
- local pingFilePath = ROUTE_DIRECTORY .. self.message.targetId .. "/" .. self.message.fileName
- if fs.exists(pingFilePath) then
- self.message.pingResult = fileReadAll(pingFilePath)
- else
- self.message.pingResult = { }
- end
- -- 別PCからpingを指定された場合もルート情報をアップデート
- --RouteInfo.update()
- modems[self.message.senderDirection].transmit(THE_CHANNEL, THE_CHANNEL, serializeMessage(self.message))
- Ping.savePingResult(self)
- RouteInfo.update()
- else
- -- ping対象が自分の場合、タイムアウトのタイミングでルート情報を再構築する
- local tmpPingData = Ping.loadLatestPingData(os.getComputerID())
- Ping.printPingResultSummary(tmpPingData)
- RouteInfo.update()
- end
- end
- obj.OnReboot = function(self)
- end
- return obj
- end
- -- ==============================================
- -- SysUpdate
- -- ==============================================
- SysUpdate = { }
- SysUpdate.TYPE_NAME = "SYS_UPDATE"
- SysUpdate.new = function(message)
- local obj = { }
- if nil ~= message then
- obj.message = message
- else
- obj.message = CommonMessage.new(SysUpdate.TYPE_NAME)
- end
- obj.OnReceive = function(self, modemSide, senderChannel, replyChannel, senderDistance)
- if (self.message.commanderId == os.getComputerID()) or
- ("" == self.message.targetId or self.message.targetId == os.getComputerID()) then
- if not fs.exists(REBOOT_HISTORY_DIRECTORY .. self.message.fileName) then
- saveFile(STATUS_DIRECTORY .. "systemUpdateDate", tostring(self.message.timestamp.day) .. "-" .. tostring(self.message.timestamp.time))
- saveFile(REBOOT_DIRECTORY .. self.message.fileName, self.message)
- if self.message.commanderId ~= os.getComputerID() then
- fileOverwrite(self.message.appFileName, self.message.source)
- fileOverwrite("/startup", "shell.run(\"" .. self.message.appFileName .. "\")")
- end
- os.reboot()
- end
- end
- end
- obj.OnTimer = function(self)
- end
- obj.OnReboot = function(self)
- for _, mdm in pairs(modems) do
- mdm.transmit(THE_CHANNEL, THE_CHANNEL, serializeMessage(self.message))
- end
- fs.delete(REBOOT_HISTORY_DIRECTORY .. self.message.fileName)
- saveFile(REBOOT_HISTORY_DIRECTORY .. self.message.fileName, self.message)
- fs.delete(REBOOT_DIRECTORY .. self.message.fileName)
- end
- return obj
- end
- -- ==============================================
- -- loadAction
- -- ==============================================
- local function loadAction(msg)
- if Ping.TYPE_NAME == msg.typeName then
- return Ping.new(msg)
- elseif SysUpdate.TYPE_NAME == msg.typeName then
- return SysUpdate.new(msg)
- end
- end
- -- ============================================
- -- == Application
- -- ============================================
- local SIDES = { "top", "bottom", "left", "right", "front", "back" }
- local periodicTimer
- local function refreshModemInfo()
- local mdmCnt = 0
- for _, side in ipairs(SIDES) do
- if "modem" == peripheral.getType(side) then
- modems[side] = peripheral.wrap(side)
- modems[side].open(THE_CHANNEL)
- mdmCnt = mdmCnt + 1
- end
- end
- debug("modemCount = " .. tostring(mdmCnt))
- end
- local function printHeader()
- local timestamp = loadFile(STATUS_DIRECTORY .. "systemUpdateDate")
- debug("== =========================================")
- debug("== kssr3951's network component.(atupd5)")
- debug("== last update : " .. tostring(timestamp))
- debug("== computer ID : " .. os.getComputerID())
- debug("== =========================================")
- debug("waiting.")
- end
- local function send(action)
- if action.message.targetId == os.getComputerID() then
- action:OnReceive()
- end
- if action.message.targetId ~= os.getComputerID() then
- local side = RouteInfo.findSide(action.message.targetId)
- if nil ~= side then
- modems[side].transmit(THE_CHANNEL, THE_CHANNEL, serializeMessage(action.message))
- else
- debug("side for [" .. action.message.targetId .. "] is not found.")
- end
- end
- end
- -- ============================================
- -- == main
- -- ============================================
- local exitModemLoop
- local function timerAction(timerId)
- if periodicTimer == timerId then
- local cx, cy = term.getCursorPos()
- term.setCursorPos(1, 1)
- term.clearLine()
- term.write("[" .. os.day() .. "-" .. os.time() .. "]")
- term.setCursorPos(cx, cy)
- periodicTimer = os.startTimer(3)
- if true == exitModemLoop then
- return false
- end
- else
- local fileName = timers[timerId]
- if nil ~= fileName then
- local action = loadAction(loadFile(TASK_DIRECTORY .. fileName))
- if nil ~= action then
- action:OnTimer()
- end
- end
- end
- return true
- end
- local function modemAction(modemSide, senderChannel, replyChannel, msg, senderDistance)
- local text = unserializeMessage(msg)
- if nil == text then
- return
- else
- end
- local action = loadAction(text)
- action:OnReceive(modemSide, senderChannel, replyChannel, senderDistance)
- print("waiting.")
- end
- local function modemLoop()
- exitModemLoop = false
- periodicTimer = os.startTimer(3)
- while true do
- local event, r1, r2, r3, r4, r5 = os.pullEvent()
- if "modem_message" == event then
- modemAction(r1, r2, r3, r4, r5)
- elseif "timer" == event then
- local rslt = timerAction(r1, r2, r3, r4, r5)
- if false == rslt then
- break
- end
- end
- end
- end
- local function consoleLoop()
- print("*** admin mode ***")
- print("type 'exit' to back to normal mode.")
- print("type 'help' to know how to use.")
- while true do
- term.write("admin>")
- local args = splitCommand(read())
- local command
- if 1 <= #args then
- command = args[1]
- end
- if "exit" == command then
- exitModemLoop = true
- break
- elseif "help" == command then
- print("available commands are below.")
- print("exit help id ping refresh requestRoute sysUpdate")
- print("type 'help (command)' to know detail.")
- elseif "id" == command then
- print("this computer's id is " .. tostring(os.getComputerID()))
- elseif "ping" == command then
- -- non arguements -> ping(me)
- local p = Ping.new()
- p.message.commanderId = os.getComputerID()
- if 2 <= #args and nil ~= tonumber(args[2]) then
- p.message.targetId = tonumber(args[2])
- else
- p.message.targetId = os.getComputerID()
- end
- p.message.timeout = 1.0
- p.message.cacheDayCount = 0.5
- send(p)
- elseif "refresh" == command then
- refreshModemInfo()
- --elseif "requestRoute" == line then
- -- requestRoute(os.day() .. "-" .. os.time(), PING_TIMEOUT, nil)
- elseif "sysUpdate" == command then
- for cnt = 3, 1, -1 do
- term.write(tostring(cnt) .. " ")
- os.sleep(1)
- end
- local s = SysUpdate.new()
- s.message.commanderId = os.getComputerID()
- s.message.appFileName = APP_FILE_PATH
- s.message.source = fileReadAll(APP_FILE_PATH)
- s:OnReceive()
- elseif "label" == command then
- if 2 == #args and "get" == args[2] then
- local tmp = os.getComputerLabel()
- if nil ~= tmp then
- print(tmp)
- else
- print("")
- end
- elseif 3 == #args and "set" == args[2] then
- os.setComputerLabel(args[3])
- else
- print("Usages:")
- print("label get")
- print("label set <text>")
- end
- else
- print("no such command [" .. command .. "]")
- end
- end
- end
- local function rebootAction()
- local list = Timestamp.sortAscByTimestamp(REBOOT_DIRECTORY)
- for i, v in ipairs(list) do
- local action = loadAction(loadFile(REBOOT_DIRECTORY .. v))
- action:OnReboot()
- end
- end
- -- ============================================
- -- == main
- -- ============================================
- fileOverwrite("/startup", "shell.run(\"" .. APP_FILE_PATH .. "\")")
- fs.makeDir(STATUS_DIRECTORY)
- fs.makeDir(PING_DIRECTORY)
- fs.makeDir(ROUTE_DIRECTORY)
- fs.makeDir(REBOOT_DIRECTORY)
- fs.makeDir(TASK_DIRECTORY)
- fs.makeDir(PING_DIRECTORY)
- refreshModemInfo()
- rebootAction()
- printHeader()
- exitModemLoop = false
- periodicTimer = os.startTimer(3)
- while true do
- local event, r1, r2, r3, r4, r5 = os.pullEvent()
- if "modem_message" == event then
- modemAction(r1, r2, r3, r4, r5)
- elseif "timer" == event then
- timerAction(r1, r2, r3, r4, r5)
- elseif "key" == event then
- parallel.waitForAll(consoleLoop, modemLoop)
- print("=== normal mode ===")
- printHeader()
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement